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);
1211 /*-----------------------------------------------------------------*/
1212 /* popGetImmd - asm operator to pcode immediate conversion */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1217 return newpCodeOpImmd(name, offset,index, 0, is_func);
1221 /*-----------------------------------------------------------------*/
1222 /* popGet - asm operator to pcode operator conversion */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetWithString(char *str, int isExtern)
1230 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1234 pcop = newpCodeOp(str,PO_STR);
1235 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1240 /*-----------------------------------------------------------------*/
1241 /* popRegFromString - */
1242 /*-----------------------------------------------------------------*/
1243 pCodeOp *popRegFromString(char *str, int size, int offset)
1246 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1247 pcop->type = PO_DIR;
1249 DEBUGpic14_emitcode(";","%d",__LINE__);
1254 pcop->name = Safe_calloc(1,strlen(str)+1);
1255 strcpy(pcop->name,str);
1257 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1259 PCOR(pcop)->r = dirregWithName(pcop->name);
1260 if(PCOR(pcop)->r == NULL) {
1261 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1262 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1263 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1265 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1267 PCOR(pcop)->instance = offset;
1272 /*-----------------------------------------------------------------*/
1273 /*-----------------------------------------------------------------*/
1274 pCodeOp *popRegFromIdx(int rIdx)
1278 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1279 __FUNCTION__,__LINE__,rIdx);
1281 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1283 PCOR(pcop)->rIdx = rIdx;
1284 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1285 PCOR(pcop)->r->isFree = 0;
1286 PCOR(pcop)->r->wasUsed = 1;
1288 pcop->type = PCOR(pcop)->r->pc_type;
1294 /*-----------------------------------------------------------------*/
1295 /* popGet - asm operator to pcode operator conversion */
1296 /*-----------------------------------------------------------------*/
1297 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1299 //char *s = buffer ;
1304 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1305 /* offset is greater than
1308 if (offset > (aop->size - 1) &&
1309 aop->type != AOP_LIT)
1310 return NULL; //zero;
1312 /* depending on type */
1313 switch (aop->type) {
1320 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1324 DEBUGpic14_emitcode(";","%d",__LINE__);
1325 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1328 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1330 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1331 pcop->type = PO_DIR;
1335 sprintf(s,"(%s + %d)",
1339 sprintf(s,"%s",aop->aopu.aop_dir);
1340 pcop->name = Safe_calloc(1,strlen(s)+1);
1341 strcpy(pcop->name,s);
1343 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1344 strcpy(pcop->name,aop->aopu.aop_dir);
1345 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1346 if(PCOR(pcop)->r == NULL) {
1347 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1348 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1349 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1351 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1353 PCOR(pcop)->instance = offset;
1360 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1362 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1363 PCOR(pcop)->rIdx = rIdx;
1364 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1365 PCOR(pcop)->r->wasUsed=1;
1366 PCOR(pcop)->r->isFree=0;
1368 PCOR(pcop)->instance = offset;
1369 pcop->type = PCOR(pcop)->r->pc_type;
1370 //rs = aop->aopu.aop_reg[offset]->name;
1371 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1376 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1377 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1378 //if(PCOR(pcop)->r == NULL)
1379 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1383 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1386 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1387 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1389 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1390 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1391 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1392 pcop->type = PCOR(pcop)->r->pc_type;
1393 pcop->name = PCOR(pcop)->r->name;
1399 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1401 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1402 pcop = pCodeOpCopy(aop->aopu.pcop);
1403 PCOI(pcop)->offset = offset;
1407 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1408 "popGet got unsupported aop->type");
1411 /*-----------------------------------------------------------------*/
1412 /* aopPut - puts a string for a aop */
1413 /*-----------------------------------------------------------------*/
1414 void aopPut (asmop *aop, char *s, int offset)
1419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1421 if (aop->size && offset > ( aop->size - 1)) {
1422 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1423 "aopPut got offset > aop->size");
1427 /* will assign value to value */
1428 /* depending on where it is ofcourse */
1429 switch (aop->type) {
1432 sprintf(d,"(%s + %d)",
1433 aop->aopu.aop_dir,offset);
1434 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1437 sprintf(d,"%s",aop->aopu.aop_dir);
1440 DEBUGpic14_emitcode(";","%d",__LINE__);
1442 pic14_emitcode("movf","%s,w",s);
1443 pic14_emitcode("movwf","%s",d);
1446 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1447 if(offset >= aop->size) {
1448 emitpcode(POC_CLRF,popGet(aop,offset));
1451 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1454 emitpcode(POC_MOVWF,popGet(aop,offset));
1461 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1462 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1465 strcmp(s,"r0") == 0 ||
1466 strcmp(s,"r1") == 0 ||
1467 strcmp(s,"r2") == 0 ||
1468 strcmp(s,"r3") == 0 ||
1469 strcmp(s,"r4") == 0 ||
1470 strcmp(s,"r5") == 0 ||
1471 strcmp(s,"r6") == 0 ||
1472 strcmp(s,"r7") == 0 )
1473 pic14_emitcode("mov","%s,%s ; %d",
1474 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1478 if(strcmp(s,"W")==0 )
1479 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1481 pic14_emitcode("movwf","%s",
1482 aop->aopu.aop_reg[offset]->name);
1484 if(strcmp(s,zero)==0) {
1485 emitpcode(POC_CLRF,popGet(aop,offset));
1487 } else if(strcmp(s,"W")==0) {
1488 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1489 pcop->type = PO_GPR_REGISTER;
1491 PCOR(pcop)->rIdx = -1;
1492 PCOR(pcop)->r = NULL;
1494 DEBUGpic14_emitcode(";","%d",__LINE__);
1495 pcop->name = Safe_strdup(s);
1496 emitpcode(POC_MOVFW,pcop);
1497 emitpcode(POC_MOVWF,popGet(aop,offset));
1498 } else if(strcmp(s,one)==0) {
1499 emitpcode(POC_CLRF,popGet(aop,offset));
1500 emitpcode(POC_INCF,popGet(aop,offset));
1502 emitpcode(POC_MOVWF,popGet(aop,offset));
1510 if (aop->type == AOP_DPTR2)
1516 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1517 "aopPut writting to code space");
1521 while (offset > aop->coff) {
1523 pic14_emitcode ("inc","dptr");
1526 while (offset < aop->coff) {
1528 pic14_emitcode("lcall","__decdptr");
1533 /* if not in accumulater */
1536 pic14_emitcode ("movx","@dptr,a");
1538 if (aop->type == AOP_DPTR2)
1546 while (offset > aop->coff) {
1548 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1550 while (offset < aop->coff) {
1552 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1558 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1563 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1565 if (strcmp(s,"r0") == 0 ||
1566 strcmp(s,"r1") == 0 ||
1567 strcmp(s,"r2") == 0 ||
1568 strcmp(s,"r3") == 0 ||
1569 strcmp(s,"r4") == 0 ||
1570 strcmp(s,"r5") == 0 ||
1571 strcmp(s,"r6") == 0 ||
1572 strcmp(s,"r7") == 0 ) {
1574 sprintf(buffer,"a%s",s);
1575 pic14_emitcode("mov","@%s,%s",
1576 aop->aopu.aop_ptr->name,buffer);
1578 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1583 if (strcmp(s,"a") == 0)
1584 pic14_emitcode("push","acc");
1586 pic14_emitcode("push","%s",s);
1591 /* if bit variable */
1592 if (!aop->aopu.aop_dir) {
1593 pic14_emitcode("clr","a");
1594 pic14_emitcode("rlc","a");
1597 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1600 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1603 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1605 lbl = newiTempLabel(NULL);
1607 if (strcmp(s,"a")) {
1610 pic14_emitcode("clr","c");
1611 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1612 pic14_emitcode("cpl","c");
1613 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1614 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1621 if (strcmp(aop->aopu.aop_str[offset],s))
1622 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1627 if (!offset && (strcmp(s,"acc") == 0))
1630 if (strcmp(aop->aopu.aop_str[offset],s))
1631 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1635 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1636 "aopPut got unsupported aop->type");
1642 /*-----------------------------------------------------------------*/
1643 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1644 /*-----------------------------------------------------------------*/
1645 void mov2w (asmop *aop, int offset)
1651 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1653 if ( aop->type == AOP_PCODE ||
1654 aop->type == AOP_LIT ||
1655 aop->type == AOP_IMMD )
1656 emitpcode(POC_MOVLW,popGet(aop,offset));
1658 emitpcode(POC_MOVFW,popGet(aop,offset));
1662 /*-----------------------------------------------------------------*/
1663 /* reAdjustPreg - points a register back to where it should */
1664 /*-----------------------------------------------------------------*/
1665 static void reAdjustPreg (asmop *aop)
1669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1671 if ((size = aop->size) <= 1)
1674 switch (aop->type) {
1678 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1682 if (aop->type == AOP_DPTR2)
1688 pic14_emitcode("lcall","__decdptr");
1691 if (aop->type == AOP_DPTR2)
1703 /*-----------------------------------------------------------------*/
1704 /* opIsGptr: returns non-zero if the passed operand is */
1705 /* a generic pointer type. */
1706 /*-----------------------------------------------------------------*/
1707 static int opIsGptr(operand *op)
1709 sym_link *type = operandType(op);
1711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1712 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1720 /*-----------------------------------------------------------------*/
1721 /* pic14_getDataSize - get the operand data size */
1722 /*-----------------------------------------------------------------*/
1723 int pic14_getDataSize(operand *op)
1725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1728 return AOP_SIZE(op);
1730 // tsd- in the pic port, the genptr size is 1, so this code here
1731 // fails. ( in the 8051 port, the size was 4).
1734 size = AOP_SIZE(op);
1735 if (size == GPTRSIZE)
1737 sym_link *type = operandType(op);
1738 if (IS_GENPTR(type))
1740 /* generic pointer; arithmetic operations
1741 * should ignore the high byte (pointer type).
1744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1751 /*-----------------------------------------------------------------*/
1752 /* pic14_outAcc - output Acc */
1753 /*-----------------------------------------------------------------*/
1754 void pic14_outAcc(operand *result)
1757 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1758 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1761 size = pic14_getDataSize(result);
1763 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1766 /* unsigned or positive */
1768 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1773 /*-----------------------------------------------------------------*/
1774 /* pic14_outBitC - output a bit C */
1775 /*-----------------------------------------------------------------*/
1776 void pic14_outBitC(operand *result)
1779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1780 /* if the result is bit */
1781 if (AOP_TYPE(result) == AOP_CRY)
1782 aopPut(AOP(result),"c",0);
1784 pic14_emitcode("clr","a ; %d", __LINE__);
1785 pic14_emitcode("rlc","a");
1786 pic14_outAcc(result);
1790 /*-----------------------------------------------------------------*/
1791 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1792 /*-----------------------------------------------------------------*/
1793 void pic14_toBoolean(operand *oper)
1795 int size = AOP_SIZE(oper) - 1;
1798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1800 if ( AOP_TYPE(oper) != AOP_ACC) {
1801 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1804 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1809 /*-----------------------------------------------------------------*/
1810 /* genNot - generate code for ! operation */
1811 /*-----------------------------------------------------------------*/
1812 static void genNot (iCode *ic)
1817 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1818 /* assign asmOps to operand & result */
1819 aopOp (IC_LEFT(ic),ic,FALSE);
1820 aopOp (IC_RESULT(ic),ic,TRUE);
1822 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1823 /* if in bit space then a special case */
1824 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1825 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1826 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1827 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1829 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1830 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1831 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1836 size = AOP_SIZE(IC_LEFT(ic));
1838 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1839 emitpcode(POC_ANDLW,popGetLit(1));
1840 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1843 pic14_toBoolean(IC_LEFT(ic));
1845 tlbl = newiTempLabel(NULL);
1846 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1847 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1848 pic14_outBitC(IC_RESULT(ic));
1851 /* release the aops */
1852 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1853 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1857 /*-----------------------------------------------------------------*/
1858 /* genCpl - generate code for complement */
1859 /*-----------------------------------------------------------------*/
1860 static void genCpl (iCode *ic)
1862 operand *left, *result;
1866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1867 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1868 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1870 /* if both are in bit space then
1872 if (AOP_TYPE(result) == AOP_CRY &&
1873 AOP_TYPE(left) == AOP_CRY ) {
1875 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1876 pic14_emitcode("cpl","c");
1877 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1881 size = AOP_SIZE(result);
1884 if(AOP_TYPE(left) == AOP_ACC)
1885 emitpcode(POC_XORLW, popGetLit(0xff));
1887 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1889 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1895 /* release the aops */
1896 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1897 freeAsmop(result,NULL,ic,TRUE);
1900 /*-----------------------------------------------------------------*/
1901 /* genUminusFloat - unary minus for floating points */
1902 /*-----------------------------------------------------------------*/
1903 static void genUminusFloat(operand *op,operand *result)
1905 int size ,offset =0 ;
1908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1909 /* for this we just need to flip the
1910 first it then copy the rest in place */
1911 size = AOP_SIZE(op) - 1;
1912 l = aopGet(AOP(op),3,FALSE,FALSE);
1916 pic14_emitcode("cpl","acc.7");
1917 aopPut(AOP(result),"a",3);
1921 aopGet(AOP(op),offset,FALSE,FALSE),
1927 /*-----------------------------------------------------------------*/
1928 /* genUminus - unary minus code generation */
1929 /*-----------------------------------------------------------------*/
1930 static void genUminus (iCode *ic)
1933 sym_link *optype, *rtype;
1936 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1938 aopOp(IC_LEFT(ic),ic,FALSE);
1939 aopOp(IC_RESULT(ic),ic,TRUE);
1941 /* if both in bit space then special
1943 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1944 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1946 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1947 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1948 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1953 optype = operandType(IC_LEFT(ic));
1954 rtype = operandType(IC_RESULT(ic));
1956 /* if float then do float stuff */
1957 if (IS_FLOAT(optype)) {
1958 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1962 /* otherwise subtract from zero by taking the 2's complement */
1963 size = AOP_SIZE(IC_LEFT(ic));
1965 for(i=0; i<size; i++) {
1966 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1967 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1969 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1970 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1974 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1975 for(i=1; i<size; i++) {
1977 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1981 /* release the aops */
1982 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1983 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1986 /*-----------------------------------------------------------------*/
1987 /* saveRegisters - will look for a call and save the registers */
1988 /*-----------------------------------------------------------------*/
1989 static void saveRegisters(iCode *lic)
1996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1998 for (ic = lic ; ic ; ic = ic->next)
1999 if (ic->op == CALL || ic->op == PCALL)
2003 fprintf(stderr,"found parameter push with no function call\n");
2007 /* if the registers have been saved already then
2009 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2012 /* find the registers in use at this time
2013 and push them away to safety */
2014 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2018 if (options.useXstack) {
2019 if (bitVectBitValue(rsave,R0_IDX))
2020 pic14_emitcode("mov","b,r0");
2021 pic14_emitcode("mov","r0,%s",spname);
2022 for (i = 0 ; i < pic14_nRegs ; i++) {
2023 if (bitVectBitValue(rsave,i)) {
2025 pic14_emitcode("mov","a,b");
2027 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2028 pic14_emitcode("movx","@r0,a");
2029 pic14_emitcode("inc","r0");
2032 pic14_emitcode("mov","%s,r0",spname);
2033 if (bitVectBitValue(rsave,R0_IDX))
2034 pic14_emitcode("mov","r0,b");
2036 //for (i = 0 ; i < pic14_nRegs ; i++) {
2037 // if (bitVectBitValue(rsave,i))
2038 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2041 dtype = operandType(IC_LEFT(ic));
2042 if (currFunc && dtype &&
2043 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2044 IFFUNC_ISISR(currFunc->type) &&
2047 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2050 /*-----------------------------------------------------------------*/
2051 /* unsaveRegisters - pop the pushed registers */
2052 /*-----------------------------------------------------------------*/
2053 static void unsaveRegisters (iCode *ic)
2058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2059 /* find the registers in use at this time
2060 and push them away to safety */
2061 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2064 if (options.useXstack) {
2065 pic14_emitcode("mov","r0,%s",spname);
2066 for (i = pic14_nRegs ; i >= 0 ; i--) {
2067 if (bitVectBitValue(rsave,i)) {
2068 pic14_emitcode("dec","r0");
2069 pic14_emitcode("movx","a,@r0");
2071 pic14_emitcode("mov","b,a");
2073 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2077 pic14_emitcode("mov","%s,r0",spname);
2078 if (bitVectBitValue(rsave,R0_IDX))
2079 pic14_emitcode("mov","r0,b");
2081 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2082 // if (bitVectBitValue(rsave,i))
2083 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2089 /*-----------------------------------------------------------------*/
2091 /*-----------------------------------------------------------------*/
2092 static void pushSide(operand * oper, int size)
2096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2098 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2099 if (AOP_TYPE(oper) != AOP_REG &&
2100 AOP_TYPE(oper) != AOP_DIR &&
2102 pic14_emitcode("mov","a,%s",l);
2103 pic14_emitcode("push","acc");
2105 pic14_emitcode("push","%s",l);
2110 /*-----------------------------------------------------------------*/
2111 /* assignResultValue - */
2112 /*-----------------------------------------------------------------*/
2113 static void assignResultValue(operand * oper)
2115 int size = AOP_SIZE(oper);
2117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2119 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2122 if (GpsuedoStkPtr++)
2123 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2124 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2129 /*-----------------------------------------------------------------*/
2130 /* genIpush - genrate code for pushing this gets a little complex */
2131 /*-----------------------------------------------------------------*/
2132 static void genIpush (iCode *ic)
2135 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2137 int size, offset = 0 ;
2141 /* if this is not a parm push : ie. it is spill push
2142 and spill push is always done on the local stack */
2143 if (!ic->parmPush) {
2145 /* and the item is spilt then do nothing */
2146 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2149 aopOp(IC_LEFT(ic),ic,FALSE);
2150 size = AOP_SIZE(IC_LEFT(ic));
2151 /* push it on the stack */
2153 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2158 pic14_emitcode("push","%s",l);
2163 /* this is a paramter push: in this case we call
2164 the routine to find the call and save those
2165 registers that need to be saved */
2168 /* then do the push */
2169 aopOp(IC_LEFT(ic),ic,FALSE);
2172 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2173 size = AOP_SIZE(IC_LEFT(ic));
2176 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2177 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2178 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2180 pic14_emitcode("mov","a,%s",l);
2181 pic14_emitcode("push","acc");
2183 pic14_emitcode("push","%s",l);
2186 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2190 /*-----------------------------------------------------------------*/
2191 /* genIpop - recover the registers: can happen only for spilling */
2192 /*-----------------------------------------------------------------*/
2193 static void genIpop (iCode *ic)
2195 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2200 /* if the temp was not pushed then */
2201 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2204 aopOp(IC_LEFT(ic),ic,FALSE);
2205 size = AOP_SIZE(IC_LEFT(ic));
2208 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2211 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2215 /*-----------------------------------------------------------------*/
2216 /* unsaverbank - restores the resgister bank from stack */
2217 /*-----------------------------------------------------------------*/
2218 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2220 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2228 if (options.useXstack) {
2230 r = getFreePtr(ic,&aop,FALSE);
2233 pic14_emitcode("mov","%s,_spx",r->name);
2234 pic14_emitcode("movx","a,@%s",r->name);
2235 pic14_emitcode("mov","psw,a");
2236 pic14_emitcode("dec","%s",r->name);
2239 pic14_emitcode ("pop","psw");
2242 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2243 if (options.useXstack) {
2244 pic14_emitcode("movx","a,@%s",r->name);
2245 //pic14_emitcode("mov","(%s+%d),a",
2246 // regspic14[i].base,8*bank+regspic14[i].offset);
2247 pic14_emitcode("dec","%s",r->name);
2250 pic14_emitcode("pop",""); //"(%s+%d)",
2251 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2254 if (options.useXstack) {
2256 pic14_emitcode("mov","_spx,%s",r->name);
2257 freeAsmop(NULL,aop,ic,TRUE);
2263 /*-----------------------------------------------------------------*/
2264 /* saverbank - saves an entire register bank on the stack */
2265 /*-----------------------------------------------------------------*/
2266 static void saverbank (int bank, iCode *ic, bool pushPsw)
2268 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2275 if (options.useXstack) {
2278 r = getFreePtr(ic,&aop,FALSE);
2279 pic14_emitcode("mov","%s,_spx",r->name);
2283 for (i = 0 ; i < pic14_nRegs ;i++) {
2284 if (options.useXstack) {
2285 pic14_emitcode("inc","%s",r->name);
2286 //pic14_emitcode("mov","a,(%s+%d)",
2287 // regspic14[i].base,8*bank+regspic14[i].offset);
2288 pic14_emitcode("movx","@%s,a",r->name);
2290 pic14_emitcode("push","");// "(%s+%d)",
2291 //regspic14[i].base,8*bank+regspic14[i].offset);
2295 if (options.useXstack) {
2296 pic14_emitcode("mov","a,psw");
2297 pic14_emitcode("movx","@%s,a",r->name);
2298 pic14_emitcode("inc","%s",r->name);
2299 pic14_emitcode("mov","_spx,%s",r->name);
2300 freeAsmop (NULL,aop,ic,TRUE);
2303 pic14_emitcode("push","psw");
2305 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2311 /*-----------------------------------------------------------------*/
2312 /* genCall - generates a call statement */
2313 /*-----------------------------------------------------------------*/
2314 static void genCall (iCode *ic)
2318 unsigned char *name;
2321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2323 /* if caller saves & we have not saved then */
2327 /* if we are calling a function that is not using
2328 the same register bank then we need to save the
2329 destination registers on the stack */
2330 dtype = operandType(IC_LEFT(ic));
2331 if (currFunc && dtype &&
2332 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2333 IFFUNC_ISISR(currFunc->type) &&
2336 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2338 /* if send set is not empty the assign */
2341 /* For the Pic port, there is no data stack.
2342 * So parameters passed to functions are stored
2343 * in registers. (The pCode optimizer will get
2344 * rid of most of these :).
2346 int psuedoStkPtr=-1;
2347 int firstTimeThruLoop = 1;
2349 _G.sendSet = reverseSet(_G.sendSet);
2351 /* First figure how many parameters are getting passed */
2352 for (sic = setFirstItem(_G.sendSet) ; sic ;
2353 sic = setNextItem(_G.sendSet)) {
2355 aopOp(IC_LEFT(sic),sic,FALSE);
2356 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2357 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2360 for (sic = setFirstItem(_G.sendSet) ; sic ;
2361 sic = setNextItem(_G.sendSet)) {
2362 int size, offset = 0;
2364 aopOp(IC_LEFT(sic),sic,FALSE);
2365 size = AOP_SIZE(IC_LEFT(sic));
2368 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2369 AopType(AOP_TYPE(IC_LEFT(sic))));
2371 if(!firstTimeThruLoop) {
2372 /* If this is not the first time we've been through the loop
2373 * then we need to save the parameter in a temporary
2374 * register. The last byte of the last parameter is
2376 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2379 firstTimeThruLoop=0;
2381 mov2w (AOP(IC_LEFT(sic)), offset);
2384 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2389 sym = OP_SYMBOL(IC_LEFT(ic));
2390 name = sym->rname[0] ? sym->rname : sym->name;
2391 isExtern = IS_EXTERN(sym->etype);
2393 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2395 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2397 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2400 /* if we need assign a result value */
2401 if ((IS_ITEMP(IC_RESULT(ic)) &&
2402 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2403 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2404 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2407 aopOp(IC_RESULT(ic),ic,FALSE);
2410 assignResultValue(IC_RESULT(ic));
2412 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2413 AopType(AOP_TYPE(IC_RESULT(ic))));
2415 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2418 /* adjust the stack for parameters if
2420 if (ic->parmBytes) {
2422 if (ic->parmBytes > 3) {
2423 pic14_emitcode("mov","a,%s",spname);
2424 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2425 pic14_emitcode("mov","%s,a",spname);
2427 for ( i = 0 ; i < ic->parmBytes ;i++)
2428 pic14_emitcode("dec","%s",spname);
2432 /* if register bank was saved then pop them */
2434 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2436 /* if we hade saved some registers then unsave them */
2437 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2438 unsaveRegisters (ic);
2443 /*-----------------------------------------------------------------*/
2444 /* genPcall - generates a call by pointer statement */
2445 /*-----------------------------------------------------------------*/
2446 static void genPcall (iCode *ic)
2449 symbol *albl = newiTempLabel(NULL);
2450 symbol *blbl = newiTempLabel(NULL);
2455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2456 /* if caller saves & we have not saved then */
2460 /* if we are calling a function that is not using
2461 the same register bank then we need to save the
2462 destination registers on the stack */
2463 dtype = operandType(IC_LEFT(ic));
2464 if (currFunc && dtype &&
2465 IFFUNC_ISISR(currFunc->type) &&
2466 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2467 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2470 aopOp(left,ic,FALSE);
2471 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2473 pushSide(IC_LEFT(ic), FPTRSIZE);
2475 /* if send set is not empty, assign parameters */
2478 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2479 /* no way to pass args - W always gets used to make the call */
2481 /* first idea - factor out a common helper function and call it.
2482 But don't know how to get it generated only once in its own block
2484 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2487 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2488 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2489 buffer = Safe_calloc(1,strlen(rname)+16);
2490 sprintf(buffer, "%s_goto_helper", rname);
2491 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2495 emitpcode(POC_CALL,popGetLabel(albl->key));
2496 pcop = popGetLabel(blbl->key);
2497 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2498 emitpcode(POC_GOTO,pcop);
2499 emitpLabel(albl->key);
2501 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2503 emitpcode(poc,popGet(AOP(left),1));
2504 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2505 emitpcode(poc,popGet(AOP(left),0));
2506 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2508 emitpLabel(blbl->key);
2510 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2512 /* if we need to assign a result value */
2513 if ((IS_ITEMP(IC_RESULT(ic)) &&
2514 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2515 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2516 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2519 aopOp(IC_RESULT(ic),ic,FALSE);
2522 assignResultValue(IC_RESULT(ic));
2524 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2527 /* if register bank was saved then unsave them */
2528 if (currFunc && dtype &&
2529 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2530 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2532 /* if we hade saved some registers then
2535 unsaveRegisters (ic);
2539 /*-----------------------------------------------------------------*/
2540 /* resultRemat - result is rematerializable */
2541 /*-----------------------------------------------------------------*/
2542 static int resultRemat (iCode *ic)
2544 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2545 if (SKIP_IC(ic) || ic->op == IFX)
2548 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2549 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2550 if (sym->remat && !POINTER_SET(ic))
2557 #if defined(__BORLANDC__) || defined(_MSC_VER)
2558 #define STRCASECMP stricmp
2560 #define STRCASECMP strcasecmp
2564 /*-----------------------------------------------------------------*/
2565 /* inExcludeList - return 1 if the string is in exclude Reg list */
2566 /*-----------------------------------------------------------------*/
2567 static bool inExcludeList(char *s)
2569 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2573 if (options.excludeRegs[i] &&
2574 STRCASECMP(options.excludeRegs[i],"none") == 0)
2577 for ( i = 0 ; options.excludeRegs[i]; i++) {
2578 if (options.excludeRegs[i] &&
2579 STRCASECMP(s,options.excludeRegs[i]) == 0)
2586 /*-----------------------------------------------------------------*/
2587 /* genFunction - generated code for function entry */
2588 /*-----------------------------------------------------------------*/
2589 static void genFunction (iCode *ic)
2594 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2596 labelOffset += (max_key+4);
2600 /* create the function header */
2601 pic14_emitcode(";","-----------------------------------------");
2602 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2603 pic14_emitcode(";","-----------------------------------------");
2605 pic14_emitcode("","%s:",sym->rname);
2606 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2608 ftype = operandType(IC_LEFT(ic));
2610 /* if critical function then turn interrupts off */
2611 if (IFFUNC_ISCRITICAL(ftype))
2612 pic14_emitcode("clr","ea");
2614 /* here we need to generate the equates for the
2615 register bank if required */
2617 if (FUNC_REGBANK(ftype) != rbank) {
2620 rbank = FUNC_REGBANK(ftype);
2621 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2622 if (strcmp(regspic14[i].base,"0") == 0)
2623 pic14_emitcode("","%s = 0x%02x",
2625 8*rbank+regspic14[i].offset);
2627 pic14_emitcode ("","%s = %s + 0x%02x",
2630 8*rbank+regspic14[i].offset);
2635 /* if this is an interrupt service routine */
2636 if (IFFUNC_ISISR(sym->type)) {
2637 /* already done in pic14createInterruptVect() - delete me
2638 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2639 emitpcodeNULLop(POC_NOP);
2640 emitpcodeNULLop(POC_NOP);
2641 emitpcodeNULLop(POC_NOP);
2643 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2644 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2645 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2646 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2647 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2648 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2649 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2651 pBlockConvert2ISR(pb);
2653 if (!inExcludeList("acc"))
2654 pic14_emitcode ("push","acc");
2655 if (!inExcludeList("b"))
2656 pic14_emitcode ("push","b");
2657 if (!inExcludeList("dpl"))
2658 pic14_emitcode ("push","dpl");
2659 if (!inExcludeList("dph"))
2660 pic14_emitcode ("push","dph");
2661 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2663 pic14_emitcode ("push", "dpx");
2664 /* Make sure we're using standard DPTR */
2665 pic14_emitcode ("push", "dps");
2666 pic14_emitcode ("mov", "dps, #0x00");
2667 if (options.stack10bit)
2669 /* This ISR could conceivably use DPTR2. Better save it. */
2670 pic14_emitcode ("push", "dpl1");
2671 pic14_emitcode ("push", "dph1");
2672 pic14_emitcode ("push", "dpx1");
2675 /* if this isr has no bank i.e. is going to
2676 run with bank 0 , then we need to save more
2678 if (!FUNC_REGBANK(sym->type)) {
2680 /* if this function does not call any other
2681 function then we can be economical and
2682 save only those registers that are used */
2683 if (! IFFUNC_HASFCALL(sym->type)) {
2686 /* if any registers used */
2687 if (sym->regsUsed) {
2688 /* save the registers used */
2689 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2690 if (bitVectBitValue(sym->regsUsed,i) ||
2691 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2692 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2697 /* this function has a function call cannot
2698 determines register usage so we will have the
2700 saverbank(0,ic,FALSE);
2705 /* if callee-save to be used for this function
2706 then save the registers being used in this function */
2707 if (IFFUNC_CALLEESAVES(sym->type)) {
2710 /* if any registers used */
2711 if (sym->regsUsed) {
2712 /* save the registers used */
2713 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2714 if (bitVectBitValue(sym->regsUsed,i) ||
2715 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2716 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2724 /* set the register bank to the desired value */
2725 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2726 pic14_emitcode("push","psw");
2727 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2730 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2732 if (options.useXstack) {
2733 pic14_emitcode("mov","r0,%s",spname);
2734 pic14_emitcode("mov","a,_bp");
2735 pic14_emitcode("movx","@r0,a");
2736 pic14_emitcode("inc","%s",spname);
2740 /* set up the stack */
2741 pic14_emitcode ("push","_bp"); /* save the callers stack */
2743 pic14_emitcode ("mov","_bp,%s",spname);
2746 /* adjust the stack for the function */
2751 werror(W_STACK_OVERFLOW,sym->name);
2753 if (i > 3 && sym->recvSize < 4) {
2755 pic14_emitcode ("mov","a,sp");
2756 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2757 pic14_emitcode ("mov","sp,a");
2762 pic14_emitcode("inc","sp");
2767 pic14_emitcode ("mov","a,_spx");
2768 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2769 pic14_emitcode ("mov","_spx,a");
2774 /*-----------------------------------------------------------------*/
2775 /* genEndFunction - generates epilogue for functions */
2776 /*-----------------------------------------------------------------*/
2777 static void genEndFunction (iCode *ic)
2779 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2783 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2785 pic14_emitcode ("mov","%s,_bp",spname);
2788 /* if use external stack but some variables were
2789 added to the local stack then decrement the
2791 if (options.useXstack && sym->stack) {
2792 pic14_emitcode("mov","a,sp");
2793 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2794 pic14_emitcode("mov","sp,a");
2798 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2799 if (options.useXstack) {
2800 pic14_emitcode("mov","r0,%s",spname);
2801 pic14_emitcode("movx","a,@r0");
2802 pic14_emitcode("mov","_bp,a");
2803 pic14_emitcode("dec","%s",spname);
2807 pic14_emitcode ("pop","_bp");
2811 /* restore the register bank */
2812 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2813 pic14_emitcode ("pop","psw");
2815 if (IFFUNC_ISISR(sym->type)) {
2817 /* now we need to restore the registers */
2818 /* if this isr has no bank i.e. is going to
2819 run with bank 0 , then we need to save more
2821 if (!FUNC_REGBANK(sym->type)) {
2823 /* if this function does not call any other
2824 function then we can be economical and
2825 save only those registers that are used */
2826 if (! IFFUNC_HASFCALL(sym->type)) {
2829 /* if any registers used */
2830 if (sym->regsUsed) {
2831 /* save the registers used */
2832 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2833 if (bitVectBitValue(sym->regsUsed,i) ||
2834 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2835 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2840 /* this function has a function call cannot
2841 determines register usage so we will have the
2843 unsaverbank(0,ic,FALSE);
2847 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2849 if (options.stack10bit)
2851 pic14_emitcode ("pop", "dpx1");
2852 pic14_emitcode ("pop", "dph1");
2853 pic14_emitcode ("pop", "dpl1");
2855 pic14_emitcode ("pop", "dps");
2856 pic14_emitcode ("pop", "dpx");
2858 if (!inExcludeList("dph"))
2859 pic14_emitcode ("pop","dph");
2860 if (!inExcludeList("dpl"))
2861 pic14_emitcode ("pop","dpl");
2862 if (!inExcludeList("b"))
2863 pic14_emitcode ("pop","b");
2864 if (!inExcludeList("acc"))
2865 pic14_emitcode ("pop","acc");
2867 if (IFFUNC_ISCRITICAL(sym->type))
2868 pic14_emitcode("setb","ea");
2871 /* if debug then send end of function */
2872 /* if (options.debug && currFunc) { */
2875 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2876 FileBaseName(ic->filename),currFunc->lastLine,
2877 ic->level,ic->block);
2878 if (IS_STATIC(currFunc->etype))
2879 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2881 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2885 pic14_emitcode ("reti","");
2886 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2887 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2888 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2889 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2890 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2891 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2892 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2893 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2894 emitpcodeNULLop(POC_RETFIE);
2897 if (IFFUNC_ISCRITICAL(sym->type))
2898 pic14_emitcode("setb","ea");
2900 if (IFFUNC_CALLEESAVES(sym->type)) {
2903 /* if any registers used */
2904 if (sym->regsUsed) {
2905 /* save the registers used */
2906 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2907 if (bitVectBitValue(sym->regsUsed,i) ||
2908 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2909 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2915 /* if debug then send end of function */
2918 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2919 FileBaseName(ic->filename),currFunc->lastLine,
2920 ic->level,ic->block);
2921 if (IS_STATIC(currFunc->etype))
2922 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2924 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2928 pic14_emitcode ("return","");
2929 emitpcodeNULLop(POC_RETURN);
2931 /* Mark the end of a function */
2932 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2937 /*-----------------------------------------------------------------*/
2938 /* genRet - generate code for return statement */
2939 /*-----------------------------------------------------------------*/
2940 static void genRet (iCode *ic)
2942 int size,offset = 0 , pushed = 0;
2944 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2945 /* if we have no return value then
2946 just generate the "ret" */
2950 /* we have something to return then
2951 move the return value into place */
2952 aopOp(IC_LEFT(ic),ic,FALSE);
2953 size = AOP_SIZE(IC_LEFT(ic));
2957 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2959 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2961 pic14_emitcode("push","%s",l);
2964 l = aopGet(AOP(IC_LEFT(ic)),offset,
2966 if (strcmp(fReturn[offset],l)) {
2967 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2968 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2969 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2970 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2971 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2973 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2976 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2986 if (strcmp(fReturn[pushed],"a"))
2987 pic14_emitcode("pop",fReturn[pushed]);
2989 pic14_emitcode("pop","acc");
2992 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2995 /* generate a jump to the return label
2996 if the next is not the return statement */
2997 if (!(ic->next && ic->next->op == LABEL &&
2998 IC_LABEL(ic->next) == returnLabel)) {
3000 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3001 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3006 /*-----------------------------------------------------------------*/
3007 /* genLabel - generates a label */
3008 /*-----------------------------------------------------------------*/
3009 static void genLabel (iCode *ic)
3011 /* special case never generate */
3012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3013 if (IC_LABEL(ic) == entryLabel)
3016 emitpLabel(IC_LABEL(ic)->key);
3017 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3020 /*-----------------------------------------------------------------*/
3021 /* genGoto - generates a goto */
3022 /*-----------------------------------------------------------------*/
3024 static void genGoto (iCode *ic)
3026 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3027 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3031 /*-----------------------------------------------------------------*/
3032 /* genMultbits :- multiplication of bits */
3033 /*-----------------------------------------------------------------*/
3034 static void genMultbits (operand *left,
3038 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3040 if(!pic14_sameRegs(AOP(result),AOP(right)))
3041 emitpcode(POC_BSF, popGet(AOP(result),0));
3043 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3044 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3045 emitpcode(POC_BCF, popGet(AOP(result),0));
3050 /*-----------------------------------------------------------------*/
3051 /* genMultOneByte : 8 bit multiplication & division */
3052 /*-----------------------------------------------------------------*/
3053 static void genMultOneByte (operand *left,
3057 sym_link *opetype = operandType(result);
3062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3063 DEBUGpic14_AopType(__LINE__,left,right,result);
3064 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3066 /* (if two literals, the value is computed before) */
3067 /* if one literal, literal on the right */
3068 if (AOP_TYPE(left) == AOP_LIT){
3074 size = AOP_SIZE(result);
3077 if (AOP_TYPE(right) == AOP_LIT){
3078 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3079 aopGet(AOP(right),0,FALSE,FALSE),
3080 aopGet(AOP(left),0,FALSE,FALSE),
3081 aopGet(AOP(result),0,FALSE,FALSE));
3082 pic14_emitcode("call","genMultLit");
3084 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3085 aopGet(AOP(right),0,FALSE,FALSE),
3086 aopGet(AOP(left),0,FALSE,FALSE),
3087 aopGet(AOP(result),0,FALSE,FALSE));
3088 pic14_emitcode("call","genMult8X8_8");
3091 genMult8X8_8 (left, right,result);
3094 /* signed or unsigned */
3095 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3096 //l = aopGet(AOP(left),0,FALSE,FALSE);
3098 //pic14_emitcode("mul","ab");
3099 /* if result size = 1, mul signed = mul unsigned */
3100 //aopPut(AOP(result),"a",0);
3102 } else { // (size > 1)
3104 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3105 aopGet(AOP(right),0,FALSE,FALSE),
3106 aopGet(AOP(left),0,FALSE,FALSE),
3107 aopGet(AOP(result),0,FALSE,FALSE));
3109 if (SPEC_USIGN(opetype)){
3110 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3111 genUMult8X8_16 (left, right, result, NULL);
3114 /* for filling the MSBs */
3115 emitpcode(POC_CLRF, popGet(AOP(result),2));
3116 emitpcode(POC_CLRF, popGet(AOP(result),3));
3120 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3122 pic14_emitcode("mov","a,b");
3124 /* adjust the MSB if left or right neg */
3126 /* if one literal */
3127 if (AOP_TYPE(right) == AOP_LIT){
3128 pic14_emitcode("multiply ","right is a lit");
3129 /* AND literal negative */
3130 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3131 /* adjust MSB (c==0 after mul) */
3132 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3136 genSMult8X8_16 (left, right, result, NULL);
3140 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3142 pic14_emitcode("rlc","a");
3143 pic14_emitcode("subb","a,acc");
3151 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3152 //aopPut(AOP(result),"a",offset++);
3156 /*-----------------------------------------------------------------*/
3157 /* genMult - generates code for multiplication */
3158 /*-----------------------------------------------------------------*/
3159 static void genMult (iCode *ic)
3161 operand *left = IC_LEFT(ic);
3162 operand *right = IC_RIGHT(ic);
3163 operand *result= IC_RESULT(ic);
3165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3166 /* assign the amsops */
3167 aopOp (left,ic,FALSE);
3168 aopOp (right,ic,FALSE);
3169 aopOp (result,ic,TRUE);
3171 DEBUGpic14_AopType(__LINE__,left,right,result);
3173 /* special cases first */
3175 if (AOP_TYPE(left) == AOP_CRY &&
3176 AOP_TYPE(right)== AOP_CRY) {
3177 genMultbits(left,right,result);
3181 /* if both are of size == 1 */
3182 if (AOP_SIZE(left) == 1 &&
3183 AOP_SIZE(right) == 1 ) {
3184 genMultOneByte(left,right,result);
3188 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3190 /* should have been converted to function call */
3194 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3195 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3196 freeAsmop(result,NULL,ic,TRUE);
3199 /*-----------------------------------------------------------------*/
3200 /* genDivbits :- division of bits */
3201 /*-----------------------------------------------------------------*/
3202 static void genDivbits (operand *left,
3209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3210 /* the result must be bit */
3211 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3212 l = aopGet(AOP(left),0,FALSE,FALSE);
3216 pic14_emitcode("div","ab");
3217 pic14_emitcode("rrc","a");
3218 aopPut(AOP(result),"c",0);
3221 /*-----------------------------------------------------------------*/
3222 /* genDivOneByte : 8 bit division */
3223 /*-----------------------------------------------------------------*/
3224 static void genDivOneByte (operand *left,
3228 sym_link *opetype = operandType(result);
3233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3234 size = AOP_SIZE(result) - 1;
3236 /* signed or unsigned */
3237 if (SPEC_USIGN(opetype)) {
3238 /* unsigned is easy */
3239 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3240 l = aopGet(AOP(left),0,FALSE,FALSE);
3242 pic14_emitcode("div","ab");
3243 aopPut(AOP(result),"a",0);
3245 aopPut(AOP(result),zero,offset++);
3249 /* signed is a little bit more difficult */
3251 /* save the signs of the operands */
3252 l = aopGet(AOP(left),0,FALSE,FALSE);
3254 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3255 pic14_emitcode("push","acc"); /* save it on the stack */
3257 /* now sign adjust for both left & right */
3258 l = aopGet(AOP(right),0,FALSE,FALSE);
3260 lbl = newiTempLabel(NULL);
3261 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3262 pic14_emitcode("cpl","a");
3263 pic14_emitcode("inc","a");
3264 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3265 pic14_emitcode("mov","b,a");
3267 /* sign adjust left side */
3268 l = aopGet(AOP(left),0,FALSE,FALSE);
3271 lbl = newiTempLabel(NULL);
3272 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3273 pic14_emitcode("cpl","a");
3274 pic14_emitcode("inc","a");
3275 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3277 /* now the division */
3278 pic14_emitcode("div","ab");
3279 /* we are interested in the lower order
3281 pic14_emitcode("mov","b,a");
3282 lbl = newiTempLabel(NULL);
3283 pic14_emitcode("pop","acc");
3284 /* if there was an over flow we don't
3285 adjust the sign of the result */
3286 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3287 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3289 pic14_emitcode("clr","a");
3290 pic14_emitcode("subb","a,b");
3291 pic14_emitcode("mov","b,a");
3292 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3294 /* now we are done */
3295 aopPut(AOP(result),"b",0);
3297 pic14_emitcode("mov","c,b.7");
3298 pic14_emitcode("subb","a,acc");
3301 aopPut(AOP(result),"a",offset++);
3305 /*-----------------------------------------------------------------*/
3306 /* genDiv - generates code for division */
3307 /*-----------------------------------------------------------------*/
3308 static void genDiv (iCode *ic)
3310 operand *left = IC_LEFT(ic);
3311 operand *right = IC_RIGHT(ic);
3312 operand *result= IC_RESULT(ic);
3314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3315 /* assign the amsops */
3316 aopOp (left,ic,FALSE);
3317 aopOp (right,ic,FALSE);
3318 aopOp (result,ic,TRUE);
3320 /* special cases first */
3322 if (AOP_TYPE(left) == AOP_CRY &&
3323 AOP_TYPE(right)== AOP_CRY) {
3324 genDivbits(left,right,result);
3328 /* if both are of size == 1 */
3329 if (AOP_SIZE(left) == 1 &&
3330 AOP_SIZE(right) == 1 ) {
3331 genDivOneByte(left,right,result);
3335 /* should have been converted to function call */
3338 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3339 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3340 freeAsmop(result,NULL,ic,TRUE);
3343 /*-----------------------------------------------------------------*/
3344 /* genModbits :- modulus of bits */
3345 /*-----------------------------------------------------------------*/
3346 static void genModbits (operand *left,
3353 /* the result must be bit */
3354 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3355 l = aopGet(AOP(left),0,FALSE,FALSE);
3359 pic14_emitcode("div","ab");
3360 pic14_emitcode("mov","a,b");
3361 pic14_emitcode("rrc","a");
3362 aopPut(AOP(result),"c",0);
3365 /*-----------------------------------------------------------------*/
3366 /* genModOneByte : 8 bit modulus */
3367 /*-----------------------------------------------------------------*/
3368 static void genModOneByte (operand *left,
3372 sym_link *opetype = operandType(result);
3376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3377 /* signed or unsigned */
3378 if (SPEC_USIGN(opetype)) {
3379 /* unsigned is easy */
3380 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3381 l = aopGet(AOP(left),0,FALSE,FALSE);
3383 pic14_emitcode("div","ab");
3384 aopPut(AOP(result),"b",0);
3388 /* signed is a little bit more difficult */
3390 /* save the signs of the operands */
3391 l = aopGet(AOP(left),0,FALSE,FALSE);
3394 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3395 pic14_emitcode("push","acc"); /* save it on the stack */
3397 /* now sign adjust for both left & right */
3398 l = aopGet(AOP(right),0,FALSE,FALSE);
3401 lbl = newiTempLabel(NULL);
3402 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3403 pic14_emitcode("cpl","a");
3404 pic14_emitcode("inc","a");
3405 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3406 pic14_emitcode("mov","b,a");
3408 /* sign adjust left side */
3409 l = aopGet(AOP(left),0,FALSE,FALSE);
3412 lbl = newiTempLabel(NULL);
3413 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3414 pic14_emitcode("cpl","a");
3415 pic14_emitcode("inc","a");
3416 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3418 /* now the multiplication */
3419 pic14_emitcode("div","ab");
3420 /* we are interested in the lower order
3422 lbl = newiTempLabel(NULL);
3423 pic14_emitcode("pop","acc");
3424 /* if there was an over flow we don't
3425 adjust the sign of the result */
3426 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3427 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3429 pic14_emitcode("clr","a");
3430 pic14_emitcode("subb","a,b");
3431 pic14_emitcode("mov","b,a");
3432 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3434 /* now we are done */
3435 aopPut(AOP(result),"b",0);
3439 /*-----------------------------------------------------------------*/
3440 /* genMod - generates code for division */
3441 /*-----------------------------------------------------------------*/
3442 static void genMod (iCode *ic)
3444 operand *left = IC_LEFT(ic);
3445 operand *right = IC_RIGHT(ic);
3446 operand *result= IC_RESULT(ic);
3448 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3449 /* assign the amsops */
3450 aopOp (left,ic,FALSE);
3451 aopOp (right,ic,FALSE);
3452 aopOp (result,ic,TRUE);
3454 /* special cases first */
3456 if (AOP_TYPE(left) == AOP_CRY &&
3457 AOP_TYPE(right)== AOP_CRY) {
3458 genModbits(left,right,result);
3462 /* if both are of size == 1 */
3463 if (AOP_SIZE(left) == 1 &&
3464 AOP_SIZE(right) == 1 ) {
3465 genModOneByte(left,right,result);
3469 /* should have been converted to function call */
3473 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3474 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3475 freeAsmop(result,NULL,ic,TRUE);
3478 /*-----------------------------------------------------------------*/
3479 /* genIfxJump :- will create a jump depending on the ifx */
3480 /*-----------------------------------------------------------------*/
3482 note: May need to add parameter to indicate when a variable is in bit space.
3484 static void genIfxJump (iCode *ic, char *jval)
3487 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3488 /* if true label then we jump if condition
3490 if ( IC_TRUE(ic) ) {
3492 if(strcmp(jval,"a") == 0)
3494 else if (strcmp(jval,"c") == 0)
3497 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3498 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3501 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3502 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3506 /* false label is present */
3507 if(strcmp(jval,"a") == 0)
3509 else if (strcmp(jval,"c") == 0)
3512 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3513 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3516 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3517 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3522 /* mark the icode as generated */
3526 /*-----------------------------------------------------------------*/
3528 /*-----------------------------------------------------------------*/
3529 static void genSkip(iCode *ifx,int status_bit)
3534 if ( IC_TRUE(ifx) ) {
3535 switch(status_bit) {
3550 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3551 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3555 switch(status_bit) {
3569 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3570 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3576 /*-----------------------------------------------------------------*/
3578 /*-----------------------------------------------------------------*/
3579 static void genSkipc(resolvedIfx *rifx)
3589 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3590 rifx->generated = 1;
3593 /*-----------------------------------------------------------------*/
3595 /*-----------------------------------------------------------------*/
3596 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3601 if( (rifx->condition ^ invert_condition) & 1)
3606 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3607 rifx->generated = 1;
3610 /*-----------------------------------------------------------------*/
3612 /*-----------------------------------------------------------------*/
3613 static void genSkipz(iCode *ifx, int condition)
3624 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3626 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3629 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3631 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3634 /*-----------------------------------------------------------------*/
3636 /*-----------------------------------------------------------------*/
3637 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3643 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3645 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3648 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3649 rifx->generated = 1;
3653 /*-----------------------------------------------------------------*/
3654 /* genChkZeroes :- greater or less than comparison */
3655 /* For each byte in a literal that is zero, inclusive or the */
3656 /* the corresponding byte in the operand with W */
3657 /* returns true if any of the bytes are zero */
3658 /*-----------------------------------------------------------------*/
3659 static int genChkZeroes(operand *op, int lit, int size)
3666 i = (lit >> (size*8)) & 0xff;
3670 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3672 emitpcode(POC_IORFW, popGet(AOP(op),size));
3681 /*-----------------------------------------------------------------*/
3682 /* genCmp :- greater or less than comparison */
3683 /*-----------------------------------------------------------------*/
3684 static void genCmp (operand *left,operand *right,
3685 operand *result, iCode *ifx, int sign)
3687 int size; //, offset = 0 ;
3688 unsigned long lit = 0L,i = 0;
3689 resolvedIfx rFalseIfx;
3690 // resolvedIfx rTrueIfx;
3692 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3695 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3696 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3700 resolveIfx(&rFalseIfx,ifx);
3701 truelbl = newiTempLabel(NULL);
3702 size = max(AOP_SIZE(left),AOP_SIZE(right));
3704 DEBUGpic14_AopType(__LINE__,left,right,result);
3708 /* if literal is on the right then swap with left */
3709 if ((AOP_TYPE(right) == AOP_LIT)) {
3710 operand *tmp = right ;
3711 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3712 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3715 lit = (lit - 1) & mask;
3718 rFalseIfx.condition ^= 1;
3721 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3722 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3726 //if(IC_TRUE(ifx) == NULL)
3727 /* if left & right are bit variables */
3728 if (AOP_TYPE(left) == AOP_CRY &&
3729 AOP_TYPE(right) == AOP_CRY ) {
3730 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3731 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3733 /* subtract right from left if at the
3734 end the carry flag is set then we know that
3735 left is greater than right */
3739 symbol *lbl = newiTempLabel(NULL);
3742 if(AOP_TYPE(right) == AOP_LIT) {
3744 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3746 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3753 genSkipCond(&rFalseIfx,left,size-1,7);
3755 /* no need to compare to 0...*/
3756 /* NOTE: this is a de-generate compare that most certainly
3757 * creates some dead code. */
3758 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3760 if(ifx) ifx->generated = 1;
3767 //i = (lit >> (size*8)) & 0xff;
3768 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3770 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3772 i = ((0-lit) & 0xff);
3775 /* lit is 0x7f, all signed chars are less than
3776 * this except for 0x7f itself */
3777 emitpcode(POC_XORLW, popGetLit(0x7f));
3778 genSkipz2(&rFalseIfx,0);
3780 emitpcode(POC_ADDLW, popGetLit(0x80));
3781 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3782 genSkipc(&rFalseIfx);
3787 genSkipz2(&rFalseIfx,1);
3789 emitpcode(POC_ADDLW, popGetLit(i));
3790 genSkipc(&rFalseIfx);
3794 if(ifx) ifx->generated = 1;
3798 /* chars are out of the way. now do ints and longs */
3801 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3808 genSkipCond(&rFalseIfx,left,size,7);
3809 if(ifx) ifx->generated = 1;
3814 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3816 //rFalseIfx.condition ^= 1;
3817 //genSkipCond(&rFalseIfx,left,size,7);
3818 //rFalseIfx.condition ^= 1;
3820 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3821 if(rFalseIfx.condition)
3822 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3824 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3826 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3827 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3828 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3831 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3833 if(rFalseIfx.condition) {
3835 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3841 genSkipc(&rFalseIfx);
3842 emitpLabel(truelbl->key);
3843 if(ifx) ifx->generated = 1;
3850 if( (lit & 0xff) == 0) {
3851 /* lower byte is zero */
3852 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3853 i = ((lit >> 8) & 0xff) ^0x80;
3854 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3855 emitpcode(POC_ADDLW, popGetLit( 0x80));
3856 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3857 genSkipc(&rFalseIfx);
3860 if(ifx) ifx->generated = 1;
3865 /* Special cases for signed longs */
3866 if( (lit & 0xffffff) == 0) {
3867 /* lower byte is zero */
3868 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3869 i = ((lit >> 8*3) & 0xff) ^0x80;
3870 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3871 emitpcode(POC_ADDLW, popGetLit( 0x80));
3872 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3873 genSkipc(&rFalseIfx);
3876 if(ifx) ifx->generated = 1;
3884 if(lit & (0x80 << (size*8))) {
3885 /* lit is negative */
3886 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3888 //genSkipCond(&rFalseIfx,left,size,7);
3890 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3892 if(rFalseIfx.condition)
3893 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3895 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3899 /* lit is positive */
3900 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3901 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3902 if(rFalseIfx.condition)
3903 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3905 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3909 /* There are no more special cases, so perform a general compare */
3911 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3912 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3916 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3918 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3920 //rFalseIfx.condition ^= 1;
3921 genSkipc(&rFalseIfx);
3923 emitpLabel(truelbl->key);
3925 if(ifx) ifx->generated = 1;
3932 /* sign is out of the way. So now do an unsigned compare */
3933 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3936 /* General case - compare to an unsigned literal on the right.*/
3938 i = (lit >> (size*8)) & 0xff;
3939 emitpcode(POC_MOVLW, popGetLit(i));
3940 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3942 i = (lit >> (size*8)) & 0xff;
3945 emitpcode(POC_MOVLW, popGetLit(i));
3947 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3949 /* this byte of the lit is zero,
3950 *if it's not the last then OR in the variable */
3952 emitpcode(POC_IORFW, popGet(AOP(left),size));
3957 emitpLabel(lbl->key);
3958 //if(emitFinalCheck)
3959 genSkipc(&rFalseIfx);
3961 emitpLabel(truelbl->key);
3963 if(ifx) ifx->generated = 1;
3970 if(AOP_TYPE(left) == AOP_LIT) {
3971 //symbol *lbl = newiTempLabel(NULL);
3973 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3976 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3979 if((lit == 0) && (sign == 0)){
3982 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3984 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3986 genSkipz2(&rFalseIfx,0);
3987 if(ifx) ifx->generated = 1;
3994 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3995 /* degenerate compare can never be true */
3996 if(rFalseIfx.condition == 0)
3997 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3999 if(ifx) ifx->generated = 1;
4004 /* signed comparisons to a literal byte */
4006 int lp1 = (lit+1) & 0xff;
4008 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4011 rFalseIfx.condition ^= 1;
4012 genSkipCond(&rFalseIfx,right,0,7);
4015 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4016 emitpcode(POC_XORLW, popGetLit(0x7f));
4017 genSkipz2(&rFalseIfx,1);
4020 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4021 emitpcode(POC_ADDLW, popGetLit(0x80));
4022 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4023 rFalseIfx.condition ^= 1;
4024 genSkipc(&rFalseIfx);
4027 if(ifx) ifx->generated = 1;
4029 /* unsigned comparisons to a literal byte */
4031 switch(lit & 0xff ) {
4033 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4034 genSkipz2(&rFalseIfx,0);
4035 if(ifx) ifx->generated = 1;
4038 genSkipCond(&rFalseIfx,right,0,7);
4039 if(ifx) ifx->generated = 1;
4043 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4044 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4045 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4046 rFalseIfx.condition ^= 1;
4047 if (AOP_TYPE(result) == AOP_CRY) {
4048 genSkipc(&rFalseIfx);
4049 if(ifx) ifx->generated = 1;
4051 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4052 emitpcode(POC_CLRF, popGet(AOP(result),0));
4053 emitpcode(POC_RLF, popGet(AOP(result),0));
4054 emitpcode(POC_MOVLW, popGetLit(0x01));
4055 emitpcode(POC_XORWF, popGet(AOP(result),0));
4066 /* Size is greater than 1 */
4074 /* this means lit = 0xffffffff, or -1 */
4077 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4078 rFalseIfx.condition ^= 1;
4079 genSkipCond(&rFalseIfx,right,size,7);
4080 if(ifx) ifx->generated = 1;
4087 if(rFalseIfx.condition) {
4088 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4089 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4092 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4094 emitpcode(POC_IORFW, popGet(AOP(right),size));
4098 if(rFalseIfx.condition) {
4099 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4100 emitpLabel(truelbl->key);
4102 rFalseIfx.condition ^= 1;
4103 genSkipCond(&rFalseIfx,right,s,7);
4106 if(ifx) ifx->generated = 1;
4110 if((size == 1) && (0 == (lp1&0xff))) {
4111 /* lower byte of signed word is zero */
4112 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4113 i = ((lp1 >> 8) & 0xff) ^0x80;
4114 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4115 emitpcode(POC_ADDLW, popGetLit( 0x80));
4116 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4117 rFalseIfx.condition ^= 1;
4118 genSkipc(&rFalseIfx);
4121 if(ifx) ifx->generated = 1;
4125 if(lit & (0x80 << (size*8))) {
4126 /* Lit is less than zero */
4127 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4128 //rFalseIfx.condition ^= 1;
4129 //genSkipCond(&rFalseIfx,left,size,7);
4130 //rFalseIfx.condition ^= 1;
4131 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4134 if(rFalseIfx.condition)
4135 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4137 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4141 /* Lit is greater than or equal to zero */
4142 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4143 //rFalseIfx.condition ^= 1;
4144 //genSkipCond(&rFalseIfx,right,size,7);
4145 //rFalseIfx.condition ^= 1;
4147 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4148 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4150 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4151 if(rFalseIfx.condition)
4152 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4154 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4159 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4160 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4164 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4166 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4168 rFalseIfx.condition ^= 1;
4169 //rFalseIfx.condition = 1;
4170 genSkipc(&rFalseIfx);
4172 emitpLabel(truelbl->key);
4174 if(ifx) ifx->generated = 1;
4179 /* compare word or long to an unsigned literal on the right.*/
4184 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4187 break; /* handled above */
4190 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4192 emitpcode(POC_IORFW, popGet(AOP(right),size));
4193 genSkipz2(&rFalseIfx,0);
4197 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4199 emitpcode(POC_IORFW, popGet(AOP(right),size));
4202 if(rFalseIfx.condition)
4203 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4205 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4208 emitpcode(POC_MOVLW, popGetLit(lit+1));
4209 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4211 rFalseIfx.condition ^= 1;
4212 genSkipc(&rFalseIfx);
4215 emitpLabel(truelbl->key);
4217 if(ifx) ifx->generated = 1;
4223 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4224 i = (lit >> (size*8)) & 0xff;
4226 emitpcode(POC_MOVLW, popGetLit(i));
4227 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230 i = (lit >> (size*8)) & 0xff;
4233 emitpcode(POC_MOVLW, popGetLit(i));
4235 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4237 /* this byte of the lit is zero,
4238 *if it's not the last then OR in the variable */
4240 emitpcode(POC_IORFW, popGet(AOP(right),size));
4245 emitpLabel(lbl->key);
4247 rFalseIfx.condition ^= 1;
4248 genSkipc(&rFalseIfx);
4252 emitpLabel(truelbl->key);
4253 if(ifx) ifx->generated = 1;
4257 /* Compare two variables */
4259 DEBUGpic14_emitcode(";sign","%d",sign);
4263 /* Sigh. thus sucks... */
4265 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4266 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4267 emitpcode(POC_MOVLW, popGetLit(0x80));
4268 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4269 emitpcode(POC_XORFW, popGet(AOP(right),size));
4270 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4272 /* Signed char comparison */
4273 /* Special thanks to Nikolai Golovchenko for this snippet */
4274 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4275 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4276 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4277 emitpcode(POC_XORFW, popGet(AOP(left),0));
4278 emitpcode(POC_XORFW, popGet(AOP(right),0));
4279 emitpcode(POC_ADDLW, popGetLit(0x80));
4281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4282 genSkipc(&rFalseIfx);
4284 if(ifx) ifx->generated = 1;
4290 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4291 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4295 /* The rest of the bytes of a multi-byte compare */
4299 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4302 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4303 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4308 emitpLabel(lbl->key);
4310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4311 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4312 (AOP_TYPE(result) == AOP_REG)) {
4313 emitpcode(POC_CLRF, popGet(AOP(result),0));
4314 emitpcode(POC_RLF, popGet(AOP(result),0));
4316 genSkipc(&rFalseIfx);
4318 //genSkipc(&rFalseIfx);
4319 if(ifx) ifx->generated = 1;
4326 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4327 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4328 pic14_outBitC(result);
4330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4331 /* if the result is used in the next
4332 ifx conditional branch then generate
4333 code a little differently */
4335 genIfxJump (ifx,"c");
4337 pic14_outBitC(result);
4338 /* leave the result in acc */
4343 /*-----------------------------------------------------------------*/
4344 /* genCmpGt :- greater than comparison */
4345 /*-----------------------------------------------------------------*/
4346 static void genCmpGt (iCode *ic, iCode *ifx)
4348 operand *left, *right, *result;
4349 sym_link *letype , *retype;
4352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4354 right= IC_RIGHT(ic);
4355 result = IC_RESULT(ic);
4357 letype = getSpec(operandType(left));
4358 retype =getSpec(operandType(right));
4359 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4360 /* assign the amsops */
4361 aopOp (left,ic,FALSE);
4362 aopOp (right,ic,FALSE);
4363 aopOp (result,ic,TRUE);
4365 genCmp(right, left, result, ifx, sign);
4367 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4368 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4369 freeAsmop(result,NULL,ic,TRUE);
4372 /*-----------------------------------------------------------------*/
4373 /* genCmpLt - less than comparisons */
4374 /*-----------------------------------------------------------------*/
4375 static void genCmpLt (iCode *ic, iCode *ifx)
4377 operand *left, *right, *result;
4378 sym_link *letype , *retype;
4381 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4383 right= IC_RIGHT(ic);
4384 result = IC_RESULT(ic);
4386 letype = getSpec(operandType(left));
4387 retype =getSpec(operandType(right));
4388 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4390 /* assign the amsops */
4391 aopOp (left,ic,FALSE);
4392 aopOp (right,ic,FALSE);
4393 aopOp (result,ic,TRUE);
4395 genCmp(left, right, result, ifx, sign);
4397 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4398 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4399 freeAsmop(result,NULL,ic,TRUE);
4402 /*-----------------------------------------------------------------*/
4403 /* genc16bit2lit - compare a 16 bit value to a literal */
4404 /*-----------------------------------------------------------------*/
4405 static void genc16bit2lit(operand *op, int lit, int offset)
4409 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4410 if( (lit&0xff) == 0)
4415 switch( BYTEofLONG(lit,i)) {
4417 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4420 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4423 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4426 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4427 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4432 switch( BYTEofLONG(lit,i)) {
4434 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4438 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4442 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4445 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4447 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4453 /*-----------------------------------------------------------------*/
4454 /* gencjneshort - compare and jump if not equal */
4455 /*-----------------------------------------------------------------*/
4456 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4458 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4460 int res_offset = 0; /* the result may be a different size then left or right */
4461 int res_size = AOP_SIZE(result);
4465 unsigned long lit = 0L;
4466 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4467 DEBUGpic14_AopType(__LINE__,left,right,result);
4469 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4470 resolveIfx(&rIfx,ifx);
4471 lbl = newiTempLabel(NULL);
4474 /* if the left side is a literal or
4475 if the right is in a pointer register and left
4477 if ((AOP_TYPE(left) == AOP_LIT) ||
4478 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4483 if(AOP_TYPE(right) == AOP_LIT)
4484 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4486 /* if the right side is a literal then anything goes */
4487 if (AOP_TYPE(right) == AOP_LIT &&
4488 AOP_TYPE(left) != AOP_DIR ) {
4491 genc16bit2lit(left, lit, 0);
4493 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4498 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4499 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4501 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4505 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4507 if(res_offset < res_size-1)
4515 /* if the right side is in a register or in direct space or
4516 if the left is a pointer register & right is not */
4517 else if (AOP_TYPE(right) == AOP_REG ||
4518 AOP_TYPE(right) == AOP_DIR ||
4519 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4520 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4521 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4522 int lbl_key = lbl->key;
4525 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4526 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4528 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4529 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4530 __FUNCTION__,__LINE__);
4534 /* switch(size) { */
4536 /* genc16bit2lit(left, lit, 0); */
4538 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4543 if((AOP_TYPE(left) == AOP_DIR) &&
4544 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4546 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4547 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4549 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4551 switch (lit & 0xff) {
4553 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4556 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4557 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4558 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4562 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4563 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4564 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4565 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4569 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4570 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4575 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4578 if(AOP_TYPE(result) == AOP_CRY) {
4579 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4584 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4586 /* fix me. probably need to check result size too */
4587 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4592 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4593 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4600 if(res_offset < res_size-1)
4605 } else if(AOP_TYPE(right) == AOP_REG &&
4606 AOP_TYPE(left) != AOP_DIR){
4609 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4610 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4611 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4616 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4618 if(res_offset < res_size-1)
4623 /* right is a pointer reg need both a & b */
4625 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4627 pic14_emitcode("mov","b,%s",l);
4628 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4629 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4634 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4636 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4638 emitpLabel(lbl->key);
4640 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4647 /*-----------------------------------------------------------------*/
4648 /* gencjne - compare and jump if not equal */
4649 /*-----------------------------------------------------------------*/
4650 static void gencjne(operand *left, operand *right, iCode *ifx)
4652 symbol *tlbl = newiTempLabel(NULL);
4654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4655 gencjneshort(left, right, lbl);
4657 pic14_emitcode("mov","a,%s",one);
4658 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4659 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4660 pic14_emitcode("clr","a");
4661 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4663 emitpLabel(lbl->key);
4664 emitpLabel(tlbl->key);
4669 /*-----------------------------------------------------------------*/
4670 /* genCmpEq - generates code for equal to */
4671 /*-----------------------------------------------------------------*/
4672 static void genCmpEq (iCode *ic, iCode *ifx)
4674 operand *left, *right, *result;
4675 unsigned long lit = 0L;
4678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4681 DEBUGpic14_emitcode ("; ifx is non-null","");
4683 DEBUGpic14_emitcode ("; ifx is null","");
4685 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4686 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4687 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4689 size = max(AOP_SIZE(left),AOP_SIZE(right));
4691 DEBUGpic14_AopType(__LINE__,left,right,result);
4693 /* if literal, literal on the right or
4694 if the right is in a pointer register and left
4696 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4697 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4698 operand *tmp = right ;
4704 if(ifx && !AOP_SIZE(result)){
4706 /* if they are both bit variables */
4707 if (AOP_TYPE(left) == AOP_CRY &&
4708 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4709 if(AOP_TYPE(right) == AOP_LIT){
4710 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4712 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4713 pic14_emitcode("cpl","c");
4714 } else if(lit == 1L) {
4715 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4717 pic14_emitcode("clr","c");
4719 /* AOP_TYPE(right) == AOP_CRY */
4721 symbol *lbl = newiTempLabel(NULL);
4722 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4723 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4724 pic14_emitcode("cpl","c");
4725 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4727 /* if true label then we jump if condition
4729 tlbl = newiTempLabel(NULL);
4730 if ( IC_TRUE(ifx) ) {
4731 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4732 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4734 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4735 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4737 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4740 /* left and right are both bit variables, result is carry */
4743 resolveIfx(&rIfx,ifx);
4745 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4746 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4747 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4748 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4753 /* They're not both bit variables. Is the right a literal? */
4754 if(AOP_TYPE(right) == AOP_LIT) {
4755 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4760 switch(lit & 0xff) {
4762 if ( IC_TRUE(ifx) ) {
4763 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4765 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4767 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4768 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4772 if ( IC_TRUE(ifx) ) {
4773 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4775 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4777 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4778 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4782 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4784 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4789 /* end of size == 1 */
4793 genc16bit2lit(left,lit,offset);
4796 /* end of size == 2 */
4801 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4802 emitpcode(POC_IORFW,popGet(AOP(left),1));
4803 emitpcode(POC_IORFW,popGet(AOP(left),2));
4804 emitpcode(POC_IORFW,popGet(AOP(left),3));
4808 /* search for patterns that can be optimized */
4810 genc16bit2lit(left,lit,0);
4813 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4815 genc16bit2lit(left,lit,2);
4817 emitpcode(POC_IORFW,popGet(AOP(left),2));
4818 emitpcode(POC_IORFW,popGet(AOP(left),3));
4831 } else if(AOP_TYPE(right) == AOP_CRY ) {
4832 /* we know the left is not a bit, but that the right is */
4833 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4834 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4835 popGet(AOP(right),offset));
4836 emitpcode(POC_XORLW,popGetLit(1));
4838 /* if the two are equal, then W will be 0 and the Z bit is set
4839 * we could test Z now, or go ahead and check the high order bytes if
4840 * the variable we're comparing is larger than a byte. */
4843 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4845 if ( IC_TRUE(ifx) ) {
4847 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4848 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4851 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4852 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4856 /* They're both variables that are larger than bits */
4859 tlbl = newiTempLabel(NULL);
4862 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4863 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4865 if ( IC_TRUE(ifx) ) {
4868 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4869 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4872 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4873 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4877 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4878 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4882 if(s>1 && IC_TRUE(ifx)) {
4883 emitpLabel(tlbl->key);
4884 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4888 /* mark the icode as generated */
4893 /* if they are both bit variables */
4894 if (AOP_TYPE(left) == AOP_CRY &&
4895 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4896 if(AOP_TYPE(right) == AOP_LIT){
4897 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4899 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4900 pic14_emitcode("cpl","c");
4901 } else if(lit == 1L) {
4902 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4904 pic14_emitcode("clr","c");
4906 /* AOP_TYPE(right) == AOP_CRY */
4908 symbol *lbl = newiTempLabel(NULL);
4909 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4910 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4911 pic14_emitcode("cpl","c");
4912 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4915 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4916 pic14_outBitC(result);
4920 genIfxJump (ifx,"c");
4923 /* if the result is used in an arithmetic operation
4924 then put the result in place */
4925 pic14_outBitC(result);
4928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4929 gencjne(left,right,result,ifx);
4932 gencjne(left,right,newiTempLabel(NULL));
4934 if(IC_TRUE(ifx)->key)
4935 gencjne(left,right,IC_TRUE(ifx)->key);
4937 gencjne(left,right,IC_FALSE(ifx)->key);
4941 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4942 aopPut(AOP(result),"a",0);
4947 genIfxJump (ifx,"a");
4951 /* if the result is used in an arithmetic operation
4952 then put the result in place */
4954 if (AOP_TYPE(result) != AOP_CRY)
4955 pic14_outAcc(result);
4957 /* leave the result in acc */
4961 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4962 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4963 freeAsmop(result,NULL,ic,TRUE);
4966 /*-----------------------------------------------------------------*/
4967 /* ifxForOp - returns the icode containing the ifx for operand */
4968 /*-----------------------------------------------------------------*/
4969 static iCode *ifxForOp ( operand *op, iCode *ic )
4971 /* if true symbol then needs to be assigned */
4972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4973 if (IS_TRUE_SYMOP(op))
4976 /* if this has register type condition and
4977 the next instruction is ifx with the same operand
4978 and live to of the operand is upto the ifx only then */
4980 ic->next->op == IFX &&
4981 IC_COND(ic->next)->key == op->key &&
4982 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4986 ic->next->op == IFX &&
4987 IC_COND(ic->next)->key == op->key) {
4988 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4992 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4994 ic->next->op == IFX)
4995 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4998 ic->next->op == IFX &&
4999 IC_COND(ic->next)->key == op->key) {
5000 DEBUGpic14_emitcode ("; "," key is okay");
5001 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5002 OP_SYMBOL(op)->liveTo,
5009 /*-----------------------------------------------------------------*/
5010 /* genAndOp - for && operation */
5011 /*-----------------------------------------------------------------*/
5012 static void genAndOp (iCode *ic)
5014 operand *left,*right, *result;
5017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5018 /* note here that && operations that are in an
5019 if statement are taken away by backPatchLabels
5020 only those used in arthmetic operations remain */
5021 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5022 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5023 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5025 DEBUGpic14_AopType(__LINE__,left,right,result);
5027 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5028 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5029 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5031 /* if both are bit variables */
5032 /* if (AOP_TYPE(left) == AOP_CRY && */
5033 /* AOP_TYPE(right) == AOP_CRY ) { */
5034 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5035 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5036 /* pic14_outBitC(result); */
5038 /* tlbl = newiTempLabel(NULL); */
5039 /* pic14_toBoolean(left); */
5040 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5041 /* pic14_toBoolean(right); */
5042 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5043 /* pic14_outBitAcc(result); */
5046 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5047 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5048 freeAsmop(result,NULL,ic,TRUE);
5052 /*-----------------------------------------------------------------*/
5053 /* genOrOp - for || operation */
5054 /*-----------------------------------------------------------------*/
5057 modified this code, but it doesn't appear to ever get called
5060 static void genOrOp (iCode *ic)
5062 operand *left,*right, *result;
5065 /* note here that || operations that are in an
5066 if statement are taken away by backPatchLabels
5067 only those used in arthmetic operations remain */
5068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5069 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5070 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5071 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5073 DEBUGpic14_AopType(__LINE__,left,right,result);
5075 /* if both are bit variables */
5076 if (AOP_TYPE(left) == AOP_CRY &&
5077 AOP_TYPE(right) == AOP_CRY ) {
5078 pic14_emitcode("clrc","");
5079 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5080 AOP(left)->aopu.aop_dir,
5081 AOP(left)->aopu.aop_dir);
5082 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5083 AOP(right)->aopu.aop_dir,
5084 AOP(right)->aopu.aop_dir);
5085 pic14_emitcode("setc","");
5088 tlbl = newiTempLabel(NULL);
5089 pic14_toBoolean(left);
5091 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5092 pic14_toBoolean(right);
5093 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5095 pic14_outBitAcc(result);
5098 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5099 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5100 freeAsmop(result,NULL,ic,TRUE);
5103 /*-----------------------------------------------------------------*/
5104 /* isLiteralBit - test if lit == 2^n */
5105 /*-----------------------------------------------------------------*/
5106 static int isLiteralBit(unsigned long lit)
5108 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5109 0x100L,0x200L,0x400L,0x800L,
5110 0x1000L,0x2000L,0x4000L,0x8000L,
5111 0x10000L,0x20000L,0x40000L,0x80000L,
5112 0x100000L,0x200000L,0x400000L,0x800000L,
5113 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5114 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5118 for(idx = 0; idx < 32; idx++)
5124 /*-----------------------------------------------------------------*/
5125 /* continueIfTrue - */
5126 /*-----------------------------------------------------------------*/
5127 static void continueIfTrue (iCode *ic)
5129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5131 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5135 /*-----------------------------------------------------------------*/
5137 /*-----------------------------------------------------------------*/
5138 static void jumpIfTrue (iCode *ic)
5140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5142 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5146 /*-----------------------------------------------------------------*/
5147 /* jmpTrueOrFalse - */
5148 /*-----------------------------------------------------------------*/
5149 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5151 // ugly but optimized by peephole
5152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5154 symbol *nlbl = newiTempLabel(NULL);
5155 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5156 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5157 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5158 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5161 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5162 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5167 /*-----------------------------------------------------------------*/
5168 /* genAnd - code for and */
5169 /*-----------------------------------------------------------------*/
5170 static void genAnd (iCode *ic, iCode *ifx)
5172 operand *left, *right, *result;
5174 unsigned long lit = 0L;
5179 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5180 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5181 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5182 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5184 resolveIfx(&rIfx,ifx);
5186 /* if left is a literal & right is not then exchange them */
5187 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5188 AOP_NEEDSACC(left)) {
5189 operand *tmp = right ;
5194 /* if result = right then exchange them */
5195 if(pic14_sameRegs(AOP(result),AOP(right))){
5196 operand *tmp = right ;
5201 /* if right is bit then exchange them */
5202 if (AOP_TYPE(right) == AOP_CRY &&
5203 AOP_TYPE(left) != AOP_CRY){
5204 operand *tmp = right ;
5208 if(AOP_TYPE(right) == AOP_LIT)
5209 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5211 size = AOP_SIZE(result);
5213 DEBUGpic14_AopType(__LINE__,left,right,result);
5216 // result = bit & yy;
5217 if (AOP_TYPE(left) == AOP_CRY){
5218 // c = bit & literal;
5219 if(AOP_TYPE(right) == AOP_LIT){
5221 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5224 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5227 if(size && (AOP_TYPE(result) == AOP_CRY)){
5228 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5231 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5235 pic14_emitcode("clr","c");
5238 if (AOP_TYPE(right) == AOP_CRY){
5240 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5241 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5244 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5246 pic14_emitcode("rrc","a");
5247 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5253 pic14_outBitC(result);
5255 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5256 genIfxJump(ifx, "c");
5260 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5261 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5262 if((AOP_TYPE(right) == AOP_LIT) &&
5263 (AOP_TYPE(result) == AOP_CRY) &&
5264 (AOP_TYPE(left) != AOP_CRY)){
5265 int posbit = isLiteralBit(lit);
5269 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5272 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5277 while (posbit > 7) {
5281 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5282 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5283 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5290 symbol *tlbl = newiTempLabel(NULL);
5291 int sizel = AOP_SIZE(left);
5293 pic14_emitcode("setb","c");
5295 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5296 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5298 if((posbit = isLiteralBit(bytelit)) != 0)
5299 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5301 if(bytelit != 0x0FFL)
5302 pic14_emitcode("anl","a,%s",
5303 aopGet(AOP(right),offset,FALSE,TRUE));
5304 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5309 // bit = left & literal
5311 pic14_emitcode("clr","c");
5312 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5314 // if(left & literal)
5317 jmpTrueOrFalse(ifx, tlbl);
5321 pic14_outBitC(result);
5325 /* if left is same as result */
5326 if(pic14_sameRegs(AOP(result),AOP(left))){
5328 for(;size--; offset++,lit>>=8) {
5329 if(AOP_TYPE(right) == AOP_LIT){
5330 switch(lit & 0xff) {
5332 /* and'ing with 0 has clears the result */
5333 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5334 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5337 /* and'ing with 0xff is a nop when the result and left are the same */
5342 int p = my_powof2( (~lit) & 0xff );
5344 /* only one bit is set in the literal, so use a bcf instruction */
5345 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5346 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5349 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5350 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5351 if(know_W != (int)(lit&0xff))
5352 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5354 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5359 if (AOP_TYPE(left) == AOP_ACC) {
5360 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5362 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5363 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5370 // left & result in different registers
5371 if(AOP_TYPE(result) == AOP_CRY){
5373 // if(size), result in bit
5374 // if(!size && ifx), conditional oper: if(left & right)
5375 symbol *tlbl = newiTempLabel(NULL);
5376 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5378 pic14_emitcode("setb","c");
5380 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5381 pic14_emitcode("anl","a,%s",
5382 aopGet(AOP(left),offset,FALSE,FALSE));
5383 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5388 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5389 pic14_outBitC(result);
5391 jmpTrueOrFalse(ifx, tlbl);
5393 for(;(size--);offset++) {
5395 // result = left & right
5396 if(AOP_TYPE(right) == AOP_LIT){
5397 int t = (lit >> (offset*8)) & 0x0FFL;
5400 pic14_emitcode("clrf","%s",
5401 aopGet(AOP(result),offset,FALSE,FALSE));
5402 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5405 if(AOP_TYPE(left) != AOP_ACC) {
5406 pic14_emitcode("movf","%s,w",
5407 aopGet(AOP(left),offset,FALSE,FALSE));
5408 pic14_emitcode("movwf","%s",
5409 aopGet(AOP(result),offset,FALSE,FALSE));
5410 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5412 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5415 if(AOP_TYPE(left) == AOP_ACC) {
5416 emitpcode(POC_ANDLW, popGetLit(t));
5418 pic14_emitcode("movlw","0x%x",t);
5419 pic14_emitcode("andwf","%s,w",
5420 aopGet(AOP(left),offset,FALSE,FALSE));
5421 pic14_emitcode("movwf","%s",
5422 aopGet(AOP(result),offset,FALSE,FALSE));
5424 emitpcode(POC_MOVLW, popGetLit(t));
5425 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5427 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5432 if (AOP_TYPE(left) == AOP_ACC) {
5433 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5434 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5436 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5437 pic14_emitcode("andwf","%s,w",
5438 aopGet(AOP(left),offset,FALSE,FALSE));
5439 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5440 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5442 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5443 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5449 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5450 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5451 freeAsmop(result,NULL,ic,TRUE);
5454 /*-----------------------------------------------------------------*/
5455 /* genOr - code for or */
5456 /*-----------------------------------------------------------------*/
5457 static void genOr (iCode *ic, iCode *ifx)
5459 operand *left, *right, *result;
5461 unsigned long lit = 0L;
5463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5465 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5466 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5467 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5469 DEBUGpic14_AopType(__LINE__,left,right,result);
5471 /* if left is a literal & right is not then exchange them */
5472 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5473 AOP_NEEDSACC(left)) {
5474 operand *tmp = right ;
5479 /* if result = right then exchange them */
5480 if(pic14_sameRegs(AOP(result),AOP(right))){
5481 operand *tmp = right ;
5486 /* if right is bit then exchange them */
5487 if (AOP_TYPE(right) == AOP_CRY &&
5488 AOP_TYPE(left) != AOP_CRY){
5489 operand *tmp = right ;
5494 DEBUGpic14_AopType(__LINE__,left,right,result);
5496 if(AOP_TYPE(right) == AOP_LIT)
5497 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5499 size = AOP_SIZE(result);
5503 if (AOP_TYPE(left) == AOP_CRY){
5504 if(AOP_TYPE(right) == AOP_LIT){
5505 // c = bit & literal;
5507 // lit != 0 => result = 1
5508 if(AOP_TYPE(result) == AOP_CRY){
5510 emitpcode(POC_BSF, popGet(AOP(result),0));
5511 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5512 // AOP(result)->aopu.aop_dir,
5513 // AOP(result)->aopu.aop_dir);
5515 continueIfTrue(ifx);
5519 // lit == 0 => result = left
5520 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5522 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5525 if (AOP_TYPE(right) == AOP_CRY){
5526 if(pic14_sameRegs(AOP(result),AOP(left))){
5528 emitpcode(POC_BCF, popGet(AOP(result),0));
5529 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5530 emitpcode(POC_BSF, popGet(AOP(result),0));
5532 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5533 AOP(result)->aopu.aop_dir,
5534 AOP(result)->aopu.aop_dir);
5535 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5536 AOP(right)->aopu.aop_dir,
5537 AOP(right)->aopu.aop_dir);
5538 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5539 AOP(result)->aopu.aop_dir,
5540 AOP(result)->aopu.aop_dir);
5542 if( AOP_TYPE(result) == AOP_ACC) {
5543 emitpcode(POC_MOVLW, popGetLit(0));
5544 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5545 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5546 emitpcode(POC_MOVLW, popGetLit(1));
5550 emitpcode(POC_BCF, popGet(AOP(result),0));
5551 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5552 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5553 emitpcode(POC_BSF, popGet(AOP(result),0));
5555 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5556 AOP(result)->aopu.aop_dir,
5557 AOP(result)->aopu.aop_dir);
5558 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5559 AOP(right)->aopu.aop_dir,
5560 AOP(right)->aopu.aop_dir);
5561 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5562 AOP(left)->aopu.aop_dir,
5563 AOP(left)->aopu.aop_dir);
5564 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5565 AOP(result)->aopu.aop_dir,
5566 AOP(result)->aopu.aop_dir);
5571 symbol *tlbl = newiTempLabel(NULL);
5572 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5575 emitpcode(POC_BCF, popGet(AOP(result),0));
5576 if( AOP_TYPE(right) == AOP_ACC) {
5577 emitpcode(POC_IORLW, popGetLit(0));
5579 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5580 emitpcode(POC_BSF, popGet(AOP(result),0));
5585 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5586 pic14_emitcode(";XXX setb","c");
5587 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5588 AOP(left)->aopu.aop_dir,tlbl->key+100);
5589 pic14_toBoolean(right);
5590 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5591 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5592 jmpTrueOrFalse(ifx, tlbl);
5596 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5603 pic14_outBitC(result);
5605 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5606 genIfxJump(ifx, "c");
5610 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5611 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5612 if((AOP_TYPE(right) == AOP_LIT) &&
5613 (AOP_TYPE(result) == AOP_CRY) &&
5614 (AOP_TYPE(left) != AOP_CRY)){
5616 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5619 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5621 continueIfTrue(ifx);
5624 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5625 // lit = 0, result = boolean(left)
5627 pic14_emitcode(";XXX setb","c");
5628 pic14_toBoolean(right);
5630 symbol *tlbl = newiTempLabel(NULL);
5631 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5633 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5635 genIfxJump (ifx,"a");
5639 pic14_outBitC(result);
5643 /* if left is same as result */
5644 if(pic14_sameRegs(AOP(result),AOP(left))){
5646 for(;size--; offset++,lit>>=8) {
5647 if(AOP_TYPE(right) == AOP_LIT){
5648 if((lit & 0xff) == 0)
5649 /* or'ing with 0 has no effect */
5652 int p = my_powof2(lit & 0xff);
5654 /* only one bit is set in the literal, so use a bsf instruction */
5656 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5658 if(know_W != (int)(lit & 0xff))
5659 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5660 know_W = lit & 0xff;
5661 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5666 if (AOP_TYPE(left) == AOP_ACC) {
5667 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5668 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5670 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5671 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5673 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5674 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5680 // left & result in different registers
5681 if(AOP_TYPE(result) == AOP_CRY){
5683 // if(size), result in bit
5684 // if(!size && ifx), conditional oper: if(left | right)
5685 symbol *tlbl = newiTempLabel(NULL);
5686 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5687 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5691 pic14_emitcode(";XXX setb","c");
5693 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5694 pic14_emitcode(";XXX orl","a,%s",
5695 aopGet(AOP(left),offset,FALSE,FALSE));
5696 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5702 pic14_outBitC(result);
5704 jmpTrueOrFalse(ifx, tlbl);
5705 } else for(;(size--);offset++){
5707 // result = left & right
5708 if(AOP_TYPE(right) == AOP_LIT){
5709 int t = (lit >> (offset*8)) & 0x0FFL;
5712 if (AOP_TYPE(left) != AOP_ACC) {
5713 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5715 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5719 if (AOP_TYPE(left) == AOP_ACC) {
5720 emitpcode(POC_IORLW, popGetLit(t));
5722 emitpcode(POC_MOVLW, popGetLit(t));
5723 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5725 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5730 // faster than result <- left, anl result,right
5731 // and better if result is SFR
5732 if (AOP_TYPE(left) == AOP_ACC) {
5733 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5734 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5736 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5737 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5739 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5740 pic14_emitcode("iorwf","%s,w",
5741 aopGet(AOP(left),offset,FALSE,FALSE));
5743 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5744 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5749 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5750 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5751 freeAsmop(result,NULL,ic,TRUE);
5754 /*-----------------------------------------------------------------*/
5755 /* genXor - code for xclusive or */
5756 /*-----------------------------------------------------------------*/
5757 static void genXor (iCode *ic, iCode *ifx)
5759 operand *left, *right, *result;
5761 unsigned long lit = 0L;
5763 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5765 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5766 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5767 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5769 /* if left is a literal & right is not ||
5770 if left needs acc & right does not */
5771 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5772 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5773 operand *tmp = right ;
5778 /* if result = right then exchange them */
5779 if(pic14_sameRegs(AOP(result),AOP(right))){
5780 operand *tmp = right ;
5785 /* if right is bit then exchange them */
5786 if (AOP_TYPE(right) == AOP_CRY &&
5787 AOP_TYPE(left) != AOP_CRY){
5788 operand *tmp = right ;
5792 if(AOP_TYPE(right) == AOP_LIT)
5793 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5795 size = AOP_SIZE(result);
5799 if (AOP_TYPE(left) == AOP_CRY){
5800 if(AOP_TYPE(right) == AOP_LIT){
5801 // c = bit & literal;
5803 // lit>>1 != 0 => result = 1
5804 if(AOP_TYPE(result) == AOP_CRY){
5806 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5807 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5809 continueIfTrue(ifx);
5812 pic14_emitcode("setb","c");
5816 // lit == 0, result = left
5817 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5819 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5821 // lit == 1, result = not(left)
5822 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5823 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5824 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5825 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5828 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5829 pic14_emitcode("cpl","c");
5836 symbol *tlbl = newiTempLabel(NULL);
5837 if (AOP_TYPE(right) == AOP_CRY){
5839 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5842 int sizer = AOP_SIZE(right);
5844 // if val>>1 != 0, result = 1
5845 pic14_emitcode("setb","c");
5847 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5849 // test the msb of the lsb
5850 pic14_emitcode("anl","a,#0xfe");
5851 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5855 pic14_emitcode("rrc","a");
5857 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5858 pic14_emitcode("cpl","c");
5859 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5864 pic14_outBitC(result);
5866 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5867 genIfxJump(ifx, "c");
5871 if(pic14_sameRegs(AOP(result),AOP(left))){
5872 /* if left is same as result */
5873 for(;size--; offset++) {
5874 if(AOP_TYPE(right) == AOP_LIT){
5875 int t = (lit >> (offset*8)) & 0x0FFL;
5879 if (IS_AOP_PREG(left)) {
5880 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5881 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5882 aopPut(AOP(result),"a",offset);
5884 emitpcode(POC_MOVLW, popGetLit(t));
5885 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5886 pic14_emitcode("xrl","%s,%s",
5887 aopGet(AOP(left),offset,FALSE,TRUE),
5888 aopGet(AOP(right),offset,FALSE,FALSE));
5891 if (AOP_TYPE(left) == AOP_ACC)
5892 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5894 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5895 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5897 if (IS_AOP_PREG(left)) {
5898 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5899 aopPut(AOP(result),"a",offset);
5901 pic14_emitcode("xrl","%s,a",
5902 aopGet(AOP(left),offset,FALSE,TRUE));
5908 // left & result in different registers
5909 if(AOP_TYPE(result) == AOP_CRY){
5911 // if(size), result in bit
5912 // if(!size && ifx), conditional oper: if(left ^ right)
5913 symbol *tlbl = newiTempLabel(NULL);
5914 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5916 pic14_emitcode("setb","c");
5918 if((AOP_TYPE(right) == AOP_LIT) &&
5919 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5920 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5922 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5923 pic14_emitcode("xrl","a,%s",
5924 aopGet(AOP(left),offset,FALSE,FALSE));
5926 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5931 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5932 pic14_outBitC(result);
5934 jmpTrueOrFalse(ifx, tlbl);
5935 } else for(;(size--);offset++){
5937 // result = left & right
5938 if(AOP_TYPE(right) == AOP_LIT){
5939 int t = (lit >> (offset*8)) & 0x0FFL;
5942 if (AOP_TYPE(left) != AOP_ACC) {
5943 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5945 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5946 pic14_emitcode("movf","%s,w",
5947 aopGet(AOP(left),offset,FALSE,FALSE));
5948 pic14_emitcode("movwf","%s",
5949 aopGet(AOP(result),offset,FALSE,FALSE));
5952 if (AOP_TYPE(left) == AOP_ACC) {
5953 emitpcode(POC_XORLW, popGetLit(t));
5955 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5957 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5960 if (AOP_TYPE(left) == AOP_ACC) {
5961 emitpcode(POC_XORLW, popGetLit(t));
5963 emitpcode(POC_MOVLW, popGetLit(t));
5964 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5966 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5967 pic14_emitcode("movlw","0x%x",t);
5968 pic14_emitcode("xorwf","%s,w",
5969 aopGet(AOP(left),offset,FALSE,FALSE));
5970 pic14_emitcode("movwf","%s",
5971 aopGet(AOP(result),offset,FALSE,FALSE));
5977 // faster than result <- left, anl result,right
5978 // and better if result is SFR
5979 if (AOP_TYPE(left) == AOP_ACC) {
5980 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5981 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5983 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5984 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5985 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5986 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5988 if ( AOP_TYPE(result) != AOP_ACC){
5989 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5990 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5996 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5997 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5998 freeAsmop(result,NULL,ic,TRUE);
6001 /*-----------------------------------------------------------------*/
6002 /* genInline - write the inline code out */
6003 /*-----------------------------------------------------------------*/
6004 static void genInline (iCode *ic)
6006 char *buffer, *bp, *bp1;
6008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6010 _G.inLine += (!options.asmpeep);
6012 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6013 strcpy(buffer,IC_INLINE(ic));
6015 /* emit each line as a code */
6021 addpCode2pBlock(pb,AssembleLine(bp1));
6028 pic14_emitcode(bp1,"");
6034 if ((bp1 != bp) && *bp1)
6035 addpCode2pBlock(pb,AssembleLine(bp1));
6039 _G.inLine -= (!options.asmpeep);
6042 /*-----------------------------------------------------------------*/
6043 /* genRRC - rotate right with carry */
6044 /*-----------------------------------------------------------------*/
6045 static void genRRC (iCode *ic)
6047 operand *left , *result ;
6048 int size, offset = 0, same;
6050 /* rotate right with carry */
6052 result=IC_RESULT(ic);
6053 aopOp (left,ic,FALSE);
6054 aopOp (result,ic,FALSE);
6056 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6058 same = pic14_sameRegs(AOP(result),AOP(left));
6060 size = AOP_SIZE(result);
6062 /* get the lsb and put it into the carry */
6063 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6070 emitpcode(POC_RRF, popGet(AOP(left),offset));
6072 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6073 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6079 freeAsmop(left,NULL,ic,TRUE);
6080 freeAsmop(result,NULL,ic,TRUE);
6083 /*-----------------------------------------------------------------*/
6084 /* genRLC - generate code for rotate left with carry */
6085 /*-----------------------------------------------------------------*/
6086 static void genRLC (iCode *ic)
6088 operand *left , *result ;
6089 int size, offset = 0;
6092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6093 /* rotate right with carry */
6095 result=IC_RESULT(ic);
6096 aopOp (left,ic,FALSE);
6097 aopOp (result,ic,FALSE);
6099 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6101 same = pic14_sameRegs(AOP(result),AOP(left));
6103 /* move it to the result */
6104 size = AOP_SIZE(result);
6106 /* get the msb and put it into the carry */
6107 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6114 emitpcode(POC_RLF, popGet(AOP(left),offset));
6116 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6117 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6124 freeAsmop(left,NULL,ic,TRUE);
6125 freeAsmop(result,NULL,ic,TRUE);
6128 /*-----------------------------------------------------------------*/
6129 /* genGetHbit - generates code get highest order bit */
6130 /*-----------------------------------------------------------------*/
6131 static void genGetHbit (iCode *ic)
6133 operand *left, *result;
6135 result=IC_RESULT(ic);
6136 aopOp (left,ic,FALSE);
6137 aopOp (result,ic,FALSE);
6139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6140 /* get the highest order byte into a */
6141 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6142 if(AOP_TYPE(result) == AOP_CRY){
6143 pic14_emitcode("rlc","a");
6144 pic14_outBitC(result);
6147 pic14_emitcode("rl","a");
6148 pic14_emitcode("anl","a,#0x01");
6149 pic14_outAcc(result);
6153 freeAsmop(left,NULL,ic,TRUE);
6154 freeAsmop(result,NULL,ic,TRUE);
6157 /*-----------------------------------------------------------------*/
6158 /* AccRol - rotate left accumulator by known count */
6159 /*-----------------------------------------------------------------*/
6160 static void AccRol (int shCount)
6162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6163 shCount &= 0x0007; // shCount : 0..7
6168 pic14_emitcode("rl","a");
6171 pic14_emitcode("rl","a");
6172 pic14_emitcode("rl","a");
6175 pic14_emitcode("swap","a");
6176 pic14_emitcode("rr","a");
6179 pic14_emitcode("swap","a");
6182 pic14_emitcode("swap","a");
6183 pic14_emitcode("rl","a");
6186 pic14_emitcode("rr","a");
6187 pic14_emitcode("rr","a");
6190 pic14_emitcode("rr","a");
6195 /*-----------------------------------------------------------------*/
6196 /* AccLsh - left shift accumulator by known count */
6197 /*-----------------------------------------------------------------*/
6198 static void AccLsh (int shCount)
6200 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6203 pic14_emitcode("add","a,acc");
6206 pic14_emitcode("add","a,acc");
6207 pic14_emitcode("add","a,acc");
6209 /* rotate left accumulator */
6211 /* and kill the lower order bits */
6212 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6217 /*-----------------------------------------------------------------*/
6218 /* AccRsh - right shift accumulator by known count */
6219 /*-----------------------------------------------------------------*/
6220 static void AccRsh (int shCount)
6222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6226 pic14_emitcode("rrc","a");
6228 /* rotate right accumulator */
6229 AccRol(8 - shCount);
6230 /* and kill the higher order bits */
6231 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6237 /*-----------------------------------------------------------------*/
6238 /* AccSRsh - signed right shift accumulator by known count */
6239 /*-----------------------------------------------------------------*/
6240 static void AccSRsh (int shCount)
6243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6246 pic14_emitcode("mov","c,acc.7");
6247 pic14_emitcode("rrc","a");
6248 } else if(shCount == 2){
6249 pic14_emitcode("mov","c,acc.7");
6250 pic14_emitcode("rrc","a");
6251 pic14_emitcode("mov","c,acc.7");
6252 pic14_emitcode("rrc","a");
6254 tlbl = newiTempLabel(NULL);
6255 /* rotate right accumulator */
6256 AccRol(8 - shCount);
6257 /* and kill the higher order bits */
6258 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6259 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6260 pic14_emitcode("orl","a,#0x%02x",
6261 (unsigned char)~SRMask[shCount]);
6262 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6267 /*-----------------------------------------------------------------*/
6268 /* shiftR1Left2Result - shift right one byte from left to result */
6269 /*-----------------------------------------------------------------*/
6270 static void shiftR1Left2ResultSigned (operand *left, int offl,
6271 operand *result, int offr,
6276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6278 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6282 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6284 emitpcode(POC_RRF, popGet(AOP(result),offr));
6286 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6287 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6293 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6295 emitpcode(POC_RRF, popGet(AOP(result),offr));
6297 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6298 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6300 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6301 emitpcode(POC_RRF, popGet(AOP(result),offr));
6307 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6309 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6310 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6313 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6314 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6315 emitpcode(POC_ANDLW, popGetLit(0x1f));
6317 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6318 emitpcode(POC_IORLW, popGetLit(0xe0));
6320 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6324 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6325 emitpcode(POC_ANDLW, popGetLit(0x0f));
6326 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6327 emitpcode(POC_IORLW, popGetLit(0xf0));
6328 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6332 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6334 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6335 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6337 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6338 emitpcode(POC_ANDLW, popGetLit(0x07));
6339 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6340 emitpcode(POC_IORLW, popGetLit(0xf8));
6341 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6346 emitpcode(POC_MOVLW, popGetLit(0x00));
6347 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6348 emitpcode(POC_MOVLW, popGetLit(0xfe));
6349 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6350 emitpcode(POC_IORLW, popGetLit(0x01));
6351 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6353 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6354 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6355 emitpcode(POC_DECF, popGet(AOP(result),offr));
6356 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6357 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6363 emitpcode(POC_MOVLW, popGetLit(0x00));
6364 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6365 emitpcode(POC_MOVLW, popGetLit(0xff));
6366 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6368 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6369 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6370 emitpcode(POC_DECF, popGet(AOP(result),offr));
6378 /*-----------------------------------------------------------------*/
6379 /* shiftR1Left2Result - shift right one byte from left to result */
6380 /*-----------------------------------------------------------------*/
6381 static void shiftR1Left2Result (operand *left, int offl,
6382 operand *result, int offr,
6383 int shCount, int sign)
6387 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6389 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6391 /* Copy the msb into the carry if signed. */
6393 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6403 emitpcode(POC_RRF, popGet(AOP(result),offr));
6405 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6406 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6412 emitpcode(POC_RRF, popGet(AOP(result),offr));
6414 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6415 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6418 emitpcode(POC_RRF, popGet(AOP(result),offr));
6423 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6425 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6426 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6429 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6430 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6431 emitpcode(POC_ANDLW, popGetLit(0x1f));
6432 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6436 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6437 emitpcode(POC_ANDLW, popGetLit(0x0f));
6438 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6442 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6443 emitpcode(POC_ANDLW, popGetLit(0x0f));
6444 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6446 emitpcode(POC_RRF, popGet(AOP(result),offr));
6451 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6452 emitpcode(POC_ANDLW, popGetLit(0x80));
6453 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6454 emitpcode(POC_RLF, popGet(AOP(result),offr));
6455 emitpcode(POC_RLF, popGet(AOP(result),offr));
6460 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6461 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6462 emitpcode(POC_RLF, popGet(AOP(result),offr));
6471 /*-----------------------------------------------------------------*/
6472 /* shiftL1Left2Result - shift left one byte from left to result */
6473 /*-----------------------------------------------------------------*/
6474 static void shiftL1Left2Result (operand *left, int offl,
6475 operand *result, int offr, int shCount)
6480 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6482 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6483 DEBUGpic14_emitcode ("; ***","same = %d",same);
6484 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6486 /* shift left accumulator */
6487 //AccLsh(shCount); // don't comment out just yet...
6488 // aopPut(AOP(result),"a",offr);
6492 /* Shift left 1 bit position */
6493 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6495 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6497 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6498 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6502 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6503 emitpcode(POC_ANDLW,popGetLit(0x7e));
6504 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6505 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6508 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6509 emitpcode(POC_ANDLW,popGetLit(0x3e));
6510 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6511 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6512 emitpcode(POC_RLF, popGet(AOP(result),offr));
6515 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6516 emitpcode(POC_ANDLW, popGetLit(0xf0));
6517 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6520 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6521 emitpcode(POC_ANDLW, popGetLit(0xf0));
6522 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6523 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6526 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6527 emitpcode(POC_ANDLW, popGetLit(0x30));
6528 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6529 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6530 emitpcode(POC_RLF, popGet(AOP(result),offr));
6533 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6534 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6535 emitpcode(POC_RRF, popGet(AOP(result),offr));
6539 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6544 /*-----------------------------------------------------------------*/
6545 /* movLeft2Result - move byte from left to result */
6546 /*-----------------------------------------------------------------*/
6547 static void movLeft2Result (operand *left, int offl,
6548 operand *result, int offr)
6551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6552 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6553 l = aopGet(AOP(left),offl,FALSE,FALSE);
6555 if (*l == '@' && (IS_AOP_PREG(result))) {
6556 pic14_emitcode("mov","a,%s",l);
6557 aopPut(AOP(result),"a",offr);
6559 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6560 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6565 /*-----------------------------------------------------------------*/
6566 /* shiftL2Left2Result - shift left two bytes from left to result */
6567 /*-----------------------------------------------------------------*/
6568 static void shiftL2Left2Result (operand *left, int offl,
6569 operand *result, int offr, int shCount)
6573 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6575 if(pic14_sameRegs(AOP(result), AOP(left))) {
6583 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6584 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6585 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6589 emitpcode(POC_RLF, popGet(AOP(result),offr));
6590 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6596 emitpcode(POC_MOVLW, popGetLit(0x0f));
6597 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6598 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6599 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6600 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6601 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6602 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6604 emitpcode(POC_RLF, popGet(AOP(result),offr));
6605 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6609 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6610 emitpcode(POC_RRF, popGet(AOP(result),offr));
6611 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6612 emitpcode(POC_RRF, popGet(AOP(result),offr));
6613 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6614 emitpcode(POC_ANDLW,popGetLit(0xc0));
6615 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6616 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6617 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6618 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6621 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6622 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6623 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6624 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6625 emitpcode(POC_RRF, popGet(AOP(result),offr));
6635 /* note, use a mov/add for the shift since the mov has a
6636 chance of getting optimized out */
6637 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6638 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6639 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6640 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6641 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6645 emitpcode(POC_RLF, popGet(AOP(result),offr));
6646 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6652 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6653 emitpcode(POC_ANDLW, popGetLit(0xF0));
6654 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6655 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6656 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6657 emitpcode(POC_ANDLW, popGetLit(0xF0));
6658 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6659 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6663 emitpcode(POC_RLF, popGet(AOP(result),offr));
6664 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6669 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6671 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6673 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_RRF, popGet(AOP(result),offr));
6675 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6676 emitpcode(POC_ANDLW,popGetLit(0xc0));
6677 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6678 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6679 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6680 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6684 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6685 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6686 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6687 emitpcode(POC_RRF, popGet(AOP(result),offr));
6692 /*-----------------------------------------------------------------*/
6693 /* shiftR2Left2Result - shift right two bytes from left to result */
6694 /*-----------------------------------------------------------------*/
6695 static void shiftR2Left2Result (operand *left, int offl,
6696 operand *result, int offr,
6697 int shCount, int sign)
6701 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6702 same = pic14_sameRegs(AOP(result), AOP(left));
6704 if(same && ((offl + MSB16) == offr)){
6706 /* don't crash result[offr] */
6707 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6708 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6711 movLeft2Result(left,offl, result, offr);
6712 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6715 /* a:x >> shCount (x = lsb(result))*/
6718 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6720 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6729 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6734 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_RRF,popGet(AOP(result),offr));
6737 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6738 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6740 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6745 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6748 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6749 emitpcode(POC_RRF,popGet(AOP(result),offr));
6756 emitpcode(POC_MOVLW, popGetLit(0xf0));
6757 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6758 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6760 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6761 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6762 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6763 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6765 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6766 emitpcode(POC_ANDLW, popGetLit(0x0f));
6767 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6769 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6770 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6771 emitpcode(POC_ANDLW, popGetLit(0xf0));
6772 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6777 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6778 emitpcode(POC_RRF, popGet(AOP(result),offr));
6782 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6783 emitpcode(POC_BTFSC,
6784 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6785 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6793 emitpcode(POC_RLF, popGet(AOP(result),offr));
6794 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6796 emitpcode(POC_RLF, popGet(AOP(result),offr));
6797 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6798 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6799 emitpcode(POC_ANDLW,popGetLit(0x03));
6801 emitpcode(POC_BTFSC,
6802 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6803 emitpcode(POC_IORLW,popGetLit(0xfc));
6805 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6806 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6807 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6810 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6811 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6812 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6813 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6814 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6815 emitpcode(POC_RLF, popGet(AOP(result),offr));
6816 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_ANDLW,popGetLit(0x03));
6819 emitpcode(POC_BTFSC,
6820 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6821 emitpcode(POC_IORLW,popGetLit(0xfc));
6823 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6824 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6831 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6832 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6833 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6834 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6837 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6844 /*-----------------------------------------------------------------*/
6845 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6846 /*-----------------------------------------------------------------*/
6847 static void shiftLLeftOrResult (operand *left, int offl,
6848 operand *result, int offr, int shCount)
6850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6851 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6852 /* shift left accumulator */
6854 /* or with result */
6855 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6856 /* back to result */
6857 aopPut(AOP(result),"a",offr);
6860 /*-----------------------------------------------------------------*/
6861 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6862 /*-----------------------------------------------------------------*/
6863 static void shiftRLeftOrResult (operand *left, int offl,
6864 operand *result, int offr, int shCount)
6866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6867 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6868 /* shift right accumulator */
6870 /* or with result */
6871 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6872 /* back to result */
6873 aopPut(AOP(result),"a",offr);
6876 /*-----------------------------------------------------------------*/
6877 /* genlshOne - left shift a one byte quantity by known count */
6878 /*-----------------------------------------------------------------*/
6879 static void genlshOne (operand *result, operand *left, int shCount)
6881 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6882 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6885 /*-----------------------------------------------------------------*/
6886 /* genlshTwo - left shift two bytes by known amount != 0 */
6887 /*-----------------------------------------------------------------*/
6888 static void genlshTwo (operand *result,operand *left, int shCount)
6892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6893 size = pic14_getDataSize(result);
6895 /* if shCount >= 8 */
6901 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6903 movLeft2Result(left, LSB, result, MSB16);
6905 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6908 /* 1 <= shCount <= 7 */
6911 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6913 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6917 /*-----------------------------------------------------------------*/
6918 /* shiftLLong - shift left one long from left to result */
6919 /* offl = LSB or MSB16 */
6920 /*-----------------------------------------------------------------*/
6921 static void shiftLLong (operand *left, operand *result, int offr )
6924 int size = AOP_SIZE(result);
6926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 if(size >= LSB+offr){
6928 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6930 pic14_emitcode("add","a,acc");
6931 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6932 size >= MSB16+offr && offr != LSB )
6933 pic14_emitcode("xch","a,%s",
6934 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6936 aopPut(AOP(result),"a",LSB+offr);
6939 if(size >= MSB16+offr){
6940 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6941 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6944 pic14_emitcode("rlc","a");
6945 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6946 size >= MSB24+offr && offr != LSB)
6947 pic14_emitcode("xch","a,%s",
6948 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6950 aopPut(AOP(result),"a",MSB16+offr);
6953 if(size >= MSB24+offr){
6954 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6955 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6958 pic14_emitcode("rlc","a");
6959 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6960 size >= MSB32+offr && offr != LSB )
6961 pic14_emitcode("xch","a,%s",
6962 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6964 aopPut(AOP(result),"a",MSB24+offr);
6967 if(size > MSB32+offr){
6968 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6969 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6972 pic14_emitcode("rlc","a");
6973 aopPut(AOP(result),"a",MSB32+offr);
6976 aopPut(AOP(result),zero,LSB);
6979 /*-----------------------------------------------------------------*/
6980 /* genlshFour - shift four byte by a known amount != 0 */
6981 /*-----------------------------------------------------------------*/
6982 static void genlshFour (operand *result, operand *left, int shCount)
6986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 size = AOP_SIZE(result);
6989 /* if shifting more that 3 bytes */
6990 if (shCount >= 24 ) {
6993 /* lowest order of left goes to the highest
6994 order of the destination */
6995 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6997 movLeft2Result(left, LSB, result, MSB32);
6998 aopPut(AOP(result),zero,LSB);
6999 aopPut(AOP(result),zero,MSB16);
7000 aopPut(AOP(result),zero,MSB32);
7004 /* more than two bytes */
7005 else if ( shCount >= 16 ) {
7006 /* lower order two bytes goes to higher order two bytes */
7008 /* if some more remaining */
7010 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7012 movLeft2Result(left, MSB16, result, MSB32);
7013 movLeft2Result(left, LSB, result, MSB24);
7015 aopPut(AOP(result),zero,MSB16);
7016 aopPut(AOP(result),zero,LSB);
7020 /* if more than 1 byte */
7021 else if ( shCount >= 8 ) {
7022 /* lower order three bytes goes to higher order three bytes */
7026 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7028 movLeft2Result(left, LSB, result, MSB16);
7030 else{ /* size = 4 */
7032 movLeft2Result(left, MSB24, result, MSB32);
7033 movLeft2Result(left, MSB16, result, MSB24);
7034 movLeft2Result(left, LSB, result, MSB16);
7035 aopPut(AOP(result),zero,LSB);
7037 else if(shCount == 1)
7038 shiftLLong(left, result, MSB16);
7040 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7041 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7042 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7043 aopPut(AOP(result),zero,LSB);
7048 /* 1 <= shCount <= 7 */
7049 else if(shCount <= 2){
7050 shiftLLong(left, result, LSB);
7052 shiftLLong(result, result, LSB);
7054 /* 3 <= shCount <= 7, optimize */
7056 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7057 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7058 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7062 /*-----------------------------------------------------------------*/
7063 /* genLeftShiftLiteral - left shifting by known count */
7064 /*-----------------------------------------------------------------*/
7065 static void genLeftShiftLiteral (operand *left,
7070 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7074 freeAsmop(right,NULL,ic,TRUE);
7076 aopOp(left,ic,FALSE);
7077 aopOp(result,ic,FALSE);
7079 size = getSize(operandType(result));
7082 pic14_emitcode("; shift left ","result %d, left %d",size,
7086 /* I suppose that the left size >= result size */
7089 movLeft2Result(left, size, result, size);
7093 else if(shCount >= (size * 8))
7095 aopPut(AOP(result),zero,size);
7099 genlshOne (result,left,shCount);
7104 genlshTwo (result,left,shCount);
7108 genlshFour (result,left,shCount);
7112 freeAsmop(left,NULL,ic,TRUE);
7113 freeAsmop(result,NULL,ic,TRUE);
7116 /*-----------------------------------------------------------------*
7117 * genMultiAsm - repeat assembly instruction for size of register.
7118 * if endian == 1, then the high byte (i.e base address + size of
7119 * register) is used first else the low byte is used first;
7120 *-----------------------------------------------------------------*/
7121 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7139 emitpcode(poc, popGet(AOP(reg),offset));
7144 /*-----------------------------------------------------------------*/
7145 /* genLeftShift - generates code for left shifting */
7146 /*-----------------------------------------------------------------*/
7147 static void genLeftShift (iCode *ic)
7149 operand *left,*right, *result;
7152 symbol *tlbl , *tlbl1;
7155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7157 right = IC_RIGHT(ic);
7159 result = IC_RESULT(ic);
7161 aopOp(right,ic,FALSE);
7163 /* if the shift count is known then do it
7164 as efficiently as possible */
7165 if (AOP_TYPE(right) == AOP_LIT) {
7166 genLeftShiftLiteral (left,right,result,ic);
7170 /* shift count is unknown then we have to form
7171 a loop get the loop count in B : Note: we take
7172 only the lower order byte since shifting
7173 more that 32 bits make no sense anyway, ( the
7174 largest size of an object can be only 32 bits ) */
7177 aopOp(left,ic,FALSE);
7178 aopOp(result,ic,FALSE);
7180 /* now move the left to the result if they are not the
7182 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7183 AOP_SIZE(result) > 1) {
7185 size = AOP_SIZE(result);
7188 l = aopGet(AOP(left),offset,FALSE,TRUE);
7189 if (*l == '@' && (IS_AOP_PREG(result))) {
7191 pic14_emitcode("mov","a,%s",l);
7192 aopPut(AOP(result),"a",offset);
7194 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7195 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7196 //aopPut(AOP(result),l,offset);
7202 size = AOP_SIZE(result);
7204 /* if it is only one byte then */
7206 if(optimized_for_speed) {
7207 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7208 emitpcode(POC_ANDLW, popGetLit(0xf0));
7209 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7210 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7211 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7212 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7213 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7214 emitpcode(POC_RLFW, popGet(AOP(result),0));
7215 emitpcode(POC_ANDLW, popGetLit(0xfe));
7216 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7217 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7218 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7221 tlbl = newiTempLabel(NULL);
7222 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7223 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7224 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7227 emitpcode(POC_COMFW, popGet(AOP(right),0));
7228 emitpcode(POC_RRF, popGet(AOP(result),0));
7229 emitpLabel(tlbl->key);
7230 emitpcode(POC_RLF, popGet(AOP(result),0));
7231 emitpcode(POC_ADDLW, popGetLit(1));
7233 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7238 if (pic14_sameRegs(AOP(left),AOP(result))) {
7240 tlbl = newiTempLabel(NULL);
7241 emitpcode(POC_COMFW, popGet(AOP(right),0));
7242 genMultiAsm(POC_RRF, result, size,1);
7243 emitpLabel(tlbl->key);
7244 genMultiAsm(POC_RLF, result, size,0);
7245 emitpcode(POC_ADDLW, popGetLit(1));
7247 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7251 //tlbl = newiTempLabel(NULL);
7253 //tlbl1 = newiTempLabel(NULL);
7255 //reAdjustPreg(AOP(result));
7257 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7258 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7259 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7261 //pic14_emitcode("add","a,acc");
7262 //aopPut(AOP(result),"a",offset++);
7264 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7266 // pic14_emitcode("rlc","a");
7267 // aopPut(AOP(result),"a",offset++);
7269 //reAdjustPreg(AOP(result));
7271 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7272 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7275 tlbl = newiTempLabel(NULL);
7276 tlbl1= newiTempLabel(NULL);
7278 size = AOP_SIZE(result);
7281 pctemp = popGetTempReg(); /* grab a temporary working register. */
7283 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7285 /* offset should be 0, 1 or 3 */
7286 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7288 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7290 emitpcode(POC_MOVWF, pctemp);
7293 emitpLabel(tlbl->key);
7296 emitpcode(POC_RLF, popGet(AOP(result),0));
7298 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7300 emitpcode(POC_DECFSZ, pctemp);
7301 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7302 emitpLabel(tlbl1->key);
7304 popReleaseTempReg(pctemp);
7308 freeAsmop (right,NULL,ic,TRUE);
7309 freeAsmop(left,NULL,ic,TRUE);
7310 freeAsmop(result,NULL,ic,TRUE);
7313 /*-----------------------------------------------------------------*/
7314 /* genrshOne - right shift a one byte quantity by known count */
7315 /*-----------------------------------------------------------------*/
7316 static void genrshOne (operand *result, operand *left,
7317 int shCount, int sign)
7319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7320 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7323 /*-----------------------------------------------------------------*/
7324 /* genrshTwo - right shift two bytes by known amount != 0 */
7325 /*-----------------------------------------------------------------*/
7326 static void genrshTwo (operand *result,operand *left,
7327 int shCount, int sign)
7329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7330 /* if shCount >= 8 */
7334 shiftR1Left2Result(left, MSB16, result, LSB,
7337 movLeft2Result(left, MSB16, result, LSB);
7339 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7342 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7343 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7347 /* 1 <= shCount <= 7 */
7349 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7352 /*-----------------------------------------------------------------*/
7353 /* shiftRLong - shift right one long from left to result */
7354 /* offl = LSB or MSB16 */
7355 /*-----------------------------------------------------------------*/
7356 static void shiftRLong (operand *left, int offl,
7357 operand *result, int sign)
7359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7361 pic14_emitcode("clr","c");
7362 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7364 pic14_emitcode("mov","c,acc.7");
7365 pic14_emitcode("rrc","a");
7366 aopPut(AOP(result),"a",MSB32-offl);
7368 /* add sign of "a" */
7369 addSign(result, MSB32, sign);
7371 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7372 pic14_emitcode("rrc","a");
7373 aopPut(AOP(result),"a",MSB24-offl);
7375 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7376 pic14_emitcode("rrc","a");
7377 aopPut(AOP(result),"a",MSB16-offl);
7380 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7381 pic14_emitcode("rrc","a");
7382 aopPut(AOP(result),"a",LSB);
7386 /*-----------------------------------------------------------------*/
7387 /* genrshFour - shift four byte by a known amount != 0 */
7388 /*-----------------------------------------------------------------*/
7389 static void genrshFour (operand *result, operand *left,
7390 int shCount, int sign)
7392 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7393 /* if shifting more that 3 bytes */
7394 if(shCount >= 24 ) {
7397 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7399 movLeft2Result(left, MSB32, result, LSB);
7401 addSign(result, MSB16, sign);
7403 else if(shCount >= 16){
7406 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7408 movLeft2Result(left, MSB24, result, LSB);
7409 movLeft2Result(left, MSB32, result, MSB16);
7411 addSign(result, MSB24, sign);
7413 else if(shCount >= 8){
7416 shiftRLong(left, MSB16, result, sign);
7417 else if(shCount == 0){
7418 movLeft2Result(left, MSB16, result, LSB);
7419 movLeft2Result(left, MSB24, result, MSB16);
7420 movLeft2Result(left, MSB32, result, MSB24);
7421 addSign(result, MSB32, sign);
7424 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7425 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7426 /* the last shift is signed */
7427 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7428 addSign(result, MSB32, sign);
7431 else{ /* 1 <= shCount <= 7 */
7433 shiftRLong(left, LSB, result, sign);
7435 shiftRLong(result, LSB, result, sign);
7438 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7439 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7440 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7445 /*-----------------------------------------------------------------*/
7446 /* genRightShiftLiteral - right shifting by known count */
7447 /*-----------------------------------------------------------------*/
7448 static void genRightShiftLiteral (operand *left,
7454 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7458 freeAsmop(right,NULL,ic,TRUE);
7460 aopOp(left,ic,FALSE);
7461 aopOp(result,ic,FALSE);
7464 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7468 lsize = pic14_getDataSize(left);
7469 res_size = pic14_getDataSize(result);
7470 /* test the LEFT size !!! */
7472 /* I suppose that the left size >= result size */
7475 movLeft2Result(left, lsize, result, res_size);
7478 else if(shCount >= (lsize * 8)){
7481 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7483 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7484 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7489 emitpcode(POC_MOVLW, popGetLit(0));
7490 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7491 emitpcode(POC_MOVLW, popGetLit(0xff));
7493 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7498 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7505 genrshOne (result,left,shCount,sign);
7509 genrshTwo (result,left,shCount,sign);
7513 genrshFour (result,left,shCount,sign);
7521 freeAsmop(left,NULL,ic,TRUE);
7522 freeAsmop(result,NULL,ic,TRUE);
7525 /*-----------------------------------------------------------------*/
7526 /* genSignedRightShift - right shift of signed number */
7527 /*-----------------------------------------------------------------*/
7528 static void genSignedRightShift (iCode *ic)
7530 operand *right, *left, *result;
7533 symbol *tlbl, *tlbl1 ;
7536 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7538 /* we do it the hard way put the shift count in b
7539 and loop thru preserving the sign */
7540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7542 right = IC_RIGHT(ic);
7544 result = IC_RESULT(ic);
7546 aopOp(right,ic,FALSE);
7547 aopOp(left,ic,FALSE);
7548 aopOp(result,ic,FALSE);
7551 if ( AOP_TYPE(right) == AOP_LIT) {
7552 genRightShiftLiteral (left,right,result,ic,1);
7555 /* shift count is unknown then we have to form
7556 a loop get the loop count in B : Note: we take
7557 only the lower order byte since shifting
7558 more that 32 bits make no sense anyway, ( the
7559 largest size of an object can be only 32 bits ) */
7561 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7562 //pic14_emitcode("inc","b");
7563 //freeAsmop (right,NULL,ic,TRUE);
7564 //aopOp(left,ic,FALSE);
7565 //aopOp(result,ic,FALSE);
7567 /* now move the left to the result if they are not the
7569 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7570 AOP_SIZE(result) > 1) {
7572 size = AOP_SIZE(result);
7576 l = aopGet(AOP(left),offset,FALSE,TRUE);
7577 if (*l == '@' && IS_AOP_PREG(result)) {
7579 pic14_emitcode("mov","a,%s",l);
7580 aopPut(AOP(result),"a",offset);
7582 aopPut(AOP(result),l,offset);
7584 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7585 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7591 /* mov the highest order bit to OVR */
7592 tlbl = newiTempLabel(NULL);
7593 tlbl1= newiTempLabel(NULL);
7595 size = AOP_SIZE(result);
7598 pctemp = popGetTempReg(); /* grab a temporary working register. */
7600 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7602 /* offset should be 0, 1 or 3 */
7603 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7605 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7607 emitpcode(POC_MOVWF, pctemp);
7610 emitpLabel(tlbl->key);
7612 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7613 emitpcode(POC_RRF, popGet(AOP(result),offset));
7616 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7619 emitpcode(POC_DECFSZ, pctemp);
7620 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7621 emitpLabel(tlbl1->key);
7623 popReleaseTempReg(pctemp);
7625 size = AOP_SIZE(result);
7627 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7628 pic14_emitcode("rlc","a");
7629 pic14_emitcode("mov","ov,c");
7630 /* if it is only one byte then */
7632 l = aopGet(AOP(left),0,FALSE,FALSE);
7634 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7635 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7636 pic14_emitcode("mov","c,ov");
7637 pic14_emitcode("rrc","a");
7638 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7639 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7640 aopPut(AOP(result),"a",0);
7644 reAdjustPreg(AOP(result));
7645 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7646 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7647 pic14_emitcode("mov","c,ov");
7649 l = aopGet(AOP(result),offset,FALSE,FALSE);
7651 pic14_emitcode("rrc","a");
7652 aopPut(AOP(result),"a",offset--);
7654 reAdjustPreg(AOP(result));
7655 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7656 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7661 freeAsmop(left,NULL,ic,TRUE);
7662 freeAsmop(result,NULL,ic,TRUE);
7663 freeAsmop(right,NULL,ic,TRUE);
7666 /*-----------------------------------------------------------------*/
7667 /* genRightShift - generate code for right shifting */
7668 /*-----------------------------------------------------------------*/
7669 static void genRightShift (iCode *ic)
7671 operand *right, *left, *result;
7675 symbol *tlbl, *tlbl1 ;
7677 /* if signed then we do it the hard way preserve the
7678 sign bit moving it inwards */
7679 retype = getSpec(operandType(IC_RESULT(ic)));
7680 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7682 if (!SPEC_USIGN(retype)) {
7683 genSignedRightShift (ic);
7687 /* signed & unsigned types are treated the same : i.e. the
7688 signed is NOT propagated inwards : quoting from the
7689 ANSI - standard : "for E1 >> E2, is equivalent to division
7690 by 2**E2 if unsigned or if it has a non-negative value,
7691 otherwise the result is implementation defined ", MY definition
7692 is that the sign does not get propagated */
7694 right = IC_RIGHT(ic);
7696 result = IC_RESULT(ic);
7698 aopOp(right,ic,FALSE);
7700 /* if the shift count is known then do it
7701 as efficiently as possible */
7702 if (AOP_TYPE(right) == AOP_LIT) {
7703 genRightShiftLiteral (left,right,result,ic, 0);
7707 /* shift count is unknown then we have to form
7708 a loop get the loop count in B : Note: we take
7709 only the lower order byte since shifting
7710 more that 32 bits make no sense anyway, ( the
7711 largest size of an object can be only 32 bits ) */
7713 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7714 pic14_emitcode("inc","b");
7715 aopOp(left,ic,FALSE);
7716 aopOp(result,ic,FALSE);
7718 /* now move the left to the result if they are not the
7720 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7721 AOP_SIZE(result) > 1) {
7723 size = AOP_SIZE(result);
7726 l = aopGet(AOP(left),offset,FALSE,TRUE);
7727 if (*l == '@' && IS_AOP_PREG(result)) {
7729 pic14_emitcode("mov","a,%s",l);
7730 aopPut(AOP(result),"a",offset);
7732 aopPut(AOP(result),l,offset);
7737 tlbl = newiTempLabel(NULL);
7738 tlbl1= newiTempLabel(NULL);
7739 size = AOP_SIZE(result);
7742 /* if it is only one byte then */
7745 tlbl = newiTempLabel(NULL);
7746 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7747 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7748 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7751 emitpcode(POC_COMFW, popGet(AOP(right),0));
7752 emitpcode(POC_RLF, popGet(AOP(result),0));
7753 emitpLabel(tlbl->key);
7754 emitpcode(POC_RRF, popGet(AOP(result),0));
7755 emitpcode(POC_ADDLW, popGetLit(1));
7757 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7762 reAdjustPreg(AOP(result));
7763 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7764 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7767 l = aopGet(AOP(result),offset,FALSE,FALSE);
7769 pic14_emitcode("rrc","a");
7770 aopPut(AOP(result),"a",offset--);
7772 reAdjustPreg(AOP(result));
7774 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7775 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7778 freeAsmop(left,NULL,ic,TRUE);
7779 freeAsmop (right,NULL,ic,TRUE);
7780 freeAsmop(result,NULL,ic,TRUE);
7783 /*-----------------------------------------------------------------*/
7784 /* genUnpackBits - generates code for unpacking bits */
7785 /*-----------------------------------------------------------------*/
7786 static void genUnpackBits (operand *result, char *rname, int ptype)
7793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7794 etype = getSpec(operandType(result));
7796 /* read the first byte */
7801 pic14_emitcode("mov","a,@%s",rname);
7805 pic14_emitcode("movx","a,@%s",rname);
7809 pic14_emitcode("movx","a,@dptr");
7813 pic14_emitcode("clr","a");
7814 pic14_emitcode("movc","a","@a+dptr");
7818 pic14_emitcode("lcall","__gptrget");
7822 /* if we have bitdisplacement then it fits */
7823 /* into this byte completely or if length is */
7824 /* less than a byte */
7825 if ((shCnt = SPEC_BSTR(etype)) ||
7826 (SPEC_BLEN(etype) <= 8)) {
7828 /* shift right acc */
7831 pic14_emitcode("anl","a,#0x%02x",
7832 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7833 aopPut(AOP(result),"a",offset);
7837 /* bit field did not fit in a byte */
7838 rlen = SPEC_BLEN(etype) - 8;
7839 aopPut(AOP(result),"a",offset++);
7846 pic14_emitcode("inc","%s",rname);
7847 pic14_emitcode("mov","a,@%s",rname);
7851 pic14_emitcode("inc","%s",rname);
7852 pic14_emitcode("movx","a,@%s",rname);
7856 pic14_emitcode("inc","dptr");
7857 pic14_emitcode("movx","a,@dptr");
7861 pic14_emitcode("clr","a");
7862 pic14_emitcode("inc","dptr");
7863 pic14_emitcode("movc","a","@a+dptr");
7867 pic14_emitcode("inc","dptr");
7868 pic14_emitcode("lcall","__gptrget");
7873 /* if we are done */
7877 aopPut(AOP(result),"a",offset++);
7882 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7883 aopPut(AOP(result),"a",offset);
7890 /*-----------------------------------------------------------------*/
7891 /* genDataPointerGet - generates code when ptr offset is known */
7892 /*-----------------------------------------------------------------*/
7893 static void genDataPointerGet (operand *left,
7897 int size , offset = 0;
7900 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7903 /* optimization - most of the time, left and result are the same
7904 * address, but different types. for the pic code, we could omit
7908 aopOp(result,ic,TRUE);
7910 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7912 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7914 size = AOP_SIZE(result);
7917 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7921 freeAsmop(left,NULL,ic,TRUE);
7922 freeAsmop(result,NULL,ic,TRUE);
7925 /*-----------------------------------------------------------------*/
7926 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7927 /*-----------------------------------------------------------------*/
7928 static void genNearPointerGet (operand *left,
7933 //regs *preg = NULL ;
7935 sym_link *rtype, *retype;
7936 sym_link *ltype = operandType(left);
7939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7941 rtype = operandType(result);
7942 retype= getSpec(rtype);
7944 aopOp(left,ic,FALSE);
7946 /* if left is rematerialisable and
7947 result is not bit variable type and
7948 the left is pointer to data space i.e
7949 lower 128 bytes of space */
7950 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7951 !IS_BITVAR(retype) &&
7952 DCL_TYPE(ltype) == POINTER) {
7953 //genDataPointerGet (left,result,ic);
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7959 /* if the value is already in a pointer register
7960 then don't need anything more */
7961 if (!AOP_INPREG(AOP(left))) {
7962 /* otherwise get a free pointer register */
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 preg = getFreePtr(ic,&aop,FALSE);
7967 pic14_emitcode("mov","%s,%s",
7969 aopGet(AOP(left),0,FALSE,TRUE));
7970 rname = preg->name ;
7974 rname = aopGet(AOP(left),0,FALSE,FALSE);
7976 aopOp (result,ic,FALSE);
7978 /* if bitfield then unpack the bits */
7979 if (IS_BITFIELD(retype))
7980 genUnpackBits (result,rname,POINTER);
7982 /* we have can just get the values */
7983 int size = AOP_SIZE(result);
7986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7988 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7989 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7991 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7992 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7994 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7998 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8000 pic14_emitcode("mov","a,@%s",rname);
8001 aopPut(AOP(result),"a",offset);
8003 sprintf(buffer,"@%s",rname);
8004 aopPut(AOP(result),buffer,offset);
8008 pic14_emitcode("inc","%s",rname);
8013 /* now some housekeeping stuff */
8015 /* we had to allocate for this iCode */
8016 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8017 freeAsmop(NULL,aop,ic,TRUE);
8019 /* we did not allocate which means left
8020 already in a pointer register, then
8021 if size > 0 && this could be used again
8022 we have to point it back to where it
8024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8025 if (AOP_SIZE(result) > 1 &&
8026 !OP_SYMBOL(left)->remat &&
8027 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8029 int size = AOP_SIZE(result) - 1;
8031 pic14_emitcode("dec","%s",rname);
8036 freeAsmop(left,NULL,ic,TRUE);
8037 freeAsmop(result,NULL,ic,TRUE);
8041 /*-----------------------------------------------------------------*/
8042 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8043 /*-----------------------------------------------------------------*/
8044 static void genPagedPointerGet (operand *left,
8051 sym_link *rtype, *retype;
8053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8055 rtype = operandType(result);
8056 retype= getSpec(rtype);
8058 aopOp(left,ic,FALSE);
8060 /* if the value is already in a pointer register
8061 then don't need anything more */
8062 if (!AOP_INPREG(AOP(left))) {
8063 /* otherwise get a free pointer register */
8065 preg = getFreePtr(ic,&aop,FALSE);
8066 pic14_emitcode("mov","%s,%s",
8068 aopGet(AOP(left),0,FALSE,TRUE));
8069 rname = preg->name ;
8071 rname = aopGet(AOP(left),0,FALSE,FALSE);
8073 freeAsmop(left,NULL,ic,TRUE);
8074 aopOp (result,ic,FALSE);
8076 /* if bitfield then unpack the bits */
8077 if (IS_BITFIELD(retype))
8078 genUnpackBits (result,rname,PPOINTER);
8080 /* we have can just get the values */
8081 int size = AOP_SIZE(result);
8086 pic14_emitcode("movx","a,@%s",rname);
8087 aopPut(AOP(result),"a",offset);
8092 pic14_emitcode("inc","%s",rname);
8096 /* now some housekeeping stuff */
8098 /* we had to allocate for this iCode */
8099 freeAsmop(NULL,aop,ic,TRUE);
8101 /* we did not allocate which means left
8102 already in a pointer register, then
8103 if size > 0 && this could be used again
8104 we have to point it back to where it
8106 if (AOP_SIZE(result) > 1 &&
8107 !OP_SYMBOL(left)->remat &&
8108 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8110 int size = AOP_SIZE(result) - 1;
8112 pic14_emitcode("dec","%s",rname);
8117 freeAsmop(result,NULL,ic,TRUE);
8122 /*-----------------------------------------------------------------*/
8123 /* genFarPointerGet - gget value from far space */
8124 /*-----------------------------------------------------------------*/
8125 static void genFarPointerGet (operand *left,
8126 operand *result, iCode *ic)
8129 sym_link *retype = getSpec(operandType(result));
8131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8133 aopOp(left,ic,FALSE);
8135 /* if the operand is already in dptr
8136 then we do nothing else we move the value to dptr */
8137 if (AOP_TYPE(left) != AOP_STR) {
8138 /* if this is remateriazable */
8139 if (AOP_TYPE(left) == AOP_IMMD)
8140 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8141 else { /* we need to get it byte by byte */
8142 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8143 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8144 if (options.model == MODEL_FLAT24)
8146 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8150 /* so dptr know contains the address */
8151 freeAsmop(left,NULL,ic,TRUE);
8152 aopOp(result,ic,FALSE);
8154 /* if bit then unpack */
8155 if (IS_BITFIELD(retype))
8156 genUnpackBits(result,"dptr",FPOINTER);
8158 size = AOP_SIZE(result);
8162 pic14_emitcode("movx","a,@dptr");
8163 aopPut(AOP(result),"a",offset++);
8165 pic14_emitcode("inc","dptr");
8169 freeAsmop(result,NULL,ic,TRUE);
8172 /*-----------------------------------------------------------------*/
8173 /* genCodePointerGet - get value from code space */
8174 /*-----------------------------------------------------------------*/
8175 static void genCodePointerGet (operand *left,
8176 operand *result, iCode *ic)
8179 sym_link *retype = getSpec(operandType(result));
8181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8183 aopOp(left,ic,FALSE);
8185 /* if the operand is already in dptr
8186 then we do nothing else we move the value to dptr */
8187 if (AOP_TYPE(left) != AOP_STR) {
8188 /* if this is remateriazable */
8189 if (AOP_TYPE(left) == AOP_IMMD)
8190 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8191 else { /* we need to get it byte by byte */
8192 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8193 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8194 if (options.model == MODEL_FLAT24)
8196 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8200 /* so dptr know contains the address */
8201 freeAsmop(left,NULL,ic,TRUE);
8202 aopOp(result,ic,FALSE);
8204 /* if bit then unpack */
8205 if (IS_BITFIELD(retype))
8206 genUnpackBits(result,"dptr",CPOINTER);
8208 size = AOP_SIZE(result);
8212 pic14_emitcode("clr","a");
8213 pic14_emitcode("movc","a,@a+dptr");
8214 aopPut(AOP(result),"a",offset++);
8216 pic14_emitcode("inc","dptr");
8220 freeAsmop(result,NULL,ic,TRUE);
8223 /*-----------------------------------------------------------------*/
8224 /* genGenPointerGet - gget value from generic pointer space */
8225 /*-----------------------------------------------------------------*/
8226 static void genGenPointerGet (operand *left,
8227 operand *result, iCode *ic)
8230 sym_link *retype = getSpec(operandType(result));
8232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8233 aopOp(left,ic,FALSE);
8234 aopOp(result,ic,FALSE);
8237 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8239 /* if the operand is already in dptr
8240 then we do nothing else we move the value to dptr */
8241 // if (AOP_TYPE(left) != AOP_STR) {
8242 /* if this is remateriazable */
8243 if (AOP_TYPE(left) == AOP_IMMD) {
8244 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8245 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8247 else { /* we need to get it byte by byte */
8249 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8250 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8252 size = AOP_SIZE(result);
8256 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8257 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8259 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8264 /* so dptr know contains the address */
8266 /* if bit then unpack */
8267 //if (IS_BITFIELD(retype))
8268 // genUnpackBits(result,"dptr",GPOINTER);
8271 freeAsmop(left,NULL,ic,TRUE);
8272 freeAsmop(result,NULL,ic,TRUE);
8276 /*-----------------------------------------------------------------*/
8277 /* genConstPointerGet - get value from const generic pointer space */
8278 /*-----------------------------------------------------------------*/
8279 static void genConstPointerGet (operand *left,
8280 operand *result, iCode *ic)
8282 //sym_link *retype = getSpec(operandType(result));
8283 symbol *albl = newiTempLabel(NULL);
8284 symbol *blbl = newiTempLabel(NULL);
8288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8289 aopOp(left,ic,FALSE);
8290 aopOp(result,ic,FALSE);
8293 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8295 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8297 emitpcode(POC_CALL,popGetLabel(albl->key));
8298 pcop = popGetLabel(blbl->key);
8299 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8300 emitpcode(POC_GOTO,pcop);
8301 emitpLabel(albl->key);
8303 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8305 emitpcode(poc,popGet(AOP(left),1));
8306 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8307 emitpcode(poc,popGet(AOP(left),0));
8308 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8310 emitpLabel(blbl->key);
8312 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8315 freeAsmop(left,NULL,ic,TRUE);
8316 freeAsmop(result,NULL,ic,TRUE);
8319 /*-----------------------------------------------------------------*/
8320 /* genPointerGet - generate code for pointer get */
8321 /*-----------------------------------------------------------------*/
8322 static void genPointerGet (iCode *ic)
8324 operand *left, *result ;
8325 sym_link *type, *etype;
8328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8331 result = IC_RESULT(ic) ;
8333 /* depending on the type of pointer we need to
8334 move it to the correct pointer register */
8335 type = operandType(left);
8336 etype = getSpec(type);
8338 if (IS_PTR_CONST(type))
8339 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8341 /* if left is of type of pointer then it is simple */
8342 if (IS_PTR(type) && !IS_FUNC(type->next))
8343 p_type = DCL_TYPE(type);
8345 /* we have to go by the storage class */
8346 p_type = PTR_TYPE(SPEC_OCLS(etype));
8348 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8350 if (SPEC_OCLS(etype)->codesp ) {
8351 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8352 //p_type = CPOINTER ;
8355 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8356 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8357 /*p_type = FPOINTER ;*/
8359 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8360 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8361 /* p_type = PPOINTER; */
8363 if (SPEC_OCLS(etype) == idata )
8364 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8365 /* p_type = IPOINTER; */
8367 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8368 /* p_type = POINTER ; */
8371 /* now that we have the pointer type we assign
8372 the pointer values */
8377 genNearPointerGet (left,result,ic);
8381 genPagedPointerGet(left,result,ic);
8385 genFarPointerGet (left,result,ic);
8389 genConstPointerGet (left,result,ic);
8390 //pic14_emitcodePointerGet (left,result,ic);
8394 if (IS_PTR_CONST(type))
8395 genConstPointerGet (left,result,ic);
8397 genGenPointerGet (left,result,ic);
8403 /*-----------------------------------------------------------------*/
8404 /* genPackBits - generates code for packed bit storage */
8405 /*-----------------------------------------------------------------*/
8406 static void genPackBits (sym_link *etype ,
8408 char *rname, int p_type)
8416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8417 blen = SPEC_BLEN(etype);
8418 bstr = SPEC_BSTR(etype);
8420 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8423 /* if the bit lenth is less than or */
8424 /* it exactly fits a byte then */
8425 if (SPEC_BLEN(etype) <= 8 ) {
8426 shCount = SPEC_BSTR(etype) ;
8428 /* shift left acc */
8431 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8436 pic14_emitcode ("mov","b,a");
8437 pic14_emitcode("mov","a,@%s",rname);
8441 pic14_emitcode ("mov","b,a");
8442 pic14_emitcode("movx","a,@dptr");
8446 pic14_emitcode ("push","b");
8447 pic14_emitcode ("push","acc");
8448 pic14_emitcode ("lcall","__gptrget");
8449 pic14_emitcode ("pop","b");
8453 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8454 ((unsigned char)(0xFF << (blen+bstr)) |
8455 (unsigned char)(0xFF >> (8-bstr)) ) );
8456 pic14_emitcode ("orl","a,b");
8457 if (p_type == GPOINTER)
8458 pic14_emitcode("pop","b");
8464 pic14_emitcode("mov","@%s,a",rname);
8468 pic14_emitcode("movx","@dptr,a");
8472 DEBUGpic14_emitcode(";lcall","__gptrput");
8477 if ( SPEC_BLEN(etype) <= 8 )
8480 pic14_emitcode("inc","%s",rname);
8481 rLen = SPEC_BLEN(etype) ;
8483 /* now generate for lengths greater than one byte */
8486 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8496 pic14_emitcode("mov","@%s,a",rname);
8498 pic14_emitcode("mov","@%s,%s",rname,l);
8503 pic14_emitcode("movx","@dptr,a");
8508 DEBUGpic14_emitcode(";lcall","__gptrput");
8511 pic14_emitcode ("inc","%s",rname);
8516 /* last last was not complete */
8518 /* save the byte & read byte */
8521 pic14_emitcode ("mov","b,a");
8522 pic14_emitcode("mov","a,@%s",rname);
8526 pic14_emitcode ("mov","b,a");
8527 pic14_emitcode("movx","a,@dptr");
8531 pic14_emitcode ("push","b");
8532 pic14_emitcode ("push","acc");
8533 pic14_emitcode ("lcall","__gptrget");
8534 pic14_emitcode ("pop","b");
8538 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8539 pic14_emitcode ("orl","a,b");
8542 if (p_type == GPOINTER)
8543 pic14_emitcode("pop","b");
8548 pic14_emitcode("mov","@%s,a",rname);
8552 pic14_emitcode("movx","@dptr,a");
8556 DEBUGpic14_emitcode(";lcall","__gptrput");
8560 /*-----------------------------------------------------------------*/
8561 /* genDataPointerSet - remat pointer to data space */
8562 /*-----------------------------------------------------------------*/
8563 static void genDataPointerSet(operand *right,
8567 int size, offset = 0 ;
8568 char *l, buffer[256];
8570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8571 aopOp(right,ic,FALSE);
8573 l = aopGet(AOP(result),0,FALSE,TRUE);
8574 size = AOP_SIZE(right);
8576 if ( AOP_TYPE(result) == AOP_PCODE) {
8577 fprintf(stderr,"genDataPointerSet %s, %d\n",
8578 AOP(result)->aopu.pcop->name,
8579 PCOI(AOP(result)->aopu.pcop)->offset);
8583 // tsd, was l+1 - the underline `_' prefix was being stripped
8586 sprintf(buffer,"(%s + %d)",l,offset);
8587 fprintf(stderr,"oops %s\n",buffer);
8589 sprintf(buffer,"%s",l);
8591 if (AOP_TYPE(right) == AOP_LIT) {
8592 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8593 lit = lit >> (8*offset);
8595 pic14_emitcode("movlw","%d",lit);
8596 pic14_emitcode("movwf","%s",buffer);
8598 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8599 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8600 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8603 pic14_emitcode("clrf","%s",buffer);
8604 //emitpcode(POC_CLRF, popRegFromString(buffer));
8605 emitpcode(POC_CLRF, popGet(AOP(result),0));
8608 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8609 pic14_emitcode("movwf","%s",buffer);
8611 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8612 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8613 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8620 freeAsmop(right,NULL,ic,TRUE);
8621 freeAsmop(result,NULL,ic,TRUE);
8624 /*-----------------------------------------------------------------*/
8625 /* genNearPointerSet - pic14_emitcode for near pointer put */
8626 /*-----------------------------------------------------------------*/
8627 static void genNearPointerSet (operand *right,
8634 sym_link *ptype = operandType(result);
8637 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8638 retype= getSpec(operandType(right));
8640 aopOp(result,ic,FALSE);
8643 /* if the result is rematerializable &
8644 in data space & not a bit variable */
8645 //if (AOP_TYPE(result) == AOP_IMMD &&
8646 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8647 DCL_TYPE(ptype) == POINTER &&
8648 !IS_BITFIELD(retype)) {
8649 genDataPointerSet (right,result,ic);
8650 freeAsmop(result,NULL,ic,TRUE);
8654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8655 aopOp(right,ic,FALSE);
8656 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8658 /* if the value is already in a pointer register
8659 then don't need anything more */
8660 if (!AOP_INPREG(AOP(result))) {
8661 /* otherwise get a free pointer register */
8662 //aop = newAsmop(0);
8663 //preg = getFreePtr(ic,&aop,FALSE);
8664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8665 //pic14_emitcode("mov","%s,%s",
8667 // aopGet(AOP(result),0,FALSE,TRUE));
8668 //rname = preg->name ;
8669 //pic14_emitcode("movwf","fsr");
8670 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8671 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8672 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8673 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8677 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8680 /* if bitfield then unpack the bits */
8681 if (IS_BITFIELD(retype)) {
8682 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8683 "The programmer is obviously confused");
8684 //genPackBits (retype,right,rname,POINTER);
8688 /* we have can just get the values */
8689 int size = AOP_SIZE(right);
8692 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8694 l = aopGet(AOP(right),offset,FALSE,TRUE);
8697 //pic14_emitcode("mov","@%s,a",rname);
8698 pic14_emitcode("movf","indf,w ;1");
8701 if (AOP_TYPE(right) == AOP_LIT) {
8702 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8704 pic14_emitcode("movlw","%s",l);
8705 pic14_emitcode("movwf","indf ;2");
8707 pic14_emitcode("clrf","indf");
8709 pic14_emitcode("movf","%s,w",l);
8710 pic14_emitcode("movwf","indf ;2");
8712 //pic14_emitcode("mov","@%s,%s",rname,l);
8715 pic14_emitcode("incf","fsr,f ;3");
8716 //pic14_emitcode("inc","%s",rname);
8721 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8722 /* now some housekeeping stuff */
8724 /* we had to allocate for this iCode */
8725 freeAsmop(NULL,aop,ic,TRUE);
8727 /* we did not allocate which means left
8728 already in a pointer register, then
8729 if size > 0 && this could be used again
8730 we have to point it back to where it
8732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8733 if (AOP_SIZE(right) > 1 &&
8734 !OP_SYMBOL(result)->remat &&
8735 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8737 int size = AOP_SIZE(right) - 1;
8739 pic14_emitcode("decf","fsr,f");
8740 //pic14_emitcode("dec","%s",rname);
8744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8747 freeAsmop(right,NULL,ic,TRUE);
8748 freeAsmop(result,NULL,ic,TRUE);
8751 /*-----------------------------------------------------------------*/
8752 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8753 /*-----------------------------------------------------------------*/
8754 static void genPagedPointerSet (operand *right,
8763 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8765 retype= getSpec(operandType(right));
8767 aopOp(result,ic,FALSE);
8769 /* if the value is already in a pointer register
8770 then don't need anything more */
8771 if (!AOP_INPREG(AOP(result))) {
8772 /* otherwise get a free pointer register */
8774 preg = getFreePtr(ic,&aop,FALSE);
8775 pic14_emitcode("mov","%s,%s",
8777 aopGet(AOP(result),0,FALSE,TRUE));
8778 rname = preg->name ;
8780 rname = aopGet(AOP(result),0,FALSE,FALSE);
8782 freeAsmop(result,NULL,ic,TRUE);
8783 aopOp (right,ic,FALSE);
8785 /* if bitfield then unpack the bits */
8786 if (IS_BITFIELD(retype))
8787 genPackBits (retype,right,rname,PPOINTER);
8789 /* we have can just get the values */
8790 int size = AOP_SIZE(right);
8794 l = aopGet(AOP(right),offset,FALSE,TRUE);
8797 pic14_emitcode("movx","@%s,a",rname);
8800 pic14_emitcode("inc","%s",rname);
8806 /* now some housekeeping stuff */
8808 /* we had to allocate for this iCode */
8809 freeAsmop(NULL,aop,ic,TRUE);
8811 /* we did not allocate which means left
8812 already in a pointer register, then
8813 if size > 0 && this could be used again
8814 we have to point it back to where it
8816 if (AOP_SIZE(right) > 1 &&
8817 !OP_SYMBOL(result)->remat &&
8818 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8820 int size = AOP_SIZE(right) - 1;
8822 pic14_emitcode("dec","%s",rname);
8827 freeAsmop(right,NULL,ic,TRUE);
8832 /*-----------------------------------------------------------------*/
8833 /* genFarPointerSet - set value from far space */
8834 /*-----------------------------------------------------------------*/
8835 static void genFarPointerSet (operand *right,
8836 operand *result, iCode *ic)
8839 sym_link *retype = getSpec(operandType(right));
8841 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8842 aopOp(result,ic,FALSE);
8844 /* if the operand is already in dptr
8845 then we do nothing else we move the value to dptr */
8846 if (AOP_TYPE(result) != AOP_STR) {
8847 /* if this is remateriazable */
8848 if (AOP_TYPE(result) == AOP_IMMD)
8849 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8850 else { /* we need to get it byte by byte */
8851 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8852 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8853 if (options.model == MODEL_FLAT24)
8855 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8859 /* so dptr know contains the address */
8860 freeAsmop(result,NULL,ic,TRUE);
8861 aopOp(right,ic,FALSE);
8863 /* if bit then unpack */
8864 if (IS_BITFIELD(retype))
8865 genPackBits(retype,right,"dptr",FPOINTER);
8867 size = AOP_SIZE(right);
8871 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8873 pic14_emitcode("movx","@dptr,a");
8875 pic14_emitcode("inc","dptr");
8879 freeAsmop(right,NULL,ic,TRUE);
8882 /*-----------------------------------------------------------------*/
8883 /* genGenPointerSet - set value from generic pointer space */
8884 /*-----------------------------------------------------------------*/
8885 static void genGenPointerSet (operand *right,
8886 operand *result, iCode *ic)
8889 sym_link *retype = getSpec(operandType(right));
8891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8893 aopOp(result,ic,FALSE);
8894 aopOp(right,ic,FALSE);
8895 size = AOP_SIZE(right);
8897 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8899 /* if the operand is already in dptr
8900 then we do nothing else we move the value to dptr */
8901 if (AOP_TYPE(result) != AOP_STR) {
8902 /* if this is remateriazable */
8903 if (AOP_TYPE(result) == AOP_IMMD) {
8904 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8905 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8907 else { /* we need to get it byte by byte */
8908 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8909 size = AOP_SIZE(right);
8912 /* hack hack! see if this the FSR. If so don't load W */
8913 if(AOP_TYPE(right) != AOP_ACC) {
8916 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8917 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8919 if(AOP_SIZE(result) > 1) {
8920 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8921 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8922 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8927 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8929 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8930 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8934 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8935 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8938 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8945 if(aopIdx(AOP(result),0) != 4) {
8947 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8951 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8956 /* so dptr know contains the address */
8959 /* if bit then unpack */
8960 if (IS_BITFIELD(retype))
8961 genPackBits(retype,right,"dptr",GPOINTER);
8963 size = AOP_SIZE(right);
8966 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8970 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8971 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8973 if (AOP_TYPE(right) == AOP_LIT)
8974 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8976 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8978 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8985 freeAsmop(right,NULL,ic,TRUE);
8986 freeAsmop(result,NULL,ic,TRUE);
8989 /*-----------------------------------------------------------------*/
8990 /* genPointerSet - stores the value into a pointer location */
8991 /*-----------------------------------------------------------------*/
8992 static void genPointerSet (iCode *ic)
8994 operand *right, *result ;
8995 sym_link *type, *etype;
8998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9000 right = IC_RIGHT(ic);
9001 result = IC_RESULT(ic) ;
9003 /* depending on the type of pointer we need to
9004 move it to the correct pointer register */
9005 type = operandType(result);
9006 etype = getSpec(type);
9007 /* if left is of type of pointer then it is simple */
9008 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9009 p_type = DCL_TYPE(type);
9012 /* we have to go by the storage class */
9013 p_type = PTR_TYPE(SPEC_OCLS(etype));
9015 /* if (SPEC_OCLS(etype)->codesp ) { */
9016 /* p_type = CPOINTER ; */
9019 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9020 /* p_type = FPOINTER ; */
9022 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9023 /* p_type = PPOINTER ; */
9025 /* if (SPEC_OCLS(etype) == idata ) */
9026 /* p_type = IPOINTER ; */
9028 /* p_type = POINTER ; */
9031 /* now that we have the pointer type we assign
9032 the pointer values */
9037 genNearPointerSet (right,result,ic);
9041 genPagedPointerSet (right,result,ic);
9045 genFarPointerSet (right,result,ic);
9049 genGenPointerSet (right,result,ic);
9053 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9054 "genPointerSet: illegal pointer type");
9058 /*-----------------------------------------------------------------*/
9059 /* genIfx - generate code for Ifx statement */
9060 /*-----------------------------------------------------------------*/
9061 static void genIfx (iCode *ic, iCode *popIc)
9063 operand *cond = IC_COND(ic);
9066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9068 aopOp(cond,ic,FALSE);
9070 /* get the value into acc */
9071 if (AOP_TYPE(cond) != AOP_CRY)
9072 pic14_toBoolean(cond);
9075 /* the result is now in the accumulator */
9076 freeAsmop(cond,NULL,ic,TRUE);
9078 /* if there was something to be popped then do it */
9082 /* if the condition is a bit variable */
9083 if (isbit && IS_ITEMP(cond) &&
9085 genIfxJump(ic,SPIL_LOC(cond)->rname);
9086 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9089 if (isbit && !IS_ITEMP(cond))
9090 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9098 /*-----------------------------------------------------------------*/
9099 /* genAddrOf - generates code for address of */
9100 /*-----------------------------------------------------------------*/
9101 static void genAddrOf (iCode *ic)
9103 operand *right, *result, *left;
9106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9109 //aopOp(IC_RESULT(ic),ic,FALSE);
9111 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9112 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9113 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9115 DEBUGpic14_AopType(__LINE__,left,right,result);
9117 size = AOP_SIZE(IC_RESULT(ic));
9121 /* fixing bug #863624, reported from (errolv) */
9122 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9123 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9126 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9127 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9132 freeAsmop(left,NULL,ic,FALSE);
9133 freeAsmop(result,NULL,ic,TRUE);
9138 /*-----------------------------------------------------------------*/
9139 /* genFarFarAssign - assignment when both are in far space */
9140 /*-----------------------------------------------------------------*/
9141 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9143 int size = AOP_SIZE(right);
9146 /* first push the right side on to the stack */
9148 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9150 pic14_emitcode ("push","acc");
9153 freeAsmop(right,NULL,ic,FALSE);
9154 /* now assign DPTR to result */
9155 aopOp(result,ic,FALSE);
9156 size = AOP_SIZE(result);
9158 pic14_emitcode ("pop","acc");
9159 aopPut(AOP(result),"a",--offset);
9161 freeAsmop(result,NULL,ic,FALSE);
9166 /*-----------------------------------------------------------------*/
9167 /* genAssign - generate code for assignment */
9168 /*-----------------------------------------------------------------*/
9169 static void genAssign (iCode *ic)
9171 operand *result, *right;
9172 int size, offset,know_W;
9173 unsigned long lit = 0L;
9175 result = IC_RESULT(ic);
9176 right = IC_RIGHT(ic) ;
9178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9180 /* if they are the same */
9181 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9184 aopOp(right,ic,FALSE);
9185 aopOp(result,ic,TRUE);
9187 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9189 /* if they are the same registers */
9190 if (pic14_sameRegs(AOP(right),AOP(result)))
9193 /* if the result is a bit */
9194 if (AOP_TYPE(result) == AOP_CRY) {
9196 /* if the right size is a literal then
9197 we know what the value is */
9198 if (AOP_TYPE(right) == AOP_LIT) {
9200 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9201 popGet(AOP(result),0));
9203 if (((int) operandLitValue(right)))
9204 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9205 AOP(result)->aopu.aop_dir,
9206 AOP(result)->aopu.aop_dir);
9208 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9209 AOP(result)->aopu.aop_dir,
9210 AOP(result)->aopu.aop_dir);
9214 /* the right is also a bit variable */
9215 if (AOP_TYPE(right) == AOP_CRY) {
9216 emitpcode(POC_BCF, popGet(AOP(result),0));
9217 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9218 emitpcode(POC_BSF, popGet(AOP(result),0));
9220 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9221 AOP(result)->aopu.aop_dir,
9222 AOP(result)->aopu.aop_dir);
9223 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9224 AOP(right)->aopu.aop_dir,
9225 AOP(right)->aopu.aop_dir);
9226 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9227 AOP(result)->aopu.aop_dir,
9228 AOP(result)->aopu.aop_dir);
9233 emitpcode(POC_BCF, popGet(AOP(result),0));
9234 pic14_toBoolean(right);
9236 emitpcode(POC_BSF, popGet(AOP(result),0));
9237 //aopPut(AOP(result),"a",0);
9241 /* bit variables done */
9243 size = AOP_SIZE(result);
9245 if(AOP_TYPE(right) == AOP_LIT)
9246 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9248 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9250 if(aopIdx(AOP(result),0) == 4) {
9251 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9252 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9253 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9256 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9261 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9262 if(AOP_TYPE(right) == AOP_LIT) {
9264 if(know_W != (int)(lit&0xff))
9265 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9267 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9269 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9273 } else if (AOP_TYPE(right) == AOP_CRY) {
9274 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9276 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9277 emitpcode(POC_INCF, popGet(AOP(result),0));
9280 mov2w (AOP(right), offset);
9281 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9289 freeAsmop (right,NULL,ic,FALSE);
9290 freeAsmop (result,NULL,ic,TRUE);
9293 /*-----------------------------------------------------------------*/
9294 /* genJumpTab - genrates code for jump table */
9295 /*-----------------------------------------------------------------*/
9296 static void genJumpTab (iCode *ic)
9301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9303 aopOp(IC_JTCOND(ic),ic,FALSE);
9304 /* get the condition into accumulator */
9305 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9307 /* multiply by three */
9308 pic14_emitcode("add","a,acc");
9309 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9311 jtab = newiTempLabel(NULL);
9312 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9313 pic14_emitcode("jmp","@a+dptr");
9314 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9316 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9317 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9318 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9319 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9321 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9322 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9323 emitpLabel(jtab->key);
9325 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9327 /* now generate the jump labels */
9328 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9329 jtab = setNextItem(IC_JTLABELS(ic))) {
9330 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9331 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9337 /*-----------------------------------------------------------------*/
9338 /* genMixedOperation - gen code for operators between mixed types */
9339 /*-----------------------------------------------------------------*/
9341 TSD - Written for the PIC port - but this unfortunately is buggy.
9342 This routine is good in that it is able to efficiently promote
9343 types to different (larger) sizes. Unfortunately, the temporary
9344 variables that are optimized out by this routine are sometimes
9345 used in other places. So until I know how to really parse the
9346 iCode tree, I'm going to not be using this routine :(.
9348 static int genMixedOperation (iCode *ic)
9351 operand *result = IC_RESULT(ic);
9352 sym_link *ctype = operandType(IC_LEFT(ic));
9353 operand *right = IC_RIGHT(ic);
9359 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9361 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9367 nextright = IC_RIGHT(nextic);
9368 nextleft = IC_LEFT(nextic);
9369 nextresult = IC_RESULT(nextic);
9371 aopOp(right,ic,FALSE);
9372 aopOp(result,ic,FALSE);
9373 aopOp(nextright, nextic, FALSE);
9374 aopOp(nextleft, nextic, FALSE);
9375 aopOp(nextresult, nextic, FALSE);
9377 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9383 pic14_emitcode(";remove right +","");
9385 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9391 pic14_emitcode(";remove left +","");
9395 big = AOP_SIZE(nextleft);
9396 small = AOP_SIZE(nextright);
9398 switch(nextic->op) {
9401 pic14_emitcode(";optimize a +","");
9402 /* if unsigned or not an integral type */
9403 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9404 pic14_emitcode(";add a bit to something","");
9407 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9409 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9410 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9411 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9413 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9421 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9422 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9423 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9426 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9429 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9430 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9431 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9432 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9435 pic14_emitcode("rlf","known_zero,w");
9442 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9443 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9444 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9446 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9456 freeAsmop(right,NULL,ic,TRUE);
9457 freeAsmop(result,NULL,ic,TRUE);
9458 freeAsmop(nextright,NULL,ic,TRUE);
9459 freeAsmop(nextleft,NULL,ic,TRUE);
9461 nextic->generated = 1;
9468 /*-----------------------------------------------------------------*/
9469 /* genCast - gen code for casting */
9470 /*-----------------------------------------------------------------*/
9471 static void genCast (iCode *ic)
9473 operand *result = IC_RESULT(ic);
9474 sym_link *ctype = operandType(IC_LEFT(ic));
9475 sym_link *rtype = operandType(IC_RIGHT(ic));
9476 operand *right = IC_RIGHT(ic);
9479 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9480 /* if they are equivalent then do nothing */
9481 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9484 aopOp(right,ic,FALSE) ;
9485 aopOp(result,ic,FALSE);
9487 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9489 /* if the result is a bit */
9490 if (AOP_TYPE(result) == AOP_CRY) {
9491 /* if the right size is a literal then
9492 we know what the value is */
9493 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9494 if (AOP_TYPE(right) == AOP_LIT) {
9496 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9497 popGet(AOP(result),0));
9499 if (((int) operandLitValue(right)))
9500 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9501 AOP(result)->aopu.aop_dir,
9502 AOP(result)->aopu.aop_dir);
9504 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9505 AOP(result)->aopu.aop_dir,
9506 AOP(result)->aopu.aop_dir);
9511 /* the right is also a bit variable */
9512 if (AOP_TYPE(right) == AOP_CRY) {
9515 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9517 pic14_emitcode("clrc","");
9518 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9519 AOP(right)->aopu.aop_dir,
9520 AOP(right)->aopu.aop_dir);
9521 aopPut(AOP(result),"c",0);
9526 if (AOP_TYPE(right) == AOP_REG) {
9527 emitpcode(POC_BCF, popGet(AOP(result),0));
9528 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9529 emitpcode(POC_BSF, popGet(AOP(result),0));
9531 pic14_toBoolean(right);
9532 aopPut(AOP(result),"a",0);
9536 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9538 size = AOP_SIZE(result);
9540 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9542 emitpcode(POC_CLRF, popGet(AOP(result),0));
9543 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9544 emitpcode(POC_INCF, popGet(AOP(result),0));
9547 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9552 /* if they are the same size : or less */
9553 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9555 /* if they are in the same place */
9556 if (pic14_sameRegs(AOP(right),AOP(result)))
9559 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9560 if (IS_PTR_CONST(rtype))
9561 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9562 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9563 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9565 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9566 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9567 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9568 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9569 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9570 if(AOP_SIZE(result) <2)
9571 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9575 /* if they in different places then copy */
9576 size = AOP_SIZE(result);
9579 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9580 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9582 //aopPut(AOP(result),
9583 // aopGet(AOP(right),offset,FALSE,FALSE),
9593 /* if the result is of type pointer */
9594 if (IS_PTR(ctype)) {
9597 sym_link *type = operandType(right);
9598 sym_link *etype = getSpec(type);
9599 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9601 /* pointer to generic pointer */
9602 if (IS_GENPTR(ctype)) {
9606 p_type = DCL_TYPE(type);
9608 /* we have to go by the storage class */
9609 p_type = PTR_TYPE(SPEC_OCLS(etype));
9611 /* if (SPEC_OCLS(etype)->codesp ) */
9612 /* p_type = CPOINTER ; */
9614 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9615 /* p_type = FPOINTER ; */
9617 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9618 /* p_type = PPOINTER; */
9620 /* if (SPEC_OCLS(etype) == idata ) */
9621 /* p_type = IPOINTER ; */
9623 /* p_type = POINTER ; */
9626 /* the first two bytes are known */
9627 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9628 size = GPTRSIZE - 1;
9631 if(offset < AOP_SIZE(right)) {
9632 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9633 if ((AOP_TYPE(right) == AOP_PCODE) &&
9634 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9635 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9636 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9639 aopGet(AOP(right),offset,FALSE,FALSE),
9643 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9646 /* the last byte depending on type */
9650 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9653 pic14_emitcode(";BUG!? ","%d",__LINE__);
9657 pic14_emitcode(";BUG!? ","%d",__LINE__);
9661 pic14_emitcode(";BUG!? ","%d",__LINE__);
9666 /* this should never happen */
9667 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9668 "got unknown pointer type");
9671 //aopPut(AOP(result),l, GPTRSIZE - 1);
9675 /* just copy the pointers */
9676 size = AOP_SIZE(result);
9680 aopGet(AOP(right),offset,FALSE,FALSE),
9689 /* so we now know that the size of destination is greater
9690 than the size of the source.
9691 Now, if the next iCode is an operator then we might be
9692 able to optimize the operation without performing a cast.
9694 if(genMixedOperation(ic))
9697 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9699 /* we move to result for the size of source */
9700 size = AOP_SIZE(right);
9703 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9704 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9708 /* now depending on the sign of the destination */
9709 size = AOP_SIZE(result) - AOP_SIZE(right);
9710 /* if unsigned or not an integral type */
9711 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9713 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9715 /* we need to extend the sign :{ */
9718 /* Save one instruction of casting char to int */
9719 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9720 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9721 emitpcode(POC_DECF, popGet(AOP(result),offset));
9723 emitpcodeNULLop(POC_CLRW);
9726 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9728 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9730 emitpcode(POC_MOVLW, popGetLit(0xff));
9733 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9738 freeAsmop(right,NULL,ic,TRUE);
9739 freeAsmop(result,NULL,ic,TRUE);
9743 /*-----------------------------------------------------------------*/
9744 /* genDjnz - generate decrement & jump if not zero instrucion */
9745 /*-----------------------------------------------------------------*/
9746 static int genDjnz (iCode *ic, iCode *ifx)
9749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9754 /* if the if condition has a false label
9755 then we cannot save */
9759 /* if the minus is not of the form
9761 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9762 !IS_OP_LITERAL(IC_RIGHT(ic)))
9765 if (operandLitValue(IC_RIGHT(ic)) != 1)
9768 /* if the size of this greater than one then no
9770 if (getSize(operandType(IC_RESULT(ic))) > 1)
9773 /* otherwise we can save BIG */
9774 lbl = newiTempLabel(NULL);
9775 lbl1= newiTempLabel(NULL);
9777 aopOp(IC_RESULT(ic),ic,FALSE);
9779 if (IS_AOP_PREG(IC_RESULT(ic))) {
9780 pic14_emitcode("dec","%s",
9781 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9782 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9783 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9787 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9788 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9790 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9791 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9794 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9795 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9796 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9797 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9800 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9805 /*-----------------------------------------------------------------*/
9806 /* genReceive - generate code for a receive iCode */
9807 /*-----------------------------------------------------------------*/
9808 static void genReceive (iCode *ic)
9810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9812 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9813 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9814 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9816 int size = getSize(operandType(IC_RESULT(ic)));
9817 int offset = fReturnSizePic - size;
9819 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9820 fReturn[fReturnSizePic - offset - 1] : "acc"));
9823 aopOp(IC_RESULT(ic),ic,FALSE);
9824 size = AOP_SIZE(IC_RESULT(ic));
9827 pic14_emitcode ("pop","acc");
9828 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9833 aopOp(IC_RESULT(ic),ic,FALSE);
9835 assignResultValue(IC_RESULT(ic));
9838 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9841 /*-----------------------------------------------------------------*/
9842 /* genDummyRead - generate code for dummy read of volatiles */
9843 /*-----------------------------------------------------------------*/
9845 genDummyRead (iCode * ic)
9847 pic14_emitcode ("; genDummyRead","");
9848 pic14_emitcode ("; not implemented","");
9853 /*-----------------------------------------------------------------*/
9854 /* genpic14Code - generate code for pic14 based controllers */
9855 /*-----------------------------------------------------------------*/
9857 * At this point, ralloc.c has gone through the iCode and attempted
9858 * to optimize in a way suitable for a PIC. Now we've got to generate
9859 * PIC instructions that correspond to the iCode.
9861 * Once the instructions are generated, we'll pass through both the
9862 * peep hole optimizer and the pCode optimizer.
9863 *-----------------------------------------------------------------*/
9865 void genpic14Code (iCode *lic)
9870 lineHead = lineCurr = NULL;
9872 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9875 /* if debug information required */
9876 if (options.debug && currFunc) {
9878 debugFile->writeFunction(currFunc);
9880 if (IS_STATIC(currFunc->etype)) {
9881 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9882 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9884 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9885 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9892 for (ic = lic ; ic ; ic = ic->next ) {
9894 DEBUGpic14_emitcode(";ic","");
9895 if ( cln != ic->lineno ) {
9896 if ( options.debug ) {
9898 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9899 FileBaseName(ic->filename),ic->lineno,
9900 ic->level,ic->block);
9904 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9905 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9906 printCLine(ic->filename, ic->lineno));
9908 if (!options.noCcodeInAsm) {
9910 newpCodeCSource(ic->lineno,
9912 printCLine(ic->filename, ic->lineno)));
9918 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9920 /* if the result is marked as
9921 spilt and rematerializable or code for
9922 this has already been generated then
9924 if (resultRemat(ic) || ic->generated )
9927 /* depending on the operation */
9946 /* IPOP happens only when trying to restore a
9947 spilt live range, if there is an ifx statement
9948 following this pop then the if statement might
9949 be using some of the registers being popped which
9950 would destory the contents of the register so
9951 we need to check for this condition and handle it */
9953 ic->next->op == IFX &&
9954 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9955 genIfx (ic->next,ic);
9973 genEndFunction (ic);
9993 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10010 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10014 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10021 /* note these two are xlated by algebraic equivalence
10022 during parsing SDCC.y */
10023 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10024 "got '>=' or '<=' shouldn't have come here");
10028 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10040 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10044 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10048 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10072 genRightShift (ic);
10075 case GET_VALUE_AT_ADDRESS:
10080 if (POINTER_SET(ic))
10107 addSet(&_G.sendSet,ic);
10110 case DUMMY_READ_VOLATILE:
10120 /* now we are ready to call the
10121 peep hole optimizer */
10122 if (!options.nopeep) {
10123 peepHole (&lineHead);
10125 /* now do the actual printing */
10126 printLine (lineHead,codeOutFile);
10129 DFPRINTF((stderr,"printing pBlock\n\n"));
10130 printpBlock(stdout,pb);