1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
220 addpCode2pBlock(pb,newpCode(poc,pcop));
222 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
225 void emitpcodeNULLop(PIC_OPCODE poc)
228 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
274 bool r0iu = FALSE , r1iu = FALSE;
275 bool r0ou = FALSE , r1ou = FALSE;
277 /* the logic: if r0 & r1 used in the instruction
278 then we are in trouble otherwise */
280 /* first check if r0 & r1 are used by this
281 instruction, in which case we are in trouble */
282 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
288 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
291 /* if no usage of r0 then return it */
292 if (!r0iu && !r0ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294 (*aopp)->type = AOP_R0;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
299 /* if no usage of r1 then return it */
300 if (!r1iu && !r1ou) {
301 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302 (*aopp)->type = AOP_R1;
304 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
307 /* now we know they both have usage */
308 /* if r0 not used in this instruction */
310 /* push it if not already pushed */
312 //pic14_emitcode ("push","%s",
313 // pic14_regWithIdx(R0_IDX)->dname);
317 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318 (*aopp)->type = AOP_R0;
320 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
323 /* if r1 not used then */
326 /* push it if not already pushed */
328 //pic14_emitcode ("push","%s",
329 // pic14_regWithIdx(R1_IDX)->dname);
333 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334 (*aopp)->type = AOP_R1;
335 return pic14_regWithIdx(R1_IDX);
339 /* I said end of world but not quite end of world yet */
340 /* if this is a result then we can push it on the stack*/
342 (*aopp)->type = AOP_STK;
346 /* other wise this is true end of the world */
347 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348 "getFreePtr should never reach here");
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
359 aop = Safe_calloc(1,sizeof(asmop));
364 static void genSetDPTR(int n)
368 pic14_emitcode(";", "Select standard DPTR");
369 pic14_emitcode("mov", "dps, #0x00");
373 pic14_emitcode(";", "Select alternate DPTR");
374 pic14_emitcode("mov", "dps, #0x01");
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for */
380 /* generating code */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
387 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
389 resIfx->condition = 1; /* assume that the ifx is true */
390 resIfx->generated = 0; /* indicate that the ifx has not been used */
393 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
395 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396 __FUNCTION__,__LINE__,resIfx->lbl->key);
400 resIfx->lbl = IC_TRUE(ifx);
402 resIfx->lbl = IC_FALSE(ifx);
403 resIfx->condition = 0;
407 DEBUGpic14_emitcode("; ***","ifx true is non-null");
409 DEBUGpic14_emitcode("; ***","ifx false is non-null");
413 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
422 return PTR_TYPE(SPEC_OCLS(etype));
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
432 memmap *space= SPEC_OCLS(sym->etype);
434 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435 /* if already has one */
439 /* assign depending on the storage class */
440 /* if it is on the stack or indirectly addressable */
441 /* space we need to assign either r0 or r1 to it */
442 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443 sym->aop = aop = newAsmop(0);
444 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445 aop->size = getSize(sym->type);
447 /* now assign the address of the variable to
448 the pointer register */
449 if (aop->type != AOP_STK) {
453 pic14_emitcode("push","acc");
455 pic14_emitcode("mov","a,_bp");
456 pic14_emitcode("add","a,#0x%02x",
458 ((char)(sym->stack - _G.nRegsSaved )) :
459 ((char)sym->stack)) & 0xff);
460 pic14_emitcode("mov","%s,a",
461 aop->aopu.aop_ptr->name);
464 pic14_emitcode("pop","acc");
466 pic14_emitcode("mov","%s,#%s",
467 aop->aopu.aop_ptr->name,
469 aop->paged = space->paged;
471 aop->aopu.aop_stk = sym->stack;
475 if (sym->onStack && options.stack10bit)
477 /* It's on the 10 bit stack, which is located in
481 //DEBUGpic14_emitcode(";","%d",__LINE__);
484 pic14_emitcode("push","acc");
486 pic14_emitcode("mov","a,_bp");
487 pic14_emitcode("add","a,#0x%02x",
489 ((char)(sym->stack - _G.nRegsSaved )) :
490 ((char)sym->stack)) & 0xff);
493 pic14_emitcode ("mov","dpx1,#0x40");
494 pic14_emitcode ("mov","dph1,#0x00");
495 pic14_emitcode ("mov","dpl1, a");
499 pic14_emitcode("pop","acc");
501 sym->aop = aop = newAsmop(AOP_DPTR2);
502 aop->size = getSize(sym->type);
506 //DEBUGpic14_emitcode(";","%d",__LINE__);
507 /* if in bit space */
508 if (IN_BITSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_CRY);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
515 /* if it is in direct space */
516 if (IN_DIRSPACE(space)) {
517 sym->aop = aop = newAsmop (AOP_DIR);
518 aop->aopu.aop_dir = sym->rname ;
519 aop->size = getSize(sym->type);
520 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524 /* special case for a function */
525 if (IS_FUNC(sym->type)) {
527 sym->aop = aop = newAsmop(AOP_PCODE);
528 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
529 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
530 PCOI(aop->aopu.pcop)->_function = 1;
531 PCOI(aop->aopu.pcop)->index = 0;
532 aop->size = FPTRSIZE;
534 sym->aop = aop = newAsmop(AOP_IMMD);
535 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
536 strcpy(aop->aopu.aop_immd,sym->rname);
537 aop->size = FPTRSIZE;
539 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
544 /* only remaining is far space */
545 /* in which case DPTR gets the address */
546 sym->aop = aop = newAsmop(AOP_PCODE);
548 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
549 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
550 PCOI(aop->aopu.pcop)->index = 0;
552 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
553 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
555 allocDirReg (IC_LEFT(ic));
557 aop->size = FPTRSIZE;
559 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
560 sym->aop = aop = newAsmop(AOP_DPTR);
561 pic14_emitcode ("mov","dptr,#%s", sym->rname);
562 aop->size = getSize(sym->type);
564 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
567 /* if it is in code space */
568 if (IN_CODESPACE(space))
574 /*-----------------------------------------------------------------*/
575 /* aopForRemat - rematerialzes an object */
576 /*-----------------------------------------------------------------*/
577 static asmop *aopForRemat (operand *op) // x symbol *sym)
579 symbol *sym = OP_SYMBOL(op);
581 asmop *aop = newAsmop(AOP_PCODE);
585 ic = sym->rematiCode;
587 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
588 if(IS_OP_POINTER(op)) {
589 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
593 val += (int) operandLitValue(IC_RIGHT(ic));
594 } else if (ic->op == '-') {
595 val -= (int) operandLitValue(IC_RIGHT(ic));
599 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
602 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
603 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
604 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
605 PCOI(aop->aopu.pcop)->index = val;
607 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
608 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
609 val, IS_PTR_CONST(operandType(op)));
611 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
613 allocDirReg (IC_LEFT(ic));
618 int aopIdx (asmop *aop, int offset)
623 if(aop->type != AOP_REG)
626 return aop->aopu.aop_reg[offset]->rIdx;
629 /*-----------------------------------------------------------------*/
630 /* regsInCommon - two operands have some registers in common */
631 /*-----------------------------------------------------------------*/
632 static bool regsInCommon (operand *op1, operand *op2)
637 /* if they have registers in common */
638 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
641 sym1 = OP_SYMBOL(op1);
642 sym2 = OP_SYMBOL(op2);
644 if (sym1->nRegs == 0 || sym2->nRegs == 0)
647 for (i = 0 ; i < sym1->nRegs ; i++) {
652 for (j = 0 ; j < sym2->nRegs ;j++ ) {
656 if (sym2->regs[j] == sym1->regs[i])
664 /*-----------------------------------------------------------------*/
665 /* operandsEqu - equivalent */
666 /*-----------------------------------------------------------------*/
667 static bool operandsEqu ( operand *op1, operand *op2)
671 /* if they not symbols */
672 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
675 sym1 = OP_SYMBOL(op1);
676 sym2 = OP_SYMBOL(op2);
678 /* if both are itemps & one is spilt
679 and the other is not then false */
680 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
681 sym1->isspilt != sym2->isspilt )
684 /* if they are the same */
688 if (strcmp(sym1->rname,sym2->rname) == 0)
692 /* if left is a tmp & right is not */
696 (sym1->usl.spillLoc == sym2))
703 (sym2->usl.spillLoc == sym1))
709 /*-----------------------------------------------------------------*/
710 /* pic14_sameRegs - two asmops have the same registers */
711 /*-----------------------------------------------------------------*/
712 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
719 if (aop1->type != AOP_REG ||
720 aop2->type != AOP_REG )
723 if (aop1->size != aop2->size )
726 for (i = 0 ; i < aop1->size ; i++ )
727 if (aop1->aopu.aop_reg[i] !=
728 aop2->aopu.aop_reg[i] )
734 /*-----------------------------------------------------------------*/
735 /* aopOp - allocates an asmop for an operand : */
736 /*-----------------------------------------------------------------*/
737 void aopOp (operand *op, iCode *ic, bool result)
746 // DEBUGpic14_emitcode(";","%d",__LINE__);
747 /* if this a literal */
748 if (IS_OP_LITERAL(op)) {
749 op->aop = aop = newAsmop(AOP_LIT);
750 aop->aopu.aop_lit = op->operand.valOperand;
751 aop->size = getSize(operandType(op));
756 sym_link *type = operandType(op);
757 if(IS_PTR_CONST(type))
758 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
761 /* if already has a asmop then continue */
765 /* if the underlying symbol has a aop */
766 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
767 DEBUGpic14_emitcode(";","%d",__LINE__);
768 op->aop = OP_SYMBOL(op)->aop;
772 /* if this is a true symbol */
773 if (IS_TRUE_SYMOP(op)) {
774 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
775 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
779 /* this is a temporary : this has
785 e) can be a return use only */
790 /* if the type is a conditional */
791 if (sym->regType == REG_CND) {
792 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
797 /* if it is spilt then two situations
799 b) has a spill location */
800 if (sym->isspilt || sym->nRegs == 0) {
802 DEBUGpic14_emitcode(";","%d",__LINE__);
803 /* rematerialize it NOW */
806 sym->aop = op->aop = aop =
808 aop->size = getSize(sym->type);
809 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
815 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
816 aop->size = getSize(sym->type);
817 for ( i = 0 ; i < 2 ; i++ )
818 aop->aopu.aop_str[i] = accUse[i];
819 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
824 if(sym->isptr) { // && sym->uptr
825 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
826 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
828 //PCOI(aop->aopu.pcop)->_const = 0;
829 //PCOI(aop->aopu.pcop)->index = 0;
831 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
832 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
834 //allocDirReg (IC_LEFT(ic));
836 aop->size = getSize(sym->type);
837 DEBUGpic14_emitcode(";","%d",__LINE__);
844 aop = op->aop = sym->aop = newAsmop(AOP_STR);
845 aop->size = getSize(sym->type);
846 for ( i = 0 ; i < fReturnSizePic ; i++ )
847 aop->aopu.aop_str[i] = fReturn[i];
849 DEBUGpic14_emitcode(";","%d",__LINE__);
854 /* else spill location */
855 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
856 /* force a new aop if sizes differ */
857 sym->usl.spillLoc->aop = NULL;
859 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
860 __FUNCTION__,__LINE__,
861 sym->usl.spillLoc->rname,
862 sym->rname, sym->usl.spillLoc->offset);
864 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
865 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
866 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
868 sym->usl.spillLoc->offset);
869 aop->size = getSize(sym->type);
875 sym_link *type = operandType(op);
876 if(IS_PTR_CONST(type))
877 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
880 /* must be in a register */
881 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
882 sym->aop = op->aop = aop = newAsmop(AOP_REG);
883 aop->size = sym->nRegs;
884 for ( i = 0 ; i < sym->nRegs ;i++)
885 aop->aopu.aop_reg[i] = sym->regs[i];
888 /*-----------------------------------------------------------------*/
889 /* freeAsmop - free up the asmop given to an operand */
890 /*----------------------------------------------------------------*/
891 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
908 /* depending on the asmop type only three cases need work AOP_RO
909 , AOP_R1 && AOP_STK */
915 pic14_emitcode ("pop","ar0");
919 bitVectUnSetBit(ic->rUsed,R0_IDX);
925 pic14_emitcode ("pop","ar1");
929 bitVectUnSetBit(ic->rUsed,R1_IDX);
935 int stk = aop->aopu.aop_stk + aop->size;
936 bitVectUnSetBit(ic->rUsed,R0_IDX);
937 bitVectUnSetBit(ic->rUsed,R1_IDX);
939 getFreePtr(ic,&aop,FALSE);
941 if (options.stack10bit)
943 /* I'm not sure what to do here yet... */
946 "*** Warning: probably generating bad code for "
947 "10 bit stack mode.\n");
951 pic14_emitcode ("mov","a,_bp");
952 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
953 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
955 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
959 pic14_emitcode("pop","acc");
960 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
962 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
965 freeAsmop(op,NULL,ic,TRUE);
967 pic14_emitcode("pop","ar0");
972 pic14_emitcode("pop","ar1");
980 /* all other cases just dealloc */
984 OP_SYMBOL(op)->aop = NULL;
985 /* if the symbol has a spill */
987 SPIL_LOC(op)->aop = NULL;
992 /*-----------------------------------------------------------------*/
993 /* aopGet - for fetching value of the aop */
994 /*-----------------------------------------------------------------*/
995 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1000 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1001 /* offset is greater than
1003 if (offset > (aop->size - 1) &&
1004 aop->type != AOP_LIT)
1007 /* depending on type */
1008 switch (aop->type) {
1012 DEBUGpic14_emitcode(";","%d",__LINE__);
1013 /* if we need to increment it */
1014 while (offset > aop->coff) {
1015 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1019 while (offset < aop->coff) {
1020 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1024 aop->coff = offset ;
1026 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1027 return (dname ? "acc" : "a");
1029 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1030 rs = Safe_calloc(1,strlen(s)+1);
1036 DEBUGpic14_emitcode(";","%d",__LINE__);
1037 if (aop->type == AOP_DPTR2)
1042 while (offset > aop->coff) {
1043 pic14_emitcode ("inc","dptr");
1047 while (offset < aop->coff) {
1048 pic14_emitcode("lcall","__decdptr");
1054 pic14_emitcode("clr","a");
1055 pic14_emitcode("movc","a,@a+dptr");
1058 pic14_emitcode("movx","a,@dptr");
1061 if (aop->type == AOP_DPTR2)
1066 return (dname ? "acc" : "a");
1071 sprintf (s,"%s",aop->aopu.aop_immd);
1074 sprintf(s,"(%s >> %d)",
1079 aop->aopu.aop_immd);
1080 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1081 rs = Safe_calloc(1,strlen(s)+1);
1087 sprintf(s,"(%s + %d)",
1090 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1092 sprintf(s,"%s",aop->aopu.aop_dir);
1093 rs = Safe_calloc(1,strlen(s)+1);
1099 // return aop->aopu.aop_reg[offset]->dname;
1101 return aop->aopu.aop_reg[offset]->name;
1104 //pic14_emitcode(";","%d",__LINE__);
1105 return aop->aopu.aop_dir;
1108 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1109 return "AOP_accumulator_bug";
1112 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1113 rs = Safe_calloc(1,strlen(s)+1);
1118 aop->coff = offset ;
1119 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1122 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1124 return aop->aopu.aop_str[offset];
1128 pCodeOp *pcop = aop->aopu.pcop;
1129 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1131 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1132 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1133 sprintf(s,"%s", pcop->name);
1135 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1138 rs = Safe_calloc(1,strlen(s)+1);
1144 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1145 "aopget got unsupported aop->type");
1150 /*-----------------------------------------------------------------*/
1151 /* popGetTempReg - create a new temporary pCodeOp */
1152 /*-----------------------------------------------------------------*/
1153 pCodeOp *popGetTempReg(void)
1158 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1159 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1160 PCOR(pcop)->r->wasUsed=1;
1161 PCOR(pcop)->r->isFree=0;
1167 /*-----------------------------------------------------------------*/
1168 /* popGetTempReg - create a new temporary pCodeOp */
1169 /*-----------------------------------------------------------------*/
1170 void popReleaseTempReg(pCodeOp *pcop)
1173 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1174 PCOR(pcop)->r->isFree = 1;
1177 /*-----------------------------------------------------------------*/
1178 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1179 /*-----------------------------------------------------------------*/
1180 pCodeOp *popGetLabel(unsigned int key)
1183 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1185 if(key>(unsigned int)max_key)
1188 return newpCodeOpLabel(NULL,key+100+labelOffset);
1191 /*-------------------------------------------------------------------*/
1192 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1193 /*-------------------------------------------------------------------*/
1194 pCodeOp *popGetHighLabel(unsigned int key)
1197 pcop = popGetLabel(key);
1198 PCOLAB(pcop)->offset = 1;
1202 /*-----------------------------------------------------------------*/
1203 /* popGet - asm operator to pcode operator conversion */
1204 /*-----------------------------------------------------------------*/
1205 pCodeOp *popGetLit(unsigned int lit)
1208 return newpCodeOpLit(lit);
1212 /*-----------------------------------------------------------------*/
1213 /* popGetImmd - asm operator to pcode immediate conversion */
1214 /*-----------------------------------------------------------------*/
1215 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1218 return newpCodeOpImmd(name, offset,index, 0, is_func);
1222 /*-----------------------------------------------------------------*/
1223 /* popGet - asm operator to pcode operator conversion */
1224 /*-----------------------------------------------------------------*/
1225 pCodeOp *popGetWithString(char *str, int isExtern)
1231 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1235 pcop = newpCodeOp(str,PO_STR);
1236 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1241 /*-----------------------------------------------------------------*/
1242 /* popRegFromString - */
1243 /*-----------------------------------------------------------------*/
1244 pCodeOp *popRegFromString(char *str, int size, int offset)
1247 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1248 pcop->type = PO_DIR;
1250 DEBUGpic14_emitcode(";","%d",__LINE__);
1255 pcop->name = Safe_calloc(1,strlen(str)+1);
1256 strcpy(pcop->name,str);
1258 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1260 PCOR(pcop)->r = dirregWithName(pcop->name);
1261 if(PCOR(pcop)->r == NULL) {
1262 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1263 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1264 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1266 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1268 PCOR(pcop)->instance = offset;
1273 /*-----------------------------------------------------------------*/
1274 /*-----------------------------------------------------------------*/
1275 pCodeOp *popRegFromIdx(int rIdx)
1279 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1280 __FUNCTION__,__LINE__,rIdx);
1282 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1284 PCOR(pcop)->rIdx = rIdx;
1285 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1286 PCOR(pcop)->r->isFree = 0;
1287 PCOR(pcop)->r->wasUsed = 1;
1289 pcop->type = PCOR(pcop)->r->pc_type;
1295 /*-----------------------------------------------------------------*/
1296 /* popGet - asm operator to pcode operator conversion */
1297 /*-----------------------------------------------------------------*/
1298 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1300 //char *s = buffer ;
1305 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1306 /* offset is greater than
1309 if (offset > (aop->size - 1) &&
1310 aop->type != AOP_LIT)
1311 return NULL; //zero;
1313 /* depending on type */
1314 switch (aop->type) {
1321 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1325 DEBUGpic14_emitcode(";","%d",__LINE__);
1326 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1329 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1331 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1332 pcop->type = PO_DIR;
1336 sprintf(s,"(%s + %d)",
1340 sprintf(s,"%s",aop->aopu.aop_dir);
1341 pcop->name = Safe_calloc(1,strlen(s)+1);
1342 strcpy(pcop->name,s);
1344 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1345 strcpy(pcop->name,aop->aopu.aop_dir);
1346 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1347 if(PCOR(pcop)->r == NULL) {
1348 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1349 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1350 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1352 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1354 PCOR(pcop)->instance = offset;
1361 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1363 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1364 PCOR(pcop)->rIdx = rIdx;
1365 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1366 PCOR(pcop)->r->wasUsed=1;
1367 PCOR(pcop)->r->isFree=0;
1369 PCOR(pcop)->instance = offset;
1370 pcop->type = PCOR(pcop)->r->pc_type;
1371 //rs = aop->aopu.aop_reg[offset]->name;
1372 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1377 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1378 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1379 //if(PCOR(pcop)->r == NULL)
1380 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1384 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1387 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1388 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1390 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1391 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1392 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1393 pcop->type = PCOR(pcop)->r->pc_type;
1394 pcop->name = PCOR(pcop)->r->name;
1400 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1402 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1403 pcop = pCodeOpCopy(aop->aopu.pcop);
1404 PCOI(pcop)->offset = offset;
1408 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1409 "popGet got unsupported aop->type");
1412 /*-----------------------------------------------------------------*/
1413 /* aopPut - puts a string for a aop */
1414 /*-----------------------------------------------------------------*/
1415 void aopPut (asmop *aop, char *s, int offset)
1420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1422 if (aop->size && offset > ( aop->size - 1)) {
1423 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1424 "aopPut got offset > aop->size");
1428 /* will assign value to value */
1429 /* depending on where it is ofcourse */
1430 switch (aop->type) {
1433 sprintf(d,"(%s + %d)",
1434 aop->aopu.aop_dir,offset);
1435 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1438 sprintf(d,"%s",aop->aopu.aop_dir);
1441 DEBUGpic14_emitcode(";","%d",__LINE__);
1443 pic14_emitcode("movf","%s,w",s);
1444 pic14_emitcode("movwf","%s",d);
1447 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1448 if(offset >= aop->size) {
1449 emitpcode(POC_CLRF,popGet(aop,offset));
1452 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1455 emitpcode(POC_MOVWF,popGet(aop,offset));
1462 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1463 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1466 strcmp(s,"r0") == 0 ||
1467 strcmp(s,"r1") == 0 ||
1468 strcmp(s,"r2") == 0 ||
1469 strcmp(s,"r3") == 0 ||
1470 strcmp(s,"r4") == 0 ||
1471 strcmp(s,"r5") == 0 ||
1472 strcmp(s,"r6") == 0 ||
1473 strcmp(s,"r7") == 0 )
1474 pic14_emitcode("mov","%s,%s ; %d",
1475 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1479 if(strcmp(s,"W")==0 )
1480 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1482 pic14_emitcode("movwf","%s",
1483 aop->aopu.aop_reg[offset]->name);
1485 if(strcmp(s,zero)==0) {
1486 emitpcode(POC_CLRF,popGet(aop,offset));
1488 } else if(strcmp(s,"W")==0) {
1489 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1490 pcop->type = PO_GPR_REGISTER;
1492 PCOR(pcop)->rIdx = -1;
1493 PCOR(pcop)->r = NULL;
1495 DEBUGpic14_emitcode(";","%d",__LINE__);
1496 pcop->name = Safe_strdup(s);
1497 emitpcode(POC_MOVFW,pcop);
1498 emitpcode(POC_MOVWF,popGet(aop,offset));
1499 } else if(strcmp(s,one)==0) {
1500 emitpcode(POC_CLRF,popGet(aop,offset));
1501 emitpcode(POC_INCF,popGet(aop,offset));
1503 emitpcode(POC_MOVWF,popGet(aop,offset));
1511 if (aop->type == AOP_DPTR2)
1517 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1518 "aopPut writting to code space");
1522 while (offset > aop->coff) {
1524 pic14_emitcode ("inc","dptr");
1527 while (offset < aop->coff) {
1529 pic14_emitcode("lcall","__decdptr");
1534 /* if not in accumulater */
1537 pic14_emitcode ("movx","@dptr,a");
1539 if (aop->type == AOP_DPTR2)
1547 while (offset > aop->coff) {
1549 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1551 while (offset < aop->coff) {
1553 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1559 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1564 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1566 if (strcmp(s,"r0") == 0 ||
1567 strcmp(s,"r1") == 0 ||
1568 strcmp(s,"r2") == 0 ||
1569 strcmp(s,"r3") == 0 ||
1570 strcmp(s,"r4") == 0 ||
1571 strcmp(s,"r5") == 0 ||
1572 strcmp(s,"r6") == 0 ||
1573 strcmp(s,"r7") == 0 ) {
1575 sprintf(buffer,"a%s",s);
1576 pic14_emitcode("mov","@%s,%s",
1577 aop->aopu.aop_ptr->name,buffer);
1579 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1584 if (strcmp(s,"a") == 0)
1585 pic14_emitcode("push","acc");
1587 pic14_emitcode("push","%s",s);
1592 /* if bit variable */
1593 if (!aop->aopu.aop_dir) {
1594 pic14_emitcode("clr","a");
1595 pic14_emitcode("rlc","a");
1598 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1601 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1604 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1606 lbl = newiTempLabel(NULL);
1608 if (strcmp(s,"a")) {
1611 pic14_emitcode("clr","c");
1612 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1613 pic14_emitcode("cpl","c");
1614 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1615 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1622 if (strcmp(aop->aopu.aop_str[offset],s))
1623 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1628 if (!offset && (strcmp(s,"acc") == 0))
1631 if (strcmp(aop->aopu.aop_str[offset],s))
1632 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1636 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1637 "aopPut got unsupported aop->type");
1643 /*-----------------------------------------------------------------*/
1644 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1645 /*-----------------------------------------------------------------*/
1646 void mov2w (asmop *aop, int offset)
1652 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1654 if ( aop->type == AOP_PCODE ||
1655 aop->type == AOP_LIT ||
1656 aop->type == AOP_IMMD )
1657 emitpcode(POC_MOVLW,popGet(aop,offset));
1659 emitpcode(POC_MOVFW,popGet(aop,offset));
1663 /*-----------------------------------------------------------------*/
1664 /* reAdjustPreg - points a register back to where it should */
1665 /*-----------------------------------------------------------------*/
1666 static void reAdjustPreg (asmop *aop)
1670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1672 if ((size = aop->size) <= 1)
1675 switch (aop->type) {
1679 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1683 if (aop->type == AOP_DPTR2)
1689 pic14_emitcode("lcall","__decdptr");
1692 if (aop->type == AOP_DPTR2)
1704 /*-----------------------------------------------------------------*/
1705 /* opIsGptr: returns non-zero if the passed operand is */
1706 /* a generic pointer type. */
1707 /*-----------------------------------------------------------------*/
1708 static int opIsGptr(operand *op)
1710 sym_link *type = operandType(op);
1712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1713 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1721 /*-----------------------------------------------------------------*/
1722 /* pic14_getDataSize - get the operand data size */
1723 /*-----------------------------------------------------------------*/
1724 int pic14_getDataSize(operand *op)
1726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1729 return AOP_SIZE(op);
1731 // tsd- in the pic port, the genptr size is 1, so this code here
1732 // fails. ( in the 8051 port, the size was 4).
1735 size = AOP_SIZE(op);
1736 if (size == GPTRSIZE)
1738 sym_link *type = operandType(op);
1739 if (IS_GENPTR(type))
1741 /* generic pointer; arithmetic operations
1742 * should ignore the high byte (pointer type).
1745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1752 /*-----------------------------------------------------------------*/
1753 /* pic14_outAcc - output Acc */
1754 /*-----------------------------------------------------------------*/
1755 void pic14_outAcc(operand *result)
1758 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1759 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1762 size = pic14_getDataSize(result);
1764 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1767 /* unsigned or positive */
1769 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1774 /*-----------------------------------------------------------------*/
1775 /* pic14_outBitC - output a bit C */
1776 /*-----------------------------------------------------------------*/
1777 void pic14_outBitC(operand *result)
1780 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1781 /* if the result is bit */
1782 if (AOP_TYPE(result) == AOP_CRY)
1783 aopPut(AOP(result),"c",0);
1785 pic14_emitcode("clr","a ; %d", __LINE__);
1786 pic14_emitcode("rlc","a");
1787 pic14_outAcc(result);
1791 /*-----------------------------------------------------------------*/
1792 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1793 /*-----------------------------------------------------------------*/
1794 void pic14_toBoolean(operand *oper)
1796 int size = AOP_SIZE(oper) - 1;
1799 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1801 if ( AOP_TYPE(oper) != AOP_ACC) {
1802 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1805 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1810 /*-----------------------------------------------------------------*/
1811 /* genNot - generate code for ! operation */
1812 /*-----------------------------------------------------------------*/
1813 static void genNot (iCode *ic)
1818 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1819 /* assign asmOps to operand & result */
1820 aopOp (IC_LEFT(ic),ic,FALSE);
1821 aopOp (IC_RESULT(ic),ic,TRUE);
1823 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1824 /* if in bit space then a special case */
1825 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1826 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1827 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1828 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1830 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1831 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1832 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1837 size = AOP_SIZE(IC_LEFT(ic));
1839 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1840 emitpcode(POC_ANDLW,popGetLit(1));
1841 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1844 pic14_toBoolean(IC_LEFT(ic));
1846 tlbl = newiTempLabel(NULL);
1847 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1848 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1849 pic14_outBitC(IC_RESULT(ic));
1852 /* release the aops */
1853 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1854 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1858 /*-----------------------------------------------------------------*/
1859 /* genCpl - generate code for complement */
1860 /*-----------------------------------------------------------------*/
1861 static void genCpl (iCode *ic)
1863 operand *left, *result;
1867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1868 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1869 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1871 /* if both are in bit space then
1873 if (AOP_TYPE(result) == AOP_CRY &&
1874 AOP_TYPE(left) == AOP_CRY ) {
1876 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1877 pic14_emitcode("cpl","c");
1878 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1882 size = AOP_SIZE(result);
1885 if(AOP_TYPE(left) == AOP_ACC)
1886 emitpcode(POC_XORLW, popGetLit(0xff));
1888 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1890 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1896 /* release the aops */
1897 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1898 freeAsmop(result,NULL,ic,TRUE);
1901 /*-----------------------------------------------------------------*/
1902 /* genUminusFloat - unary minus for floating points */
1903 /*-----------------------------------------------------------------*/
1904 static void genUminusFloat(operand *op,operand *result)
1906 int size ,offset =0 ;
1909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1910 /* for this we just need to flip the
1911 first it then copy the rest in place */
1912 size = AOP_SIZE(op) - 1;
1913 l = aopGet(AOP(op),3,FALSE,FALSE);
1917 pic14_emitcode("cpl","acc.7");
1918 aopPut(AOP(result),"a",3);
1922 aopGet(AOP(op),offset,FALSE,FALSE),
1928 /*-----------------------------------------------------------------*/
1929 /* genUminus - unary minus code generation */
1930 /*-----------------------------------------------------------------*/
1931 static void genUminus (iCode *ic)
1934 sym_link *optype, *rtype;
1937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1939 aopOp(IC_LEFT(ic),ic,FALSE);
1940 aopOp(IC_RESULT(ic),ic,TRUE);
1942 /* if both in bit space then special
1944 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1945 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1947 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1948 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1949 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1954 optype = operandType(IC_LEFT(ic));
1955 rtype = operandType(IC_RESULT(ic));
1957 /* if float then do float stuff */
1958 if (IS_FLOAT(optype)) {
1959 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1963 /* otherwise subtract from zero by taking the 2's complement */
1964 size = AOP_SIZE(IC_LEFT(ic));
1966 for(i=0; i<size; i++) {
1967 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1968 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1970 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1971 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1975 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1976 for(i=1; i<size; i++) {
1978 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1982 /* release the aops */
1983 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1984 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1987 /*-----------------------------------------------------------------*/
1988 /* saveRegisters - will look for a call and save the registers */
1989 /*-----------------------------------------------------------------*/
1990 static void saveRegisters(iCode *lic)
1997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1999 for (ic = lic ; ic ; ic = ic->next)
2000 if (ic->op == CALL || ic->op == PCALL)
2004 fprintf(stderr,"found parameter push with no function call\n");
2008 /* if the registers have been saved already then
2010 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2013 /* find the registers in use at this time
2014 and push them away to safety */
2015 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2019 if (options.useXstack) {
2020 if (bitVectBitValue(rsave,R0_IDX))
2021 pic14_emitcode("mov","b,r0");
2022 pic14_emitcode("mov","r0,%s",spname);
2023 for (i = 0 ; i < pic14_nRegs ; i++) {
2024 if (bitVectBitValue(rsave,i)) {
2026 pic14_emitcode("mov","a,b");
2028 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2029 pic14_emitcode("movx","@r0,a");
2030 pic14_emitcode("inc","r0");
2033 pic14_emitcode("mov","%s,r0",spname);
2034 if (bitVectBitValue(rsave,R0_IDX))
2035 pic14_emitcode("mov","r0,b");
2037 //for (i = 0 ; i < pic14_nRegs ; i++) {
2038 // if (bitVectBitValue(rsave,i))
2039 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2042 dtype = operandType(IC_LEFT(ic));
2043 if (currFunc && dtype &&
2044 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2045 IFFUNC_ISISR(currFunc->type) &&
2048 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2051 /*-----------------------------------------------------------------*/
2052 /* unsaveRegisters - pop the pushed registers */
2053 /*-----------------------------------------------------------------*/
2054 static void unsaveRegisters (iCode *ic)
2059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2060 /* find the registers in use at this time
2061 and push them away to safety */
2062 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2065 if (options.useXstack) {
2066 pic14_emitcode("mov","r0,%s",spname);
2067 for (i = pic14_nRegs ; i >= 0 ; i--) {
2068 if (bitVectBitValue(rsave,i)) {
2069 pic14_emitcode("dec","r0");
2070 pic14_emitcode("movx","a,@r0");
2072 pic14_emitcode("mov","b,a");
2074 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2078 pic14_emitcode("mov","%s,r0",spname);
2079 if (bitVectBitValue(rsave,R0_IDX))
2080 pic14_emitcode("mov","r0,b");
2082 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2083 // if (bitVectBitValue(rsave,i))
2084 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2090 /*-----------------------------------------------------------------*/
2092 /*-----------------------------------------------------------------*/
2093 static void pushSide(operand * oper, int size)
2097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2099 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2100 if (AOP_TYPE(oper) != AOP_REG &&
2101 AOP_TYPE(oper) != AOP_DIR &&
2103 pic14_emitcode("mov","a,%s",l);
2104 pic14_emitcode("push","acc");
2106 pic14_emitcode("push","%s",l);
2111 /*-----------------------------------------------------------------*/
2112 /* assignResultValue - */
2113 /*-----------------------------------------------------------------*/
2114 static void assignResultValue(operand * oper)
2116 int size = AOP_SIZE(oper);
2118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2120 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2123 if (GpsuedoStkPtr++)
2124 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2125 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2130 /*-----------------------------------------------------------------*/
2131 /* genIpush - genrate code for pushing this gets a little complex */
2132 /*-----------------------------------------------------------------*/
2133 static void genIpush (iCode *ic)
2136 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 int size, offset = 0 ;
2142 /* if this is not a parm push : ie. it is spill push
2143 and spill push is always done on the local stack */
2144 if (!ic->parmPush) {
2146 /* and the item is spilt then do nothing */
2147 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2150 aopOp(IC_LEFT(ic),ic,FALSE);
2151 size = AOP_SIZE(IC_LEFT(ic));
2152 /* push it on the stack */
2154 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2159 pic14_emitcode("push","%s",l);
2164 /* this is a paramter push: in this case we call
2165 the routine to find the call and save those
2166 registers that need to be saved */
2169 /* then do the push */
2170 aopOp(IC_LEFT(ic),ic,FALSE);
2173 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2174 size = AOP_SIZE(IC_LEFT(ic));
2177 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2178 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2179 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2181 pic14_emitcode("mov","a,%s",l);
2182 pic14_emitcode("push","acc");
2184 pic14_emitcode("push","%s",l);
2187 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2191 /*-----------------------------------------------------------------*/
2192 /* genIpop - recover the registers: can happen only for spilling */
2193 /*-----------------------------------------------------------------*/
2194 static void genIpop (iCode *ic)
2196 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2201 /* if the temp was not pushed then */
2202 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2205 aopOp(IC_LEFT(ic),ic,FALSE);
2206 size = AOP_SIZE(IC_LEFT(ic));
2209 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2212 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2216 /*-----------------------------------------------------------------*/
2217 /* unsaverbank - restores the resgister bank from stack */
2218 /*-----------------------------------------------------------------*/
2219 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2221 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2229 if (options.useXstack) {
2231 r = getFreePtr(ic,&aop,FALSE);
2234 pic14_emitcode("mov","%s,_spx",r->name);
2235 pic14_emitcode("movx","a,@%s",r->name);
2236 pic14_emitcode("mov","psw,a");
2237 pic14_emitcode("dec","%s",r->name);
2240 pic14_emitcode ("pop","psw");
2243 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2244 if (options.useXstack) {
2245 pic14_emitcode("movx","a,@%s",r->name);
2246 //pic14_emitcode("mov","(%s+%d),a",
2247 // regspic14[i].base,8*bank+regspic14[i].offset);
2248 pic14_emitcode("dec","%s",r->name);
2251 pic14_emitcode("pop",""); //"(%s+%d)",
2252 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2255 if (options.useXstack) {
2257 pic14_emitcode("mov","_spx,%s",r->name);
2258 freeAsmop(NULL,aop,ic,TRUE);
2264 /*-----------------------------------------------------------------*/
2265 /* saverbank - saves an entire register bank on the stack */
2266 /*-----------------------------------------------------------------*/
2267 static void saverbank (int bank, iCode *ic, bool pushPsw)
2269 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2276 if (options.useXstack) {
2279 r = getFreePtr(ic,&aop,FALSE);
2280 pic14_emitcode("mov","%s,_spx",r->name);
2284 for (i = 0 ; i < pic14_nRegs ;i++) {
2285 if (options.useXstack) {
2286 pic14_emitcode("inc","%s",r->name);
2287 //pic14_emitcode("mov","a,(%s+%d)",
2288 // regspic14[i].base,8*bank+regspic14[i].offset);
2289 pic14_emitcode("movx","@%s,a",r->name);
2291 pic14_emitcode("push","");// "(%s+%d)",
2292 //regspic14[i].base,8*bank+regspic14[i].offset);
2296 if (options.useXstack) {
2297 pic14_emitcode("mov","a,psw");
2298 pic14_emitcode("movx","@%s,a",r->name);
2299 pic14_emitcode("inc","%s",r->name);
2300 pic14_emitcode("mov","_spx,%s",r->name);
2301 freeAsmop (NULL,aop,ic,TRUE);
2304 pic14_emitcode("push","psw");
2306 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2312 /*-----------------------------------------------------------------*/
2313 /* genCall - generates a call statement */
2314 /*-----------------------------------------------------------------*/
2315 static void genCall (iCode *ic)
2319 unsigned char *name;
2322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2324 /* if caller saves & we have not saved then */
2328 /* if we are calling a function that is not using
2329 the same register bank then we need to save the
2330 destination registers on the stack */
2331 dtype = operandType(IC_LEFT(ic));
2332 if (currFunc && dtype &&
2333 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2334 IFFUNC_ISISR(currFunc->type) &&
2337 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2339 /* if send set is not empty the assign */
2342 /* For the Pic port, there is no data stack.
2343 * So parameters passed to functions are stored
2344 * in registers. (The pCode optimizer will get
2345 * rid of most of these :).
2347 int psuedoStkPtr=-1;
2348 int firstTimeThruLoop = 1;
2350 _G.sendSet = reverseSet(_G.sendSet);
2352 /* First figure how many parameters are getting passed */
2353 for (sic = setFirstItem(_G.sendSet) ; sic ;
2354 sic = setNextItem(_G.sendSet)) {
2356 aopOp(IC_LEFT(sic),sic,FALSE);
2357 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2358 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2361 for (sic = setFirstItem(_G.sendSet) ; sic ;
2362 sic = setNextItem(_G.sendSet)) {
2363 int size, offset = 0;
2365 aopOp(IC_LEFT(sic),sic,FALSE);
2366 size = AOP_SIZE(IC_LEFT(sic));
2369 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2370 AopType(AOP_TYPE(IC_LEFT(sic))));
2372 if(!firstTimeThruLoop) {
2373 /* If this is not the first time we've been through the loop
2374 * then we need to save the parameter in a temporary
2375 * register. The last byte of the last parameter is
2377 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2380 firstTimeThruLoop=0;
2382 mov2w (AOP(IC_LEFT(sic)), offset);
2385 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2390 sym = OP_SYMBOL(IC_LEFT(ic));
2391 name = sym->rname[0] ? sym->rname : sym->name;
2392 isExtern = IS_EXTERN(sym->etype);
2394 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2396 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2398 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2401 /* if we need assign a result value */
2402 if ((IS_ITEMP(IC_RESULT(ic)) &&
2403 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2404 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2405 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2408 aopOp(IC_RESULT(ic),ic,FALSE);
2411 assignResultValue(IC_RESULT(ic));
2413 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2414 AopType(AOP_TYPE(IC_RESULT(ic))));
2416 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2419 /* adjust the stack for parameters if
2421 if (ic->parmBytes) {
2423 if (ic->parmBytes > 3) {
2424 pic14_emitcode("mov","a,%s",spname);
2425 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2426 pic14_emitcode("mov","%s,a",spname);
2428 for ( i = 0 ; i < ic->parmBytes ;i++)
2429 pic14_emitcode("dec","%s",spname);
2433 /* if register bank was saved then pop them */
2435 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2437 /* if we hade saved some registers then unsave them */
2438 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2439 unsaveRegisters (ic);
2444 /*-----------------------------------------------------------------*/
2445 /* genPcall - generates a call by pointer statement */
2446 /*-----------------------------------------------------------------*/
2447 static void genPcall (iCode *ic)
2450 symbol *albl = newiTempLabel(NULL);
2451 symbol *blbl = newiTempLabel(NULL);
2456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2457 /* if caller saves & we have not saved then */
2461 /* if we are calling a function that is not using
2462 the same register bank then we need to save the
2463 destination registers on the stack */
2464 dtype = operandType(IC_LEFT(ic));
2465 if (currFunc && dtype &&
2466 IFFUNC_ISISR(currFunc->type) &&
2467 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2468 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2471 aopOp(left,ic,FALSE);
2472 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2474 pushSide(IC_LEFT(ic), FPTRSIZE);
2476 /* if send set is not empty, assign parameters */
2479 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2480 /* no way to pass args - W always gets used to make the call */
2482 /* first idea - factor out a common helper function and call it.
2483 But don't know how to get it generated only once in its own block
2485 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2488 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2489 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2490 buffer = Safe_calloc(1,strlen(rname)+16);
2491 sprintf(buffer, "%s_goto_helper", rname);
2492 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2496 emitpcode(POC_CALL,popGetLabel(albl->key));
2497 pcop = popGetLabel(blbl->key);
2498 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2499 emitpcode(POC_GOTO,pcop);
2500 emitpLabel(albl->key);
2502 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2504 emitpcode(poc,popGet(AOP(left),1));
2505 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2506 emitpcode(poc,popGet(AOP(left),0));
2507 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2509 emitpLabel(blbl->key);
2511 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2513 /* if we need to assign a result value */
2514 if ((IS_ITEMP(IC_RESULT(ic)) &&
2515 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2516 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2517 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2520 aopOp(IC_RESULT(ic),ic,FALSE);
2523 assignResultValue(IC_RESULT(ic));
2525 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2528 /* if register bank was saved then unsave them */
2529 if (currFunc && dtype &&
2530 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2531 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533 /* if we hade saved some registers then
2536 unsaveRegisters (ic);
2540 /*-----------------------------------------------------------------*/
2541 /* resultRemat - result is rematerializable */
2542 /*-----------------------------------------------------------------*/
2543 static int resultRemat (iCode *ic)
2545 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2546 if (SKIP_IC(ic) || ic->op == IFX)
2549 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2550 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2551 if (sym->remat && !POINTER_SET(ic))
2558 #if defined(__BORLANDC__) || defined(_MSC_VER)
2559 #define STRCASECMP stricmp
2561 #define STRCASECMP strcasecmp
2565 /*-----------------------------------------------------------------*/
2566 /* inExcludeList - return 1 if the string is in exclude Reg list */
2567 /*-----------------------------------------------------------------*/
2568 static bool inExcludeList(char *s)
2570 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2573 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2574 if (options.excludeRegs[i] &&
2575 STRCASECMP(options.excludeRegs[i],"none") == 0)
2578 for ( i = 0 ; options.excludeRegs[i]; i++) {
2579 if (options.excludeRegs[i] &&
2580 STRCASECMP(s,options.excludeRegs[i]) == 0)
2587 /*-----------------------------------------------------------------*/
2588 /* genFunction - generated code for function entry */
2589 /*-----------------------------------------------------------------*/
2590 static void genFunction (iCode *ic)
2595 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2597 labelOffset += (max_key+4);
2601 /* create the function header */
2602 pic14_emitcode(";","-----------------------------------------");
2603 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2604 pic14_emitcode(";","-----------------------------------------");
2606 pic14_emitcode("","%s:",sym->rname);
2607 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2609 ftype = operandType(IC_LEFT(ic));
2611 /* if critical function then turn interrupts off */
2612 if (IFFUNC_ISCRITICAL(ftype))
2613 pic14_emitcode("clr","ea");
2615 /* here we need to generate the equates for the
2616 register bank if required */
2618 if (FUNC_REGBANK(ftype) != rbank) {
2621 rbank = FUNC_REGBANK(ftype);
2622 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2623 if (strcmp(regspic14[i].base,"0") == 0)
2624 pic14_emitcode("","%s = 0x%02x",
2626 8*rbank+regspic14[i].offset);
2628 pic14_emitcode ("","%s = %s + 0x%02x",
2631 8*rbank+regspic14[i].offset);
2636 /* if this is an interrupt service routine */
2637 if (IFFUNC_ISISR(sym->type)) {
2638 /* already done in pic14createInterruptVect() - delete me
2639 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2640 emitpcodeNULLop(POC_NOP);
2641 emitpcodeNULLop(POC_NOP);
2642 emitpcodeNULLop(POC_NOP);
2644 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2645 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2646 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2647 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2648 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2649 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2650 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2652 pBlockConvert2ISR(pb);
2654 if (!inExcludeList("acc"))
2655 pic14_emitcode ("push","acc");
2656 if (!inExcludeList("b"))
2657 pic14_emitcode ("push","b");
2658 if (!inExcludeList("dpl"))
2659 pic14_emitcode ("push","dpl");
2660 if (!inExcludeList("dph"))
2661 pic14_emitcode ("push","dph");
2662 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2664 pic14_emitcode ("push", "dpx");
2665 /* Make sure we're using standard DPTR */
2666 pic14_emitcode ("push", "dps");
2667 pic14_emitcode ("mov", "dps, #0x00");
2668 if (options.stack10bit)
2670 /* This ISR could conceivably use DPTR2. Better save it. */
2671 pic14_emitcode ("push", "dpl1");
2672 pic14_emitcode ("push", "dph1");
2673 pic14_emitcode ("push", "dpx1");
2676 /* if this isr has no bank i.e. is going to
2677 run with bank 0 , then we need to save more
2679 if (!FUNC_REGBANK(sym->type)) {
2681 /* if this function does not call any other
2682 function then we can be economical and
2683 save only those registers that are used */
2684 if (! IFFUNC_HASFCALL(sym->type)) {
2687 /* if any registers used */
2688 if (sym->regsUsed) {
2689 /* save the registers used */
2690 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2691 if (bitVectBitValue(sym->regsUsed,i) ||
2692 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2693 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2698 /* this function has a function call cannot
2699 determines register usage so we will have the
2701 saverbank(0,ic,FALSE);
2706 /* if callee-save to be used for this function
2707 then save the registers being used in this function */
2708 if (IFFUNC_CALLEESAVES(sym->type)) {
2711 /* if any registers used */
2712 if (sym->regsUsed) {
2713 /* save the registers used */
2714 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2715 if (bitVectBitValue(sym->regsUsed,i) ||
2716 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2717 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2725 /* set the register bank to the desired value */
2726 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2727 pic14_emitcode("push","psw");
2728 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2731 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2733 if (options.useXstack) {
2734 pic14_emitcode("mov","r0,%s",spname);
2735 pic14_emitcode("mov","a,_bp");
2736 pic14_emitcode("movx","@r0,a");
2737 pic14_emitcode("inc","%s",spname);
2741 /* set up the stack */
2742 pic14_emitcode ("push","_bp"); /* save the callers stack */
2744 pic14_emitcode ("mov","_bp,%s",spname);
2747 /* adjust the stack for the function */
2752 werror(W_STACK_OVERFLOW,sym->name);
2754 if (i > 3 && sym->recvSize < 4) {
2756 pic14_emitcode ("mov","a,sp");
2757 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2758 pic14_emitcode ("mov","sp,a");
2763 pic14_emitcode("inc","sp");
2768 pic14_emitcode ("mov","a,_spx");
2769 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2770 pic14_emitcode ("mov","_spx,a");
2775 /*-----------------------------------------------------------------*/
2776 /* genEndFunction - generates epilogue for functions */
2777 /*-----------------------------------------------------------------*/
2778 static void genEndFunction (iCode *ic)
2780 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2784 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2786 pic14_emitcode ("mov","%s,_bp",spname);
2789 /* if use external stack but some variables were
2790 added to the local stack then decrement the
2792 if (options.useXstack && sym->stack) {
2793 pic14_emitcode("mov","a,sp");
2794 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2795 pic14_emitcode("mov","sp,a");
2799 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2800 if (options.useXstack) {
2801 pic14_emitcode("mov","r0,%s",spname);
2802 pic14_emitcode("movx","a,@r0");
2803 pic14_emitcode("mov","_bp,a");
2804 pic14_emitcode("dec","%s",spname);
2808 pic14_emitcode ("pop","_bp");
2812 /* restore the register bank */
2813 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2814 pic14_emitcode ("pop","psw");
2816 if (IFFUNC_ISISR(sym->type)) {
2818 /* now we need to restore the registers */
2819 /* if this isr has no bank i.e. is going to
2820 run with bank 0 , then we need to save more
2822 if (!FUNC_REGBANK(sym->type)) {
2824 /* if this function does not call any other
2825 function then we can be economical and
2826 save only those registers that are used */
2827 if (! IFFUNC_HASFCALL(sym->type)) {
2830 /* if any registers used */
2831 if (sym->regsUsed) {
2832 /* save the registers used */
2833 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2834 if (bitVectBitValue(sym->regsUsed,i) ||
2835 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2836 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2841 /* this function has a function call cannot
2842 determines register usage so we will have the
2844 unsaverbank(0,ic,FALSE);
2848 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2850 if (options.stack10bit)
2852 pic14_emitcode ("pop", "dpx1");
2853 pic14_emitcode ("pop", "dph1");
2854 pic14_emitcode ("pop", "dpl1");
2856 pic14_emitcode ("pop", "dps");
2857 pic14_emitcode ("pop", "dpx");
2859 if (!inExcludeList("dph"))
2860 pic14_emitcode ("pop","dph");
2861 if (!inExcludeList("dpl"))
2862 pic14_emitcode ("pop","dpl");
2863 if (!inExcludeList("b"))
2864 pic14_emitcode ("pop","b");
2865 if (!inExcludeList("acc"))
2866 pic14_emitcode ("pop","acc");
2868 if (IFFUNC_ISCRITICAL(sym->type))
2869 pic14_emitcode("setb","ea");
2872 /* if debug then send end of function */
2873 /* if (options.debug && currFunc) { */
2876 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2877 FileBaseName(ic->filename),currFunc->lastLine,
2878 ic->level,ic->block);
2879 if (IS_STATIC(currFunc->etype))
2880 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2882 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2886 pic14_emitcode ("reti","");
2887 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2888 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2889 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2890 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2891 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2892 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2893 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2894 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2895 emitpcodeNULLop(POC_RETFIE);
2898 if (IFFUNC_ISCRITICAL(sym->type))
2899 pic14_emitcode("setb","ea");
2901 if (IFFUNC_CALLEESAVES(sym->type)) {
2904 /* if any registers used */
2905 if (sym->regsUsed) {
2906 /* save the registers used */
2907 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2908 if (bitVectBitValue(sym->regsUsed,i) ||
2909 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2910 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2916 /* if debug then send end of function */
2919 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2920 FileBaseName(ic->filename),currFunc->lastLine,
2921 ic->level,ic->block);
2922 if (IS_STATIC(currFunc->etype))
2923 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2925 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2929 pic14_emitcode ("return","");
2930 emitpcodeNULLop(POC_RETURN);
2932 /* Mark the end of a function */
2933 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2938 /*-----------------------------------------------------------------*/
2939 /* genRet - generate code for return statement */
2940 /*-----------------------------------------------------------------*/
2941 static void genRet (iCode *ic)
2943 int size,offset = 0 , pushed = 0;
2945 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2946 /* if we have no return value then
2947 just generate the "ret" */
2951 /* we have something to return then
2952 move the return value into place */
2953 aopOp(IC_LEFT(ic),ic,FALSE);
2954 size = AOP_SIZE(IC_LEFT(ic));
2958 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2960 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2962 pic14_emitcode("push","%s",l);
2965 l = aopGet(AOP(IC_LEFT(ic)),offset,
2967 if (strcmp(fReturn[offset],l)) {
2968 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2969 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2970 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2971 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2972 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2974 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2977 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2987 if (strcmp(fReturn[pushed],"a"))
2988 pic14_emitcode("pop",fReturn[pushed]);
2990 pic14_emitcode("pop","acc");
2993 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2996 /* generate a jump to the return label
2997 if the next is not the return statement */
2998 if (!(ic->next && ic->next->op == LABEL &&
2999 IC_LABEL(ic->next) == returnLabel)) {
3001 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3002 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3007 /*-----------------------------------------------------------------*/
3008 /* genLabel - generates a label */
3009 /*-----------------------------------------------------------------*/
3010 static void genLabel (iCode *ic)
3012 /* special case never generate */
3013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3014 if (IC_LABEL(ic) == entryLabel)
3017 emitpLabel(IC_LABEL(ic)->key);
3018 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3021 /*-----------------------------------------------------------------*/
3022 /* genGoto - generates a goto */
3023 /*-----------------------------------------------------------------*/
3025 static void genGoto (iCode *ic)
3027 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3028 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3032 /*-----------------------------------------------------------------*/
3033 /* genMultbits :- multiplication of bits */
3034 /*-----------------------------------------------------------------*/
3035 static void genMultbits (operand *left,
3039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3041 if(!pic14_sameRegs(AOP(result),AOP(right)))
3042 emitpcode(POC_BSF, popGet(AOP(result),0));
3044 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3045 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3046 emitpcode(POC_BCF, popGet(AOP(result),0));
3051 /*-----------------------------------------------------------------*/
3052 /* genMultOneByte : 8 bit multiplication & division */
3053 /*-----------------------------------------------------------------*/
3054 static void genMultOneByte (operand *left,
3058 sym_link *opetype = operandType(result);
3063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3064 DEBUGpic14_AopType(__LINE__,left,right,result);
3065 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3067 /* (if two literals, the value is computed before) */
3068 /* if one literal, literal on the right */
3069 if (AOP_TYPE(left) == AOP_LIT){
3075 size = AOP_SIZE(result);
3078 if (AOP_TYPE(right) == AOP_LIT){
3079 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3080 aopGet(AOP(right),0,FALSE,FALSE),
3081 aopGet(AOP(left),0,FALSE,FALSE),
3082 aopGet(AOP(result),0,FALSE,FALSE));
3083 pic14_emitcode("call","genMultLit");
3085 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3086 aopGet(AOP(right),0,FALSE,FALSE),
3087 aopGet(AOP(left),0,FALSE,FALSE),
3088 aopGet(AOP(result),0,FALSE,FALSE));
3089 pic14_emitcode("call","genMult8X8_8");
3092 genMult8X8_8 (left, right,result);
3095 /* signed or unsigned */
3096 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3097 //l = aopGet(AOP(left),0,FALSE,FALSE);
3099 //pic14_emitcode("mul","ab");
3100 /* if result size = 1, mul signed = mul unsigned */
3101 //aopPut(AOP(result),"a",0);
3103 } else { // (size > 1)
3105 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3106 aopGet(AOP(right),0,FALSE,FALSE),
3107 aopGet(AOP(left),0,FALSE,FALSE),
3108 aopGet(AOP(result),0,FALSE,FALSE));
3110 if (SPEC_USIGN(opetype)){
3111 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3112 genUMult8X8_16 (left, right, result, NULL);
3115 /* for filling the MSBs */
3116 emitpcode(POC_CLRF, popGet(AOP(result),2));
3117 emitpcode(POC_CLRF, popGet(AOP(result),3));
3121 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3123 pic14_emitcode("mov","a,b");
3125 /* adjust the MSB if left or right neg */
3127 /* if one literal */
3128 if (AOP_TYPE(right) == AOP_LIT){
3129 pic14_emitcode("multiply ","right is a lit");
3130 /* AND literal negative */
3131 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3132 /* adjust MSB (c==0 after mul) */
3133 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3137 genSMult8X8_16 (left, right, result, NULL);
3141 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3143 pic14_emitcode("rlc","a");
3144 pic14_emitcode("subb","a,acc");
3152 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3153 //aopPut(AOP(result),"a",offset++);
3157 /*-----------------------------------------------------------------*/
3158 /* genMult - generates code for multiplication */
3159 /*-----------------------------------------------------------------*/
3160 static void genMult (iCode *ic)
3162 operand *left = IC_LEFT(ic);
3163 operand *right = IC_RIGHT(ic);
3164 operand *result= IC_RESULT(ic);
3166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3167 /* assign the amsops */
3168 aopOp (left,ic,FALSE);
3169 aopOp (right,ic,FALSE);
3170 aopOp (result,ic,TRUE);
3172 DEBUGpic14_AopType(__LINE__,left,right,result);
3174 /* special cases first */
3176 if (AOP_TYPE(left) == AOP_CRY &&
3177 AOP_TYPE(right)== AOP_CRY) {
3178 genMultbits(left,right,result);
3182 /* if both are of size == 1 */
3183 if (AOP_SIZE(left) == 1 &&
3184 AOP_SIZE(right) == 1 ) {
3185 genMultOneByte(left,right,result);
3189 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3191 /* should have been converted to function call */
3195 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3196 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3197 freeAsmop(result,NULL,ic,TRUE);
3200 /*-----------------------------------------------------------------*/
3201 /* genDivbits :- division of bits */
3202 /*-----------------------------------------------------------------*/
3203 static void genDivbits (operand *left,
3210 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3211 /* the result must be bit */
3212 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3213 l = aopGet(AOP(left),0,FALSE,FALSE);
3217 pic14_emitcode("div","ab");
3218 pic14_emitcode("rrc","a");
3219 aopPut(AOP(result),"c",0);
3222 /*-----------------------------------------------------------------*/
3223 /* genDivOneByte : 8 bit division */
3224 /*-----------------------------------------------------------------*/
3225 static void genDivOneByte (operand *left,
3229 sym_link *opetype = operandType(result);
3234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3235 size = AOP_SIZE(result) - 1;
3237 /* signed or unsigned */
3238 if (SPEC_USIGN(opetype)) {
3239 /* unsigned is easy */
3240 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3241 l = aopGet(AOP(left),0,FALSE,FALSE);
3243 pic14_emitcode("div","ab");
3244 aopPut(AOP(result),"a",0);
3246 aopPut(AOP(result),zero,offset++);
3250 /* signed is a little bit more difficult */
3252 /* save the signs of the operands */
3253 l = aopGet(AOP(left),0,FALSE,FALSE);
3255 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3256 pic14_emitcode("push","acc"); /* save it on the stack */
3258 /* now sign adjust for both left & right */
3259 l = aopGet(AOP(right),0,FALSE,FALSE);
3261 lbl = newiTempLabel(NULL);
3262 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3263 pic14_emitcode("cpl","a");
3264 pic14_emitcode("inc","a");
3265 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3266 pic14_emitcode("mov","b,a");
3268 /* sign adjust left side */
3269 l = aopGet(AOP(left),0,FALSE,FALSE);
3272 lbl = newiTempLabel(NULL);
3273 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3274 pic14_emitcode("cpl","a");
3275 pic14_emitcode("inc","a");
3276 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3278 /* now the division */
3279 pic14_emitcode("div","ab");
3280 /* we are interested in the lower order
3282 pic14_emitcode("mov","b,a");
3283 lbl = newiTempLabel(NULL);
3284 pic14_emitcode("pop","acc");
3285 /* if there was an over flow we don't
3286 adjust the sign of the result */
3287 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3288 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3290 pic14_emitcode("clr","a");
3291 pic14_emitcode("subb","a,b");
3292 pic14_emitcode("mov","b,a");
3293 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3295 /* now we are done */
3296 aopPut(AOP(result),"b",0);
3298 pic14_emitcode("mov","c,b.7");
3299 pic14_emitcode("subb","a,acc");
3302 aopPut(AOP(result),"a",offset++);
3306 /*-----------------------------------------------------------------*/
3307 /* genDiv - generates code for division */
3308 /*-----------------------------------------------------------------*/
3309 static void genDiv (iCode *ic)
3311 operand *left = IC_LEFT(ic);
3312 operand *right = IC_RIGHT(ic);
3313 operand *result= IC_RESULT(ic);
3315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3316 /* assign the amsops */
3317 aopOp (left,ic,FALSE);
3318 aopOp (right,ic,FALSE);
3319 aopOp (result,ic,TRUE);
3321 /* special cases first */
3323 if (AOP_TYPE(left) == AOP_CRY &&
3324 AOP_TYPE(right)== AOP_CRY) {
3325 genDivbits(left,right,result);
3329 /* if both are of size == 1 */
3330 if (AOP_SIZE(left) == 1 &&
3331 AOP_SIZE(right) == 1 ) {
3332 genDivOneByte(left,right,result);
3336 /* should have been converted to function call */
3339 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3340 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3341 freeAsmop(result,NULL,ic,TRUE);
3344 /*-----------------------------------------------------------------*/
3345 /* genModbits :- modulus of bits */
3346 /*-----------------------------------------------------------------*/
3347 static void genModbits (operand *left,
3354 /* the result must be bit */
3355 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3356 l = aopGet(AOP(left),0,FALSE,FALSE);
3360 pic14_emitcode("div","ab");
3361 pic14_emitcode("mov","a,b");
3362 pic14_emitcode("rrc","a");
3363 aopPut(AOP(result),"c",0);
3366 /*-----------------------------------------------------------------*/
3367 /* genModOneByte : 8 bit modulus */
3368 /*-----------------------------------------------------------------*/
3369 static void genModOneByte (operand *left,
3373 sym_link *opetype = operandType(result);
3377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3378 /* signed or unsigned */
3379 if (SPEC_USIGN(opetype)) {
3380 /* unsigned is easy */
3381 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3382 l = aopGet(AOP(left),0,FALSE,FALSE);
3384 pic14_emitcode("div","ab");
3385 aopPut(AOP(result),"b",0);
3389 /* signed is a little bit more difficult */
3391 /* save the signs of the operands */
3392 l = aopGet(AOP(left),0,FALSE,FALSE);
3395 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3396 pic14_emitcode("push","acc"); /* save it on the stack */
3398 /* now sign adjust for both left & right */
3399 l = aopGet(AOP(right),0,FALSE,FALSE);
3402 lbl = newiTempLabel(NULL);
3403 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3404 pic14_emitcode("cpl","a");
3405 pic14_emitcode("inc","a");
3406 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3407 pic14_emitcode("mov","b,a");
3409 /* sign adjust left side */
3410 l = aopGet(AOP(left),0,FALSE,FALSE);
3413 lbl = newiTempLabel(NULL);
3414 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3415 pic14_emitcode("cpl","a");
3416 pic14_emitcode("inc","a");
3417 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3419 /* now the multiplication */
3420 pic14_emitcode("div","ab");
3421 /* we are interested in the lower order
3423 lbl = newiTempLabel(NULL);
3424 pic14_emitcode("pop","acc");
3425 /* if there was an over flow we don't
3426 adjust the sign of the result */
3427 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3428 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3430 pic14_emitcode("clr","a");
3431 pic14_emitcode("subb","a,b");
3432 pic14_emitcode("mov","b,a");
3433 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3435 /* now we are done */
3436 aopPut(AOP(result),"b",0);
3440 /*-----------------------------------------------------------------*/
3441 /* genMod - generates code for division */
3442 /*-----------------------------------------------------------------*/
3443 static void genMod (iCode *ic)
3445 operand *left = IC_LEFT(ic);
3446 operand *right = IC_RIGHT(ic);
3447 operand *result= IC_RESULT(ic);
3449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3450 /* assign the amsops */
3451 aopOp (left,ic,FALSE);
3452 aopOp (right,ic,FALSE);
3453 aopOp (result,ic,TRUE);
3455 /* special cases first */
3457 if (AOP_TYPE(left) == AOP_CRY &&
3458 AOP_TYPE(right)== AOP_CRY) {
3459 genModbits(left,right,result);
3463 /* if both are of size == 1 */
3464 if (AOP_SIZE(left) == 1 &&
3465 AOP_SIZE(right) == 1 ) {
3466 genModOneByte(left,right,result);
3470 /* should have been converted to function call */
3474 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3475 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3476 freeAsmop(result,NULL,ic,TRUE);
3479 /*-----------------------------------------------------------------*/
3480 /* genIfxJump :- will create a jump depending on the ifx */
3481 /*-----------------------------------------------------------------*/
3483 note: May need to add parameter to indicate when a variable is in bit space.
3485 static void genIfxJump (iCode *ic, char *jval)
3488 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3489 /* if true label then we jump if condition
3491 if ( IC_TRUE(ic) ) {
3493 if(strcmp(jval,"a") == 0)
3495 else if (strcmp(jval,"c") == 0)
3498 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3499 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3502 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3503 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3507 /* false label is present */
3508 if(strcmp(jval,"a") == 0)
3510 else if (strcmp(jval,"c") == 0)
3513 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3514 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3517 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3518 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3523 /* mark the icode as generated */
3527 /*-----------------------------------------------------------------*/
3529 /*-----------------------------------------------------------------*/
3530 static void genSkip(iCode *ifx,int status_bit)
3535 if ( IC_TRUE(ifx) ) {
3536 switch(status_bit) {
3551 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3552 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3556 switch(status_bit) {
3570 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3571 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3577 /*-----------------------------------------------------------------*/
3579 /*-----------------------------------------------------------------*/
3580 static void genSkipc(resolvedIfx *rifx)
3590 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3591 rifx->generated = 1;
3594 /*-----------------------------------------------------------------*/
3596 /*-----------------------------------------------------------------*/
3597 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3602 if( (rifx->condition ^ invert_condition) & 1)
3607 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3608 rifx->generated = 1;
3611 /*-----------------------------------------------------------------*/
3613 /*-----------------------------------------------------------------*/
3614 static void genSkipz(iCode *ifx, int condition)
3625 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3627 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3630 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3632 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3635 /*-----------------------------------------------------------------*/
3637 /*-----------------------------------------------------------------*/
3638 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3644 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3646 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3649 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3650 rifx->generated = 1;
3654 /*-----------------------------------------------------------------*/
3655 /* genChkZeroes :- greater or less than comparison */
3656 /* For each byte in a literal that is zero, inclusive or the */
3657 /* the corresponding byte in the operand with W */
3658 /* returns true if any of the bytes are zero */
3659 /*-----------------------------------------------------------------*/
3660 static int genChkZeroes(operand *op, int lit, int size)
3667 i = (lit >> (size*8)) & 0xff;
3671 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3673 emitpcode(POC_IORFW, popGet(AOP(op),size));
3682 /*-----------------------------------------------------------------*/
3683 /* genCmp :- greater or less than comparison */
3684 /*-----------------------------------------------------------------*/
3685 static void genCmp (operand *left,operand *right,
3686 operand *result, iCode *ifx, int sign)
3688 int size; //, offset = 0 ;
3689 unsigned long lit = 0L,i = 0;
3690 resolvedIfx rFalseIfx;
3691 // resolvedIfx rTrueIfx;
3693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3696 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3697 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3701 resolveIfx(&rFalseIfx,ifx);
3702 truelbl = newiTempLabel(NULL);
3703 size = max(AOP_SIZE(left),AOP_SIZE(right));
3705 DEBUGpic14_AopType(__LINE__,left,right,result);
3709 /* if literal is on the right then swap with left */
3710 if ((AOP_TYPE(right) == AOP_LIT)) {
3711 operand *tmp = right ;
3712 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3713 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3716 lit = (lit - 1) & mask;
3719 rFalseIfx.condition ^= 1;
3722 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3723 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3727 //if(IC_TRUE(ifx) == NULL)
3728 /* if left & right are bit variables */
3729 if (AOP_TYPE(left) == AOP_CRY &&
3730 AOP_TYPE(right) == AOP_CRY ) {
3731 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3732 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3734 /* subtract right from left if at the
3735 end the carry flag is set then we know that
3736 left is greater than right */
3740 symbol *lbl = newiTempLabel(NULL);
3743 if(AOP_TYPE(right) == AOP_LIT) {
3745 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3747 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3754 genSkipCond(&rFalseIfx,left,size-1,7);
3756 /* no need to compare to 0...*/
3757 /* NOTE: this is a de-generate compare that most certainly
3758 * creates some dead code. */
3759 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3761 if(ifx) ifx->generated = 1;
3768 //i = (lit >> (size*8)) & 0xff;
3769 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3771 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3773 i = ((0-lit) & 0xff);
3776 /* lit is 0x7f, all signed chars are less than
3777 * this except for 0x7f itself */
3778 emitpcode(POC_XORLW, popGetLit(0x7f));
3779 genSkipz2(&rFalseIfx,0);
3781 emitpcode(POC_ADDLW, popGetLit(0x80));
3782 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3783 genSkipc(&rFalseIfx);
3788 genSkipz2(&rFalseIfx,1);
3790 emitpcode(POC_ADDLW, popGetLit(i));
3791 genSkipc(&rFalseIfx);
3795 if(ifx) ifx->generated = 1;
3799 /* chars are out of the way. now do ints and longs */
3802 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3809 genSkipCond(&rFalseIfx,left,size,7);
3810 if(ifx) ifx->generated = 1;
3815 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3817 //rFalseIfx.condition ^= 1;
3818 //genSkipCond(&rFalseIfx,left,size,7);
3819 //rFalseIfx.condition ^= 1;
3821 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3822 if(rFalseIfx.condition)
3823 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3825 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3827 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3828 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3829 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3832 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3834 if(rFalseIfx.condition) {
3836 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3842 genSkipc(&rFalseIfx);
3843 emitpLabel(truelbl->key);
3844 if(ifx) ifx->generated = 1;
3851 if( (lit & 0xff) == 0) {
3852 /* lower byte is zero */
3853 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3854 i = ((lit >> 8) & 0xff) ^0x80;
3855 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3856 emitpcode(POC_ADDLW, popGetLit( 0x80));
3857 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3858 genSkipc(&rFalseIfx);
3861 if(ifx) ifx->generated = 1;
3866 /* Special cases for signed longs */
3867 if( (lit & 0xffffff) == 0) {
3868 /* lower byte is zero */
3869 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3870 i = ((lit >> 8*3) & 0xff) ^0x80;
3871 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3872 emitpcode(POC_ADDLW, popGetLit( 0x80));
3873 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3874 genSkipc(&rFalseIfx);
3877 if(ifx) ifx->generated = 1;
3885 if(lit & (0x80 << (size*8))) {
3886 /* lit is negative */
3887 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3889 //genSkipCond(&rFalseIfx,left,size,7);
3891 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3893 if(rFalseIfx.condition)
3894 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3896 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3900 /* lit is positive */
3901 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3902 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3903 if(rFalseIfx.condition)
3904 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3906 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3910 /* There are no more special cases, so perform a general compare */
3912 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3913 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3917 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3919 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3921 //rFalseIfx.condition ^= 1;
3922 genSkipc(&rFalseIfx);
3924 emitpLabel(truelbl->key);
3926 if(ifx) ifx->generated = 1;
3933 /* sign is out of the way. So now do an unsigned compare */
3934 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3937 /* General case - compare to an unsigned literal on the right.*/
3939 i = (lit >> (size*8)) & 0xff;
3940 emitpcode(POC_MOVLW, popGetLit(i));
3941 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3943 i = (lit >> (size*8)) & 0xff;
3946 emitpcode(POC_MOVLW, popGetLit(i));
3948 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3950 /* this byte of the lit is zero,
3951 *if it's not the last then OR in the variable */
3953 emitpcode(POC_IORFW, popGet(AOP(left),size));
3958 emitpLabel(lbl->key);
3959 //if(emitFinalCheck)
3960 genSkipc(&rFalseIfx);
3962 emitpLabel(truelbl->key);
3964 if(ifx) ifx->generated = 1;
3971 if(AOP_TYPE(left) == AOP_LIT) {
3972 //symbol *lbl = newiTempLabel(NULL);
3974 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3977 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3980 if((lit == 0) && (sign == 0)){
3983 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3985 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3987 genSkipz2(&rFalseIfx,0);
3988 if(ifx) ifx->generated = 1;
3995 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3996 /* degenerate compare can never be true */
3997 if(rFalseIfx.condition == 0)
3998 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4000 if(ifx) ifx->generated = 1;
4005 /* signed comparisons to a literal byte */
4007 int lp1 = (lit+1) & 0xff;
4009 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4012 rFalseIfx.condition ^= 1;
4013 genSkipCond(&rFalseIfx,right,0,7);
4016 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4017 emitpcode(POC_XORLW, popGetLit(0x7f));
4018 genSkipz2(&rFalseIfx,1);
4021 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4022 emitpcode(POC_ADDLW, popGetLit(0x80));
4023 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4024 rFalseIfx.condition ^= 1;
4025 genSkipc(&rFalseIfx);
4028 if(ifx) ifx->generated = 1;
4030 /* unsigned comparisons to a literal byte */
4032 switch(lit & 0xff ) {
4034 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4035 genSkipz2(&rFalseIfx,0);
4036 if(ifx) ifx->generated = 1;
4039 genSkipCond(&rFalseIfx,right,0,7);
4040 if(ifx) ifx->generated = 1;
4044 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4045 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4047 rFalseIfx.condition ^= 1;
4048 if (AOP_TYPE(result) == AOP_CRY) {
4049 genSkipc(&rFalseIfx);
4050 if(ifx) ifx->generated = 1;
4052 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4053 emitpcode(POC_CLRF, popGet(AOP(result),0));
4054 emitpcode(POC_RLF, popGet(AOP(result),0));
4055 emitpcode(POC_MOVLW, popGetLit(0x01));
4056 emitpcode(POC_XORWF, popGet(AOP(result),0));
4067 /* Size is greater than 1 */
4075 /* this means lit = 0xffffffff, or -1 */
4078 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4079 rFalseIfx.condition ^= 1;
4080 genSkipCond(&rFalseIfx,right,size,7);
4081 if(ifx) ifx->generated = 1;
4088 if(rFalseIfx.condition) {
4089 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4090 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4093 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4095 emitpcode(POC_IORFW, popGet(AOP(right),size));
4099 if(rFalseIfx.condition) {
4100 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4101 emitpLabel(truelbl->key);
4103 rFalseIfx.condition ^= 1;
4104 genSkipCond(&rFalseIfx,right,s,7);
4107 if(ifx) ifx->generated = 1;
4111 if((size == 1) && (0 == (lp1&0xff))) {
4112 /* lower byte of signed word is zero */
4113 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4114 i = ((lp1 >> 8) & 0xff) ^0x80;
4115 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4116 emitpcode(POC_ADDLW, popGetLit( 0x80));
4117 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4118 rFalseIfx.condition ^= 1;
4119 genSkipc(&rFalseIfx);
4122 if(ifx) ifx->generated = 1;
4126 if(lit & (0x80 << (size*8))) {
4127 /* Lit is less than zero */
4128 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4129 //rFalseIfx.condition ^= 1;
4130 //genSkipCond(&rFalseIfx,left,size,7);
4131 //rFalseIfx.condition ^= 1;
4132 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4133 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4135 if(rFalseIfx.condition)
4136 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4138 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4142 /* Lit is greater than or equal to zero */
4143 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4144 //rFalseIfx.condition ^= 1;
4145 //genSkipCond(&rFalseIfx,right,size,7);
4146 //rFalseIfx.condition ^= 1;
4148 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4149 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4151 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152 if(rFalseIfx.condition)
4153 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4155 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4160 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4161 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4165 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4167 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4169 rFalseIfx.condition ^= 1;
4170 //rFalseIfx.condition = 1;
4171 genSkipc(&rFalseIfx);
4173 emitpLabel(truelbl->key);
4175 if(ifx) ifx->generated = 1;
4180 /* compare word or long to an unsigned literal on the right.*/
4185 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4188 break; /* handled above */
4191 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4193 emitpcode(POC_IORFW, popGet(AOP(right),size));
4194 genSkipz2(&rFalseIfx,0);
4198 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4200 emitpcode(POC_IORFW, popGet(AOP(right),size));
4203 if(rFalseIfx.condition)
4204 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4206 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4209 emitpcode(POC_MOVLW, popGetLit(lit+1));
4210 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4212 rFalseIfx.condition ^= 1;
4213 genSkipc(&rFalseIfx);
4216 emitpLabel(truelbl->key);
4218 if(ifx) ifx->generated = 1;
4224 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4225 i = (lit >> (size*8)) & 0xff;
4227 emitpcode(POC_MOVLW, popGetLit(i));
4228 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4231 i = (lit >> (size*8)) & 0xff;
4234 emitpcode(POC_MOVLW, popGetLit(i));
4236 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4238 /* this byte of the lit is zero,
4239 *if it's not the last then OR in the variable */
4241 emitpcode(POC_IORFW, popGet(AOP(right),size));
4246 emitpLabel(lbl->key);
4248 rFalseIfx.condition ^= 1;
4249 genSkipc(&rFalseIfx);
4253 emitpLabel(truelbl->key);
4254 if(ifx) ifx->generated = 1;
4258 /* Compare two variables */
4260 DEBUGpic14_emitcode(";sign","%d",sign);
4264 /* Sigh. thus sucks... */
4266 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4267 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4268 emitpcode(POC_MOVLW, popGetLit(0x80));
4269 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4270 emitpcode(POC_XORFW, popGet(AOP(right),size));
4271 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4273 /* Signed char comparison */
4274 /* Special thanks to Nikolai Golovchenko for this snippet */
4275 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4276 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4277 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4278 emitpcode(POC_XORFW, popGet(AOP(left),0));
4279 emitpcode(POC_XORFW, popGet(AOP(right),0));
4280 emitpcode(POC_ADDLW, popGetLit(0x80));
4282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4283 genSkipc(&rFalseIfx);
4285 if(ifx) ifx->generated = 1;
4291 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4292 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4296 /* The rest of the bytes of a multi-byte compare */
4300 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4303 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4304 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4309 emitpLabel(lbl->key);
4311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4312 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4313 (AOP_TYPE(result) == AOP_REG)) {
4314 emitpcode(POC_CLRF, popGet(AOP(result),0));
4315 emitpcode(POC_RLF, popGet(AOP(result),0));
4317 genSkipc(&rFalseIfx);
4319 //genSkipc(&rFalseIfx);
4320 if(ifx) ifx->generated = 1;
4327 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4329 pic14_outBitC(result);
4331 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4332 /* if the result is used in the next
4333 ifx conditional branch then generate
4334 code a little differently */
4336 genIfxJump (ifx,"c");
4338 pic14_outBitC(result);
4339 /* leave the result in acc */
4344 /*-----------------------------------------------------------------*/
4345 /* genCmpGt :- greater than comparison */
4346 /*-----------------------------------------------------------------*/
4347 static void genCmpGt (iCode *ic, iCode *ifx)
4349 operand *left, *right, *result;
4350 sym_link *letype , *retype;
4353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4355 right= IC_RIGHT(ic);
4356 result = IC_RESULT(ic);
4358 letype = getSpec(operandType(left));
4359 retype =getSpec(operandType(right));
4360 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4361 /* assign the amsops */
4362 aopOp (left,ic,FALSE);
4363 aopOp (right,ic,FALSE);
4364 aopOp (result,ic,TRUE);
4366 genCmp(right, left, result, ifx, sign);
4368 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4369 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4370 freeAsmop(result,NULL,ic,TRUE);
4373 /*-----------------------------------------------------------------*/
4374 /* genCmpLt - less than comparisons */
4375 /*-----------------------------------------------------------------*/
4376 static void genCmpLt (iCode *ic, iCode *ifx)
4378 operand *left, *right, *result;
4379 sym_link *letype , *retype;
4382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4384 right= IC_RIGHT(ic);
4385 result = IC_RESULT(ic);
4387 letype = getSpec(operandType(left));
4388 retype =getSpec(operandType(right));
4389 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4391 /* assign the amsops */
4392 aopOp (left,ic,FALSE);
4393 aopOp (right,ic,FALSE);
4394 aopOp (result,ic,TRUE);
4396 genCmp(left, right, result, ifx, sign);
4398 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4399 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4400 freeAsmop(result,NULL,ic,TRUE);
4403 /*-----------------------------------------------------------------*/
4404 /* genc16bit2lit - compare a 16 bit value to a literal */
4405 /*-----------------------------------------------------------------*/
4406 static void genc16bit2lit(operand *op, int lit, int offset)
4410 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4411 if( (lit&0xff) == 0)
4416 switch( BYTEofLONG(lit,i)) {
4418 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4421 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4424 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4427 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4428 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4433 switch( BYTEofLONG(lit,i)) {
4435 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4439 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4443 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4446 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4448 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4454 /*-----------------------------------------------------------------*/
4455 /* gencjneshort - compare and jump if not equal */
4456 /*-----------------------------------------------------------------*/
4457 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4459 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4461 int res_offset = 0; /* the result may be a different size then left or right */
4462 int res_size = AOP_SIZE(result);
4466 unsigned long lit = 0L;
4467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4468 DEBUGpic14_AopType(__LINE__,left,right,result);
4470 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4471 resolveIfx(&rIfx,ifx);
4472 lbl = newiTempLabel(NULL);
4475 /* if the left side is a literal or
4476 if the right is in a pointer register and left
4478 if ((AOP_TYPE(left) == AOP_LIT) ||
4479 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4484 if(AOP_TYPE(right) == AOP_LIT)
4485 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4487 /* if the right side is a literal then anything goes */
4488 if (AOP_TYPE(right) == AOP_LIT &&
4489 AOP_TYPE(left) != AOP_DIR ) {
4492 genc16bit2lit(left, lit, 0);
4494 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4499 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4500 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4502 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4506 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4508 if(res_offset < res_size-1)
4516 /* if the right side is in a register or in direct space or
4517 if the left is a pointer register & right is not */
4518 else if (AOP_TYPE(right) == AOP_REG ||
4519 AOP_TYPE(right) == AOP_DIR ||
4520 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4521 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4522 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4523 int lbl_key = lbl->key;
4526 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4527 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4529 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4530 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4531 __FUNCTION__,__LINE__);
4535 /* switch(size) { */
4537 /* genc16bit2lit(left, lit, 0); */
4539 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4544 if((AOP_TYPE(left) == AOP_DIR) &&
4545 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4547 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4548 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4550 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4552 switch (lit & 0xff) {
4554 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4557 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4558 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4559 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4563 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4564 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4565 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4566 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4570 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4571 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4576 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4579 if(AOP_TYPE(result) == AOP_CRY) {
4580 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4585 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4587 /* fix me. probably need to check result size too */
4588 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4593 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4594 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4601 if(res_offset < res_size-1)
4606 } else if(AOP_TYPE(right) == AOP_REG &&
4607 AOP_TYPE(left) != AOP_DIR){
4610 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4611 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4612 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4617 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4619 if(res_offset < res_size-1)
4624 /* right is a pointer reg need both a & b */
4626 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4628 pic14_emitcode("mov","b,%s",l);
4629 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4630 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4635 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4637 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4639 emitpLabel(lbl->key);
4641 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4648 /*-----------------------------------------------------------------*/
4649 /* gencjne - compare and jump if not equal */
4650 /*-----------------------------------------------------------------*/
4651 static void gencjne(operand *left, operand *right, iCode *ifx)
4653 symbol *tlbl = newiTempLabel(NULL);
4655 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4656 gencjneshort(left, right, lbl);
4658 pic14_emitcode("mov","a,%s",one);
4659 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4660 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4661 pic14_emitcode("clr","a");
4662 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4664 emitpLabel(lbl->key);
4665 emitpLabel(tlbl->key);
4670 /*-----------------------------------------------------------------*/
4671 /* genCmpEq - generates code for equal to */
4672 /*-----------------------------------------------------------------*/
4673 static void genCmpEq (iCode *ic, iCode *ifx)
4675 operand *left, *right, *result;
4676 unsigned long lit = 0L;
4679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4682 DEBUGpic14_emitcode ("; ifx is non-null","");
4684 DEBUGpic14_emitcode ("; ifx is null","");
4686 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4687 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4688 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4690 size = max(AOP_SIZE(left),AOP_SIZE(right));
4692 DEBUGpic14_AopType(__LINE__,left,right,result);
4694 /* if literal, literal on the right or
4695 if the right is in a pointer register and left
4697 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4698 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4699 operand *tmp = right ;
4705 if(ifx && !AOP_SIZE(result)){
4707 /* if they are both bit variables */
4708 if (AOP_TYPE(left) == AOP_CRY &&
4709 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4710 if(AOP_TYPE(right) == AOP_LIT){
4711 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4713 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4714 pic14_emitcode("cpl","c");
4715 } else if(lit == 1L) {
4716 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4718 pic14_emitcode("clr","c");
4720 /* AOP_TYPE(right) == AOP_CRY */
4722 symbol *lbl = newiTempLabel(NULL);
4723 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4724 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4725 pic14_emitcode("cpl","c");
4726 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4728 /* if true label then we jump if condition
4730 tlbl = newiTempLabel(NULL);
4731 if ( IC_TRUE(ifx) ) {
4732 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4733 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4735 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4736 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4738 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4741 /* left and right are both bit variables, result is carry */
4744 resolveIfx(&rIfx,ifx);
4746 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4747 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4748 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4749 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4754 /* They're not both bit variables. Is the right a literal? */
4755 if(AOP_TYPE(right) == AOP_LIT) {
4756 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4761 switch(lit & 0xff) {
4763 if ( IC_TRUE(ifx) ) {
4764 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4766 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4768 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4769 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4773 if ( IC_TRUE(ifx) ) {
4774 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4776 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4778 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4779 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4783 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4785 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4790 /* end of size == 1 */
4794 genc16bit2lit(left,lit,offset);
4797 /* end of size == 2 */
4802 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4803 emitpcode(POC_IORFW,popGet(AOP(left),1));
4804 emitpcode(POC_IORFW,popGet(AOP(left),2));
4805 emitpcode(POC_IORFW,popGet(AOP(left),3));
4809 /* search for patterns that can be optimized */
4811 genc16bit2lit(left,lit,0);
4814 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4816 genc16bit2lit(left,lit,2);
4818 emitpcode(POC_IORFW,popGet(AOP(left),2));
4819 emitpcode(POC_IORFW,popGet(AOP(left),3));
4832 } else if(AOP_TYPE(right) == AOP_CRY ) {
4833 /* we know the left is not a bit, but that the right is */
4834 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4835 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4836 popGet(AOP(right),offset));
4837 emitpcode(POC_XORLW,popGetLit(1));
4839 /* if the two are equal, then W will be 0 and the Z bit is set
4840 * we could test Z now, or go ahead and check the high order bytes if
4841 * the variable we're comparing is larger than a byte. */
4844 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4846 if ( IC_TRUE(ifx) ) {
4848 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4849 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4852 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4853 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4857 /* They're both variables that are larger than bits */
4860 tlbl = newiTempLabel(NULL);
4863 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4864 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4866 if ( IC_TRUE(ifx) ) {
4869 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4870 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4873 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4874 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4878 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4879 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4883 if(s>1 && IC_TRUE(ifx)) {
4884 emitpLabel(tlbl->key);
4885 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4889 /* mark the icode as generated */
4894 /* if they are both bit variables */
4895 if (AOP_TYPE(left) == AOP_CRY &&
4896 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4897 if(AOP_TYPE(right) == AOP_LIT){
4898 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4900 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4901 pic14_emitcode("cpl","c");
4902 } else if(lit == 1L) {
4903 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4905 pic14_emitcode("clr","c");
4907 /* AOP_TYPE(right) == AOP_CRY */
4909 symbol *lbl = newiTempLabel(NULL);
4910 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4911 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4912 pic14_emitcode("cpl","c");
4913 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4916 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4917 pic14_outBitC(result);
4921 genIfxJump (ifx,"c");
4924 /* if the result is used in an arithmetic operation
4925 then put the result in place */
4926 pic14_outBitC(result);
4929 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4930 gencjne(left,right,result,ifx);
4933 gencjne(left,right,newiTempLabel(NULL));
4935 if(IC_TRUE(ifx)->key)
4936 gencjne(left,right,IC_TRUE(ifx)->key);
4938 gencjne(left,right,IC_FALSE(ifx)->key);
4942 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4943 aopPut(AOP(result),"a",0);
4948 genIfxJump (ifx,"a");
4952 /* if the result is used in an arithmetic operation
4953 then put the result in place */
4955 if (AOP_TYPE(result) != AOP_CRY)
4956 pic14_outAcc(result);
4958 /* leave the result in acc */
4962 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4963 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4964 freeAsmop(result,NULL,ic,TRUE);
4967 /*-----------------------------------------------------------------*/
4968 /* ifxForOp - returns the icode containing the ifx for operand */
4969 /*-----------------------------------------------------------------*/
4970 static iCode *ifxForOp ( operand *op, iCode *ic )
4972 /* if true symbol then needs to be assigned */
4973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4974 if (IS_TRUE_SYMOP(op))
4977 /* if this has register type condition and
4978 the next instruction is ifx with the same operand
4979 and live to of the operand is upto the ifx only then */
4981 ic->next->op == IFX &&
4982 IC_COND(ic->next)->key == op->key &&
4983 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4987 ic->next->op == IFX &&
4988 IC_COND(ic->next)->key == op->key) {
4989 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4993 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4995 ic->next->op == IFX)
4996 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4999 ic->next->op == IFX &&
5000 IC_COND(ic->next)->key == op->key) {
5001 DEBUGpic14_emitcode ("; "," key is okay");
5002 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5003 OP_SYMBOL(op)->liveTo,
5010 /*-----------------------------------------------------------------*/
5011 /* genAndOp - for && operation */
5012 /*-----------------------------------------------------------------*/
5013 static void genAndOp (iCode *ic)
5015 operand *left,*right, *result;
5018 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5019 /* note here that && operations that are in an
5020 if statement are taken away by backPatchLabels
5021 only those used in arthmetic operations remain */
5022 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5023 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5024 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5026 DEBUGpic14_AopType(__LINE__,left,right,result);
5028 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5029 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5030 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5032 /* if both are bit variables */
5033 /* if (AOP_TYPE(left) == AOP_CRY && */
5034 /* AOP_TYPE(right) == AOP_CRY ) { */
5035 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5036 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5037 /* pic14_outBitC(result); */
5039 /* tlbl = newiTempLabel(NULL); */
5040 /* pic14_toBoolean(left); */
5041 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5042 /* pic14_toBoolean(right); */
5043 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5044 /* pic14_outBitAcc(result); */
5047 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5048 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5049 freeAsmop(result,NULL,ic,TRUE);
5053 /*-----------------------------------------------------------------*/
5054 /* genOrOp - for || operation */
5055 /*-----------------------------------------------------------------*/
5058 modified this code, but it doesn't appear to ever get called
5061 static void genOrOp (iCode *ic)
5063 operand *left,*right, *result;
5066 /* note here that || operations that are in an
5067 if statement are taken away by backPatchLabels
5068 only those used in arthmetic operations remain */
5069 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5070 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5071 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5072 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5074 DEBUGpic14_AopType(__LINE__,left,right,result);
5076 /* if both are bit variables */
5077 if (AOP_TYPE(left) == AOP_CRY &&
5078 AOP_TYPE(right) == AOP_CRY ) {
5079 pic14_emitcode("clrc","");
5080 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5081 AOP(left)->aopu.aop_dir,
5082 AOP(left)->aopu.aop_dir);
5083 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5084 AOP(right)->aopu.aop_dir,
5085 AOP(right)->aopu.aop_dir);
5086 pic14_emitcode("setc","");
5089 tlbl = newiTempLabel(NULL);
5090 pic14_toBoolean(left);
5092 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5093 pic14_toBoolean(right);
5094 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5096 pic14_outBitAcc(result);
5099 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5100 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5101 freeAsmop(result,NULL,ic,TRUE);
5104 /*-----------------------------------------------------------------*/
5105 /* isLiteralBit - test if lit == 2^n */
5106 /*-----------------------------------------------------------------*/
5107 static int isLiteralBit(unsigned long lit)
5109 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5110 0x100L,0x200L,0x400L,0x800L,
5111 0x1000L,0x2000L,0x4000L,0x8000L,
5112 0x10000L,0x20000L,0x40000L,0x80000L,
5113 0x100000L,0x200000L,0x400000L,0x800000L,
5114 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5115 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5119 for(idx = 0; idx < 32; idx++)
5125 /*-----------------------------------------------------------------*/
5126 /* continueIfTrue - */
5127 /*-----------------------------------------------------------------*/
5128 static void continueIfTrue (iCode *ic)
5130 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5132 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5136 /*-----------------------------------------------------------------*/
5138 /*-----------------------------------------------------------------*/
5139 static void jumpIfTrue (iCode *ic)
5141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5143 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5147 /*-----------------------------------------------------------------*/
5148 /* jmpTrueOrFalse - */
5149 /*-----------------------------------------------------------------*/
5150 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5152 // ugly but optimized by peephole
5153 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5155 symbol *nlbl = newiTempLabel(NULL);
5156 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5157 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5158 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5159 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5162 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5163 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5168 /*-----------------------------------------------------------------*/
5169 /* genAnd - code for and */
5170 /*-----------------------------------------------------------------*/
5171 static void genAnd (iCode *ic, iCode *ifx)
5173 operand *left, *right, *result;
5175 unsigned long lit = 0L;
5180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5181 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5182 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5183 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5185 resolveIfx(&rIfx,ifx);
5187 /* if left is a literal & right is not then exchange them */
5188 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5189 AOP_NEEDSACC(left)) {
5190 operand *tmp = right ;
5195 /* if result = right then exchange them */
5196 if(pic14_sameRegs(AOP(result),AOP(right))){
5197 operand *tmp = right ;
5202 /* if right is bit then exchange them */
5203 if (AOP_TYPE(right) == AOP_CRY &&
5204 AOP_TYPE(left) != AOP_CRY){
5205 operand *tmp = right ;
5209 if(AOP_TYPE(right) == AOP_LIT)
5210 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5212 size = AOP_SIZE(result);
5214 DEBUGpic14_AopType(__LINE__,left,right,result);
5217 // result = bit & yy;
5218 if (AOP_TYPE(left) == AOP_CRY){
5219 // c = bit & literal;
5220 if(AOP_TYPE(right) == AOP_LIT){
5222 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5225 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5228 if(size && (AOP_TYPE(result) == AOP_CRY)){
5229 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5232 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5236 pic14_emitcode("clr","c");
5239 if (AOP_TYPE(right) == AOP_CRY){
5241 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5242 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5245 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5247 pic14_emitcode("rrc","a");
5248 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5254 pic14_outBitC(result);
5256 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5257 genIfxJump(ifx, "c");
5261 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5262 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5263 if((AOP_TYPE(right) == AOP_LIT) &&
5264 (AOP_TYPE(result) == AOP_CRY) &&
5265 (AOP_TYPE(left) != AOP_CRY)){
5266 int posbit = isLiteralBit(lit);
5270 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5273 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5278 while (posbit > 7) {
5282 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5283 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5284 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5291 symbol *tlbl = newiTempLabel(NULL);
5292 int sizel = AOP_SIZE(left);
5294 pic14_emitcode("setb","c");
5296 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5297 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5299 if((posbit = isLiteralBit(bytelit)) != 0)
5300 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5302 if(bytelit != 0x0FFL)
5303 pic14_emitcode("anl","a,%s",
5304 aopGet(AOP(right),offset,FALSE,TRUE));
5305 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5310 // bit = left & literal
5312 pic14_emitcode("clr","c");
5313 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5315 // if(left & literal)
5318 jmpTrueOrFalse(ifx, tlbl);
5322 pic14_outBitC(result);
5326 /* if left is same as result */
5327 if(pic14_sameRegs(AOP(result),AOP(left))){
5329 for(;size--; offset++,lit>>=8) {
5330 if(AOP_TYPE(right) == AOP_LIT){
5331 switch(lit & 0xff) {
5333 /* and'ing with 0 has clears the result */
5334 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5335 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5338 /* and'ing with 0xff is a nop when the result and left are the same */
5343 int p = my_powof2( (~lit) & 0xff );
5345 /* only one bit is set in the literal, so use a bcf instruction */
5346 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5347 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5350 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5351 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5352 if(know_W != (int)(lit&0xff))
5353 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5355 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5360 if (AOP_TYPE(left) == AOP_ACC) {
5361 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5363 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5364 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5371 // left & result in different registers
5372 if(AOP_TYPE(result) == AOP_CRY){
5374 // if(size), result in bit
5375 // if(!size && ifx), conditional oper: if(left & right)
5376 symbol *tlbl = newiTempLabel(NULL);
5377 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5379 pic14_emitcode("setb","c");
5381 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5382 pic14_emitcode("anl","a,%s",
5383 aopGet(AOP(left),offset,FALSE,FALSE));
5384 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5389 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5390 pic14_outBitC(result);
5392 jmpTrueOrFalse(ifx, tlbl);
5394 for(;(size--);offset++) {
5396 // result = left & right
5397 if(AOP_TYPE(right) == AOP_LIT){
5398 int t = (lit >> (offset*8)) & 0x0FFL;
5401 pic14_emitcode("clrf","%s",
5402 aopGet(AOP(result),offset,FALSE,FALSE));
5403 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5406 if(AOP_TYPE(left) != AOP_ACC) {
5407 pic14_emitcode("movf","%s,w",
5408 aopGet(AOP(left),offset,FALSE,FALSE));
5409 pic14_emitcode("movwf","%s",
5410 aopGet(AOP(result),offset,FALSE,FALSE));
5411 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5413 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5416 if(AOP_TYPE(left) == AOP_ACC) {
5417 emitpcode(POC_ANDLW, popGetLit(t));
5419 pic14_emitcode("movlw","0x%x",t);
5420 pic14_emitcode("andwf","%s,w",
5421 aopGet(AOP(left),offset,FALSE,FALSE));
5422 pic14_emitcode("movwf","%s",
5423 aopGet(AOP(result),offset,FALSE,FALSE));
5425 emitpcode(POC_MOVLW, popGetLit(t));
5426 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5428 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5433 if (AOP_TYPE(left) == AOP_ACC) {
5434 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5435 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5437 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5438 pic14_emitcode("andwf","%s,w",
5439 aopGet(AOP(left),offset,FALSE,FALSE));
5440 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5441 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5443 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5444 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5450 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5451 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5452 freeAsmop(result,NULL,ic,TRUE);
5455 /*-----------------------------------------------------------------*/
5456 /* genOr - code for or */
5457 /*-----------------------------------------------------------------*/
5458 static void genOr (iCode *ic, iCode *ifx)
5460 operand *left, *right, *result;
5462 unsigned long lit = 0L;
5464 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5466 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5467 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5468 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5470 DEBUGpic14_AopType(__LINE__,left,right,result);
5472 /* if left is a literal & right is not then exchange them */
5473 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5474 AOP_NEEDSACC(left)) {
5475 operand *tmp = right ;
5480 /* if result = right then exchange them */
5481 if(pic14_sameRegs(AOP(result),AOP(right))){
5482 operand *tmp = right ;
5487 /* if right is bit then exchange them */
5488 if (AOP_TYPE(right) == AOP_CRY &&
5489 AOP_TYPE(left) != AOP_CRY){
5490 operand *tmp = right ;
5495 DEBUGpic14_AopType(__LINE__,left,right,result);
5497 if(AOP_TYPE(right) == AOP_LIT)
5498 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5500 size = AOP_SIZE(result);
5504 if (AOP_TYPE(left) == AOP_CRY){
5505 if(AOP_TYPE(right) == AOP_LIT){
5506 // c = bit & literal;
5508 // lit != 0 => result = 1
5509 if(AOP_TYPE(result) == AOP_CRY){
5511 emitpcode(POC_BSF, popGet(AOP(result),0));
5512 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5513 // AOP(result)->aopu.aop_dir,
5514 // AOP(result)->aopu.aop_dir);
5516 continueIfTrue(ifx);
5520 // lit == 0 => result = left
5521 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5523 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5526 if (AOP_TYPE(right) == AOP_CRY){
5527 if(pic14_sameRegs(AOP(result),AOP(left))){
5529 emitpcode(POC_BCF, popGet(AOP(result),0));
5530 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5531 emitpcode(POC_BSF, popGet(AOP(result),0));
5533 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5534 AOP(result)->aopu.aop_dir,
5535 AOP(result)->aopu.aop_dir);
5536 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5537 AOP(right)->aopu.aop_dir,
5538 AOP(right)->aopu.aop_dir);
5539 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5540 AOP(result)->aopu.aop_dir,
5541 AOP(result)->aopu.aop_dir);
5543 if( AOP_TYPE(result) == AOP_ACC) {
5544 emitpcode(POC_MOVLW, popGetLit(0));
5545 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5546 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5547 emitpcode(POC_MOVLW, popGetLit(1));
5551 emitpcode(POC_BCF, popGet(AOP(result),0));
5552 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5553 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5554 emitpcode(POC_BSF, popGet(AOP(result),0));
5556 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5557 AOP(result)->aopu.aop_dir,
5558 AOP(result)->aopu.aop_dir);
5559 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5560 AOP(right)->aopu.aop_dir,
5561 AOP(right)->aopu.aop_dir);
5562 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5563 AOP(left)->aopu.aop_dir,
5564 AOP(left)->aopu.aop_dir);
5565 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5566 AOP(result)->aopu.aop_dir,
5567 AOP(result)->aopu.aop_dir);
5572 symbol *tlbl = newiTempLabel(NULL);
5573 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5576 emitpcode(POC_BCF, popGet(AOP(result),0));
5577 if( AOP_TYPE(right) == AOP_ACC) {
5578 emitpcode(POC_IORLW, popGetLit(0));
5580 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5581 emitpcode(POC_BSF, popGet(AOP(result),0));
5586 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5587 pic14_emitcode(";XXX setb","c");
5588 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5589 AOP(left)->aopu.aop_dir,tlbl->key+100);
5590 pic14_toBoolean(right);
5591 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5592 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5593 jmpTrueOrFalse(ifx, tlbl);
5597 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5604 pic14_outBitC(result);
5606 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5607 genIfxJump(ifx, "c");
5611 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5612 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5613 if((AOP_TYPE(right) == AOP_LIT) &&
5614 (AOP_TYPE(result) == AOP_CRY) &&
5615 (AOP_TYPE(left) != AOP_CRY)){
5617 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5620 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5622 continueIfTrue(ifx);
5625 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5626 // lit = 0, result = boolean(left)
5628 pic14_emitcode(";XXX setb","c");
5629 pic14_toBoolean(right);
5631 symbol *tlbl = newiTempLabel(NULL);
5632 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5634 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5636 genIfxJump (ifx,"a");
5640 pic14_outBitC(result);
5644 /* if left is same as result */
5645 if(pic14_sameRegs(AOP(result),AOP(left))){
5647 for(;size--; offset++,lit>>=8) {
5648 if(AOP_TYPE(right) == AOP_LIT){
5649 if((lit & 0xff) == 0)
5650 /* or'ing with 0 has no effect */
5653 int p = my_powof2(lit & 0xff);
5655 /* only one bit is set in the literal, so use a bsf instruction */
5657 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5659 if(know_W != (int)(lit & 0xff))
5660 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5661 know_W = lit & 0xff;
5662 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5667 if (AOP_TYPE(left) == AOP_ACC) {
5668 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5669 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5671 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5672 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5674 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5675 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5681 // left & result in different registers
5682 if(AOP_TYPE(result) == AOP_CRY){
5684 // if(size), result in bit
5685 // if(!size && ifx), conditional oper: if(left | right)
5686 symbol *tlbl = newiTempLabel(NULL);
5687 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5688 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5692 pic14_emitcode(";XXX setb","c");
5694 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5695 pic14_emitcode(";XXX orl","a,%s",
5696 aopGet(AOP(left),offset,FALSE,FALSE));
5697 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5702 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5703 pic14_outBitC(result);
5705 jmpTrueOrFalse(ifx, tlbl);
5706 } else for(;(size--);offset++){
5708 // result = left & right
5709 if(AOP_TYPE(right) == AOP_LIT){
5710 int t = (lit >> (offset*8)) & 0x0FFL;
5713 if (AOP_TYPE(left) != AOP_ACC) {
5714 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5716 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5720 if (AOP_TYPE(left) == AOP_ACC) {
5721 emitpcode(POC_IORLW, popGetLit(t));
5723 emitpcode(POC_MOVLW, popGetLit(t));
5724 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5726 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5731 // faster than result <- left, anl result,right
5732 // and better if result is SFR
5733 if (AOP_TYPE(left) == AOP_ACC) {
5734 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5735 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5737 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5738 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5740 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5741 pic14_emitcode("iorwf","%s,w",
5742 aopGet(AOP(left),offset,FALSE,FALSE));
5744 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5745 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5750 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5751 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5752 freeAsmop(result,NULL,ic,TRUE);
5755 /*-----------------------------------------------------------------*/
5756 /* genXor - code for xclusive or */
5757 /*-----------------------------------------------------------------*/
5758 static void genXor (iCode *ic, iCode *ifx)
5760 operand *left, *right, *result;
5762 unsigned long lit = 0L;
5764 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5766 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5767 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5768 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5770 /* if left is a literal & right is not ||
5771 if left needs acc & right does not */
5772 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5773 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5774 operand *tmp = right ;
5779 /* if result = right then exchange them */
5780 if(pic14_sameRegs(AOP(result),AOP(right))){
5781 operand *tmp = right ;
5786 /* if right is bit then exchange them */
5787 if (AOP_TYPE(right) == AOP_CRY &&
5788 AOP_TYPE(left) != AOP_CRY){
5789 operand *tmp = right ;
5793 if(AOP_TYPE(right) == AOP_LIT)
5794 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5796 size = AOP_SIZE(result);
5800 if (AOP_TYPE(left) == AOP_CRY){
5801 if(AOP_TYPE(right) == AOP_LIT){
5802 // c = bit & literal;
5804 // lit>>1 != 0 => result = 1
5805 if(AOP_TYPE(result) == AOP_CRY){
5807 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5808 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5810 continueIfTrue(ifx);
5813 pic14_emitcode("setb","c");
5817 // lit == 0, result = left
5818 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5820 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5822 // lit == 1, result = not(left)
5823 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5824 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5825 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5826 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5829 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5830 pic14_emitcode("cpl","c");
5837 symbol *tlbl = newiTempLabel(NULL);
5838 if (AOP_TYPE(right) == AOP_CRY){
5840 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5843 int sizer = AOP_SIZE(right);
5845 // if val>>1 != 0, result = 1
5846 pic14_emitcode("setb","c");
5848 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5850 // test the msb of the lsb
5851 pic14_emitcode("anl","a,#0xfe");
5852 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5856 pic14_emitcode("rrc","a");
5858 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5859 pic14_emitcode("cpl","c");
5860 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5865 pic14_outBitC(result);
5867 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5868 genIfxJump(ifx, "c");
5872 if(pic14_sameRegs(AOP(result),AOP(left))){
5873 /* if left is same as result */
5874 for(;size--; offset++) {
5875 if(AOP_TYPE(right) == AOP_LIT){
5876 int t = (lit >> (offset*8)) & 0x0FFL;
5880 if (IS_AOP_PREG(left)) {
5881 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5882 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5883 aopPut(AOP(result),"a",offset);
5885 emitpcode(POC_MOVLW, popGetLit(t));
5886 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5887 pic14_emitcode("xrl","%s,%s",
5888 aopGet(AOP(left),offset,FALSE,TRUE),
5889 aopGet(AOP(right),offset,FALSE,FALSE));
5892 if (AOP_TYPE(left) == AOP_ACC)
5893 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5895 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5896 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5898 if (IS_AOP_PREG(left)) {
5899 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5900 aopPut(AOP(result),"a",offset);
5902 pic14_emitcode("xrl","%s,a",
5903 aopGet(AOP(left),offset,FALSE,TRUE));
5909 // left & result in different registers
5910 if(AOP_TYPE(result) == AOP_CRY){
5912 // if(size), result in bit
5913 // if(!size && ifx), conditional oper: if(left ^ right)
5914 symbol *tlbl = newiTempLabel(NULL);
5915 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5917 pic14_emitcode("setb","c");
5919 if((AOP_TYPE(right) == AOP_LIT) &&
5920 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5921 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5923 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5924 pic14_emitcode("xrl","a,%s",
5925 aopGet(AOP(left),offset,FALSE,FALSE));
5927 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5932 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5933 pic14_outBitC(result);
5935 jmpTrueOrFalse(ifx, tlbl);
5936 } else for(;(size--);offset++){
5938 // result = left & right
5939 if(AOP_TYPE(right) == AOP_LIT){
5940 int t = (lit >> (offset*8)) & 0x0FFL;
5943 if (AOP_TYPE(left) != AOP_ACC) {
5944 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5946 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5947 pic14_emitcode("movf","%s,w",
5948 aopGet(AOP(left),offset,FALSE,FALSE));
5949 pic14_emitcode("movwf","%s",
5950 aopGet(AOP(result),offset,FALSE,FALSE));
5953 if (AOP_TYPE(left) == AOP_ACC) {
5954 emitpcode(POC_XORLW, popGetLit(t));
5956 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5958 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5961 if (AOP_TYPE(left) == AOP_ACC) {
5962 emitpcode(POC_XORLW, popGetLit(t));
5964 emitpcode(POC_MOVLW, popGetLit(t));
5965 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5967 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5968 pic14_emitcode("movlw","0x%x",t);
5969 pic14_emitcode("xorwf","%s,w",
5970 aopGet(AOP(left),offset,FALSE,FALSE));
5971 pic14_emitcode("movwf","%s",
5972 aopGet(AOP(result),offset,FALSE,FALSE));
5978 // faster than result <- left, anl result,right
5979 // and better if result is SFR
5980 if (AOP_TYPE(left) == AOP_ACC) {
5981 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5982 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5984 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5985 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5986 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5987 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5989 if ( AOP_TYPE(result) != AOP_ACC){
5990 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5991 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5997 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5998 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5999 freeAsmop(result,NULL,ic,TRUE);
6002 /*-----------------------------------------------------------------*/
6003 /* genInline - write the inline code out */
6004 /*-----------------------------------------------------------------*/
6005 static void genInline (iCode *ic)
6007 char *buffer, *bp, *bp1;
6009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6011 _G.inLine += (!options.asmpeep);
6013 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6014 strcpy(buffer,IC_INLINE(ic));
6016 /* emit each line as a code */
6022 addpCode2pBlock(pb,AssembleLine(bp1));
6029 pic14_emitcode(bp1,"");
6035 if ((bp1 != bp) && *bp1)
6036 addpCode2pBlock(pb,AssembleLine(bp1));
6040 _G.inLine -= (!options.asmpeep);
6043 /*-----------------------------------------------------------------*/
6044 /* genRRC - rotate right with carry */
6045 /*-----------------------------------------------------------------*/
6046 static void genRRC (iCode *ic)
6048 operand *left , *result ;
6049 int size, offset = 0, same;
6051 /* rotate right with carry */
6053 result=IC_RESULT(ic);
6054 aopOp (left,ic,FALSE);
6055 aopOp (result,ic,FALSE);
6057 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6059 same = pic14_sameRegs(AOP(result),AOP(left));
6061 size = AOP_SIZE(result);
6063 /* get the lsb and put it into the carry */
6064 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6071 emitpcode(POC_RRF, popGet(AOP(left),offset));
6073 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6074 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6080 freeAsmop(left,NULL,ic,TRUE);
6081 freeAsmop(result,NULL,ic,TRUE);
6084 /*-----------------------------------------------------------------*/
6085 /* genRLC - generate code for rotate left with carry */
6086 /*-----------------------------------------------------------------*/
6087 static void genRLC (iCode *ic)
6089 operand *left , *result ;
6090 int size, offset = 0;
6093 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6094 /* rotate right with carry */
6096 result=IC_RESULT(ic);
6097 aopOp (left,ic,FALSE);
6098 aopOp (result,ic,FALSE);
6100 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6102 same = pic14_sameRegs(AOP(result),AOP(left));
6104 /* move it to the result */
6105 size = AOP_SIZE(result);
6107 /* get the msb and put it into the carry */
6108 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6115 emitpcode(POC_RLF, popGet(AOP(left),offset));
6117 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6118 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6125 freeAsmop(left,NULL,ic,TRUE);
6126 freeAsmop(result,NULL,ic,TRUE);
6129 /*-----------------------------------------------------------------*/
6130 /* genGetHbit - generates code get highest order bit */
6131 /*-----------------------------------------------------------------*/
6132 static void genGetHbit (iCode *ic)
6134 operand *left, *result;
6136 result=IC_RESULT(ic);
6137 aopOp (left,ic,FALSE);
6138 aopOp (result,ic,FALSE);
6140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6141 /* get the highest order byte into a */
6142 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6143 if(AOP_TYPE(result) == AOP_CRY){
6144 pic14_emitcode("rlc","a");
6145 pic14_outBitC(result);
6148 pic14_emitcode("rl","a");
6149 pic14_emitcode("anl","a,#0x01");
6150 pic14_outAcc(result);
6154 freeAsmop(left,NULL,ic,TRUE);
6155 freeAsmop(result,NULL,ic,TRUE);
6158 /*-----------------------------------------------------------------*/
6159 /* AccRol - rotate left accumulator by known count */
6160 /*-----------------------------------------------------------------*/
6161 static void AccRol (int shCount)
6163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6164 shCount &= 0x0007; // shCount : 0..7
6169 pic14_emitcode("rl","a");
6172 pic14_emitcode("rl","a");
6173 pic14_emitcode("rl","a");
6176 pic14_emitcode("swap","a");
6177 pic14_emitcode("rr","a");
6180 pic14_emitcode("swap","a");
6183 pic14_emitcode("swap","a");
6184 pic14_emitcode("rl","a");
6187 pic14_emitcode("rr","a");
6188 pic14_emitcode("rr","a");
6191 pic14_emitcode("rr","a");
6196 /*-----------------------------------------------------------------*/
6197 /* AccLsh - left shift accumulator by known count */
6198 /*-----------------------------------------------------------------*/
6199 static void AccLsh (int shCount)
6201 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6204 pic14_emitcode("add","a,acc");
6207 pic14_emitcode("add","a,acc");
6208 pic14_emitcode("add","a,acc");
6210 /* rotate left accumulator */
6212 /* and kill the lower order bits */
6213 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6218 /*-----------------------------------------------------------------*/
6219 /* AccRsh - right shift accumulator by known count */
6220 /*-----------------------------------------------------------------*/
6221 static void AccRsh (int shCount)
6223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6227 pic14_emitcode("rrc","a");
6229 /* rotate right accumulator */
6230 AccRol(8 - shCount);
6231 /* and kill the higher order bits */
6232 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6238 /*-----------------------------------------------------------------*/
6239 /* AccSRsh - signed right shift accumulator by known count */
6240 /*-----------------------------------------------------------------*/
6241 static void AccSRsh (int shCount)
6244 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6247 pic14_emitcode("mov","c,acc.7");
6248 pic14_emitcode("rrc","a");
6249 } else if(shCount == 2){
6250 pic14_emitcode("mov","c,acc.7");
6251 pic14_emitcode("rrc","a");
6252 pic14_emitcode("mov","c,acc.7");
6253 pic14_emitcode("rrc","a");
6255 tlbl = newiTempLabel(NULL);
6256 /* rotate right accumulator */
6257 AccRol(8 - shCount);
6258 /* and kill the higher order bits */
6259 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6260 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6261 pic14_emitcode("orl","a,#0x%02x",
6262 (unsigned char)~SRMask[shCount]);
6263 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6268 /*-----------------------------------------------------------------*/
6269 /* shiftR1Left2Result - shift right one byte from left to result */
6270 /*-----------------------------------------------------------------*/
6271 static void shiftR1Left2ResultSigned (operand *left, int offl,
6272 operand *result, int offr,
6277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6279 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6283 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6285 emitpcode(POC_RRF, popGet(AOP(result),offr));
6287 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6288 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6294 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6296 emitpcode(POC_RRF, popGet(AOP(result),offr));
6298 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6299 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6301 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6302 emitpcode(POC_RRF, popGet(AOP(result),offr));
6308 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6310 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6311 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6314 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6315 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6316 emitpcode(POC_ANDLW, popGetLit(0x1f));
6318 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6319 emitpcode(POC_IORLW, popGetLit(0xe0));
6321 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6325 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6326 emitpcode(POC_ANDLW, popGetLit(0x0f));
6327 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6328 emitpcode(POC_IORLW, popGetLit(0xf0));
6329 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6333 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6335 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6336 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6338 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6339 emitpcode(POC_ANDLW, popGetLit(0x07));
6340 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6341 emitpcode(POC_IORLW, popGetLit(0xf8));
6342 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6347 emitpcode(POC_MOVLW, popGetLit(0x00));
6348 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6349 emitpcode(POC_MOVLW, popGetLit(0xfe));
6350 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6351 emitpcode(POC_IORLW, popGetLit(0x01));
6352 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6354 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6355 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6356 emitpcode(POC_DECF, popGet(AOP(result),offr));
6357 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6358 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6364 emitpcode(POC_MOVLW, popGetLit(0x00));
6365 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6366 emitpcode(POC_MOVLW, popGetLit(0xff));
6367 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6369 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6370 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6371 emitpcode(POC_DECF, popGet(AOP(result),offr));
6379 /*-----------------------------------------------------------------*/
6380 /* shiftR1Left2Result - shift right one byte from left to result */
6381 /*-----------------------------------------------------------------*/
6382 static void shiftR1Left2Result (operand *left, int offl,
6383 operand *result, int offr,
6384 int shCount, int sign)
6388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6390 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6392 /* Copy the msb into the carry if signed. */
6394 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6404 emitpcode(POC_RRF, popGet(AOP(result),offr));
6406 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6407 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413 emitpcode(POC_RRF, popGet(AOP(result),offr));
6415 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6416 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6419 emitpcode(POC_RRF, popGet(AOP(result),offr));
6424 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6426 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6427 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6430 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6431 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6432 emitpcode(POC_ANDLW, popGetLit(0x1f));
6433 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6437 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6438 emitpcode(POC_ANDLW, popGetLit(0x0f));
6439 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6443 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6444 emitpcode(POC_ANDLW, popGetLit(0x0f));
6445 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6447 emitpcode(POC_RRF, popGet(AOP(result),offr));
6452 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6453 emitpcode(POC_ANDLW, popGetLit(0x80));
6454 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6455 emitpcode(POC_RLF, popGet(AOP(result),offr));
6456 emitpcode(POC_RLF, popGet(AOP(result),offr));
6461 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6462 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6463 emitpcode(POC_RLF, popGet(AOP(result),offr));
6472 /*-----------------------------------------------------------------*/
6473 /* shiftL1Left2Result - shift left one byte from left to result */
6474 /*-----------------------------------------------------------------*/
6475 static void shiftL1Left2Result (operand *left, int offl,
6476 operand *result, int offr, int shCount)
6481 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6483 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6484 DEBUGpic14_emitcode ("; ***","same = %d",same);
6485 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6487 /* shift left accumulator */
6488 //AccLsh(shCount); // don't comment out just yet...
6489 // aopPut(AOP(result),"a",offr);
6493 /* Shift left 1 bit position */
6494 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6496 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6498 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6499 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6503 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6504 emitpcode(POC_ANDLW,popGetLit(0x7e));
6505 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6506 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6509 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6510 emitpcode(POC_ANDLW,popGetLit(0x3e));
6511 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6512 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6513 emitpcode(POC_RLF, popGet(AOP(result),offr));
6516 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6517 emitpcode(POC_ANDLW, popGetLit(0xf0));
6518 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6521 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6522 emitpcode(POC_ANDLW, popGetLit(0xf0));
6523 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6524 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6527 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6528 emitpcode(POC_ANDLW, popGetLit(0x30));
6529 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6530 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6531 emitpcode(POC_RLF, popGet(AOP(result),offr));
6534 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6535 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6536 emitpcode(POC_RRF, popGet(AOP(result),offr));
6540 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6545 /*-----------------------------------------------------------------*/
6546 /* movLeft2Result - move byte from left to result */
6547 /*-----------------------------------------------------------------*/
6548 static void movLeft2Result (operand *left, int offl,
6549 operand *result, int offr)
6552 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6553 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6554 l = aopGet(AOP(left),offl,FALSE,FALSE);
6556 if (*l == '@' && (IS_AOP_PREG(result))) {
6557 pic14_emitcode("mov","a,%s",l);
6558 aopPut(AOP(result),"a",offr);
6560 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6561 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6566 /*-----------------------------------------------------------------*/
6567 /* shiftL2Left2Result - shift left two bytes from left to result */
6568 /*-----------------------------------------------------------------*/
6569 static void shiftL2Left2Result (operand *left, int offl,
6570 operand *result, int offr, int shCount)
6574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6576 if(pic14_sameRegs(AOP(result), AOP(left))) {
6584 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6585 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6586 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6590 emitpcode(POC_RLF, popGet(AOP(result),offr));
6591 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6597 emitpcode(POC_MOVLW, popGetLit(0x0f));
6598 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6599 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6600 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6601 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6602 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6603 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_RLF, popGet(AOP(result),offr));
6606 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6610 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6611 emitpcode(POC_RRF, popGet(AOP(result),offr));
6612 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_RRF, popGet(AOP(result),offr));
6614 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6615 emitpcode(POC_ANDLW,popGetLit(0xc0));
6616 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6617 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6618 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6619 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6622 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6623 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6624 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6625 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6626 emitpcode(POC_RRF, popGet(AOP(result),offr));
6636 /* note, use a mov/add for the shift since the mov has a
6637 chance of getting optimized out */
6638 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6639 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6640 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6641 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6642 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6646 emitpcode(POC_RLF, popGet(AOP(result),offr));
6647 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6653 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6654 emitpcode(POC_ANDLW, popGetLit(0xF0));
6655 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6656 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6657 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6658 emitpcode(POC_ANDLW, popGetLit(0xF0));
6659 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6660 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RLF, popGet(AOP(result),offr));
6665 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6669 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6670 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6671 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6672 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6674 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6675 emitpcode(POC_RRF, popGet(AOP(result),offr));
6676 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6677 emitpcode(POC_ANDLW,popGetLit(0xc0));
6678 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6679 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6680 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6681 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6685 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6686 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6687 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6688 emitpcode(POC_RRF, popGet(AOP(result),offr));
6693 /*-----------------------------------------------------------------*/
6694 /* shiftR2Left2Result - shift right two bytes from left to result */
6695 /*-----------------------------------------------------------------*/
6696 static void shiftR2Left2Result (operand *left, int offl,
6697 operand *result, int offr,
6698 int shCount, int sign)
6702 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6703 same = pic14_sameRegs(AOP(result), AOP(left));
6705 if(same && ((offl + MSB16) == offr)){
6707 /* don't crash result[offr] */
6708 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6709 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6712 movLeft2Result(left,offl, result, offr);
6713 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6716 /* a:x >> shCount (x = lsb(result))*/
6719 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6721 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6730 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRF,popGet(AOP(result),offr));
6738 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6739 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6740 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6741 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6746 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6749 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_RRF,popGet(AOP(result),offr));
6757 emitpcode(POC_MOVLW, popGetLit(0xf0));
6758 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6759 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6761 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6762 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6763 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6764 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6766 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6767 emitpcode(POC_ANDLW, popGetLit(0x0f));
6768 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6770 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6771 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6772 emitpcode(POC_ANDLW, popGetLit(0xf0));
6773 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6774 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6778 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6779 emitpcode(POC_RRF, popGet(AOP(result),offr));
6783 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6784 emitpcode(POC_BTFSC,
6785 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6786 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_RLF, popGet(AOP(result),offr));
6795 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6797 emitpcode(POC_RLF, popGet(AOP(result),offr));
6798 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6799 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6800 emitpcode(POC_ANDLW,popGetLit(0x03));
6802 emitpcode(POC_BTFSC,
6803 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6804 emitpcode(POC_IORLW,popGetLit(0xfc));
6806 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6807 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6811 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6812 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6813 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6814 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6815 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_RLF, popGet(AOP(result),offr));
6817 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6818 emitpcode(POC_ANDLW,popGetLit(0x03));
6820 emitpcode(POC_BTFSC,
6821 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6822 emitpcode(POC_IORLW,popGetLit(0xfc));
6824 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6825 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6832 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6833 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6834 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6835 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6838 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6840 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6845 /*-----------------------------------------------------------------*/
6846 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6847 /*-----------------------------------------------------------------*/
6848 static void shiftLLeftOrResult (operand *left, int offl,
6849 operand *result, int offr, int shCount)
6851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6852 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6853 /* shift left accumulator */
6855 /* or with result */
6856 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6857 /* back to result */
6858 aopPut(AOP(result),"a",offr);
6861 /*-----------------------------------------------------------------*/
6862 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6863 /*-----------------------------------------------------------------*/
6864 static void shiftRLeftOrResult (operand *left, int offl,
6865 operand *result, int offr, int shCount)
6867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6868 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6869 /* shift right accumulator */
6871 /* or with result */
6872 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6873 /* back to result */
6874 aopPut(AOP(result),"a",offr);
6877 /*-----------------------------------------------------------------*/
6878 /* genlshOne - left shift a one byte quantity by known count */
6879 /*-----------------------------------------------------------------*/
6880 static void genlshOne (operand *result, operand *left, int shCount)
6882 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6883 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6886 /*-----------------------------------------------------------------*/
6887 /* genlshTwo - left shift two bytes by known amount != 0 */
6888 /*-----------------------------------------------------------------*/
6889 static void genlshTwo (operand *result,operand *left, int shCount)
6893 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6894 size = pic14_getDataSize(result);
6896 /* if shCount >= 8 */
6902 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6904 movLeft2Result(left, LSB, result, MSB16);
6906 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6909 /* 1 <= shCount <= 7 */
6912 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6914 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6918 /*-----------------------------------------------------------------*/
6919 /* shiftLLong - shift left one long from left to result */
6920 /* offl = LSB or MSB16 */
6921 /*-----------------------------------------------------------------*/
6922 static void shiftLLong (operand *left, operand *result, int offr )
6925 int size = AOP_SIZE(result);
6927 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6928 if(size >= LSB+offr){
6929 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6931 pic14_emitcode("add","a,acc");
6932 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6933 size >= MSB16+offr && offr != LSB )
6934 pic14_emitcode("xch","a,%s",
6935 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6937 aopPut(AOP(result),"a",LSB+offr);
6940 if(size >= MSB16+offr){
6941 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6942 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6945 pic14_emitcode("rlc","a");
6946 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6947 size >= MSB24+offr && offr != LSB)
6948 pic14_emitcode("xch","a,%s",
6949 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6951 aopPut(AOP(result),"a",MSB16+offr);
6954 if(size >= MSB24+offr){
6955 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6956 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6959 pic14_emitcode("rlc","a");
6960 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6961 size >= MSB32+offr && offr != LSB )
6962 pic14_emitcode("xch","a,%s",
6963 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6965 aopPut(AOP(result),"a",MSB24+offr);
6968 if(size > MSB32+offr){
6969 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6970 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6973 pic14_emitcode("rlc","a");
6974 aopPut(AOP(result),"a",MSB32+offr);
6977 aopPut(AOP(result),zero,LSB);
6980 /*-----------------------------------------------------------------*/
6981 /* genlshFour - shift four byte by a known amount != 0 */
6982 /*-----------------------------------------------------------------*/
6983 static void genlshFour (operand *result, operand *left, int shCount)
6987 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6988 size = AOP_SIZE(result);
6990 /* if shifting more that 3 bytes */
6991 if (shCount >= 24 ) {
6994 /* lowest order of left goes to the highest
6995 order of the destination */
6996 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6998 movLeft2Result(left, LSB, result, MSB32);
6999 aopPut(AOP(result),zero,LSB);
7000 aopPut(AOP(result),zero,MSB16);
7001 aopPut(AOP(result),zero,MSB32);
7005 /* more than two bytes */
7006 else if ( shCount >= 16 ) {
7007 /* lower order two bytes goes to higher order two bytes */
7009 /* if some more remaining */
7011 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7013 movLeft2Result(left, MSB16, result, MSB32);
7014 movLeft2Result(left, LSB, result, MSB24);
7016 aopPut(AOP(result),zero,MSB16);
7017 aopPut(AOP(result),zero,LSB);
7021 /* if more than 1 byte */
7022 else if ( shCount >= 8 ) {
7023 /* lower order three bytes goes to higher order three bytes */
7027 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7029 movLeft2Result(left, LSB, result, MSB16);
7031 else{ /* size = 4 */
7033 movLeft2Result(left, MSB24, result, MSB32);
7034 movLeft2Result(left, MSB16, result, MSB24);
7035 movLeft2Result(left, LSB, result, MSB16);
7036 aopPut(AOP(result),zero,LSB);
7038 else if(shCount == 1)
7039 shiftLLong(left, result, MSB16);
7041 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7042 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7043 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7044 aopPut(AOP(result),zero,LSB);
7049 /* 1 <= shCount <= 7 */
7050 else if(shCount <= 2){
7051 shiftLLong(left, result, LSB);
7053 shiftLLong(result, result, LSB);
7055 /* 3 <= shCount <= 7, optimize */
7057 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7058 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7059 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7063 /*-----------------------------------------------------------------*/
7064 /* genLeftShiftLiteral - left shifting by known count */
7065 /*-----------------------------------------------------------------*/
7066 static void genLeftShiftLiteral (operand *left,
7071 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7075 freeAsmop(right,NULL,ic,TRUE);
7077 aopOp(left,ic,FALSE);
7078 aopOp(result,ic,FALSE);
7080 size = getSize(operandType(result));
7083 pic14_emitcode("; shift left ","result %d, left %d",size,
7087 /* I suppose that the left size >= result size */
7090 movLeft2Result(left, size, result, size);
7094 else if(shCount >= (size * 8))
7096 aopPut(AOP(result),zero,size);
7100 genlshOne (result,left,shCount);
7105 genlshTwo (result,left,shCount);
7109 genlshFour (result,left,shCount);
7113 freeAsmop(left,NULL,ic,TRUE);
7114 freeAsmop(result,NULL,ic,TRUE);
7117 /*-----------------------------------------------------------------*
7118 * genMultiAsm - repeat assembly instruction for size of register.
7119 * if endian == 1, then the high byte (i.e base address + size of
7120 * register) is used first else the low byte is used first;
7121 *-----------------------------------------------------------------*/
7122 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7127 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7140 emitpcode(poc, popGet(AOP(reg),offset));
7145 /*-----------------------------------------------------------------*/
7146 /* genLeftShift - generates code for left shifting */
7147 /*-----------------------------------------------------------------*/
7148 static void genLeftShift (iCode *ic)
7150 operand *left,*right, *result;
7153 symbol *tlbl , *tlbl1;
7156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7158 right = IC_RIGHT(ic);
7160 result = IC_RESULT(ic);
7162 aopOp(right,ic,FALSE);
7164 /* if the shift count is known then do it
7165 as efficiently as possible */
7166 if (AOP_TYPE(right) == AOP_LIT) {
7167 genLeftShiftLiteral (left,right,result,ic);
7171 /* shift count is unknown then we have to form
7172 a loop get the loop count in B : Note: we take
7173 only the lower order byte since shifting
7174 more that 32 bits make no sense anyway, ( the
7175 largest size of an object can be only 32 bits ) */
7178 aopOp(left,ic,FALSE);
7179 aopOp(result,ic,FALSE);
7181 /* now move the left to the result if they are not the
7183 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7184 AOP_SIZE(result) > 1) {
7186 size = AOP_SIZE(result);
7189 l = aopGet(AOP(left),offset,FALSE,TRUE);
7190 if (*l == '@' && (IS_AOP_PREG(result))) {
7192 pic14_emitcode("mov","a,%s",l);
7193 aopPut(AOP(result),"a",offset);
7195 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7196 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7197 //aopPut(AOP(result),l,offset);
7203 size = AOP_SIZE(result);
7205 /* if it is only one byte then */
7207 if(optimized_for_speed) {
7208 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7209 emitpcode(POC_ANDLW, popGetLit(0xf0));
7210 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7211 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7212 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7213 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7214 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7215 emitpcode(POC_RLFW, popGet(AOP(result),0));
7216 emitpcode(POC_ANDLW, popGetLit(0xfe));
7217 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7218 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7219 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7222 tlbl = newiTempLabel(NULL);
7223 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7224 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7225 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7228 emitpcode(POC_COMFW, popGet(AOP(right),0));
7229 emitpcode(POC_RRF, popGet(AOP(result),0));
7230 emitpLabel(tlbl->key);
7231 emitpcode(POC_RLF, popGet(AOP(result),0));
7232 emitpcode(POC_ADDLW, popGetLit(1));
7234 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7239 if (pic14_sameRegs(AOP(left),AOP(result))) {
7241 tlbl = newiTempLabel(NULL);
7242 emitpcode(POC_COMFW, popGet(AOP(right),0));
7243 genMultiAsm(POC_RRF, result, size,1);
7244 emitpLabel(tlbl->key);
7245 genMultiAsm(POC_RLF, result, size,0);
7246 emitpcode(POC_ADDLW, popGetLit(1));
7248 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7252 //tlbl = newiTempLabel(NULL);
7254 //tlbl1 = newiTempLabel(NULL);
7256 //reAdjustPreg(AOP(result));
7258 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7259 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7260 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7262 //pic14_emitcode("add","a,acc");
7263 //aopPut(AOP(result),"a",offset++);
7265 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7267 // pic14_emitcode("rlc","a");
7268 // aopPut(AOP(result),"a",offset++);
7270 //reAdjustPreg(AOP(result));
7272 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7273 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7276 tlbl = newiTempLabel(NULL);
7277 tlbl1= newiTempLabel(NULL);
7279 size = AOP_SIZE(result);
7282 pctemp = popGetTempReg(); /* grab a temporary working register. */
7284 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7286 /* offset should be 0, 1 or 3 */
7287 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7289 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7291 emitpcode(POC_MOVWF, pctemp);
7294 emitpLabel(tlbl->key);
7297 emitpcode(POC_RLF, popGet(AOP(result),0));
7299 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7301 emitpcode(POC_DECFSZ, pctemp);
7302 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7303 emitpLabel(tlbl1->key);
7305 popReleaseTempReg(pctemp);
7309 freeAsmop (right,NULL,ic,TRUE);
7310 freeAsmop(left,NULL,ic,TRUE);
7311 freeAsmop(result,NULL,ic,TRUE);
7314 /*-----------------------------------------------------------------*/
7315 /* genrshOne - right shift a one byte quantity by known count */
7316 /*-----------------------------------------------------------------*/
7317 static void genrshOne (operand *result, operand *left,
7318 int shCount, int sign)
7320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7321 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7324 /*-----------------------------------------------------------------*/
7325 /* genrshTwo - right shift two bytes by known amount != 0 */
7326 /*-----------------------------------------------------------------*/
7327 static void genrshTwo (operand *result,operand *left,
7328 int shCount, int sign)
7330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7331 /* if shCount >= 8 */
7335 shiftR1Left2Result(left, MSB16, result, LSB,
7338 movLeft2Result(left, MSB16, result, LSB);
7340 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7343 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7344 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7348 /* 1 <= shCount <= 7 */
7350 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7353 /*-----------------------------------------------------------------*/
7354 /* shiftRLong - shift right one long from left to result */
7355 /* offl = LSB or MSB16 */
7356 /*-----------------------------------------------------------------*/
7357 static void shiftRLong (operand *left, int offl,
7358 operand *result, int sign)
7360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7362 pic14_emitcode("clr","c");
7363 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7365 pic14_emitcode("mov","c,acc.7");
7366 pic14_emitcode("rrc","a");
7367 aopPut(AOP(result),"a",MSB32-offl);
7369 /* add sign of "a" */
7370 addSign(result, MSB32, sign);
7372 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7373 pic14_emitcode("rrc","a");
7374 aopPut(AOP(result),"a",MSB24-offl);
7376 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7377 pic14_emitcode("rrc","a");
7378 aopPut(AOP(result),"a",MSB16-offl);
7381 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7382 pic14_emitcode("rrc","a");
7383 aopPut(AOP(result),"a",LSB);
7387 /*-----------------------------------------------------------------*/
7388 /* genrshFour - shift four byte by a known amount != 0 */
7389 /*-----------------------------------------------------------------*/
7390 static void genrshFour (operand *result, operand *left,
7391 int shCount, int sign)
7393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7394 /* if shifting more that 3 bytes */
7395 if(shCount >= 24 ) {
7398 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7400 movLeft2Result(left, MSB32, result, LSB);
7402 addSign(result, MSB16, sign);
7404 else if(shCount >= 16){
7407 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7409 movLeft2Result(left, MSB24, result, LSB);
7410 movLeft2Result(left, MSB32, result, MSB16);
7412 addSign(result, MSB24, sign);
7414 else if(shCount >= 8){
7417 shiftRLong(left, MSB16, result, sign);
7418 else if(shCount == 0){
7419 movLeft2Result(left, MSB16, result, LSB);
7420 movLeft2Result(left, MSB24, result, MSB16);
7421 movLeft2Result(left, MSB32, result, MSB24);
7422 addSign(result, MSB32, sign);
7425 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7426 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7427 /* the last shift is signed */
7428 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7429 addSign(result, MSB32, sign);
7432 else{ /* 1 <= shCount <= 7 */
7434 shiftRLong(left, LSB, result, sign);
7436 shiftRLong(result, LSB, result, sign);
7439 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7440 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7441 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7446 /*-----------------------------------------------------------------*/
7447 /* genRightShiftLiteral - right shifting by known count */
7448 /*-----------------------------------------------------------------*/
7449 static void genRightShiftLiteral (operand *left,
7455 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7459 freeAsmop(right,NULL,ic,TRUE);
7461 aopOp(left,ic,FALSE);
7462 aopOp(result,ic,FALSE);
7465 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7469 lsize = pic14_getDataSize(left);
7470 res_size = pic14_getDataSize(result);
7471 /* test the LEFT size !!! */
7473 /* I suppose that the left size >= result size */
7476 movLeft2Result(left, lsize, result, res_size);
7479 else if(shCount >= (lsize * 8)){
7482 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7484 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7485 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7490 emitpcode(POC_MOVLW, popGetLit(0));
7491 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7492 emitpcode(POC_MOVLW, popGetLit(0xff));
7494 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7499 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7506 genrshOne (result,left,shCount,sign);
7510 genrshTwo (result,left,shCount,sign);
7514 genrshFour (result,left,shCount,sign);
7522 freeAsmop(left,NULL,ic,TRUE);
7523 freeAsmop(result,NULL,ic,TRUE);
7526 /*-----------------------------------------------------------------*/
7527 /* genSignedRightShift - right shift of signed number */
7528 /*-----------------------------------------------------------------*/
7529 static void genSignedRightShift (iCode *ic)
7531 operand *right, *left, *result;
7534 symbol *tlbl, *tlbl1 ;
7537 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7539 /* we do it the hard way put the shift count in b
7540 and loop thru preserving the sign */
7541 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7543 right = IC_RIGHT(ic);
7545 result = IC_RESULT(ic);
7547 aopOp(right,ic,FALSE);
7548 aopOp(left,ic,FALSE);
7549 aopOp(result,ic,FALSE);
7552 if ( AOP_TYPE(right) == AOP_LIT) {
7553 genRightShiftLiteral (left,right,result,ic,1);
7556 /* shift count is unknown then we have to form
7557 a loop get the loop count in B : Note: we take
7558 only the lower order byte since shifting
7559 more that 32 bits make no sense anyway, ( the
7560 largest size of an object can be only 32 bits ) */
7562 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7563 //pic14_emitcode("inc","b");
7564 //freeAsmop (right,NULL,ic,TRUE);
7565 //aopOp(left,ic,FALSE);
7566 //aopOp(result,ic,FALSE);
7568 /* now move the left to the result if they are not the
7570 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7571 AOP_SIZE(result) > 1) {
7573 size = AOP_SIZE(result);
7577 l = aopGet(AOP(left),offset,FALSE,TRUE);
7578 if (*l == '@' && IS_AOP_PREG(result)) {
7580 pic14_emitcode("mov","a,%s",l);
7581 aopPut(AOP(result),"a",offset);
7583 aopPut(AOP(result),l,offset);
7585 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7586 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7592 /* mov the highest order bit to OVR */
7593 tlbl = newiTempLabel(NULL);
7594 tlbl1= newiTempLabel(NULL);
7596 size = AOP_SIZE(result);
7599 pctemp = popGetTempReg(); /* grab a temporary working register. */
7601 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7603 /* offset should be 0, 1 or 3 */
7604 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7606 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7608 emitpcode(POC_MOVWF, pctemp);
7611 emitpLabel(tlbl->key);
7613 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7614 emitpcode(POC_RRF, popGet(AOP(result),offset));
7617 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7620 emitpcode(POC_DECFSZ, pctemp);
7621 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7622 emitpLabel(tlbl1->key);
7624 popReleaseTempReg(pctemp);
7626 size = AOP_SIZE(result);
7628 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7629 pic14_emitcode("rlc","a");
7630 pic14_emitcode("mov","ov,c");
7631 /* if it is only one byte then */
7633 l = aopGet(AOP(left),0,FALSE,FALSE);
7635 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7636 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7637 pic14_emitcode("mov","c,ov");
7638 pic14_emitcode("rrc","a");
7639 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7640 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7641 aopPut(AOP(result),"a",0);
7645 reAdjustPreg(AOP(result));
7646 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7647 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7648 pic14_emitcode("mov","c,ov");
7650 l = aopGet(AOP(result),offset,FALSE,FALSE);
7652 pic14_emitcode("rrc","a");
7653 aopPut(AOP(result),"a",offset--);
7655 reAdjustPreg(AOP(result));
7656 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7657 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7662 freeAsmop(left,NULL,ic,TRUE);
7663 freeAsmop(result,NULL,ic,TRUE);
7664 freeAsmop(right,NULL,ic,TRUE);
7667 /*-----------------------------------------------------------------*/
7668 /* genRightShift - generate code for right shifting */
7669 /*-----------------------------------------------------------------*/
7670 static void genRightShift (iCode *ic)
7672 operand *right, *left, *result;
7676 symbol *tlbl, *tlbl1 ;
7678 /* if signed then we do it the hard way preserve the
7679 sign bit moving it inwards */
7680 retype = getSpec(operandType(IC_RESULT(ic)));
7681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7683 if (!SPEC_USIGN(retype)) {
7684 genSignedRightShift (ic);
7688 /* signed & unsigned types are treated the same : i.e. the
7689 signed is NOT propagated inwards : quoting from the
7690 ANSI - standard : "for E1 >> E2, is equivalent to division
7691 by 2**E2 if unsigned or if it has a non-negative value,
7692 otherwise the result is implementation defined ", MY definition
7693 is that the sign does not get propagated */
7695 right = IC_RIGHT(ic);
7697 result = IC_RESULT(ic);
7699 aopOp(right,ic,FALSE);
7701 /* if the shift count is known then do it
7702 as efficiently as possible */
7703 if (AOP_TYPE(right) == AOP_LIT) {
7704 genRightShiftLiteral (left,right,result,ic, 0);
7708 /* shift count is unknown then we have to form
7709 a loop get the loop count in B : Note: we take
7710 only the lower order byte since shifting
7711 more that 32 bits make no sense anyway, ( the
7712 largest size of an object can be only 32 bits ) */
7714 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7715 pic14_emitcode("inc","b");
7716 aopOp(left,ic,FALSE);
7717 aopOp(result,ic,FALSE);
7719 /* now move the left to the result if they are not the
7721 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7722 AOP_SIZE(result) > 1) {
7724 size = AOP_SIZE(result);
7727 l = aopGet(AOP(left),offset,FALSE,TRUE);
7728 if (*l == '@' && IS_AOP_PREG(result)) {
7730 pic14_emitcode("mov","a,%s",l);
7731 aopPut(AOP(result),"a",offset);
7733 aopPut(AOP(result),l,offset);
7738 tlbl = newiTempLabel(NULL);
7739 tlbl1= newiTempLabel(NULL);
7740 size = AOP_SIZE(result);
7743 /* if it is only one byte then */
7746 tlbl = newiTempLabel(NULL);
7747 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7748 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7749 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7752 emitpcode(POC_COMFW, popGet(AOP(right),0));
7753 emitpcode(POC_RLF, popGet(AOP(result),0));
7754 emitpLabel(tlbl->key);
7755 emitpcode(POC_RRF, popGet(AOP(result),0));
7756 emitpcode(POC_ADDLW, popGetLit(1));
7758 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7763 reAdjustPreg(AOP(result));
7764 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7765 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7768 l = aopGet(AOP(result),offset,FALSE,FALSE);
7770 pic14_emitcode("rrc","a");
7771 aopPut(AOP(result),"a",offset--);
7773 reAdjustPreg(AOP(result));
7775 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7776 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7779 freeAsmop(left,NULL,ic,TRUE);
7780 freeAsmop (right,NULL,ic,TRUE);
7781 freeAsmop(result,NULL,ic,TRUE);
7784 /*-----------------------------------------------------------------*/
7785 /* genUnpackBits - generates code for unpacking bits */
7786 /*-----------------------------------------------------------------*/
7787 static void genUnpackBits (operand *result, char *rname, int ptype)
7794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7795 etype = getSpec(operandType(result));
7797 /* read the first byte */
7802 pic14_emitcode("mov","a,@%s",rname);
7806 pic14_emitcode("movx","a,@%s",rname);
7810 pic14_emitcode("movx","a,@dptr");
7814 pic14_emitcode("clr","a");
7815 pic14_emitcode("movc","a","@a+dptr");
7819 pic14_emitcode("lcall","__gptrget");
7823 /* if we have bitdisplacement then it fits */
7824 /* into this byte completely or if length is */
7825 /* less than a byte */
7826 if ((shCnt = SPEC_BSTR(etype)) ||
7827 (SPEC_BLEN(etype) <= 8)) {
7829 /* shift right acc */
7832 pic14_emitcode("anl","a,#0x%02x",
7833 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7834 aopPut(AOP(result),"a",offset);
7838 /* bit field did not fit in a byte */
7839 rlen = SPEC_BLEN(etype) - 8;
7840 aopPut(AOP(result),"a",offset++);
7847 pic14_emitcode("inc","%s",rname);
7848 pic14_emitcode("mov","a,@%s",rname);
7852 pic14_emitcode("inc","%s",rname);
7853 pic14_emitcode("movx","a,@%s",rname);
7857 pic14_emitcode("inc","dptr");
7858 pic14_emitcode("movx","a,@dptr");
7862 pic14_emitcode("clr","a");
7863 pic14_emitcode("inc","dptr");
7864 pic14_emitcode("movc","a","@a+dptr");
7868 pic14_emitcode("inc","dptr");
7869 pic14_emitcode("lcall","__gptrget");
7874 /* if we are done */
7878 aopPut(AOP(result),"a",offset++);
7883 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7884 aopPut(AOP(result),"a",offset);
7891 /*-----------------------------------------------------------------*/
7892 /* genDataPointerGet - generates code when ptr offset is known */
7893 /*-----------------------------------------------------------------*/
7894 static void genDataPointerGet (operand *left,
7898 int size , offset = 0;
7901 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7904 /* optimization - most of the time, left and result are the same
7905 * address, but different types. for the pic code, we could omit
7909 aopOp(result,ic,TRUE);
7911 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7913 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7915 size = AOP_SIZE(result);
7918 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7922 freeAsmop(left,NULL,ic,TRUE);
7923 freeAsmop(result,NULL,ic,TRUE);
7926 /*-----------------------------------------------------------------*/
7927 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7928 /*-----------------------------------------------------------------*/
7929 static void genNearPointerGet (operand *left,
7934 //regs *preg = NULL ;
7936 sym_link *rtype, *retype;
7937 sym_link *ltype = operandType(left);
7940 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7942 rtype = operandType(result);
7943 retype= getSpec(rtype);
7945 aopOp(left,ic,FALSE);
7947 /* if left is rematerialisable and
7948 result is not bit variable type and
7949 the left is pointer to data space i.e
7950 lower 128 bytes of space */
7951 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7952 !IS_BITVAR(retype) &&
7953 DCL_TYPE(ltype) == POINTER) {
7954 //genDataPointerGet (left,result,ic);
7958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7960 /* if the value is already in a pointer register
7961 then don't need anything more */
7962 if (!AOP_INPREG(AOP(left))) {
7963 /* otherwise get a free pointer register */
7964 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7967 preg = getFreePtr(ic,&aop,FALSE);
7968 pic14_emitcode("mov","%s,%s",
7970 aopGet(AOP(left),0,FALSE,TRUE));
7971 rname = preg->name ;
7975 rname = aopGet(AOP(left),0,FALSE,FALSE);
7977 aopOp (result,ic,FALSE);
7979 /* if bitfield then unpack the bits */
7980 if (IS_BITFIELD(retype))
7981 genUnpackBits (result,rname,POINTER);
7983 /* we have can just get the values */
7984 int size = AOP_SIZE(result);
7987 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7989 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7990 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7992 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7993 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7995 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7999 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8001 pic14_emitcode("mov","a,@%s",rname);
8002 aopPut(AOP(result),"a",offset);
8004 sprintf(buffer,"@%s",rname);
8005 aopPut(AOP(result),buffer,offset);
8009 pic14_emitcode("inc","%s",rname);
8014 /* now some housekeeping stuff */
8016 /* we had to allocate for this iCode */
8017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8018 freeAsmop(NULL,aop,ic,TRUE);
8020 /* we did not allocate which means left
8021 already in a pointer register, then
8022 if size > 0 && this could be used again
8023 we have to point it back to where it
8025 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8026 if (AOP_SIZE(result) > 1 &&
8027 !OP_SYMBOL(left)->remat &&
8028 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8030 int size = AOP_SIZE(result) - 1;
8032 pic14_emitcode("dec","%s",rname);
8037 freeAsmop(left,NULL,ic,TRUE);
8038 freeAsmop(result,NULL,ic,TRUE);
8042 /*-----------------------------------------------------------------*/
8043 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8044 /*-----------------------------------------------------------------*/
8045 static void genPagedPointerGet (operand *left,
8052 sym_link *rtype, *retype;
8054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8056 rtype = operandType(result);
8057 retype= getSpec(rtype);
8059 aopOp(left,ic,FALSE);
8061 /* if the value is already in a pointer register
8062 then don't need anything more */
8063 if (!AOP_INPREG(AOP(left))) {
8064 /* otherwise get a free pointer register */
8066 preg = getFreePtr(ic,&aop,FALSE);
8067 pic14_emitcode("mov","%s,%s",
8069 aopGet(AOP(left),0,FALSE,TRUE));
8070 rname = preg->name ;
8072 rname = aopGet(AOP(left),0,FALSE,FALSE);
8074 freeAsmop(left,NULL,ic,TRUE);
8075 aopOp (result,ic,FALSE);
8077 /* if bitfield then unpack the bits */
8078 if (IS_BITFIELD(retype))
8079 genUnpackBits (result,rname,PPOINTER);
8081 /* we have can just get the values */
8082 int size = AOP_SIZE(result);
8087 pic14_emitcode("movx","a,@%s",rname);
8088 aopPut(AOP(result),"a",offset);
8093 pic14_emitcode("inc","%s",rname);
8097 /* now some housekeeping stuff */
8099 /* we had to allocate for this iCode */
8100 freeAsmop(NULL,aop,ic,TRUE);
8102 /* we did not allocate which means left
8103 already in a pointer register, then
8104 if size > 0 && this could be used again
8105 we have to point it back to where it
8107 if (AOP_SIZE(result) > 1 &&
8108 !OP_SYMBOL(left)->remat &&
8109 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8111 int size = AOP_SIZE(result) - 1;
8113 pic14_emitcode("dec","%s",rname);
8118 freeAsmop(result,NULL,ic,TRUE);
8123 /*-----------------------------------------------------------------*/
8124 /* genFarPointerGet - gget value from far space */
8125 /*-----------------------------------------------------------------*/
8126 static void genFarPointerGet (operand *left,
8127 operand *result, iCode *ic)
8130 sym_link *retype = getSpec(operandType(result));
8132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8134 aopOp(left,ic,FALSE);
8136 /* if the operand is already in dptr
8137 then we do nothing else we move the value to dptr */
8138 if (AOP_TYPE(left) != AOP_STR) {
8139 /* if this is remateriazable */
8140 if (AOP_TYPE(left) == AOP_IMMD)
8141 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8142 else { /* we need to get it byte by byte */
8143 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8144 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8145 if (options.model == MODEL_FLAT24)
8147 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8151 /* so dptr know contains the address */
8152 freeAsmop(left,NULL,ic,TRUE);
8153 aopOp(result,ic,FALSE);
8155 /* if bit then unpack */
8156 if (IS_BITFIELD(retype))
8157 genUnpackBits(result,"dptr",FPOINTER);
8159 size = AOP_SIZE(result);
8163 pic14_emitcode("movx","a,@dptr");
8164 aopPut(AOP(result),"a",offset++);
8166 pic14_emitcode("inc","dptr");
8170 freeAsmop(result,NULL,ic,TRUE);
8173 /*-----------------------------------------------------------------*/
8174 /* genCodePointerGet - get value from code space */
8175 /*-----------------------------------------------------------------*/
8176 static void genCodePointerGet (operand *left,
8177 operand *result, iCode *ic)
8180 sym_link *retype = getSpec(operandType(result));
8182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8184 aopOp(left,ic,FALSE);
8186 /* if the operand is already in dptr
8187 then we do nothing else we move the value to dptr */
8188 if (AOP_TYPE(left) != AOP_STR) {
8189 /* if this is remateriazable */
8190 if (AOP_TYPE(left) == AOP_IMMD)
8191 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8192 else { /* we need to get it byte by byte */
8193 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8194 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8195 if (options.model == MODEL_FLAT24)
8197 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8201 /* so dptr know contains the address */
8202 freeAsmop(left,NULL,ic,TRUE);
8203 aopOp(result,ic,FALSE);
8205 /* if bit then unpack */
8206 if (IS_BITFIELD(retype))
8207 genUnpackBits(result,"dptr",CPOINTER);
8209 size = AOP_SIZE(result);
8213 pic14_emitcode("clr","a");
8214 pic14_emitcode("movc","a,@a+dptr");
8215 aopPut(AOP(result),"a",offset++);
8217 pic14_emitcode("inc","dptr");
8221 freeAsmop(result,NULL,ic,TRUE);
8224 /*-----------------------------------------------------------------*/
8225 /* genGenPointerGet - gget value from generic pointer space */
8226 /*-----------------------------------------------------------------*/
8227 static void genGenPointerGet (operand *left,
8228 operand *result, iCode *ic)
8231 sym_link *retype = getSpec(operandType(result));
8233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8234 aopOp(left,ic,FALSE);
8235 aopOp(result,ic,FALSE);
8238 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8240 /* if the operand is already in dptr
8241 then we do nothing else we move the value to dptr */
8242 // if (AOP_TYPE(left) != AOP_STR) {
8243 /* if this is remateriazable */
8244 if (AOP_TYPE(left) == AOP_IMMD) {
8245 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8246 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8248 else { /* we need to get it byte by byte */
8250 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8251 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8253 size = AOP_SIZE(result);
8257 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8258 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8260 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8265 /* so dptr know contains the address */
8267 /* if bit then unpack */
8268 //if (IS_BITFIELD(retype))
8269 // genUnpackBits(result,"dptr",GPOINTER);
8272 freeAsmop(left,NULL,ic,TRUE);
8273 freeAsmop(result,NULL,ic,TRUE);
8277 /*-----------------------------------------------------------------*/
8278 /* genConstPointerGet - get value from const generic pointer space */
8279 /*-----------------------------------------------------------------*/
8280 static void genConstPointerGet (operand *left,
8281 operand *result, iCode *ic)
8283 //sym_link *retype = getSpec(operandType(result));
8284 symbol *albl = newiTempLabel(NULL);
8285 symbol *blbl = newiTempLabel(NULL);
8289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8290 aopOp(left,ic,FALSE);
8291 aopOp(result,ic,FALSE);
8294 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8296 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8298 emitpcode(POC_CALL,popGetLabel(albl->key));
8299 pcop = popGetLabel(blbl->key);
8300 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8301 emitpcode(POC_GOTO,pcop);
8302 emitpLabel(albl->key);
8304 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8306 emitpcode(poc,popGet(AOP(left),1));
8307 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8308 emitpcode(poc,popGet(AOP(left),0));
8309 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8311 emitpLabel(blbl->key);
8313 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8316 freeAsmop(left,NULL,ic,TRUE);
8317 freeAsmop(result,NULL,ic,TRUE);
8320 /*-----------------------------------------------------------------*/
8321 /* genPointerGet - generate code for pointer get */
8322 /*-----------------------------------------------------------------*/
8323 static void genPointerGet (iCode *ic)
8325 operand *left, *result ;
8326 sym_link *type, *etype;
8329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8332 result = IC_RESULT(ic) ;
8334 /* depending on the type of pointer we need to
8335 move it to the correct pointer register */
8336 type = operandType(left);
8337 etype = getSpec(type);
8339 if (IS_PTR_CONST(type))
8340 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8342 /* if left is of type of pointer then it is simple */
8343 if (IS_PTR(type) && !IS_FUNC(type->next))
8344 p_type = DCL_TYPE(type);
8346 /* we have to go by the storage class */
8347 p_type = PTR_TYPE(SPEC_OCLS(etype));
8349 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8351 if (SPEC_OCLS(etype)->codesp ) {
8352 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8353 //p_type = CPOINTER ;
8356 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8357 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8358 /*p_type = FPOINTER ;*/
8360 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8361 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8362 /* p_type = PPOINTER; */
8364 if (SPEC_OCLS(etype) == idata )
8365 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8366 /* p_type = IPOINTER; */
8368 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8369 /* p_type = POINTER ; */
8372 /* now that we have the pointer type we assign
8373 the pointer values */
8378 genNearPointerGet (left,result,ic);
8382 genPagedPointerGet(left,result,ic);
8386 genFarPointerGet (left,result,ic);
8390 genConstPointerGet (left,result,ic);
8391 //pic14_emitcodePointerGet (left,result,ic);
8395 if (IS_PTR_CONST(type))
8396 genConstPointerGet (left,result,ic);
8398 genGenPointerGet (left,result,ic);
8404 /*-----------------------------------------------------------------*/
8405 /* genPackBits - generates code for packed bit storage */
8406 /*-----------------------------------------------------------------*/
8407 static void genPackBits (sym_link *etype ,
8409 char *rname, int p_type)
8417 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8418 blen = SPEC_BLEN(etype);
8419 bstr = SPEC_BSTR(etype);
8421 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8424 /* if the bit lenth is less than or */
8425 /* it exactly fits a byte then */
8426 if (SPEC_BLEN(etype) <= 8 ) {
8427 shCount = SPEC_BSTR(etype) ;
8429 /* shift left acc */
8432 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8437 pic14_emitcode ("mov","b,a");
8438 pic14_emitcode("mov","a,@%s",rname);
8442 pic14_emitcode ("mov","b,a");
8443 pic14_emitcode("movx","a,@dptr");
8447 pic14_emitcode ("push","b");
8448 pic14_emitcode ("push","acc");
8449 pic14_emitcode ("lcall","__gptrget");
8450 pic14_emitcode ("pop","b");
8454 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8455 ((unsigned char)(0xFF << (blen+bstr)) |
8456 (unsigned char)(0xFF >> (8-bstr)) ) );
8457 pic14_emitcode ("orl","a,b");
8458 if (p_type == GPOINTER)
8459 pic14_emitcode("pop","b");
8465 pic14_emitcode("mov","@%s,a",rname);
8469 pic14_emitcode("movx","@dptr,a");
8473 DEBUGpic14_emitcode(";lcall","__gptrput");
8478 if ( SPEC_BLEN(etype) <= 8 )
8481 pic14_emitcode("inc","%s",rname);
8482 rLen = SPEC_BLEN(etype) ;
8484 /* now generate for lengths greater than one byte */
8487 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8497 pic14_emitcode("mov","@%s,a",rname);
8499 pic14_emitcode("mov","@%s,%s",rname,l);
8504 pic14_emitcode("movx","@dptr,a");
8509 DEBUGpic14_emitcode(";lcall","__gptrput");
8512 pic14_emitcode ("inc","%s",rname);
8517 /* last last was not complete */
8519 /* save the byte & read byte */
8522 pic14_emitcode ("mov","b,a");
8523 pic14_emitcode("mov","a,@%s",rname);
8527 pic14_emitcode ("mov","b,a");
8528 pic14_emitcode("movx","a,@dptr");
8532 pic14_emitcode ("push","b");
8533 pic14_emitcode ("push","acc");
8534 pic14_emitcode ("lcall","__gptrget");
8535 pic14_emitcode ("pop","b");
8539 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8540 pic14_emitcode ("orl","a,b");
8543 if (p_type == GPOINTER)
8544 pic14_emitcode("pop","b");
8549 pic14_emitcode("mov","@%s,a",rname);
8553 pic14_emitcode("movx","@dptr,a");
8557 DEBUGpic14_emitcode(";lcall","__gptrput");
8561 /*-----------------------------------------------------------------*/
8562 /* genDataPointerSet - remat pointer to data space */
8563 /*-----------------------------------------------------------------*/
8564 static void genDataPointerSet(operand *right,
8568 int size, offset = 0 ;
8569 char *l, buffer[256];
8571 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8572 aopOp(right,ic,FALSE);
8574 l = aopGet(AOP(result),0,FALSE,TRUE);
8575 size = AOP_SIZE(right);
8577 if ( AOP_TYPE(result) == AOP_PCODE) {
8578 fprintf(stderr,"genDataPointerSet %s, %d\n",
8579 AOP(result)->aopu.pcop->name,
8580 PCOI(AOP(result)->aopu.pcop)->offset);
8584 // tsd, was l+1 - the underline `_' prefix was being stripped
8587 sprintf(buffer,"(%s + %d)",l,offset);
8588 fprintf(stderr,"oops %s\n",buffer);
8590 sprintf(buffer,"%s",l);
8592 if (AOP_TYPE(right) == AOP_LIT) {
8593 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8594 lit = lit >> (8*offset);
8596 pic14_emitcode("movlw","%d",lit);
8597 pic14_emitcode("movwf","%s",buffer);
8599 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8600 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8601 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8604 pic14_emitcode("clrf","%s",buffer);
8605 //emitpcode(POC_CLRF, popRegFromString(buffer));
8606 emitpcode(POC_CLRF, popGet(AOP(result),0));
8609 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8610 pic14_emitcode("movwf","%s",buffer);
8612 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8613 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8614 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8621 freeAsmop(right,NULL,ic,TRUE);
8622 freeAsmop(result,NULL,ic,TRUE);
8625 /*-----------------------------------------------------------------*/
8626 /* genNearPointerSet - pic14_emitcode for near pointer put */
8627 /*-----------------------------------------------------------------*/
8628 static void genNearPointerSet (operand *right,
8635 sym_link *ptype = operandType(result);
8638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8639 retype= getSpec(operandType(right));
8641 aopOp(result,ic,FALSE);
8644 /* if the result is rematerializable &
8645 in data space & not a bit variable */
8646 //if (AOP_TYPE(result) == AOP_IMMD &&
8647 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8648 DCL_TYPE(ptype) == POINTER &&
8649 !IS_BITFIELD(retype)) {
8650 genDataPointerSet (right,result,ic);
8651 freeAsmop(result,NULL,ic,TRUE);
8655 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8656 aopOp(right,ic,FALSE);
8657 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8659 /* if the value is already in a pointer register
8660 then don't need anything more */
8661 if (!AOP_INPREG(AOP(result))) {
8662 /* otherwise get a free pointer register */
8663 //aop = newAsmop(0);
8664 //preg = getFreePtr(ic,&aop,FALSE);
8665 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8666 //pic14_emitcode("mov","%s,%s",
8668 // aopGet(AOP(result),0,FALSE,TRUE));
8669 //rname = preg->name ;
8670 //pic14_emitcode("movwf","fsr");
8671 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8672 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8673 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8674 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8678 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8681 /* if bitfield then unpack the bits */
8682 if (IS_BITFIELD(retype)) {
8683 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8684 "The programmer is obviously confused");
8685 //genPackBits (retype,right,rname,POINTER);
8689 /* we have can just get the values */
8690 int size = AOP_SIZE(right);
8693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8695 l = aopGet(AOP(right),offset,FALSE,TRUE);
8698 //pic14_emitcode("mov","@%s,a",rname);
8699 pic14_emitcode("movf","indf,w ;1");
8702 if (AOP_TYPE(right) == AOP_LIT) {
8703 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8705 pic14_emitcode("movlw","%s",l);
8706 pic14_emitcode("movwf","indf ;2");
8708 pic14_emitcode("clrf","indf");
8710 pic14_emitcode("movf","%s,w",l);
8711 pic14_emitcode("movwf","indf ;2");
8713 //pic14_emitcode("mov","@%s,%s",rname,l);
8716 pic14_emitcode("incf","fsr,f ;3");
8717 //pic14_emitcode("inc","%s",rname);
8722 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8723 /* now some housekeeping stuff */
8725 /* we had to allocate for this iCode */
8726 freeAsmop(NULL,aop,ic,TRUE);
8728 /* we did not allocate which means left
8729 already in a pointer register, then
8730 if size > 0 && this could be used again
8731 we have to point it back to where it
8733 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8734 if (AOP_SIZE(right) > 1 &&
8735 !OP_SYMBOL(result)->remat &&
8736 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8738 int size = AOP_SIZE(right) - 1;
8740 pic14_emitcode("decf","fsr,f");
8741 //pic14_emitcode("dec","%s",rname);
8745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8748 freeAsmop(right,NULL,ic,TRUE);
8749 freeAsmop(result,NULL,ic,TRUE);
8752 /*-----------------------------------------------------------------*/
8753 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8754 /*-----------------------------------------------------------------*/
8755 static void genPagedPointerSet (operand *right,
8764 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8766 retype= getSpec(operandType(right));
8768 aopOp(result,ic,FALSE);
8770 /* if the value is already in a pointer register
8771 then don't need anything more */
8772 if (!AOP_INPREG(AOP(result))) {
8773 /* otherwise get a free pointer register */
8775 preg = getFreePtr(ic,&aop,FALSE);
8776 pic14_emitcode("mov","%s,%s",
8778 aopGet(AOP(result),0,FALSE,TRUE));
8779 rname = preg->name ;
8781 rname = aopGet(AOP(result),0,FALSE,FALSE);
8783 freeAsmop(result,NULL,ic,TRUE);
8784 aopOp (right,ic,FALSE);
8786 /* if bitfield then unpack the bits */
8787 if (IS_BITFIELD(retype))
8788 genPackBits (retype,right,rname,PPOINTER);
8790 /* we have can just get the values */
8791 int size = AOP_SIZE(right);
8795 l = aopGet(AOP(right),offset,FALSE,TRUE);
8798 pic14_emitcode("movx","@%s,a",rname);
8801 pic14_emitcode("inc","%s",rname);
8807 /* now some housekeeping stuff */
8809 /* we had to allocate for this iCode */
8810 freeAsmop(NULL,aop,ic,TRUE);
8812 /* we did not allocate which means left
8813 already in a pointer register, then
8814 if size > 0 && this could be used again
8815 we have to point it back to where it
8817 if (AOP_SIZE(right) > 1 &&
8818 !OP_SYMBOL(result)->remat &&
8819 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8821 int size = AOP_SIZE(right) - 1;
8823 pic14_emitcode("dec","%s",rname);
8828 freeAsmop(right,NULL,ic,TRUE);
8833 /*-----------------------------------------------------------------*/
8834 /* genFarPointerSet - set value from far space */
8835 /*-----------------------------------------------------------------*/
8836 static void genFarPointerSet (operand *right,
8837 operand *result, iCode *ic)
8840 sym_link *retype = getSpec(operandType(right));
8842 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8843 aopOp(result,ic,FALSE);
8845 /* if the operand is already in dptr
8846 then we do nothing else we move the value to dptr */
8847 if (AOP_TYPE(result) != AOP_STR) {
8848 /* if this is remateriazable */
8849 if (AOP_TYPE(result) == AOP_IMMD)
8850 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8851 else { /* we need to get it byte by byte */
8852 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8853 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8854 if (options.model == MODEL_FLAT24)
8856 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8860 /* so dptr know contains the address */
8861 freeAsmop(result,NULL,ic,TRUE);
8862 aopOp(right,ic,FALSE);
8864 /* if bit then unpack */
8865 if (IS_BITFIELD(retype))
8866 genPackBits(retype,right,"dptr",FPOINTER);
8868 size = AOP_SIZE(right);
8872 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8874 pic14_emitcode("movx","@dptr,a");
8876 pic14_emitcode("inc","dptr");
8880 freeAsmop(right,NULL,ic,TRUE);
8883 /*-----------------------------------------------------------------*/
8884 /* genGenPointerSet - set value from generic pointer space */
8885 /*-----------------------------------------------------------------*/
8886 static void genGenPointerSet (operand *right,
8887 operand *result, iCode *ic)
8890 sym_link *retype = getSpec(operandType(right));
8892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8894 aopOp(result,ic,FALSE);
8895 aopOp(right,ic,FALSE);
8896 size = AOP_SIZE(right);
8898 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8900 /* if the operand is already in dptr
8901 then we do nothing else we move the value to dptr */
8902 if (AOP_TYPE(result) != AOP_STR) {
8903 /* if this is remateriazable */
8904 if (AOP_TYPE(result) == AOP_IMMD) {
8905 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8906 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8908 else { /* we need to get it byte by byte */
8909 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8910 size = AOP_SIZE(right);
8913 /* hack hack! see if this the FSR. If so don't load W */
8914 if(AOP_TYPE(right) != AOP_ACC) {
8917 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8918 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8920 if(AOP_SIZE(result) > 1) {
8921 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8922 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8923 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8928 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8930 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8931 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8935 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8936 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8939 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8946 if(aopIdx(AOP(result),0) != 4) {
8948 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8952 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8957 /* so dptr know contains the address */
8960 /* if bit then unpack */
8961 if (IS_BITFIELD(retype))
8962 genPackBits(retype,right,"dptr",GPOINTER);
8964 size = AOP_SIZE(right);
8967 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8971 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8972 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8974 if (AOP_TYPE(right) == AOP_LIT)
8975 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8977 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8979 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8986 freeAsmop(right,NULL,ic,TRUE);
8987 freeAsmop(result,NULL,ic,TRUE);
8990 /*-----------------------------------------------------------------*/
8991 /* genPointerSet - stores the value into a pointer location */
8992 /*-----------------------------------------------------------------*/
8993 static void genPointerSet (iCode *ic)
8995 operand *right, *result ;
8996 sym_link *type, *etype;
8999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9001 right = IC_RIGHT(ic);
9002 result = IC_RESULT(ic) ;
9004 /* depending on the type of pointer we need to
9005 move it to the correct pointer register */
9006 type = operandType(result);
9007 etype = getSpec(type);
9008 /* if left is of type of pointer then it is simple */
9009 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9010 p_type = DCL_TYPE(type);
9013 /* we have to go by the storage class */
9014 p_type = PTR_TYPE(SPEC_OCLS(etype));
9016 /* if (SPEC_OCLS(etype)->codesp ) { */
9017 /* p_type = CPOINTER ; */
9020 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9021 /* p_type = FPOINTER ; */
9023 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9024 /* p_type = PPOINTER ; */
9026 /* if (SPEC_OCLS(etype) == idata ) */
9027 /* p_type = IPOINTER ; */
9029 /* p_type = POINTER ; */
9032 /* now that we have the pointer type we assign
9033 the pointer values */
9038 genNearPointerSet (right,result,ic);
9042 genPagedPointerSet (right,result,ic);
9046 genFarPointerSet (right,result,ic);
9050 genGenPointerSet (right,result,ic);
9054 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9055 "genPointerSet: illegal pointer type");
9059 /*-----------------------------------------------------------------*/
9060 /* genIfx - generate code for Ifx statement */
9061 /*-----------------------------------------------------------------*/
9062 static void genIfx (iCode *ic, iCode *popIc)
9064 operand *cond = IC_COND(ic);
9067 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9069 aopOp(cond,ic,FALSE);
9071 /* get the value into acc */
9072 if (AOP_TYPE(cond) != AOP_CRY)
9073 pic14_toBoolean(cond);
9076 /* the result is now in the accumulator */
9077 freeAsmop(cond,NULL,ic,TRUE);
9079 /* if there was something to be popped then do it */
9083 /* if the condition is a bit variable */
9084 if (isbit && IS_ITEMP(cond) &&
9086 genIfxJump(ic,SPIL_LOC(cond)->rname);
9087 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9090 if (isbit && !IS_ITEMP(cond))
9091 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9099 /*-----------------------------------------------------------------*/
9100 /* genAddrOf - generates code for address of */
9101 /*-----------------------------------------------------------------*/
9102 static void genAddrOf (iCode *ic)
9104 operand *right, *result, *left;
9107 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9110 //aopOp(IC_RESULT(ic),ic,FALSE);
9112 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9113 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9114 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9116 DEBUGpic14_AopType(__LINE__,left,right,result);
9118 size = AOP_SIZE(IC_RESULT(ic));
9122 /* fixing bug #863624, reported from (errolv) */
9123 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9124 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9127 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9128 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9133 freeAsmop(left,NULL,ic,FALSE);
9134 freeAsmop(result,NULL,ic,TRUE);
9139 /*-----------------------------------------------------------------*/
9140 /* genFarFarAssign - assignment when both are in far space */
9141 /*-----------------------------------------------------------------*/
9142 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9144 int size = AOP_SIZE(right);
9147 /* first push the right side on to the stack */
9149 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9151 pic14_emitcode ("push","acc");
9154 freeAsmop(right,NULL,ic,FALSE);
9155 /* now assign DPTR to result */
9156 aopOp(result,ic,FALSE);
9157 size = AOP_SIZE(result);
9159 pic14_emitcode ("pop","acc");
9160 aopPut(AOP(result),"a",--offset);
9162 freeAsmop(result,NULL,ic,FALSE);
9167 /*-----------------------------------------------------------------*/
9168 /* genAssign - generate code for assignment */
9169 /*-----------------------------------------------------------------*/
9170 static void genAssign (iCode *ic)
9172 operand *result, *right;
9173 int size, offset,know_W;
9174 unsigned long lit = 0L;
9176 result = IC_RESULT(ic);
9177 right = IC_RIGHT(ic) ;
9179 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9181 /* if they are the same */
9182 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9185 aopOp(right,ic,FALSE);
9186 aopOp(result,ic,TRUE);
9188 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9190 /* if they are the same registers */
9191 if (pic14_sameRegs(AOP(right),AOP(result)))
9194 /* if the result is a bit */
9195 if (AOP_TYPE(result) == AOP_CRY) {
9197 /* if the right size is a literal then
9198 we know what the value is */
9199 if (AOP_TYPE(right) == AOP_LIT) {
9201 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9202 popGet(AOP(result),0));
9204 if (((int) operandLitValue(right)))
9205 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9206 AOP(result)->aopu.aop_dir,
9207 AOP(result)->aopu.aop_dir);
9209 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9210 AOP(result)->aopu.aop_dir,
9211 AOP(result)->aopu.aop_dir);
9215 /* the right is also a bit variable */
9216 if (AOP_TYPE(right) == AOP_CRY) {
9217 emitpcode(POC_BCF, popGet(AOP(result),0));
9218 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9219 emitpcode(POC_BSF, popGet(AOP(result),0));
9221 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9222 AOP(result)->aopu.aop_dir,
9223 AOP(result)->aopu.aop_dir);
9224 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9225 AOP(right)->aopu.aop_dir,
9226 AOP(right)->aopu.aop_dir);
9227 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9228 AOP(result)->aopu.aop_dir,
9229 AOP(result)->aopu.aop_dir);
9234 emitpcode(POC_BCF, popGet(AOP(result),0));
9235 pic14_toBoolean(right);
9237 emitpcode(POC_BSF, popGet(AOP(result),0));
9238 //aopPut(AOP(result),"a",0);
9242 /* bit variables done */
9244 size = AOP_SIZE(result);
9246 if(AOP_TYPE(right) == AOP_LIT)
9247 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9249 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9250 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9251 if(aopIdx(AOP(result),0) == 4) {
9252 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9253 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9254 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9257 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9263 if(AOP_TYPE(right) == AOP_LIT) {
9265 if(know_W != (int)(lit&0xff))
9266 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9268 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9270 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9274 } else if (AOP_TYPE(right) == AOP_CRY) {
9275 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9277 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9278 emitpcode(POC_INCF, popGet(AOP(result),0));
9281 mov2w (AOP(right), offset);
9282 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9290 freeAsmop (right,NULL,ic,FALSE);
9291 freeAsmop (result,NULL,ic,TRUE);
9294 /*-----------------------------------------------------------------*/
9295 /* genJumpTab - genrates code for jump table */
9296 /*-----------------------------------------------------------------*/
9297 static void genJumpTab (iCode *ic)
9302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9304 aopOp(IC_JTCOND(ic),ic,FALSE);
9305 /* get the condition into accumulator */
9306 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9308 /* multiply by three */
9309 pic14_emitcode("add","a,acc");
9310 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9312 jtab = newiTempLabel(NULL);
9313 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9314 pic14_emitcode("jmp","@a+dptr");
9315 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9317 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9318 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9319 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9320 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9322 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9323 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9324 emitpLabel(jtab->key);
9326 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9328 /* now generate the jump labels */
9329 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9330 jtab = setNextItem(IC_JTLABELS(ic))) {
9331 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9332 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9338 /*-----------------------------------------------------------------*/
9339 /* genMixedOperation - gen code for operators between mixed types */
9340 /*-----------------------------------------------------------------*/
9342 TSD - Written for the PIC port - but this unfortunately is buggy.
9343 This routine is good in that it is able to efficiently promote
9344 types to different (larger) sizes. Unfortunately, the temporary
9345 variables that are optimized out by this routine are sometimes
9346 used in other places. So until I know how to really parse the
9347 iCode tree, I'm going to not be using this routine :(.
9349 static int genMixedOperation (iCode *ic)
9352 operand *result = IC_RESULT(ic);
9353 sym_link *ctype = operandType(IC_LEFT(ic));
9354 operand *right = IC_RIGHT(ic);
9360 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9362 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9368 nextright = IC_RIGHT(nextic);
9369 nextleft = IC_LEFT(nextic);
9370 nextresult = IC_RESULT(nextic);
9372 aopOp(right,ic,FALSE);
9373 aopOp(result,ic,FALSE);
9374 aopOp(nextright, nextic, FALSE);
9375 aopOp(nextleft, nextic, FALSE);
9376 aopOp(nextresult, nextic, FALSE);
9378 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9384 pic14_emitcode(";remove right +","");
9386 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9392 pic14_emitcode(";remove left +","");
9396 big = AOP_SIZE(nextleft);
9397 small = AOP_SIZE(nextright);
9399 switch(nextic->op) {
9402 pic14_emitcode(";optimize a +","");
9403 /* if unsigned or not an integral type */
9404 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9405 pic14_emitcode(";add a bit to something","");
9408 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9410 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9411 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9412 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9414 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9422 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9423 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9424 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9427 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9429 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9430 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9431 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9432 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9433 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9436 pic14_emitcode("rlf","known_zero,w");
9443 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9444 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9445 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9447 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9457 freeAsmop(right,NULL,ic,TRUE);
9458 freeAsmop(result,NULL,ic,TRUE);
9459 freeAsmop(nextright,NULL,ic,TRUE);
9460 freeAsmop(nextleft,NULL,ic,TRUE);
9462 nextic->generated = 1;
9469 /*-----------------------------------------------------------------*/
9470 /* genCast - gen code for casting */
9471 /*-----------------------------------------------------------------*/
9472 static void genCast (iCode *ic)
9474 operand *result = IC_RESULT(ic);
9475 sym_link *ctype = operandType(IC_LEFT(ic));
9476 sym_link *rtype = operandType(IC_RIGHT(ic));
9477 operand *right = IC_RIGHT(ic);
9480 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9481 /* if they are equivalent then do nothing */
9482 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9485 aopOp(right,ic,FALSE) ;
9486 aopOp(result,ic,FALSE);
9488 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9490 /* if the result is a bit */
9491 if (AOP_TYPE(result) == AOP_CRY) {
9492 /* if the right size is a literal then
9493 we know what the value is */
9494 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9495 if (AOP_TYPE(right) == AOP_LIT) {
9497 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9498 popGet(AOP(result),0));
9500 if (((int) operandLitValue(right)))
9501 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9502 AOP(result)->aopu.aop_dir,
9503 AOP(result)->aopu.aop_dir);
9505 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9506 AOP(result)->aopu.aop_dir,
9507 AOP(result)->aopu.aop_dir);
9512 /* the right is also a bit variable */
9513 if (AOP_TYPE(right) == AOP_CRY) {
9516 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9518 pic14_emitcode("clrc","");
9519 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9520 AOP(right)->aopu.aop_dir,
9521 AOP(right)->aopu.aop_dir);
9522 aopPut(AOP(result),"c",0);
9527 if (AOP_TYPE(right) == AOP_REG) {
9528 emitpcode(POC_BCF, popGet(AOP(result),0));
9529 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9530 emitpcode(POC_BSF, popGet(AOP(result),0));
9532 pic14_toBoolean(right);
9533 aopPut(AOP(result),"a",0);
9537 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9539 size = AOP_SIZE(result);
9541 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9543 emitpcode(POC_CLRF, popGet(AOP(result),0));
9544 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9545 emitpcode(POC_INCF, popGet(AOP(result),0));
9548 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9553 /* if they are the same size : or less */
9554 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9556 /* if they are in the same place */
9557 if (pic14_sameRegs(AOP(right),AOP(result)))
9560 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9561 if (IS_PTR_CONST(rtype))
9562 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9563 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9564 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9566 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9567 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9568 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9569 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9570 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9571 if(AOP_SIZE(result) <2)
9572 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9576 /* if they in different places then copy */
9577 size = AOP_SIZE(result);
9580 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9581 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9583 //aopPut(AOP(result),
9584 // aopGet(AOP(right),offset,FALSE,FALSE),
9594 /* if the result is of type pointer */
9595 if (IS_PTR(ctype)) {
9598 sym_link *type = operandType(right);
9599 sym_link *etype = getSpec(type);
9600 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9602 /* pointer to generic pointer */
9603 if (IS_GENPTR(ctype)) {
9607 p_type = DCL_TYPE(type);
9609 /* we have to go by the storage class */
9610 p_type = PTR_TYPE(SPEC_OCLS(etype));
9612 /* if (SPEC_OCLS(etype)->codesp ) */
9613 /* p_type = CPOINTER ; */
9615 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9616 /* p_type = FPOINTER ; */
9618 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9619 /* p_type = PPOINTER; */
9621 /* if (SPEC_OCLS(etype) == idata ) */
9622 /* p_type = IPOINTER ; */
9624 /* p_type = POINTER ; */
9627 /* the first two bytes are known */
9628 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9629 size = GPTRSIZE - 1;
9632 if(offset < AOP_SIZE(right)) {
9633 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9634 if ((AOP_TYPE(right) == AOP_PCODE) &&
9635 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9636 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9637 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9640 aopGet(AOP(right),offset,FALSE,FALSE),
9644 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9647 /* the last byte depending on type */
9651 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9654 pic14_emitcode(";BUG!? ","%d",__LINE__);
9658 pic14_emitcode(";BUG!? ","%d",__LINE__);
9662 pic14_emitcode(";BUG!? ","%d",__LINE__);
9667 /* this should never happen */
9668 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9669 "got unknown pointer type");
9672 //aopPut(AOP(result),l, GPTRSIZE - 1);
9676 /* just copy the pointers */
9677 size = AOP_SIZE(result);
9681 aopGet(AOP(right),offset,FALSE,FALSE),
9690 /* so we now know that the size of destination is greater
9691 than the size of the source.
9692 Now, if the next iCode is an operator then we might be
9693 able to optimize the operation without performing a cast.
9695 if(genMixedOperation(ic))
9698 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9700 /* we move to result for the size of source */
9701 size = AOP_SIZE(right);
9704 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9705 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9709 /* now depending on the sign of the destination */
9710 size = AOP_SIZE(result) - AOP_SIZE(right);
9711 /* if unsigned or not an integral type */
9712 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9714 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9716 /* we need to extend the sign :{ */
9719 /* Save one instruction of casting char to int */
9720 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9721 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9722 emitpcode(POC_DECF, popGet(AOP(result),offset));
9724 emitpcodeNULLop(POC_CLRW);
9727 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9729 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9731 emitpcode(POC_MOVLW, popGetLit(0xff));
9734 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9739 freeAsmop(right,NULL,ic,TRUE);
9740 freeAsmop(result,NULL,ic,TRUE);
9744 /*-----------------------------------------------------------------*/
9745 /* genDjnz - generate decrement & jump if not zero instrucion */
9746 /*-----------------------------------------------------------------*/
9747 static int genDjnz (iCode *ic, iCode *ifx)
9750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9755 /* if the if condition has a false label
9756 then we cannot save */
9760 /* if the minus is not of the form
9762 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9763 !IS_OP_LITERAL(IC_RIGHT(ic)))
9766 if (operandLitValue(IC_RIGHT(ic)) != 1)
9769 /* if the size of this greater than one then no
9771 if (getSize(operandType(IC_RESULT(ic))) > 1)
9774 /* otherwise we can save BIG */
9775 lbl = newiTempLabel(NULL);
9776 lbl1= newiTempLabel(NULL);
9778 aopOp(IC_RESULT(ic),ic,FALSE);
9780 if (IS_AOP_PREG(IC_RESULT(ic))) {
9781 pic14_emitcode("dec","%s",
9782 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9783 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9784 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9788 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9789 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9791 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9792 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9795 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9796 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9797 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9798 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9801 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9806 /*-----------------------------------------------------------------*/
9807 /* genReceive - generate code for a receive iCode */
9808 /*-----------------------------------------------------------------*/
9809 static void genReceive (iCode *ic)
9811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9813 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9814 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9815 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9817 int size = getSize(operandType(IC_RESULT(ic)));
9818 int offset = fReturnSizePic - size;
9820 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9821 fReturn[fReturnSizePic - offset - 1] : "acc"));
9824 aopOp(IC_RESULT(ic),ic,FALSE);
9825 size = AOP_SIZE(IC_RESULT(ic));
9828 pic14_emitcode ("pop","acc");
9829 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9834 aopOp(IC_RESULT(ic),ic,FALSE);
9836 assignResultValue(IC_RESULT(ic));
9839 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9842 /*-----------------------------------------------------------------*/
9843 /* genDummyRead - generate code for dummy read of volatiles */
9844 /*-----------------------------------------------------------------*/
9846 genDummyRead (iCode * ic)
9848 pic14_emitcode ("; genDummyRead","");
9849 pic14_emitcode ("; not implemented","");
9854 /*-----------------------------------------------------------------*/
9855 /* genpic14Code - generate code for pic14 based controllers */
9856 /*-----------------------------------------------------------------*/
9858 * At this point, ralloc.c has gone through the iCode and attempted
9859 * to optimize in a way suitable for a PIC. Now we've got to generate
9860 * PIC instructions that correspond to the iCode.
9862 * Once the instructions are generated, we'll pass through both the
9863 * peep hole optimizer and the pCode optimizer.
9864 *-----------------------------------------------------------------*/
9866 void genpic14Code (iCode *lic)
9871 lineHead = lineCurr = NULL;
9873 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9876 /* if debug information required */
9877 if (options.debug && currFunc) {
9879 debugFile->writeFunction(currFunc);
9881 if (IS_STATIC(currFunc->etype)) {
9882 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9883 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9885 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9886 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9893 for (ic = lic ; ic ; ic = ic->next ) {
9895 DEBUGpic14_emitcode(";ic","");
9896 if ( cln != ic->lineno ) {
9897 if ( options.debug ) {
9899 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9900 FileBaseName(ic->filename),ic->lineno,
9901 ic->level,ic->block);
9905 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9906 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9907 printCLine(ic->filename, ic->lineno));
9909 if (!options.noCcodeInAsm) {
9911 newpCodeCSource(ic->lineno,
9913 printCLine(ic->filename, ic->lineno)));
9919 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9921 /* if the result is marked as
9922 spilt and rematerializable or code for
9923 this has already been generated then
9925 if (resultRemat(ic) || ic->generated )
9928 /* depending on the operation */
9947 /* IPOP happens only when trying to restore a
9948 spilt live range, if there is an ifx statement
9949 following this pop then the if statement might
9950 be using some of the registers being popped which
9951 would destory the contents of the register so
9952 we need to check for this condition and handle it */
9954 ic->next->op == IFX &&
9955 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9956 genIfx (ic->next,ic);
9974 genEndFunction (ic);
9994 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10011 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10015 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10022 /* note these two are xlated by algebraic equivalence
10023 during parsing SDCC.y */
10024 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10025 "got '>=' or '<=' shouldn't have come here");
10029 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10041 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10045 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10049 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10073 genRightShift (ic);
10076 case GET_VALUE_AT_ADDRESS:
10081 if (POINTER_SET(ic))
10108 addSet(&_G.sendSet,ic);
10111 case DUMMY_READ_VOLATILE:
10121 /* now we are ready to call the
10122 peep hole optimizer */
10123 if (!options.nopeep) {
10124 peepHole (&lineHead);
10126 /* now do the actual printing */
10127 printLine (lineHead,codeOutFile);
10130 DFPRINTF((stderr,"printing pBlock\n\n"));
10131 printpBlock(stdout,pb);