1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
221 addpCode2pBlock(pb,newpCode(poc,pcop));
223 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
226 void emitpcodeNULLop(PIC_OPCODE poc)
229 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
274 bool r0iu = FALSE , r1iu = FALSE;
275 bool r0ou = FALSE , r1ou = FALSE;
277 /* the logic: if r0 & r1 used in the instruction
278 then we are in trouble otherwise */
280 /* first check if r0 & r1 are used by this
281 instruction, in which case we are in trouble */
282 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
288 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
291 /* if no usage of r0 then return it */
292 if (!r0iu && !r0ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294 (*aopp)->type = AOP_R0;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
299 /* if no usage of r1 then return it */
300 if (!r1iu && !r1ou) {
301 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302 (*aopp)->type = AOP_R1;
304 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
307 /* now we know they both have usage */
308 /* if r0 not used in this instruction */
310 /* push it if not already pushed */
312 //pic14_emitcode ("push","%s",
313 // pic14_regWithIdx(R0_IDX)->dname);
317 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318 (*aopp)->type = AOP_R0;
320 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
323 /* if r1 not used then */
326 /* push it if not already pushed */
328 //pic14_emitcode ("push","%s",
329 // pic14_regWithIdx(R1_IDX)->dname);
333 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334 (*aopp)->type = AOP_R1;
335 return pic14_regWithIdx(R1_IDX);
339 /* I said end of world but not quite end of world yet */
340 /* if this is a result then we can push it on the stack*/
342 (*aopp)->type = AOP_STK;
346 /* other wise this is true end of the world */
347 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348 "getFreePtr should never reach here");
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
359 aop = Safe_calloc(1,sizeof(asmop));
364 static void genSetDPTR(int n)
368 pic14_emitcode(";", "Select standard DPTR");
369 pic14_emitcode("mov", "dps, #0x00");
373 pic14_emitcode(";", "Select alternate DPTR");
374 pic14_emitcode("mov", "dps, #0x01");
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for */
380 /* generating code */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
387 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
389 resIfx->condition = 1; /* assume that the ifx is true */
390 resIfx->generated = 0; /* indicate that the ifx has not been used */
393 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
395 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396 __FUNCTION__,__LINE__,resIfx->lbl->key);
400 resIfx->lbl = IC_TRUE(ifx);
402 resIfx->lbl = IC_FALSE(ifx);
403 resIfx->condition = 0;
407 DEBUGpic14_emitcode("; ***","ifx true is non-null");
409 DEBUGpic14_emitcode("; ***","ifx false is non-null");
413 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
422 return PTR_TYPE(SPEC_OCLS(etype));
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
432 memmap *space= SPEC_OCLS(sym->etype);
434 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435 /* if already has one */
439 /* assign depending on the storage class */
440 /* if it is on the stack or indirectly addressable */
441 /* space we need to assign either r0 or r1 to it */
442 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443 sym->aop = aop = newAsmop(0);
444 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445 aop->size = getSize(sym->type);
447 /* now assign the address of the variable to
448 the pointer register */
449 if (aop->type != AOP_STK) {
453 pic14_emitcode("push","acc");
455 pic14_emitcode("mov","a,_bp");
456 pic14_emitcode("add","a,#0x%02x",
458 ((char)(sym->stack - _G.nRegsSaved )) :
459 ((char)sym->stack)) & 0xff);
460 pic14_emitcode("mov","%s,a",
461 aop->aopu.aop_ptr->name);
464 pic14_emitcode("pop","acc");
466 pic14_emitcode("mov","%s,#%s",
467 aop->aopu.aop_ptr->name,
469 aop->paged = space->paged;
471 aop->aopu.aop_stk = sym->stack;
475 if (sym->onStack && options.stack10bit)
477 /* It's on the 10 bit stack, which is located in
481 //DEBUGpic14_emitcode(";","%d",__LINE__);
484 pic14_emitcode("push","acc");
486 pic14_emitcode("mov","a,_bp");
487 pic14_emitcode("add","a,#0x%02x",
489 ((char)(sym->stack - _G.nRegsSaved )) :
490 ((char)sym->stack)) & 0xff);
493 pic14_emitcode ("mov","dpx1,#0x40");
494 pic14_emitcode ("mov","dph1,#0x00");
495 pic14_emitcode ("mov","dpl1, a");
499 pic14_emitcode("pop","acc");
501 sym->aop = aop = newAsmop(AOP_DPTR2);
502 aop->size = getSize(sym->type);
506 //DEBUGpic14_emitcode(";","%d",__LINE__);
507 /* if in bit space */
508 if (IN_BITSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_CRY);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
515 /* if it is in direct space */
516 if (IN_DIRSPACE(space)) {
517 sym->aop = aop = newAsmop (AOP_DIR);
518 aop->aopu.aop_dir = sym->rname ;
519 aop->size = getSize(sym->type);
520 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524 /* special case for a function */
525 if (IS_FUNC(sym->type)) {
526 sym->aop = aop = newAsmop(AOP_IMMD);
527 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
528 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
529 strcpy(aop->aopu.aop_immd,sym->rname);
530 aop->size = FPTRSIZE;
531 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
536 /* only remaining is far space */
537 /* in which case DPTR gets the address */
538 sym->aop = aop = newAsmop(AOP_PCODE);
540 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
541 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542 PCOI(aop->aopu.pcop)->index = 0;
544 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
545 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
547 allocDirReg (IC_LEFT(ic));
549 aop->size = FPTRSIZE;
551 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552 sym->aop = aop = newAsmop(AOP_DPTR);
553 pic14_emitcode ("mov","dptr,#%s", sym->rname);
554 aop->size = getSize(sym->type);
556 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
559 /* if it is in code space */
560 if (IN_CODESPACE(space))
566 /*-----------------------------------------------------------------*/
567 /* aopForRemat - rematerialzes an object */
568 /*-----------------------------------------------------------------*/
569 static asmop *aopForRemat (operand *op) // x symbol *sym)
571 symbol *sym = OP_SYMBOL(op);
573 asmop *aop = newAsmop(AOP_PCODE);
577 ic = sym->rematiCode;
579 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
580 if(IS_OP_POINTER(op)) {
581 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
585 val += (int) operandLitValue(IC_RIGHT(ic));
586 } else if (ic->op == '-') {
587 val -= (int) operandLitValue(IC_RIGHT(ic));
591 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
594 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
595 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
596 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
597 PCOI(aop->aopu.pcop)->index = val;
599 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
600 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
601 val, IS_PTR_CONST(operandType(op)));
603 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
605 allocDirReg (IC_LEFT(ic));
610 int aopIdx (asmop *aop, int offset)
615 if(aop->type != AOP_REG)
618 return aop->aopu.aop_reg[offset]->rIdx;
621 /*-----------------------------------------------------------------*/
622 /* regsInCommon - two operands have some registers in common */
623 /*-----------------------------------------------------------------*/
624 static bool regsInCommon (operand *op1, operand *op2)
629 /* if they have registers in common */
630 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
633 sym1 = OP_SYMBOL(op1);
634 sym2 = OP_SYMBOL(op2);
636 if (sym1->nRegs == 0 || sym2->nRegs == 0)
639 for (i = 0 ; i < sym1->nRegs ; i++) {
644 for (j = 0 ; j < sym2->nRegs ;j++ ) {
648 if (sym2->regs[j] == sym1->regs[i])
656 /*-----------------------------------------------------------------*/
657 /* operandsEqu - equivalent */
658 /*-----------------------------------------------------------------*/
659 static bool operandsEqu ( operand *op1, operand *op2)
663 /* if they not symbols */
664 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
667 sym1 = OP_SYMBOL(op1);
668 sym2 = OP_SYMBOL(op2);
670 /* if both are itemps & one is spilt
671 and the other is not then false */
672 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
673 sym1->isspilt != sym2->isspilt )
676 /* if they are the same */
680 if (strcmp(sym1->rname,sym2->rname) == 0)
684 /* if left is a tmp & right is not */
688 (sym1->usl.spillLoc == sym2))
695 (sym2->usl.spillLoc == sym1))
701 /*-----------------------------------------------------------------*/
702 /* pic14_sameRegs - two asmops have the same registers */
703 /*-----------------------------------------------------------------*/
704 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
711 if (aop1->type != AOP_REG ||
712 aop2->type != AOP_REG )
715 if (aop1->size != aop2->size )
718 for (i = 0 ; i < aop1->size ; i++ )
719 if (aop1->aopu.aop_reg[i] !=
720 aop2->aopu.aop_reg[i] )
726 /*-----------------------------------------------------------------*/
727 /* aopOp - allocates an asmop for an operand : */
728 /*-----------------------------------------------------------------*/
729 void aopOp (operand *op, iCode *ic, bool result)
738 // DEBUGpic14_emitcode(";","%d",__LINE__);
739 /* if this a literal */
740 if (IS_OP_LITERAL(op)) {
741 op->aop = aop = newAsmop(AOP_LIT);
742 aop->aopu.aop_lit = op->operand.valOperand;
743 aop->size = getSize(operandType(op));
748 sym_link *type = operandType(op);
749 if(IS_PTR_CONST(type))
750 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
753 /* if already has a asmop then continue */
757 /* if the underlying symbol has a aop */
758 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
759 DEBUGpic14_emitcode(";","%d",__LINE__);
760 op->aop = OP_SYMBOL(op)->aop;
764 /* if this is a true symbol */
765 if (IS_TRUE_SYMOP(op)) {
766 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
767 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
771 /* this is a temporary : this has
777 e) can be a return use only */
782 /* if the type is a conditional */
783 if (sym->regType == REG_CND) {
784 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
789 /* if it is spilt then two situations
791 b) has a spill location */
792 if (sym->isspilt || sym->nRegs == 0) {
794 DEBUGpic14_emitcode(";","%d",__LINE__);
795 /* rematerialize it NOW */
798 sym->aop = op->aop = aop =
800 aop->size = getSize(sym->type);
801 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
807 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
808 aop->size = getSize(sym->type);
809 for ( i = 0 ; i < 2 ; i++ )
810 aop->aopu.aop_str[i] = accUse[i];
811 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
817 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
818 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
819 //allocDirReg (IC_LEFT(ic));
820 aop->size = getSize(sym->type);
825 aop = op->aop = sym->aop = newAsmop(AOP_STR);
826 aop->size = getSize(sym->type);
827 for ( i = 0 ; i < fReturnSizePic ; i++ )
828 aop->aopu.aop_str[i] = fReturn[i];
830 DEBUGpic14_emitcode(";","%d",__LINE__);
834 /* else spill location */
835 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
836 /* force a new aop if sizes differ */
837 sym->usl.spillLoc->aop = NULL;
839 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
840 __FUNCTION__,__LINE__,
841 sym->usl.spillLoc->rname,
842 sym->rname, sym->usl.spillLoc->offset);
844 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
845 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
846 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
848 sym->usl.spillLoc->offset);
849 aop->size = getSize(sym->type);
855 sym_link *type = operandType(op);
856 if(IS_PTR_CONST(type))
857 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
860 /* must be in a register */
861 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
862 sym->aop = op->aop = aop = newAsmop(AOP_REG);
863 aop->size = sym->nRegs;
864 for ( i = 0 ; i < sym->nRegs ;i++)
865 aop->aopu.aop_reg[i] = sym->regs[i];
868 /*-----------------------------------------------------------------*/
869 /* freeAsmop - free up the asmop given to an operand */
870 /*----------------------------------------------------------------*/
871 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
888 /* depending on the asmop type only three cases need work AOP_RO
889 , AOP_R1 && AOP_STK */
895 pic14_emitcode ("pop","ar0");
899 bitVectUnSetBit(ic->rUsed,R0_IDX);
905 pic14_emitcode ("pop","ar1");
909 bitVectUnSetBit(ic->rUsed,R1_IDX);
915 int stk = aop->aopu.aop_stk + aop->size;
916 bitVectUnSetBit(ic->rUsed,R0_IDX);
917 bitVectUnSetBit(ic->rUsed,R1_IDX);
919 getFreePtr(ic,&aop,FALSE);
921 if (options.stack10bit)
923 /* I'm not sure what to do here yet... */
926 "*** Warning: probably generating bad code for "
927 "10 bit stack mode.\n");
931 pic14_emitcode ("mov","a,_bp");
932 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
933 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
935 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
939 pic14_emitcode("pop","acc");
940 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
942 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
945 freeAsmop(op,NULL,ic,TRUE);
947 pic14_emitcode("pop","ar0");
952 pic14_emitcode("pop","ar1");
960 /* all other cases just dealloc */
964 OP_SYMBOL(op)->aop = NULL;
965 /* if the symbol has a spill */
967 SPIL_LOC(op)->aop = NULL;
972 /*-----------------------------------------------------------------*/
973 /* aopGet - for fetching value of the aop */
974 /*-----------------------------------------------------------------*/
975 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
980 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
981 /* offset is greater than
983 if (offset > (aop->size - 1) &&
984 aop->type != AOP_LIT)
987 /* depending on type */
992 DEBUGpic14_emitcode(";","%d",__LINE__);
993 /* if we need to increment it */
994 while (offset > aop->coff) {
995 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
999 while (offset < aop->coff) {
1000 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1004 aop->coff = offset ;
1006 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1007 return (dname ? "acc" : "a");
1009 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1010 rs = Safe_calloc(1,strlen(s)+1);
1016 DEBUGpic14_emitcode(";","%d",__LINE__);
1017 if (aop->type == AOP_DPTR2)
1022 while (offset > aop->coff) {
1023 pic14_emitcode ("inc","dptr");
1027 while (offset < aop->coff) {
1028 pic14_emitcode("lcall","__decdptr");
1034 pic14_emitcode("clr","a");
1035 pic14_emitcode("movc","a,@a+dptr");
1038 pic14_emitcode("movx","a,@dptr");
1041 if (aop->type == AOP_DPTR2)
1046 return (dname ? "acc" : "a");
1051 sprintf (s,"%s",aop->aopu.aop_immd);
1054 sprintf(s,"(%s >> %d)",
1059 aop->aopu.aop_immd);
1060 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1061 rs = Safe_calloc(1,strlen(s)+1);
1067 sprintf(s,"(%s + %d)",
1070 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1072 sprintf(s,"%s",aop->aopu.aop_dir);
1073 rs = Safe_calloc(1,strlen(s)+1);
1079 // return aop->aopu.aop_reg[offset]->dname;
1081 return aop->aopu.aop_reg[offset]->name;
1084 //pic14_emitcode(";","%d",__LINE__);
1085 return aop->aopu.aop_dir;
1088 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1089 return "AOP_accumulator_bug";
1092 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1093 rs = Safe_calloc(1,strlen(s)+1);
1098 aop->coff = offset ;
1099 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1102 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1104 return aop->aopu.aop_str[offset];
1108 pCodeOp *pcop = aop->aopu.pcop;
1109 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1111 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1112 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1113 sprintf(s,"%s", pcop->name);
1115 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1118 rs = Safe_calloc(1,strlen(s)+1);
1124 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1125 "aopget got unsupported aop->type");
1130 /*-----------------------------------------------------------------*/
1131 /* popGetTempReg - create a new temporary pCodeOp */
1132 /*-----------------------------------------------------------------*/
1133 pCodeOp *popGetTempReg(void)
1138 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1139 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1140 PCOR(pcop)->r->wasUsed=1;
1141 PCOR(pcop)->r->isFree=0;
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp */
1149 /*-----------------------------------------------------------------*/
1150 void popReleaseTempReg(pCodeOp *pcop)
1153 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1154 PCOR(pcop)->r->isFree = 1;
1157 /*-----------------------------------------------------------------*/
1158 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1159 /*-----------------------------------------------------------------*/
1160 pCodeOp *popGetLabel(unsigned int key)
1163 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1168 return newpCodeOpLabel(NULL,key+100+labelOffset);
1171 /*-----------------------------------------------------------------*/
1172 /* popCopyReg - copy a pcode operator */
1173 /*-----------------------------------------------------------------*/
1174 pCodeOp *popCopyReg(pCodeOpReg *pc)
1178 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1179 pcor->pcop.type = pc->pcop.type;
1181 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1182 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1184 pcor->pcop.name = NULL;
1187 pcor->rIdx = pc->rIdx;
1190 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1194 /*-----------------------------------------------------------------*/
1195 /* popGet - asm operator to pcode operator conversion */
1196 /*-----------------------------------------------------------------*/
1197 pCodeOp *popGetLit(unsigned int lit)
1200 return newpCodeOpLit(lit);
1204 /*-----------------------------------------------------------------*/
1205 /* popGetImmd - asm operator to pcode immediate conversion */
1206 /*-----------------------------------------------------------------*/
1207 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1210 return newpCodeOpImmd(name, offset,index, 0);
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetWithString(char *str)
1223 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1227 pcop = newpCodeOp(str,PO_STR);
1232 /*-----------------------------------------------------------------*/
1233 /* popRegFromString - */
1234 /*-----------------------------------------------------------------*/
1235 pCodeOp *popRegFromString(char *str, int size, int offset)
1238 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1239 pcop->type = PO_DIR;
1241 DEBUGpic14_emitcode(";","%d",__LINE__);
1246 pcop->name = Safe_calloc(1,strlen(str)+1);
1247 strcpy(pcop->name,str);
1249 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1251 PCOR(pcop)->r = dirregWithName(pcop->name);
1252 if(PCOR(pcop)->r == NULL) {
1253 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1254 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1255 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1257 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1259 PCOR(pcop)->instance = offset;
1264 pCodeOp *popRegFromIdx(int rIdx)
1268 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1269 __FUNCTION__,__LINE__,rIdx);
1271 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1273 PCOR(pcop)->rIdx = rIdx;
1274 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1275 PCOR(pcop)->r->isFree = 0;
1276 PCOR(pcop)->r->wasUsed = 1;
1278 pcop->type = PCOR(pcop)->r->pc_type;
1283 /*-----------------------------------------------------------------*/
1284 /* popGet - asm operator to pcode operator conversion */
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1288 //char *s = buffer ;
1293 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1294 /* offset is greater than
1297 if (offset > (aop->size - 1) &&
1298 aop->type != AOP_LIT)
1299 return NULL; //zero;
1301 /* depending on type */
1302 switch (aop->type) {
1309 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1313 DEBUGpic14_emitcode(";","%d",__LINE__);
1314 return popGetImmd(aop->aopu.aop_immd,offset,0);
1317 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1319 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1320 pcop->type = PO_DIR;
1324 sprintf(s,"(%s + %d)",
1328 sprintf(s,"%s",aop->aopu.aop_dir);
1329 pcop->name = Safe_calloc(1,strlen(s)+1);
1330 strcpy(pcop->name,s);
1332 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1333 strcpy(pcop->name,aop->aopu.aop_dir);
1334 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1335 if(PCOR(pcop)->r == NULL) {
1336 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1337 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1338 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1340 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1342 PCOR(pcop)->instance = offset;
1349 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1351 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1352 PCOR(pcop)->rIdx = rIdx;
1353 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1354 PCOR(pcop)->r->wasUsed=1;
1355 PCOR(pcop)->r->isFree=0;
1357 PCOR(pcop)->instance = offset;
1358 pcop->type = PCOR(pcop)->r->pc_type;
1359 //rs = aop->aopu.aop_reg[offset]->name;
1360 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1365 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1366 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1367 //if(PCOR(pcop)->r == NULL)
1368 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1372 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1375 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1376 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1378 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1379 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1380 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1381 pcop->type = PCOR(pcop)->r->pc_type;
1382 pcop->name = PCOR(pcop)->r->name;
1388 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1390 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1391 pcop = pCodeOpCopy(aop->aopu.pcop);
1392 PCOI(pcop)->offset = offset;
1396 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1397 "popGet got unsupported aop->type");
1400 /*-----------------------------------------------------------------*/
1401 /* aopPut - puts a string for a aop */
1402 /*-----------------------------------------------------------------*/
1403 void aopPut (asmop *aop, char *s, int offset)
1408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1410 if (aop->size && offset > ( aop->size - 1)) {
1411 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1412 "aopPut got offset > aop->size");
1416 /* will assign value to value */
1417 /* depending on where it is ofcourse */
1418 switch (aop->type) {
1421 sprintf(d,"(%s + %d)",
1422 aop->aopu.aop_dir,offset);
1423 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1426 sprintf(d,"%s",aop->aopu.aop_dir);
1429 DEBUGpic14_emitcode(";","%d",__LINE__);
1431 pic14_emitcode("movf","%s,w",s);
1432 pic14_emitcode("movwf","%s",d);
1435 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1436 if(offset >= aop->size) {
1437 emitpcode(POC_CLRF,popGet(aop,offset));
1440 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1443 emitpcode(POC_MOVWF,popGet(aop,offset));
1450 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1451 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1454 strcmp(s,"r0") == 0 ||
1455 strcmp(s,"r1") == 0 ||
1456 strcmp(s,"r2") == 0 ||
1457 strcmp(s,"r3") == 0 ||
1458 strcmp(s,"r4") == 0 ||
1459 strcmp(s,"r5") == 0 ||
1460 strcmp(s,"r6") == 0 ||
1461 strcmp(s,"r7") == 0 )
1462 pic14_emitcode("mov","%s,%s ; %d",
1463 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1467 if(strcmp(s,"W")==0 )
1468 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1470 pic14_emitcode("movwf","%s",
1471 aop->aopu.aop_reg[offset]->name);
1473 if(strcmp(s,zero)==0) {
1474 emitpcode(POC_CLRF,popGet(aop,offset));
1476 } else if(strcmp(s,"W")==0) {
1477 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1478 pcop->type = PO_GPR_REGISTER;
1480 PCOR(pcop)->rIdx = -1;
1481 PCOR(pcop)->r = NULL;
1483 DEBUGpic14_emitcode(";","%d",__LINE__);
1484 pcop->name = Safe_strdup(s);
1485 emitpcode(POC_MOVFW,pcop);
1486 emitpcode(POC_MOVWF,popGet(aop,offset));
1487 } else if(strcmp(s,one)==0) {
1488 emitpcode(POC_CLRF,popGet(aop,offset));
1489 emitpcode(POC_INCF,popGet(aop,offset));
1491 emitpcode(POC_MOVWF,popGet(aop,offset));
1499 if (aop->type == AOP_DPTR2)
1505 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1506 "aopPut writting to code space");
1510 while (offset > aop->coff) {
1512 pic14_emitcode ("inc","dptr");
1515 while (offset < aop->coff) {
1517 pic14_emitcode("lcall","__decdptr");
1522 /* if not in accumulater */
1525 pic14_emitcode ("movx","@dptr,a");
1527 if (aop->type == AOP_DPTR2)
1535 while (offset > aop->coff) {
1537 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1539 while (offset < aop->coff) {
1541 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1547 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1552 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1554 if (strcmp(s,"r0") == 0 ||
1555 strcmp(s,"r1") == 0 ||
1556 strcmp(s,"r2") == 0 ||
1557 strcmp(s,"r3") == 0 ||
1558 strcmp(s,"r4") == 0 ||
1559 strcmp(s,"r5") == 0 ||
1560 strcmp(s,"r6") == 0 ||
1561 strcmp(s,"r7") == 0 ) {
1563 sprintf(buffer,"a%s",s);
1564 pic14_emitcode("mov","@%s,%s",
1565 aop->aopu.aop_ptr->name,buffer);
1567 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1572 if (strcmp(s,"a") == 0)
1573 pic14_emitcode("push","acc");
1575 pic14_emitcode("push","%s",s);
1580 /* if bit variable */
1581 if (!aop->aopu.aop_dir) {
1582 pic14_emitcode("clr","a");
1583 pic14_emitcode("rlc","a");
1586 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1589 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1592 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1594 lbl = newiTempLabel(NULL);
1596 if (strcmp(s,"a")) {
1599 pic14_emitcode("clr","c");
1600 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1601 pic14_emitcode("cpl","c");
1602 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1603 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1610 if (strcmp(aop->aopu.aop_str[offset],s))
1611 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1616 if (!offset && (strcmp(s,"acc") == 0))
1619 if (strcmp(aop->aopu.aop_str[offset],s))
1620 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1624 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1625 "aopPut got unsupported aop->type");
1631 /*-----------------------------------------------------------------*/
1632 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1633 /*-----------------------------------------------------------------*/
1634 void mov2w (asmop *aop, int offset)
1640 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1642 if ( aop->type == AOP_PCODE ||
1643 aop->type == AOP_LIT )
1644 emitpcode(POC_MOVLW,popGet(aop,offset));
1646 emitpcode(POC_MOVFW,popGet(aop,offset));
1650 /*-----------------------------------------------------------------*/
1651 /* reAdjustPreg - points a register back to where it should */
1652 /*-----------------------------------------------------------------*/
1653 static void reAdjustPreg (asmop *aop)
1657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 if ((size = aop->size) <= 1)
1662 switch (aop->type) {
1666 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1670 if (aop->type == AOP_DPTR2)
1676 pic14_emitcode("lcall","__decdptr");
1679 if (aop->type == AOP_DPTR2)
1689 /*-----------------------------------------------------------------*/
1690 /* genNotFloat - generates not for float operations */
1691 /*-----------------------------------------------------------------*/
1692 static void genNotFloat (operand *op, operand *res)
1698 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1699 /* we will put 127 in the first byte of
1701 aopPut(AOP(res),"#127",0);
1702 size = AOP_SIZE(op) - 1;
1705 l = aopGet(op->aop,offset++,FALSE,FALSE);
1709 pic14_emitcode("orl","a,%s",
1711 offset++,FALSE,FALSE));
1713 tlbl = newiTempLabel(NULL);
1715 tlbl = newiTempLabel(NULL);
1716 aopPut(res->aop,one,1);
1717 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1718 aopPut(res->aop,zero,1);
1719 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1721 size = res->aop->size - 2;
1723 /* put zeros in the rest */
1725 aopPut(res->aop,zero,offset++);
1729 /*-----------------------------------------------------------------*/
1730 /* opIsGptr: returns non-zero if the passed operand is */
1731 /* a generic pointer type. */
1732 /*-----------------------------------------------------------------*/
1733 static int opIsGptr(operand *op)
1735 sym_link *type = operandType(op);
1737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1738 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1746 /*-----------------------------------------------------------------*/
1747 /* pic14_getDataSize - get the operand data size */
1748 /*-----------------------------------------------------------------*/
1749 int pic14_getDataSize(operand *op)
1751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1754 return AOP_SIZE(op);
1756 // tsd- in the pic port, the genptr size is 1, so this code here
1757 // fails. ( in the 8051 port, the size was 4).
1760 size = AOP_SIZE(op);
1761 if (size == GPTRSIZE)
1763 sym_link *type = operandType(op);
1764 if (IS_GENPTR(type))
1766 /* generic pointer; arithmetic operations
1767 * should ignore the high byte (pointer type).
1770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1777 /*-----------------------------------------------------------------*/
1778 /* pic14_outAcc - output Acc */
1779 /*-----------------------------------------------------------------*/
1780 void pic14_outAcc(operand *result)
1783 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1784 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1787 size = pic14_getDataSize(result);
1789 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1792 /* unsigned or positive */
1794 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1799 /*-----------------------------------------------------------------*/
1800 /* pic14_outBitC - output a bit C */
1801 /*-----------------------------------------------------------------*/
1802 void pic14_outBitC(operand *result)
1805 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1806 /* if the result is bit */
1807 if (AOP_TYPE(result) == AOP_CRY)
1808 aopPut(AOP(result),"c",0);
1810 pic14_emitcode("clr","a ; %d", __LINE__);
1811 pic14_emitcode("rlc","a");
1812 pic14_outAcc(result);
1816 /*-----------------------------------------------------------------*/
1817 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1818 /*-----------------------------------------------------------------*/
1819 void pic14_toBoolean(operand *oper)
1821 int size = AOP_SIZE(oper) - 1;
1824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1826 if ( AOP_TYPE(oper) != AOP_ACC) {
1827 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1830 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1835 /*-----------------------------------------------------------------*/
1836 /* genNot - generate code for ! operation */
1837 /*-----------------------------------------------------------------*/
1838 static void genNot (iCode *ic)
1841 sym_link *optype = operandType(IC_LEFT(ic));
1844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1845 /* assign asmOps to operand & result */
1846 aopOp (IC_LEFT(ic),ic,FALSE);
1847 aopOp (IC_RESULT(ic),ic,TRUE);
1849 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1850 /* if in bit space then a special case */
1851 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1852 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1853 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1854 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1856 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1857 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1858 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1863 /* if type float then do float */
1864 if (IS_FLOAT(optype)) {
1865 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1869 size = AOP_SIZE(IC_RESULT(ic));
1871 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1872 emitpcode(POC_ANDLW,popGetLit(1));
1873 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1876 pic14_toBoolean(IC_LEFT(ic));
1878 tlbl = newiTempLabel(NULL);
1879 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1880 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1881 pic14_outBitC(IC_RESULT(ic));
1884 /* release the aops */
1885 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1886 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1890 /*-----------------------------------------------------------------*/
1891 /* genCpl - generate code for complement */
1892 /*-----------------------------------------------------------------*/
1893 static void genCpl (iCode *ic)
1895 operand *left, *result;
1899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1900 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1901 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1903 /* if both are in bit space then
1905 if (AOP_TYPE(result) == AOP_CRY &&
1906 AOP_TYPE(left) == AOP_CRY ) {
1908 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1909 pic14_emitcode("cpl","c");
1910 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1914 size = AOP_SIZE(result);
1917 if(AOP_TYPE(left) == AOP_ACC)
1918 emitpcode(POC_XORLW, popGetLit(0xff));
1920 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1922 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1928 /* release the aops */
1929 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1930 freeAsmop(result,NULL,ic,TRUE);
1933 /*-----------------------------------------------------------------*/
1934 /* genUminusFloat - unary minus for floating points */
1935 /*-----------------------------------------------------------------*/
1936 static void genUminusFloat(operand *op,operand *result)
1938 int size ,offset =0 ;
1941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1942 /* for this we just need to flip the
1943 first it then copy the rest in place */
1944 size = AOP_SIZE(op) - 1;
1945 l = aopGet(AOP(op),3,FALSE,FALSE);
1949 pic14_emitcode("cpl","acc.7");
1950 aopPut(AOP(result),"a",3);
1954 aopGet(AOP(op),offset,FALSE,FALSE),
1960 /*-----------------------------------------------------------------*/
1961 /* genUminus - unary minus code generation */
1962 /*-----------------------------------------------------------------*/
1963 static void genUminus (iCode *ic)
1966 sym_link *optype, *rtype;
1969 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1971 aopOp(IC_LEFT(ic),ic,FALSE);
1972 aopOp(IC_RESULT(ic),ic,TRUE);
1974 /* if both in bit space then special
1976 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1977 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1979 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1980 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1981 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1986 optype = operandType(IC_LEFT(ic));
1987 rtype = operandType(IC_RESULT(ic));
1989 /* if float then do float stuff */
1990 if (IS_FLOAT(optype)) {
1991 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1995 /* otherwise subtract from zero by taking the 2's complement */
1996 size = AOP_SIZE(IC_LEFT(ic));
1998 for(i=0; i<size; i++) {
1999 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2000 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2002 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2003 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2007 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2008 for(i=1; i<size; i++) {
2010 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2014 /* release the aops */
2015 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2016 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2019 /*-----------------------------------------------------------------*/
2020 /* saveRegisters - will look for a call and save the registers */
2021 /*-----------------------------------------------------------------*/
2022 static void saveRegisters(iCode *lic)
2029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2031 for (ic = lic ; ic ; ic = ic->next)
2032 if (ic->op == CALL || ic->op == PCALL)
2036 fprintf(stderr,"found parameter push with no function call\n");
2040 /* if the registers have been saved already then
2042 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2045 /* find the registers in use at this time
2046 and push them away to safety */
2047 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2051 if (options.useXstack) {
2052 if (bitVectBitValue(rsave,R0_IDX))
2053 pic14_emitcode("mov","b,r0");
2054 pic14_emitcode("mov","r0,%s",spname);
2055 for (i = 0 ; i < pic14_nRegs ; i++) {
2056 if (bitVectBitValue(rsave,i)) {
2058 pic14_emitcode("mov","a,b");
2060 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2061 pic14_emitcode("movx","@r0,a");
2062 pic14_emitcode("inc","r0");
2065 pic14_emitcode("mov","%s,r0",spname);
2066 if (bitVectBitValue(rsave,R0_IDX))
2067 pic14_emitcode("mov","r0,b");
2069 //for (i = 0 ; i < pic14_nRegs ; i++) {
2070 // if (bitVectBitValue(rsave,i))
2071 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2074 dtype = operandType(IC_LEFT(ic));
2075 if (currFunc && dtype &&
2076 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2077 IFFUNC_ISISR(currFunc->type) &&
2080 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2083 /*-----------------------------------------------------------------*/
2084 /* unsaveRegisters - pop the pushed registers */
2085 /*-----------------------------------------------------------------*/
2086 static void unsaveRegisters (iCode *ic)
2091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2092 /* find the registers in use at this time
2093 and push them away to safety */
2094 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2097 if (options.useXstack) {
2098 pic14_emitcode("mov","r0,%s",spname);
2099 for (i = pic14_nRegs ; i >= 0 ; i--) {
2100 if (bitVectBitValue(rsave,i)) {
2101 pic14_emitcode("dec","r0");
2102 pic14_emitcode("movx","a,@r0");
2104 pic14_emitcode("mov","b,a");
2106 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2110 pic14_emitcode("mov","%s,r0",spname);
2111 if (bitVectBitValue(rsave,R0_IDX))
2112 pic14_emitcode("mov","r0,b");
2114 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2115 // if (bitVectBitValue(rsave,i))
2116 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2122 /*-----------------------------------------------------------------*/
2124 /*-----------------------------------------------------------------*/
2125 static void pushSide(operand * oper, int size)
2129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2131 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2132 if (AOP_TYPE(oper) != AOP_REG &&
2133 AOP_TYPE(oper) != AOP_DIR &&
2135 pic14_emitcode("mov","a,%s",l);
2136 pic14_emitcode("push","acc");
2138 pic14_emitcode("push","%s",l);
2143 /*-----------------------------------------------------------------*/
2144 /* assignResultValue - */
2145 /*-----------------------------------------------------------------*/
2146 static void assignResultValue(operand * oper)
2148 int size = AOP_SIZE(oper);
2150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2152 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2154 if(!GpsuedoStkPtr) {
2155 /* The last byte in the assignment is in W */
2157 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2162 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2164 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2169 /*-----------------------------------------------------------------*/
2170 /* genIpush - genrate code for pushing this gets a little complex */
2171 /*-----------------------------------------------------------------*/
2172 static void genIpush (iCode *ic)
2175 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2177 int size, offset = 0 ;
2181 /* if this is not a parm push : ie. it is spill push
2182 and spill push is always done on the local stack */
2183 if (!ic->parmPush) {
2185 /* and the item is spilt then do nothing */
2186 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2189 aopOp(IC_LEFT(ic),ic,FALSE);
2190 size = AOP_SIZE(IC_LEFT(ic));
2191 /* push it on the stack */
2193 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2198 pic14_emitcode("push","%s",l);
2203 /* this is a paramter push: in this case we call
2204 the routine to find the call and save those
2205 registers that need to be saved */
2208 /* then do the push */
2209 aopOp(IC_LEFT(ic),ic,FALSE);
2212 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2213 size = AOP_SIZE(IC_LEFT(ic));
2216 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2217 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2218 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2220 pic14_emitcode("mov","a,%s",l);
2221 pic14_emitcode("push","acc");
2223 pic14_emitcode("push","%s",l);
2226 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2230 /*-----------------------------------------------------------------*/
2231 /* genIpop - recover the registers: can happen only for spilling */
2232 /*-----------------------------------------------------------------*/
2233 static void genIpop (iCode *ic)
2235 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2240 /* if the temp was not pushed then */
2241 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2244 aopOp(IC_LEFT(ic),ic,FALSE);
2245 size = AOP_SIZE(IC_LEFT(ic));
2248 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2251 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2255 /*-----------------------------------------------------------------*/
2256 /* unsaverbank - restores the resgister bank from stack */
2257 /*-----------------------------------------------------------------*/
2258 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2260 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2266 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2268 if (options.useXstack) {
2270 r = getFreePtr(ic,&aop,FALSE);
2273 pic14_emitcode("mov","%s,_spx",r->name);
2274 pic14_emitcode("movx","a,@%s",r->name);
2275 pic14_emitcode("mov","psw,a");
2276 pic14_emitcode("dec","%s",r->name);
2279 pic14_emitcode ("pop","psw");
2282 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2283 if (options.useXstack) {
2284 pic14_emitcode("movx","a,@%s",r->name);
2285 //pic14_emitcode("mov","(%s+%d),a",
2286 // regspic14[i].base,8*bank+regspic14[i].offset);
2287 pic14_emitcode("dec","%s",r->name);
2290 pic14_emitcode("pop",""); //"(%s+%d)",
2291 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2294 if (options.useXstack) {
2296 pic14_emitcode("mov","_spx,%s",r->name);
2297 freeAsmop(NULL,aop,ic,TRUE);
2303 /*-----------------------------------------------------------------*/
2304 /* saverbank - saves an entire register bank on the stack */
2305 /*-----------------------------------------------------------------*/
2306 static void saverbank (int bank, iCode *ic, bool pushPsw)
2308 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2315 if (options.useXstack) {
2318 r = getFreePtr(ic,&aop,FALSE);
2319 pic14_emitcode("mov","%s,_spx",r->name);
2323 for (i = 0 ; i < pic14_nRegs ;i++) {
2324 if (options.useXstack) {
2325 pic14_emitcode("inc","%s",r->name);
2326 //pic14_emitcode("mov","a,(%s+%d)",
2327 // regspic14[i].base,8*bank+regspic14[i].offset);
2328 pic14_emitcode("movx","@%s,a",r->name);
2330 pic14_emitcode("push","");// "(%s+%d)",
2331 //regspic14[i].base,8*bank+regspic14[i].offset);
2335 if (options.useXstack) {
2336 pic14_emitcode("mov","a,psw");
2337 pic14_emitcode("movx","@%s,a",r->name);
2338 pic14_emitcode("inc","%s",r->name);
2339 pic14_emitcode("mov","_spx,%s",r->name);
2340 freeAsmop (NULL,aop,ic,TRUE);
2343 pic14_emitcode("push","psw");
2345 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2351 /*-----------------------------------------------------------------*/
2352 /* genCall - generates a call statement */
2353 /*-----------------------------------------------------------------*/
2354 static void genCall (iCode *ic)
2358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2360 /* if caller saves & we have not saved then */
2364 /* if we are calling a function that is not using
2365 the same register bank then we need to save the
2366 destination registers on the stack */
2367 dtype = operandType(IC_LEFT(ic));
2368 if (currFunc && dtype &&
2369 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2370 IFFUNC_ISISR(currFunc->type) &&
2373 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2375 /* if send set is not empty the assign */
2378 /* For the Pic port, there is no data stack.
2379 * So parameters passed to functions are stored
2380 * in registers. (The pCode optimizer will get
2381 * rid of most of these :).
2383 int psuedoStkPtr=-1;
2384 int firstTimeThruLoop = 1;
2386 _G.sendSet = reverseSet(_G.sendSet);
2388 /* First figure how many parameters are getting passed */
2389 for (sic = setFirstItem(_G.sendSet) ; sic ;
2390 sic = setNextItem(_G.sendSet)) {
2392 aopOp(IC_LEFT(sic),sic,FALSE);
2393 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2394 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2397 for (sic = setFirstItem(_G.sendSet) ; sic ;
2398 sic = setNextItem(_G.sendSet)) {
2399 int size, offset = 0;
2401 aopOp(IC_LEFT(sic),sic,FALSE);
2402 size = AOP_SIZE(IC_LEFT(sic));
2405 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2406 AopType(AOP_TYPE(IC_LEFT(sic))));
2408 if(!firstTimeThruLoop) {
2409 /* If this is not the first time we've been through the loop
2410 * then we need to save the parameter in a temporary
2411 * register. The last byte of the last parameter is
2413 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2416 firstTimeThruLoop=0;
2418 //if (strcmp(l,fReturn[offset])) {
2419 mov2w (AOP(IC_LEFT(sic)), offset);
2421 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2422 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2423 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2425 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2430 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2435 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2436 OP_SYMBOL(IC_LEFT(ic))->rname :
2437 OP_SYMBOL(IC_LEFT(ic))->name));
2440 /* if we need assign a result value */
2441 if ((IS_ITEMP(IC_RESULT(ic)) &&
2442 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2443 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2444 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2447 aopOp(IC_RESULT(ic),ic,FALSE);
2450 assignResultValue(IC_RESULT(ic));
2452 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2453 AopType(AOP_TYPE(IC_RESULT(ic))));
2455 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2458 /* adjust the stack for parameters if
2460 if (ic->parmBytes) {
2462 if (ic->parmBytes > 3) {
2463 pic14_emitcode("mov","a,%s",spname);
2464 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2465 pic14_emitcode("mov","%s,a",spname);
2467 for ( i = 0 ; i < ic->parmBytes ;i++)
2468 pic14_emitcode("dec","%s",spname);
2472 /* if register bank was saved then pop them */
2474 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2476 /* if we hade saved some registers then unsave them */
2477 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2478 unsaveRegisters (ic);
2483 /*-----------------------------------------------------------------*/
2484 /* genPcall - generates a call by pointer statement */
2485 /*-----------------------------------------------------------------*/
2486 static void genPcall (iCode *ic)
2489 symbol *rlbl = newiTempLabel(NULL);
2492 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2493 /* if caller saves & we have not saved then */
2497 /* if we are calling a function that is not using
2498 the same register bank then we need to save the
2499 destination registers on the stack */
2500 dtype = operandType(IC_LEFT(ic));
2501 if (currFunc && dtype &&
2502 IFFUNC_ISISR(currFunc->type) &&
2503 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2504 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2507 /* push the return address on to the stack */
2508 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2509 pic14_emitcode("push","acc");
2510 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2511 pic14_emitcode("push","acc");
2513 if (options.model == MODEL_FLAT24)
2515 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2516 pic14_emitcode("push","acc");
2519 /* now push the calling address */
2520 aopOp(IC_LEFT(ic),ic,FALSE);
2522 pushSide(IC_LEFT(ic), FPTRSIZE);
2524 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2526 /* if send set is not empty the assign */
2530 for (sic = setFirstItem(_G.sendSet) ; sic ;
2531 sic = setNextItem(_G.sendSet)) {
2532 int size, offset = 0;
2533 aopOp(IC_LEFT(sic),sic,FALSE);
2534 size = AOP_SIZE(IC_LEFT(sic));
2536 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2538 if (strcmp(l,fReturn[offset]))
2539 pic14_emitcode("mov","%s,%s",
2544 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2549 pic14_emitcode("ret","");
2550 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2553 /* if we need assign a result value */
2554 if ((IS_ITEMP(IC_RESULT(ic)) &&
2555 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2556 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2557 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2560 aopOp(IC_RESULT(ic),ic,FALSE);
2563 assignResultValue(IC_RESULT(ic));
2565 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2568 /* adjust the stack for parameters if
2570 if (ic->parmBytes) {
2572 if (ic->parmBytes > 3) {
2573 pic14_emitcode("mov","a,%s",spname);
2574 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2575 pic14_emitcode("mov","%s,a",spname);
2577 for ( i = 0 ; i < ic->parmBytes ;i++)
2578 pic14_emitcode("dec","%s",spname);
2582 /* if register bank was saved then unsave them */
2583 if (currFunc && dtype &&
2584 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2585 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2587 /* if we hade saved some registers then
2590 unsaveRegisters (ic);
2594 /*-----------------------------------------------------------------*/
2595 /* resultRemat - result is rematerializable */
2596 /*-----------------------------------------------------------------*/
2597 static int resultRemat (iCode *ic)
2599 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2600 if (SKIP_IC(ic) || ic->op == IFX)
2603 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2604 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2605 if (sym->remat && !POINTER_SET(ic))
2612 #if defined(__BORLANDC__) || defined(_MSC_VER)
2613 #define STRCASECMP stricmp
2615 #define STRCASECMP strcasecmp
2619 /*-----------------------------------------------------------------*/
2620 /* inExcludeList - return 1 if the string is in exclude Reg list */
2621 /*-----------------------------------------------------------------*/
2622 static bool inExcludeList(char *s)
2624 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2628 if (options.excludeRegs[i] &&
2629 STRCASECMP(options.excludeRegs[i],"none") == 0)
2632 for ( i = 0 ; options.excludeRegs[i]; i++) {
2633 if (options.excludeRegs[i] &&
2634 STRCASECMP(s,options.excludeRegs[i]) == 0)
2641 /*-----------------------------------------------------------------*/
2642 /* genFunction - generated code for function entry */
2643 /*-----------------------------------------------------------------*/
2644 static void genFunction (iCode *ic)
2649 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2651 labelOffset += (max_key+4);
2655 /* create the function header */
2656 pic14_emitcode(";","-----------------------------------------");
2657 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2658 pic14_emitcode(";","-----------------------------------------");
2660 pic14_emitcode("","%s:",sym->rname);
2661 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2663 ftype = operandType(IC_LEFT(ic));
2665 /* if critical function then turn interrupts off */
2666 if (IFFUNC_ISCRITICAL(ftype))
2667 pic14_emitcode("clr","ea");
2669 /* here we need to generate the equates for the
2670 register bank if required */
2672 if (FUNC_REGBANK(ftype) != rbank) {
2675 rbank = FUNC_REGBANK(ftype);
2676 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2677 if (strcmp(regspic14[i].base,"0") == 0)
2678 pic14_emitcode("","%s = 0x%02x",
2680 8*rbank+regspic14[i].offset);
2682 pic14_emitcode ("","%s = %s + 0x%02x",
2685 8*rbank+regspic14[i].offset);
2690 /* if this is an interrupt service routine then
2691 save acc, b, dpl, dph */
2692 if (IFFUNC_ISISR(sym->type)) {
2693 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2694 emitpcodeNULLop(POC_NOP);
2695 emitpcodeNULLop(POC_NOP);
2696 emitpcodeNULLop(POC_NOP);
2697 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2698 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2699 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2700 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2702 pBlockConvert2ISR(pb);
2704 if (!inExcludeList("acc"))
2705 pic14_emitcode ("push","acc");
2706 if (!inExcludeList("b"))
2707 pic14_emitcode ("push","b");
2708 if (!inExcludeList("dpl"))
2709 pic14_emitcode ("push","dpl");
2710 if (!inExcludeList("dph"))
2711 pic14_emitcode ("push","dph");
2712 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2714 pic14_emitcode ("push", "dpx");
2715 /* Make sure we're using standard DPTR */
2716 pic14_emitcode ("push", "dps");
2717 pic14_emitcode ("mov", "dps, #0x00");
2718 if (options.stack10bit)
2720 /* This ISR could conceivably use DPTR2. Better save it. */
2721 pic14_emitcode ("push", "dpl1");
2722 pic14_emitcode ("push", "dph1");
2723 pic14_emitcode ("push", "dpx1");
2726 /* if this isr has no bank i.e. is going to
2727 run with bank 0 , then we need to save more
2729 if (!FUNC_REGBANK(sym->type)) {
2731 /* if this function does not call any other
2732 function then we can be economical and
2733 save only those registers that are used */
2734 if (! IFFUNC_HASFCALL(sym->type)) {
2737 /* if any registers used */
2738 if (sym->regsUsed) {
2739 /* save the registers used */
2740 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2741 if (bitVectBitValue(sym->regsUsed,i) ||
2742 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2743 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2748 /* this function has a function call cannot
2749 determines register usage so we will have the
2751 saverbank(0,ic,FALSE);
2756 /* if callee-save to be used for this function
2757 then save the registers being used in this function */
2758 if (IFFUNC_CALLEESAVES(sym->type)) {
2761 /* if any registers used */
2762 if (sym->regsUsed) {
2763 /* save the registers used */
2764 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2765 if (bitVectBitValue(sym->regsUsed,i) ||
2766 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2767 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2775 /* set the register bank to the desired value */
2776 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2777 pic14_emitcode("push","psw");
2778 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2781 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2783 if (options.useXstack) {
2784 pic14_emitcode("mov","r0,%s",spname);
2785 pic14_emitcode("mov","a,_bp");
2786 pic14_emitcode("movx","@r0,a");
2787 pic14_emitcode("inc","%s",spname);
2791 /* set up the stack */
2792 pic14_emitcode ("push","_bp"); /* save the callers stack */
2794 pic14_emitcode ("mov","_bp,%s",spname);
2797 /* adjust the stack for the function */
2802 werror(W_STACK_OVERFLOW,sym->name);
2804 if (i > 3 && sym->recvSize < 4) {
2806 pic14_emitcode ("mov","a,sp");
2807 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2808 pic14_emitcode ("mov","sp,a");
2813 pic14_emitcode("inc","sp");
2818 pic14_emitcode ("mov","a,_spx");
2819 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2820 pic14_emitcode ("mov","_spx,a");
2825 /*-----------------------------------------------------------------*/
2826 /* genEndFunction - generates epilogue for functions */
2827 /*-----------------------------------------------------------------*/
2828 static void genEndFunction (iCode *ic)
2830 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2834 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2836 pic14_emitcode ("mov","%s,_bp",spname);
2839 /* if use external stack but some variables were
2840 added to the local stack then decrement the
2842 if (options.useXstack && sym->stack) {
2843 pic14_emitcode("mov","a,sp");
2844 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2845 pic14_emitcode("mov","sp,a");
2849 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2850 if (options.useXstack) {
2851 pic14_emitcode("mov","r0,%s",spname);
2852 pic14_emitcode("movx","a,@r0");
2853 pic14_emitcode("mov","_bp,a");
2854 pic14_emitcode("dec","%s",spname);
2858 pic14_emitcode ("pop","_bp");
2862 /* restore the register bank */
2863 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2864 pic14_emitcode ("pop","psw");
2866 if (IFFUNC_ISISR(sym->type)) {
2868 /* now we need to restore the registers */
2869 /* if this isr has no bank i.e. is going to
2870 run with bank 0 , then we need to save more
2872 if (!FUNC_REGBANK(sym->type)) {
2874 /* if this function does not call any other
2875 function then we can be economical and
2876 save only those registers that are used */
2877 if (! IFFUNC_HASFCALL(sym->type)) {
2880 /* if any registers used */
2881 if (sym->regsUsed) {
2882 /* save the registers used */
2883 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2884 if (bitVectBitValue(sym->regsUsed,i) ||
2885 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2886 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2891 /* this function has a function call cannot
2892 determines register usage so we will have the
2894 unsaverbank(0,ic,FALSE);
2898 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2900 if (options.stack10bit)
2902 pic14_emitcode ("pop", "dpx1");
2903 pic14_emitcode ("pop", "dph1");
2904 pic14_emitcode ("pop", "dpl1");
2906 pic14_emitcode ("pop", "dps");
2907 pic14_emitcode ("pop", "dpx");
2909 if (!inExcludeList("dph"))
2910 pic14_emitcode ("pop","dph");
2911 if (!inExcludeList("dpl"))
2912 pic14_emitcode ("pop","dpl");
2913 if (!inExcludeList("b"))
2914 pic14_emitcode ("pop","b");
2915 if (!inExcludeList("acc"))
2916 pic14_emitcode ("pop","acc");
2918 if (IFFUNC_ISCRITICAL(sym->type))
2919 pic14_emitcode("setb","ea");
2922 /* if debug then send end of function */
2923 /* if (options.debug && currFunc) { */
2926 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2927 FileBaseName(ic->filename),currFunc->lastLine,
2928 ic->level,ic->block);
2929 if (IS_STATIC(currFunc->etype))
2930 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2932 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2936 pic14_emitcode ("reti","");
2938 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2939 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2940 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2941 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2942 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2943 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2945 emitpcodeNULLop(POC_RETFIE);
2949 if (IFFUNC_ISCRITICAL(sym->type))
2950 pic14_emitcode("setb","ea");
2952 if (IFFUNC_CALLEESAVES(sym->type)) {
2955 /* if any registers used */
2956 if (sym->regsUsed) {
2957 /* save the registers used */
2958 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2959 if (bitVectBitValue(sym->regsUsed,i) ||
2960 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2961 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2967 /* if debug then send end of function */
2970 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2971 FileBaseName(ic->filename),currFunc->lastLine,
2972 ic->level,ic->block);
2973 if (IS_STATIC(currFunc->etype))
2974 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2976 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2980 pic14_emitcode ("return","");
2981 emitpcodeNULLop(POC_RETURN);
2983 /* Mark the end of a function */
2984 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2989 /*-----------------------------------------------------------------*/
2990 /* genRet - generate code for return statement */
2991 /*-----------------------------------------------------------------*/
2992 static void genRet (iCode *ic)
2994 int size,offset = 0 , pushed = 0;
2996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2997 /* if we have no return value then
2998 just generate the "ret" */
3002 /* we have something to return then
3003 move the return value into place */
3004 aopOp(IC_LEFT(ic),ic,FALSE);
3005 size = AOP_SIZE(IC_LEFT(ic));
3009 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3011 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3013 pic14_emitcode("push","%s",l);
3016 l = aopGet(AOP(IC_LEFT(ic)),offset,
3018 if (strcmp(fReturn[offset],l)) {
3019 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3020 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3021 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3023 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3026 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3036 if (strcmp(fReturn[pushed],"a"))
3037 pic14_emitcode("pop",fReturn[pushed]);
3039 pic14_emitcode("pop","acc");
3042 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3045 /* generate a jump to the return label
3046 if the next is not the return statement */
3047 if (!(ic->next && ic->next->op == LABEL &&
3048 IC_LABEL(ic->next) == returnLabel)) {
3050 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3051 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3056 /*-----------------------------------------------------------------*/
3057 /* genLabel - generates a label */
3058 /*-----------------------------------------------------------------*/
3059 static void genLabel (iCode *ic)
3061 /* special case never generate */
3062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3063 if (IC_LABEL(ic) == entryLabel)
3066 emitpLabel(IC_LABEL(ic)->key);
3067 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3070 /*-----------------------------------------------------------------*/
3071 /* genGoto - generates a goto */
3072 /*-----------------------------------------------------------------*/
3074 static void genGoto (iCode *ic)
3076 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3077 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3081 /*-----------------------------------------------------------------*/
3082 /* genMultbits :- multiplication of bits */
3083 /*-----------------------------------------------------------------*/
3084 static void genMultbits (operand *left,
3088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3090 if(!pic14_sameRegs(AOP(result),AOP(right)))
3091 emitpcode(POC_BSF, popGet(AOP(result),0));
3093 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3094 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3095 emitpcode(POC_BCF, popGet(AOP(result),0));
3100 /*-----------------------------------------------------------------*/
3101 /* genMultOneByte : 8 bit multiplication & division */
3102 /*-----------------------------------------------------------------*/
3103 static void genMultOneByte (operand *left,
3107 sym_link *opetype = operandType(result);
3112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3113 DEBUGpic14_AopType(__LINE__,left,right,result);
3114 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3116 /* (if two literals, the value is computed before) */
3117 /* if one literal, literal on the right */
3118 if (AOP_TYPE(left) == AOP_LIT){
3124 size = AOP_SIZE(result);
3127 if (AOP_TYPE(right) == AOP_LIT){
3128 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3129 aopGet(AOP(right),0,FALSE,FALSE),
3130 aopGet(AOP(left),0,FALSE,FALSE),
3131 aopGet(AOP(result),0,FALSE,FALSE));
3132 pic14_emitcode("call","genMultLit");
3134 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3135 aopGet(AOP(right),0,FALSE,FALSE),
3136 aopGet(AOP(left),0,FALSE,FALSE),
3137 aopGet(AOP(result),0,FALSE,FALSE));
3138 pic14_emitcode("call","genMult8X8_8");
3141 genMult8X8_8 (left, right,result);
3144 /* signed or unsigned */
3145 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3146 //l = aopGet(AOP(left),0,FALSE,FALSE);
3148 //pic14_emitcode("mul","ab");
3149 /* if result size = 1, mul signed = mul unsigned */
3150 //aopPut(AOP(result),"a",0);
3152 } else { // (size > 1)
3154 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3155 aopGet(AOP(right),0,FALSE,FALSE),
3156 aopGet(AOP(left),0,FALSE,FALSE),
3157 aopGet(AOP(result),0,FALSE,FALSE));
3159 if (SPEC_USIGN(opetype)){
3160 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3161 genUMult8X8_16 (left, right, result, NULL);
3164 /* for filling the MSBs */
3165 emitpcode(POC_CLRF, popGet(AOP(result),2));
3166 emitpcode(POC_CLRF, popGet(AOP(result),3));
3170 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3172 pic14_emitcode("mov","a,b");
3174 /* adjust the MSB if left or right neg */
3176 /* if one literal */
3177 if (AOP_TYPE(right) == AOP_LIT){
3178 pic14_emitcode("multiply ","right is a lit");
3179 /* AND literal negative */
3180 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3181 /* adjust MSB (c==0 after mul) */
3182 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3186 genSMult8X8_16 (left, right, result, NULL);
3190 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3192 pic14_emitcode("rlc","a");
3193 pic14_emitcode("subb","a,acc");
3201 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3202 //aopPut(AOP(result),"a",offset++);
3206 /*-----------------------------------------------------------------*/
3207 /* genMult - generates code for multiplication */
3208 /*-----------------------------------------------------------------*/
3209 static void genMult (iCode *ic)
3211 operand *left = IC_LEFT(ic);
3212 operand *right = IC_RIGHT(ic);
3213 operand *result= IC_RESULT(ic);
3215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3216 /* assign the amsops */
3217 aopOp (left,ic,FALSE);
3218 aopOp (right,ic,FALSE);
3219 aopOp (result,ic,TRUE);
3221 DEBUGpic14_AopType(__LINE__,left,right,result);
3223 /* special cases first */
3225 if (AOP_TYPE(left) == AOP_CRY &&
3226 AOP_TYPE(right)== AOP_CRY) {
3227 genMultbits(left,right,result);
3231 /* if both are of size == 1 */
3232 if (AOP_SIZE(left) == 1 &&
3233 AOP_SIZE(right) == 1 ) {
3234 genMultOneByte(left,right,result);
3238 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3240 /* should have been converted to function call */
3244 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3245 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3246 freeAsmop(result,NULL,ic,TRUE);
3249 /*-----------------------------------------------------------------*/
3250 /* genDivbits :- division of bits */
3251 /*-----------------------------------------------------------------*/
3252 static void genDivbits (operand *left,
3259 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3260 /* the result must be bit */
3261 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3262 l = aopGet(AOP(left),0,FALSE,FALSE);
3266 pic14_emitcode("div","ab");
3267 pic14_emitcode("rrc","a");
3268 aopPut(AOP(result),"c",0);
3271 /*-----------------------------------------------------------------*/
3272 /* genDivOneByte : 8 bit division */
3273 /*-----------------------------------------------------------------*/
3274 static void genDivOneByte (operand *left,
3278 sym_link *opetype = operandType(result);
3283 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3284 size = AOP_SIZE(result) - 1;
3286 /* signed or unsigned */
3287 if (SPEC_USIGN(opetype)) {
3288 /* unsigned is easy */
3289 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3290 l = aopGet(AOP(left),0,FALSE,FALSE);
3292 pic14_emitcode("div","ab");
3293 aopPut(AOP(result),"a",0);
3295 aopPut(AOP(result),zero,offset++);
3299 /* signed is a little bit more difficult */
3301 /* save the signs of the operands */
3302 l = aopGet(AOP(left),0,FALSE,FALSE);
3304 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3305 pic14_emitcode("push","acc"); /* save it on the stack */
3307 /* now sign adjust for both left & right */
3308 l = aopGet(AOP(right),0,FALSE,FALSE);
3310 lbl = newiTempLabel(NULL);
3311 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3312 pic14_emitcode("cpl","a");
3313 pic14_emitcode("inc","a");
3314 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3315 pic14_emitcode("mov","b,a");
3317 /* sign adjust left side */
3318 l = aopGet(AOP(left),0,FALSE,FALSE);
3321 lbl = newiTempLabel(NULL);
3322 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3323 pic14_emitcode("cpl","a");
3324 pic14_emitcode("inc","a");
3325 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3327 /* now the division */
3328 pic14_emitcode("div","ab");
3329 /* we are interested in the lower order
3331 pic14_emitcode("mov","b,a");
3332 lbl = newiTempLabel(NULL);
3333 pic14_emitcode("pop","acc");
3334 /* if there was an over flow we don't
3335 adjust the sign of the result */
3336 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3337 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3339 pic14_emitcode("clr","a");
3340 pic14_emitcode("subb","a,b");
3341 pic14_emitcode("mov","b,a");
3342 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3344 /* now we are done */
3345 aopPut(AOP(result),"b",0);
3347 pic14_emitcode("mov","c,b.7");
3348 pic14_emitcode("subb","a,acc");
3351 aopPut(AOP(result),"a",offset++);
3355 /*-----------------------------------------------------------------*/
3356 /* genDiv - generates code for division */
3357 /*-----------------------------------------------------------------*/
3358 static void genDiv (iCode *ic)
3360 operand *left = IC_LEFT(ic);
3361 operand *right = IC_RIGHT(ic);
3362 operand *result= IC_RESULT(ic);
3364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3365 /* assign the amsops */
3366 aopOp (left,ic,FALSE);
3367 aopOp (right,ic,FALSE);
3368 aopOp (result,ic,TRUE);
3370 /* special cases first */
3372 if (AOP_TYPE(left) == AOP_CRY &&
3373 AOP_TYPE(right)== AOP_CRY) {
3374 genDivbits(left,right,result);
3378 /* if both are of size == 1 */
3379 if (AOP_SIZE(left) == 1 &&
3380 AOP_SIZE(right) == 1 ) {
3381 genDivOneByte(left,right,result);
3385 /* should have been converted to function call */
3388 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3389 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3390 freeAsmop(result,NULL,ic,TRUE);
3393 /*-----------------------------------------------------------------*/
3394 /* genModbits :- modulus of bits */
3395 /*-----------------------------------------------------------------*/
3396 static void genModbits (operand *left,
3403 /* the result must be bit */
3404 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3405 l = aopGet(AOP(left),0,FALSE,FALSE);
3409 pic14_emitcode("div","ab");
3410 pic14_emitcode("mov","a,b");
3411 pic14_emitcode("rrc","a");
3412 aopPut(AOP(result),"c",0);
3415 /*-----------------------------------------------------------------*/
3416 /* genModOneByte : 8 bit modulus */
3417 /*-----------------------------------------------------------------*/
3418 static void genModOneByte (operand *left,
3422 sym_link *opetype = operandType(result);
3426 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3427 /* signed or unsigned */
3428 if (SPEC_USIGN(opetype)) {
3429 /* unsigned is easy */
3430 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3431 l = aopGet(AOP(left),0,FALSE,FALSE);
3433 pic14_emitcode("div","ab");
3434 aopPut(AOP(result),"b",0);
3438 /* signed is a little bit more difficult */
3440 /* save the signs of the operands */
3441 l = aopGet(AOP(left),0,FALSE,FALSE);
3444 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3445 pic14_emitcode("push","acc"); /* save it on the stack */
3447 /* now sign adjust for both left & right */
3448 l = aopGet(AOP(right),0,FALSE,FALSE);
3451 lbl = newiTempLabel(NULL);
3452 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3453 pic14_emitcode("cpl","a");
3454 pic14_emitcode("inc","a");
3455 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3456 pic14_emitcode("mov","b,a");
3458 /* sign adjust left side */
3459 l = aopGet(AOP(left),0,FALSE,FALSE);
3462 lbl = newiTempLabel(NULL);
3463 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3464 pic14_emitcode("cpl","a");
3465 pic14_emitcode("inc","a");
3466 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3468 /* now the multiplication */
3469 pic14_emitcode("div","ab");
3470 /* we are interested in the lower order
3472 lbl = newiTempLabel(NULL);
3473 pic14_emitcode("pop","acc");
3474 /* if there was an over flow we don't
3475 adjust the sign of the result */
3476 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3477 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3479 pic14_emitcode("clr","a");
3480 pic14_emitcode("subb","a,b");
3481 pic14_emitcode("mov","b,a");
3482 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3484 /* now we are done */
3485 aopPut(AOP(result),"b",0);
3489 /*-----------------------------------------------------------------*/
3490 /* genMod - generates code for division */
3491 /*-----------------------------------------------------------------*/
3492 static void genMod (iCode *ic)
3494 operand *left = IC_LEFT(ic);
3495 operand *right = IC_RIGHT(ic);
3496 operand *result= IC_RESULT(ic);
3498 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3499 /* assign the amsops */
3500 aopOp (left,ic,FALSE);
3501 aopOp (right,ic,FALSE);
3502 aopOp (result,ic,TRUE);
3504 /* special cases first */
3506 if (AOP_TYPE(left) == AOP_CRY &&
3507 AOP_TYPE(right)== AOP_CRY) {
3508 genModbits(left,right,result);
3512 /* if both are of size == 1 */
3513 if (AOP_SIZE(left) == 1 &&
3514 AOP_SIZE(right) == 1 ) {
3515 genModOneByte(left,right,result);
3519 /* should have been converted to function call */
3523 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3524 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3525 freeAsmop(result,NULL,ic,TRUE);
3528 /*-----------------------------------------------------------------*/
3529 /* genIfxJump :- will create a jump depending on the ifx */
3530 /*-----------------------------------------------------------------*/
3532 note: May need to add parameter to indicate when a variable is in bit space.
3534 static void genIfxJump (iCode *ic, char *jval)
3537 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3538 /* if true label then we jump if condition
3540 if ( IC_TRUE(ic) ) {
3542 if(strcmp(jval,"a") == 0)
3544 else if (strcmp(jval,"c") == 0)
3547 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3548 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3551 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3552 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3556 /* false label is present */
3557 if(strcmp(jval,"a") == 0)
3559 else if (strcmp(jval,"c") == 0)
3562 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3563 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3566 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3567 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3572 /* mark the icode as generated */
3576 /*-----------------------------------------------------------------*/
3578 /*-----------------------------------------------------------------*/
3579 static void genSkip(iCode *ifx,int status_bit)
3584 if ( IC_TRUE(ifx) ) {
3585 switch(status_bit) {
3600 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3601 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3605 switch(status_bit) {
3619 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3620 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3626 /*-----------------------------------------------------------------*/
3628 /*-----------------------------------------------------------------*/
3629 static void genSkipc(resolvedIfx *rifx)
3639 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3640 rifx->generated = 1;
3643 /*-----------------------------------------------------------------*/
3645 /*-----------------------------------------------------------------*/
3646 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3651 if( (rifx->condition ^ invert_condition) & 1)
3656 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3657 rifx->generated = 1;
3660 /*-----------------------------------------------------------------*/
3662 /*-----------------------------------------------------------------*/
3663 static void genSkipz(iCode *ifx, int condition)
3674 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3676 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3679 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3681 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3684 /*-----------------------------------------------------------------*/
3686 /*-----------------------------------------------------------------*/
3687 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3693 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3695 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3698 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3699 rifx->generated = 1;
3703 /*-----------------------------------------------------------------*/
3704 /* genChkZeroes :- greater or less than comparison */
3705 /* For each byte in a literal that is zero, inclusive or the */
3706 /* the corresponding byte in the operand with W */
3707 /* returns true if any of the bytes are zero */
3708 /*-----------------------------------------------------------------*/
3709 static int genChkZeroes(operand *op, int lit, int size)
3716 i = (lit >> (size*8)) & 0xff;
3720 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3722 emitpcode(POC_IORFW, popGet(AOP(op),size));
3731 /*-----------------------------------------------------------------*/
3732 /* genCmp :- greater or less than comparison */
3733 /*-----------------------------------------------------------------*/
3734 static void genCmp (operand *left,operand *right,
3735 operand *result, iCode *ifx, int sign)
3737 int size; //, offset = 0 ;
3738 unsigned long lit = 0L,i = 0;
3739 resolvedIfx rFalseIfx;
3740 // resolvedIfx rTrueIfx;
3742 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3745 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3746 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3750 resolveIfx(&rFalseIfx,ifx);
3751 truelbl = newiTempLabel(NULL);
3752 size = max(AOP_SIZE(left),AOP_SIZE(right));
3754 DEBUGpic14_AopType(__LINE__,left,right,result);
3758 /* if literal is on the right then swap with left */
3759 if ((AOP_TYPE(right) == AOP_LIT)) {
3760 operand *tmp = right ;
3761 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3762 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3765 lit = (lit - 1) & mask;
3768 rFalseIfx.condition ^= 1;
3771 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3772 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3776 //if(IC_TRUE(ifx) == NULL)
3777 /* if left & right are bit variables */
3778 if (AOP_TYPE(left) == AOP_CRY &&
3779 AOP_TYPE(right) == AOP_CRY ) {
3780 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3781 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3783 /* subtract right from left if at the
3784 end the carry flag is set then we know that
3785 left is greater than right */
3789 symbol *lbl = newiTempLabel(NULL);
3792 if(AOP_TYPE(right) == AOP_LIT) {
3794 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3796 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3803 genSkipCond(&rFalseIfx,left,size-1,7);
3805 /* no need to compare to 0...*/
3806 /* NOTE: this is a de-generate compare that most certainly
3807 * creates some dead code. */
3808 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3810 if(ifx) ifx->generated = 1;
3817 //i = (lit >> (size*8)) & 0xff;
3818 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3820 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3822 i = ((0-lit) & 0xff);
3825 /* lit is 0x7f, all signed chars are less than
3826 * this except for 0x7f itself */
3827 emitpcode(POC_XORLW, popGetLit(0x7f));
3828 genSkipz2(&rFalseIfx,0);
3830 emitpcode(POC_ADDLW, popGetLit(0x80));
3831 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3832 genSkipc(&rFalseIfx);
3837 genSkipz2(&rFalseIfx,1);
3839 emitpcode(POC_ADDLW, popGetLit(i));
3840 genSkipc(&rFalseIfx);
3844 if(ifx) ifx->generated = 1;
3848 /* chars are out of the way. now do ints and longs */
3851 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3858 genSkipCond(&rFalseIfx,left,size,7);
3859 if(ifx) ifx->generated = 1;
3864 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3866 //rFalseIfx.condition ^= 1;
3867 //genSkipCond(&rFalseIfx,left,size,7);
3868 //rFalseIfx.condition ^= 1;
3870 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3871 if(rFalseIfx.condition)
3872 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3874 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3876 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3877 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3878 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3881 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3883 if(rFalseIfx.condition) {
3885 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3891 genSkipc(&rFalseIfx);
3892 emitpLabel(truelbl->key);
3893 if(ifx) ifx->generated = 1;
3900 if( (lit & 0xff) == 0) {
3901 /* lower byte is zero */
3902 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3903 i = ((lit >> 8) & 0xff) ^0x80;
3904 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3905 emitpcode(POC_ADDLW, popGetLit( 0x80));
3906 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3907 genSkipc(&rFalseIfx);
3910 if(ifx) ifx->generated = 1;
3915 /* Special cases for signed longs */
3916 if( (lit & 0xffffff) == 0) {
3917 /* lower byte is zero */
3918 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3919 i = ((lit >> 8*3) & 0xff) ^0x80;
3920 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3921 emitpcode(POC_ADDLW, popGetLit( 0x80));
3922 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3923 genSkipc(&rFalseIfx);
3926 if(ifx) ifx->generated = 1;
3934 if(lit & (0x80 << (size*8))) {
3935 /* lit is negative */
3936 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3938 //genSkipCond(&rFalseIfx,left,size,7);
3940 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3942 if(rFalseIfx.condition)
3943 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3945 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3949 /* lit is positive */
3950 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3951 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3952 if(rFalseIfx.condition)
3953 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3955 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3960 This works, but is only good for ints.
3961 It also requires a "known zero" register.
3962 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3963 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3964 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3965 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3966 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3967 genSkipc(&rFalseIfx);
3969 emitpLabel(truelbl->key);
3970 if(ifx) ifx->generated = 1;
3974 /* There are no more special cases, so perform a general compare */
3976 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3977 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3981 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3983 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3985 //rFalseIfx.condition ^= 1;
3986 genSkipc(&rFalseIfx);
3988 emitpLabel(truelbl->key);
3990 if(ifx) ifx->generated = 1;
3997 /* sign is out of the way. So now do an unsigned compare */
3998 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4001 /* General case - compare to an unsigned literal on the right.*/
4003 i = (lit >> (size*8)) & 0xff;
4004 emitpcode(POC_MOVLW, popGetLit(i));
4005 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4007 i = (lit >> (size*8)) & 0xff;
4010 emitpcode(POC_MOVLW, popGetLit(i));
4012 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4014 /* this byte of the lit is zero,
4015 *if it's not the last then OR in the variable */
4017 emitpcode(POC_IORFW, popGet(AOP(left),size));
4022 emitpLabel(lbl->key);
4023 //if(emitFinalCheck)
4024 genSkipc(&rFalseIfx);
4026 emitpLabel(truelbl->key);
4028 if(ifx) ifx->generated = 1;
4035 if(AOP_TYPE(left) == AOP_LIT) {
4036 //symbol *lbl = newiTempLabel(NULL);
4038 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4041 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4044 if((lit == 0) && (sign == 0)){
4047 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4049 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4051 genSkipz2(&rFalseIfx,0);
4052 if(ifx) ifx->generated = 1;
4059 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4060 /* degenerate compare can never be true */
4061 if(rFalseIfx.condition == 0)
4062 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4064 if(ifx) ifx->generated = 1;
4069 /* signed comparisons to a literal byte */
4071 int lp1 = (lit+1) & 0xff;
4073 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4076 rFalseIfx.condition ^= 1;
4077 genSkipCond(&rFalseIfx,right,0,7);
4080 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4081 emitpcode(POC_XORLW, popGetLit(0x7f));
4082 genSkipz2(&rFalseIfx,1);
4085 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4086 emitpcode(POC_ADDLW, popGetLit(0x80));
4087 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4088 rFalseIfx.condition ^= 1;
4089 genSkipc(&rFalseIfx);
4092 if(ifx) ifx->generated = 1;
4094 /* unsigned comparisons to a literal byte */
4096 switch(lit & 0xff ) {
4098 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4099 genSkipz2(&rFalseIfx,0);
4100 if(ifx) ifx->generated = 1;
4103 rFalseIfx.condition ^= 1;
4104 genSkipCond(&rFalseIfx,right,0,7);
4105 if(ifx) ifx->generated = 1;
4109 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4110 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4112 rFalseIfx.condition ^= 1;
4113 if (AOP_TYPE(result) == AOP_CRY) {
4114 genSkipc(&rFalseIfx);
4115 if(ifx) ifx->generated = 1;
4117 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4118 emitpcode(POC_CLRF, popGet(AOP(result),0));
4119 emitpcode(POC_RLF, popGet(AOP(result),0));
4120 emitpcode(POC_MOVLW, popGetLit(0x01));
4121 emitpcode(POC_XORWF, popGet(AOP(result),0));
4132 /* Size is greater than 1 */
4140 /* this means lit = 0xffffffff, or -1 */
4143 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4144 rFalseIfx.condition ^= 1;
4145 genSkipCond(&rFalseIfx,right,size,7);
4146 if(ifx) ifx->generated = 1;
4153 if(rFalseIfx.condition) {
4154 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4155 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4158 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4160 emitpcode(POC_IORFW, popGet(AOP(right),size));
4164 if(rFalseIfx.condition) {
4165 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4166 emitpLabel(truelbl->key);
4168 rFalseIfx.condition ^= 1;
4169 genSkipCond(&rFalseIfx,right,s,7);
4172 if(ifx) ifx->generated = 1;
4176 if((size == 1) && (0 == (lp1&0xff))) {
4177 /* lower byte of signed word is zero */
4178 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4179 i = ((lp1 >> 8) & 0xff) ^0x80;
4180 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4181 emitpcode(POC_ADDLW, popGetLit( 0x80));
4182 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4183 rFalseIfx.condition ^= 1;
4184 genSkipc(&rFalseIfx);
4187 if(ifx) ifx->generated = 1;
4191 if(lit & (0x80 << (size*8))) {
4192 /* Lit is less than zero */
4193 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4194 //rFalseIfx.condition ^= 1;
4195 //genSkipCond(&rFalseIfx,left,size,7);
4196 //rFalseIfx.condition ^= 1;
4197 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4198 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4200 if(rFalseIfx.condition)
4201 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4203 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4207 /* Lit is greater than or equal to zero */
4208 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4209 //rFalseIfx.condition ^= 1;
4210 //genSkipCond(&rFalseIfx,right,size,7);
4211 //rFalseIfx.condition ^= 1;
4213 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4216 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4217 if(rFalseIfx.condition)
4218 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4220 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4225 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4226 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4232 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4234 rFalseIfx.condition ^= 1;
4235 //rFalseIfx.condition = 1;
4236 genSkipc(&rFalseIfx);
4238 emitpLabel(truelbl->key);
4240 if(ifx) ifx->generated = 1;
4245 /* compare word or long to an unsigned literal on the right.*/
4250 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4253 break; /* handled above */
4256 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4258 emitpcode(POC_IORFW, popGet(AOP(right),size));
4259 genSkipz2(&rFalseIfx,0);
4263 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4265 emitpcode(POC_IORFW, popGet(AOP(right),size));
4268 if(rFalseIfx.condition)
4269 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4271 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4274 emitpcode(POC_MOVLW, popGetLit(lit+1));
4275 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4277 rFalseIfx.condition ^= 1;
4278 genSkipc(&rFalseIfx);
4281 emitpLabel(truelbl->key);
4283 if(ifx) ifx->generated = 1;
4289 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4290 i = (lit >> (size*8)) & 0xff;
4292 emitpcode(POC_MOVLW, popGetLit(i));
4293 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4296 i = (lit >> (size*8)) & 0xff;
4299 emitpcode(POC_MOVLW, popGetLit(i));
4301 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4303 /* this byte of the lit is zero,
4304 *if it's not the last then OR in the variable */
4306 emitpcode(POC_IORFW, popGet(AOP(right),size));
4311 emitpLabel(lbl->key);
4313 rFalseIfx.condition ^= 1;
4314 genSkipc(&rFalseIfx);
4318 emitpLabel(truelbl->key);
4319 if(ifx) ifx->generated = 1;
4323 /* Compare two variables */
4325 DEBUGpic14_emitcode(";sign","%d",sign);
4329 /* Sigh. thus sucks... */
4331 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4332 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4333 emitpcode(POC_MOVLW, popGetLit(0x80));
4334 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4335 emitpcode(POC_XORFW, popGet(AOP(right),size));
4336 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4338 /* Signed char comparison */
4339 /* Special thanks to Nikolai Golovchenko for this snippet */
4340 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4341 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4342 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4343 emitpcode(POC_XORFW, popGet(AOP(left),0));
4344 emitpcode(POC_XORFW, popGet(AOP(right),0));
4345 emitpcode(POC_ADDLW, popGetLit(0x80));
4347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4348 genSkipc(&rFalseIfx);
4350 if(ifx) ifx->generated = 1;
4356 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4357 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4361 /* The rest of the bytes of a multi-byte compare */
4365 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4368 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4369 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4374 emitpLabel(lbl->key);
4376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4377 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4378 (AOP_TYPE(result) == AOP_REG)) {
4379 emitpcode(POC_CLRF, popGet(AOP(result),0));
4380 emitpcode(POC_RLF, popGet(AOP(result),0));
4382 genSkipc(&rFalseIfx);
4384 //genSkipc(&rFalseIfx);
4385 if(ifx) ifx->generated = 1;
4392 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4394 pic14_outBitC(result);
4396 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4397 /* if the result is used in the next
4398 ifx conditional branch then generate
4399 code a little differently */
4401 genIfxJump (ifx,"c");
4403 pic14_outBitC(result);
4404 /* leave the result in acc */
4409 /*-----------------------------------------------------------------*/
4410 /* genCmpGt :- greater than comparison */
4411 /*-----------------------------------------------------------------*/
4412 static void genCmpGt (iCode *ic, iCode *ifx)
4414 operand *left, *right, *result;
4415 sym_link *letype , *retype;
4418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4420 right= IC_RIGHT(ic);
4421 result = IC_RESULT(ic);
4423 letype = getSpec(operandType(left));
4424 retype =getSpec(operandType(right));
4425 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4426 /* assign the amsops */
4427 aopOp (left,ic,FALSE);
4428 aopOp (right,ic,FALSE);
4429 aopOp (result,ic,TRUE);
4431 genCmp(right, left, result, ifx, sign);
4433 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4434 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4435 freeAsmop(result,NULL,ic,TRUE);
4438 /*-----------------------------------------------------------------*/
4439 /* genCmpLt - less than comparisons */
4440 /*-----------------------------------------------------------------*/
4441 static void genCmpLt (iCode *ic, iCode *ifx)
4443 operand *left, *right, *result;
4444 sym_link *letype , *retype;
4447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4449 right= IC_RIGHT(ic);
4450 result = IC_RESULT(ic);
4452 letype = getSpec(operandType(left));
4453 retype =getSpec(operandType(right));
4454 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4456 /* assign the amsops */
4457 aopOp (left,ic,FALSE);
4458 aopOp (right,ic,FALSE);
4459 aopOp (result,ic,TRUE);
4461 genCmp(left, right, result, ifx, sign);
4463 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4464 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4465 freeAsmop(result,NULL,ic,TRUE);
4468 /*-----------------------------------------------------------------*/
4469 /* genc16bit2lit - compare a 16 bit value to a literal */
4470 /*-----------------------------------------------------------------*/
4471 static void genc16bit2lit(operand *op, int lit, int offset)
4475 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4476 if( (lit&0xff) == 0)
4481 switch( BYTEofLONG(lit,i)) {
4483 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4486 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4489 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4492 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4493 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4498 switch( BYTEofLONG(lit,i)) {
4500 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4504 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4508 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4511 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4513 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4519 /*-----------------------------------------------------------------*/
4520 /* gencjneshort - compare and jump if not equal */
4521 /*-----------------------------------------------------------------*/
4522 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4524 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4526 int res_offset = 0; /* the result may be a different size then left or right */
4527 int res_size = AOP_SIZE(result);
4531 unsigned long lit = 0L;
4532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4533 DEBUGpic14_AopType(__LINE__,left,right,result);
4535 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4536 resolveIfx(&rIfx,ifx);
4537 lbl = newiTempLabel(NULL);
4540 /* if the left side is a literal or
4541 if the right is in a pointer register and left
4543 if ((AOP_TYPE(left) == AOP_LIT) ||
4544 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4549 if(AOP_TYPE(right) == AOP_LIT)
4550 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4552 /* if the right side is a literal then anything goes */
4553 if (AOP_TYPE(right) == AOP_LIT &&
4554 AOP_TYPE(left) != AOP_DIR ) {
4557 genc16bit2lit(left, lit, 0);
4559 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4564 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4565 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4567 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4571 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4573 if(res_offset < res_size-1)
4581 /* if the right side is in a register or in direct space or
4582 if the left is a pointer register & right is not */
4583 else if (AOP_TYPE(right) == AOP_REG ||
4584 AOP_TYPE(right) == AOP_DIR ||
4585 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4586 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4587 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4588 int lbl_key = lbl->key;
4591 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4592 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4594 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4595 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4596 __FUNCTION__,__LINE__);
4600 /* switch(size) { */
4602 /* genc16bit2lit(left, lit, 0); */
4604 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4609 if((AOP_TYPE(left) == AOP_DIR) &&
4610 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4612 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4613 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4615 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4617 switch (lit & 0xff) {
4619 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4622 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4623 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4624 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4628 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4629 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4631 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4635 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4636 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4641 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4644 if(AOP_TYPE(result) == AOP_CRY) {
4645 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4650 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4652 /* fix me. probably need to check result size too */
4653 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4658 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4659 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4666 if(res_offset < res_size-1)
4671 } else if(AOP_TYPE(right) == AOP_REG &&
4672 AOP_TYPE(left) != AOP_DIR){
4675 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4676 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4677 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4682 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4684 if(res_offset < res_size-1)
4689 /* right is a pointer reg need both a & b */
4691 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4693 pic14_emitcode("mov","b,%s",l);
4694 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4695 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4700 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4702 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4704 emitpLabel(lbl->key);
4706 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4713 /*-----------------------------------------------------------------*/
4714 /* gencjne - compare and jump if not equal */
4715 /*-----------------------------------------------------------------*/
4716 static void gencjne(operand *left, operand *right, iCode *ifx)
4718 symbol *tlbl = newiTempLabel(NULL);
4720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4721 gencjneshort(left, right, lbl);
4723 pic14_emitcode("mov","a,%s",one);
4724 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4725 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4726 pic14_emitcode("clr","a");
4727 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4729 emitpLabel(lbl->key);
4730 emitpLabel(tlbl->key);
4735 /*-----------------------------------------------------------------*/
4736 /* genCmpEq - generates code for equal to */
4737 /*-----------------------------------------------------------------*/
4738 static void genCmpEq (iCode *ic, iCode *ifx)
4740 operand *left, *right, *result;
4741 unsigned long lit = 0L;
4744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4747 DEBUGpic14_emitcode ("; ifx is non-null","");
4749 DEBUGpic14_emitcode ("; ifx is null","");
4751 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4752 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4753 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4755 size = max(AOP_SIZE(left),AOP_SIZE(right));
4757 DEBUGpic14_AopType(__LINE__,left,right,result);
4759 /* if literal, literal on the right or
4760 if the right is in a pointer register and left
4762 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4763 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4764 operand *tmp = right ;
4770 if(ifx && !AOP_SIZE(result)){
4772 /* if they are both bit variables */
4773 if (AOP_TYPE(left) == AOP_CRY &&
4774 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4775 if(AOP_TYPE(right) == AOP_LIT){
4776 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4778 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4779 pic14_emitcode("cpl","c");
4780 } else if(lit == 1L) {
4781 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4783 pic14_emitcode("clr","c");
4785 /* AOP_TYPE(right) == AOP_CRY */
4787 symbol *lbl = newiTempLabel(NULL);
4788 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4790 pic14_emitcode("cpl","c");
4791 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4793 /* if true label then we jump if condition
4795 tlbl = newiTempLabel(NULL);
4796 if ( IC_TRUE(ifx) ) {
4797 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4798 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4800 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4801 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4803 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4806 /* left and right are both bit variables, result is carry */
4809 resolveIfx(&rIfx,ifx);
4811 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4812 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4813 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4814 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4819 /* They're not both bit variables. Is the right a literal? */
4820 if(AOP_TYPE(right) == AOP_LIT) {
4821 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4826 switch(lit & 0xff) {
4828 if ( IC_TRUE(ifx) ) {
4829 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4831 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4833 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4834 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4838 if ( IC_TRUE(ifx) ) {
4839 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4841 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4843 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4844 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4848 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4850 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4855 /* end of size == 1 */
4859 genc16bit2lit(left,lit,offset);
4862 /* end of size == 2 */
4867 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4868 emitpcode(POC_IORFW,popGet(AOP(left),1));
4869 emitpcode(POC_IORFW,popGet(AOP(left),2));
4870 emitpcode(POC_IORFW,popGet(AOP(left),3));
4874 /* search for patterns that can be optimized */
4876 genc16bit2lit(left,lit,0);
4879 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4881 genc16bit2lit(left,lit,2);
4883 emitpcode(POC_IORFW,popGet(AOP(left),2));
4884 emitpcode(POC_IORFW,popGet(AOP(left),3));
4897 } else if(AOP_TYPE(right) == AOP_CRY ) {
4898 /* we know the left is not a bit, but that the right is */
4899 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4900 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4901 popGet(AOP(right),offset));
4902 emitpcode(POC_XORLW,popGetLit(1));
4904 /* if the two are equal, then W will be 0 and the Z bit is set
4905 * we could test Z now, or go ahead and check the high order bytes if
4906 * the variable we're comparing is larger than a byte. */
4909 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4911 if ( IC_TRUE(ifx) ) {
4913 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4914 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4917 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4918 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4922 /* They're both variables that are larger than bits */
4925 tlbl = newiTempLabel(NULL);
4928 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4929 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4931 if ( IC_TRUE(ifx) ) {
4934 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4935 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4938 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4939 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4943 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4944 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4948 if(s>1 && IC_TRUE(ifx)) {
4949 emitpLabel(tlbl->key);
4950 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4954 /* mark the icode as generated */
4959 /* if they are both bit variables */
4960 if (AOP_TYPE(left) == AOP_CRY &&
4961 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4962 if(AOP_TYPE(right) == AOP_LIT){
4963 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4965 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4966 pic14_emitcode("cpl","c");
4967 } else if(lit == 1L) {
4968 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4970 pic14_emitcode("clr","c");
4972 /* AOP_TYPE(right) == AOP_CRY */
4974 symbol *lbl = newiTempLabel(NULL);
4975 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4977 pic14_emitcode("cpl","c");
4978 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4981 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4982 pic14_outBitC(result);
4986 genIfxJump (ifx,"c");
4989 /* if the result is used in an arithmetic operation
4990 then put the result in place */
4991 pic14_outBitC(result);
4994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4995 gencjne(left,right,result,ifx);
4998 gencjne(left,right,newiTempLabel(NULL));
5000 if(IC_TRUE(ifx)->key)
5001 gencjne(left,right,IC_TRUE(ifx)->key);
5003 gencjne(left,right,IC_FALSE(ifx)->key);
5007 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5008 aopPut(AOP(result),"a",0);
5013 genIfxJump (ifx,"a");
5017 /* if the result is used in an arithmetic operation
5018 then put the result in place */
5020 if (AOP_TYPE(result) != AOP_CRY)
5021 pic14_outAcc(result);
5023 /* leave the result in acc */
5027 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5028 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5029 freeAsmop(result,NULL,ic,TRUE);
5032 /*-----------------------------------------------------------------*/
5033 /* ifxForOp - returns the icode containing the ifx for operand */
5034 /*-----------------------------------------------------------------*/
5035 static iCode *ifxForOp ( operand *op, iCode *ic )
5037 /* if true symbol then needs to be assigned */
5038 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5039 if (IS_TRUE_SYMOP(op))
5042 /* if this has register type condition and
5043 the next instruction is ifx with the same operand
5044 and live to of the operand is upto the ifx only then */
5046 ic->next->op == IFX &&
5047 IC_COND(ic->next)->key == op->key &&
5048 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5052 ic->next->op == IFX &&
5053 IC_COND(ic->next)->key == op->key) {
5054 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5058 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5060 ic->next->op == IFX)
5061 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5064 ic->next->op == IFX &&
5065 IC_COND(ic->next)->key == op->key) {
5066 DEBUGpic14_emitcode ("; "," key is okay");
5067 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5068 OP_SYMBOL(op)->liveTo,
5075 /*-----------------------------------------------------------------*/
5076 /* genAndOp - for && operation */
5077 /*-----------------------------------------------------------------*/
5078 static void genAndOp (iCode *ic)
5080 operand *left,*right, *result;
5083 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5084 /* note here that && operations that are in an
5085 if statement are taken away by backPatchLabels
5086 only those used in arthmetic operations remain */
5087 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5088 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5089 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5091 DEBUGpic14_AopType(__LINE__,left,right,result);
5093 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5094 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5095 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5097 /* if both are bit variables */
5098 /* if (AOP_TYPE(left) == AOP_CRY && */
5099 /* AOP_TYPE(right) == AOP_CRY ) { */
5100 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5101 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5102 /* pic14_outBitC(result); */
5104 /* tlbl = newiTempLabel(NULL); */
5105 /* pic14_toBoolean(left); */
5106 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5107 /* pic14_toBoolean(right); */
5108 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5109 /* pic14_outBitAcc(result); */
5112 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5113 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5114 freeAsmop(result,NULL,ic,TRUE);
5118 /*-----------------------------------------------------------------*/
5119 /* genOrOp - for || operation */
5120 /*-----------------------------------------------------------------*/
5123 modified this code, but it doesn't appear to ever get called
5126 static void genOrOp (iCode *ic)
5128 operand *left,*right, *result;
5131 /* note here that || operations that are in an
5132 if statement are taken away by backPatchLabels
5133 only those used in arthmetic operations remain */
5134 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5135 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5136 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5137 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5139 DEBUGpic14_AopType(__LINE__,left,right,result);
5141 /* if both are bit variables */
5142 if (AOP_TYPE(left) == AOP_CRY &&
5143 AOP_TYPE(right) == AOP_CRY ) {
5144 pic14_emitcode("clrc","");
5145 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5146 AOP(left)->aopu.aop_dir,
5147 AOP(left)->aopu.aop_dir);
5148 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5149 AOP(right)->aopu.aop_dir,
5150 AOP(right)->aopu.aop_dir);
5151 pic14_emitcode("setc","");
5154 tlbl = newiTempLabel(NULL);
5155 pic14_toBoolean(left);
5157 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5158 pic14_toBoolean(right);
5159 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5161 pic14_outBitAcc(result);
5164 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5165 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5166 freeAsmop(result,NULL,ic,TRUE);
5169 /*-----------------------------------------------------------------*/
5170 /* isLiteralBit - test if lit == 2^n */
5171 /*-----------------------------------------------------------------*/
5172 static int isLiteralBit(unsigned long lit)
5174 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5175 0x100L,0x200L,0x400L,0x800L,
5176 0x1000L,0x2000L,0x4000L,0x8000L,
5177 0x10000L,0x20000L,0x40000L,0x80000L,
5178 0x100000L,0x200000L,0x400000L,0x800000L,
5179 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5180 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5184 for(idx = 0; idx < 32; idx++)
5190 /*-----------------------------------------------------------------*/
5191 /* continueIfTrue - */
5192 /*-----------------------------------------------------------------*/
5193 static void continueIfTrue (iCode *ic)
5195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5197 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5201 /*-----------------------------------------------------------------*/
5203 /*-----------------------------------------------------------------*/
5204 static void jumpIfTrue (iCode *ic)
5206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5208 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5212 /*-----------------------------------------------------------------*/
5213 /* jmpTrueOrFalse - */
5214 /*-----------------------------------------------------------------*/
5215 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5217 // ugly but optimized by peephole
5218 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5220 symbol *nlbl = newiTempLabel(NULL);
5221 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5222 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5223 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5224 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5227 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5228 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5233 /*-----------------------------------------------------------------*/
5234 /* genAnd - code for and */
5235 /*-----------------------------------------------------------------*/
5236 static void genAnd (iCode *ic, iCode *ifx)
5238 operand *left, *right, *result;
5240 unsigned long lit = 0L;
5245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5246 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5247 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5248 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5250 resolveIfx(&rIfx,ifx);
5252 /* if left is a literal & right is not then exchange them */
5253 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5254 AOP_NEEDSACC(left)) {
5255 operand *tmp = right ;
5260 /* if result = right then exchange them */
5261 if(pic14_sameRegs(AOP(result),AOP(right))){
5262 operand *tmp = right ;
5267 /* if right is bit then exchange them */
5268 if (AOP_TYPE(right) == AOP_CRY &&
5269 AOP_TYPE(left) != AOP_CRY){
5270 operand *tmp = right ;
5274 if(AOP_TYPE(right) == AOP_LIT)
5275 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5277 size = AOP_SIZE(result);
5279 DEBUGpic14_AopType(__LINE__,left,right,result);
5282 // result = bit & yy;
5283 if (AOP_TYPE(left) == AOP_CRY){
5284 // c = bit & literal;
5285 if(AOP_TYPE(right) == AOP_LIT){
5287 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5290 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5293 if(size && (AOP_TYPE(result) == AOP_CRY)){
5294 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5297 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5301 pic14_emitcode("clr","c");
5304 if (AOP_TYPE(right) == AOP_CRY){
5306 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5307 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5310 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5312 pic14_emitcode("rrc","a");
5313 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5319 pic14_outBitC(result);
5321 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5322 genIfxJump(ifx, "c");
5326 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5327 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5328 if((AOP_TYPE(right) == AOP_LIT) &&
5329 (AOP_TYPE(result) == AOP_CRY) &&
5330 (AOP_TYPE(left) != AOP_CRY)){
5331 int posbit = isLiteralBit(lit);
5335 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5338 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5344 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5345 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5347 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5348 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5351 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5352 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5353 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5360 symbol *tlbl = newiTempLabel(NULL);
5361 int sizel = AOP_SIZE(left);
5363 pic14_emitcode("setb","c");
5365 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5366 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5368 if((posbit = isLiteralBit(bytelit)) != 0)
5369 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5371 if(bytelit != 0x0FFL)
5372 pic14_emitcode("anl","a,%s",
5373 aopGet(AOP(right),offset,FALSE,TRUE));
5374 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5379 // bit = left & literal
5381 pic14_emitcode("clr","c");
5382 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5384 // if(left & literal)
5387 jmpTrueOrFalse(ifx, tlbl);
5391 pic14_outBitC(result);
5395 /* if left is same as result */
5396 if(pic14_sameRegs(AOP(result),AOP(left))){
5398 for(;size--; offset++,lit>>=8) {
5399 if(AOP_TYPE(right) == AOP_LIT){
5400 switch(lit & 0xff) {
5402 /* and'ing with 0 has clears the result */
5403 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5404 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5407 /* and'ing with 0xff is a nop when the result and left are the same */
5412 int p = my_powof2( (~lit) & 0xff );
5414 /* only one bit is set in the literal, so use a bcf instruction */
5415 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5416 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5419 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5420 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5421 if(know_W != (lit&0xff))
5422 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5424 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5429 if (AOP_TYPE(left) == AOP_ACC) {
5430 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5432 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5433 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5440 // left & result in different registers
5441 if(AOP_TYPE(result) == AOP_CRY){
5443 // if(size), result in bit
5444 // if(!size && ifx), conditional oper: if(left & right)
5445 symbol *tlbl = newiTempLabel(NULL);
5446 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5448 pic14_emitcode("setb","c");
5450 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5451 pic14_emitcode("anl","a,%s",
5452 aopGet(AOP(left),offset,FALSE,FALSE));
5453 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5458 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5459 pic14_outBitC(result);
5461 jmpTrueOrFalse(ifx, tlbl);
5463 for(;(size--);offset++) {
5465 // result = left & right
5466 if(AOP_TYPE(right) == AOP_LIT){
5467 int t = (lit >> (offset*8)) & 0x0FFL;
5470 pic14_emitcode("clrf","%s",
5471 aopGet(AOP(result),offset,FALSE,FALSE));
5472 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5475 if(AOP_TYPE(left) != AOP_ACC) {
5476 pic14_emitcode("movf","%s,w",
5477 aopGet(AOP(left),offset,FALSE,FALSE));
5478 pic14_emitcode("movwf","%s",
5479 aopGet(AOP(result),offset,FALSE,FALSE));
5480 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5482 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5485 if(AOP_TYPE(left) == AOP_ACC) {
5486 emitpcode(POC_ANDLW, popGetLit(t));
5488 pic14_emitcode("movlw","0x%x",t);
5489 pic14_emitcode("andwf","%s,w",
5490 aopGet(AOP(left),offset,FALSE,FALSE));
5491 pic14_emitcode("movwf","%s",
5492 aopGet(AOP(result),offset,FALSE,FALSE));
5494 emitpcode(POC_MOVLW, popGetLit(t));
5495 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5497 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5502 if (AOP_TYPE(left) == AOP_ACC) {
5503 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5504 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5506 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5507 pic14_emitcode("andwf","%s,w",
5508 aopGet(AOP(left),offset,FALSE,FALSE));
5509 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5510 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5512 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5513 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5519 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5520 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521 freeAsmop(result,NULL,ic,TRUE);
5524 /*-----------------------------------------------------------------*/
5525 /* genOr - code for or */
5526 /*-----------------------------------------------------------------*/
5527 static void genOr (iCode *ic, iCode *ifx)
5529 operand *left, *right, *result;
5531 unsigned long lit = 0L;
5533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5535 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5536 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5537 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5539 DEBUGpic14_AopType(__LINE__,left,right,result);
5541 /* if left is a literal & right is not then exchange them */
5542 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5543 AOP_NEEDSACC(left)) {
5544 operand *tmp = right ;
5549 /* if result = right then exchange them */
5550 if(pic14_sameRegs(AOP(result),AOP(right))){
5551 operand *tmp = right ;
5556 /* if right is bit then exchange them */
5557 if (AOP_TYPE(right) == AOP_CRY &&
5558 AOP_TYPE(left) != AOP_CRY){
5559 operand *tmp = right ;
5564 DEBUGpic14_AopType(__LINE__,left,right,result);
5566 if(AOP_TYPE(right) == AOP_LIT)
5567 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5569 size = AOP_SIZE(result);
5573 if (AOP_TYPE(left) == AOP_CRY){
5574 if(AOP_TYPE(right) == AOP_LIT){
5575 // c = bit & literal;
5577 // lit != 0 => result = 1
5578 if(AOP_TYPE(result) == AOP_CRY){
5580 emitpcode(POC_BSF, popGet(AOP(result),0));
5581 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5582 // AOP(result)->aopu.aop_dir,
5583 // AOP(result)->aopu.aop_dir);
5585 continueIfTrue(ifx);
5589 // lit == 0 => result = left
5590 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5592 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5595 if (AOP_TYPE(right) == AOP_CRY){
5596 if(pic14_sameRegs(AOP(result),AOP(left))){
5598 emitpcode(POC_BCF, popGet(AOP(result),0));
5599 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5600 emitpcode(POC_BSF, popGet(AOP(result),0));
5602 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5603 AOP(result)->aopu.aop_dir,
5604 AOP(result)->aopu.aop_dir);
5605 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5606 AOP(right)->aopu.aop_dir,
5607 AOP(right)->aopu.aop_dir);
5608 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5609 AOP(result)->aopu.aop_dir,
5610 AOP(result)->aopu.aop_dir);
5612 if( AOP_TYPE(result) == AOP_ACC) {
5613 emitpcode(POC_MOVLW, popGetLit(0));
5614 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5615 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5616 emitpcode(POC_MOVLW, popGetLit(1));
5620 emitpcode(POC_BCF, popGet(AOP(result),0));
5621 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5622 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5623 emitpcode(POC_BSF, popGet(AOP(result),0));
5625 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5626 AOP(result)->aopu.aop_dir,
5627 AOP(result)->aopu.aop_dir);
5628 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5629 AOP(right)->aopu.aop_dir,
5630 AOP(right)->aopu.aop_dir);
5631 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5632 AOP(left)->aopu.aop_dir,
5633 AOP(left)->aopu.aop_dir);
5634 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5635 AOP(result)->aopu.aop_dir,
5636 AOP(result)->aopu.aop_dir);
5641 symbol *tlbl = newiTempLabel(NULL);
5642 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5645 emitpcode(POC_BCF, popGet(AOP(result),0));
5646 if( AOP_TYPE(right) == AOP_ACC) {
5647 emitpcode(POC_IORLW, popGetLit(0));
5649 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5650 emitpcode(POC_BSF, popGet(AOP(result),0));
5655 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5656 pic14_emitcode(";XXX setb","c");
5657 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5658 AOP(left)->aopu.aop_dir,tlbl->key+100);
5659 pic14_toBoolean(right);
5660 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5661 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5662 jmpTrueOrFalse(ifx, tlbl);
5666 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5673 pic14_outBitC(result);
5675 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5676 genIfxJump(ifx, "c");
5680 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5681 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5682 if((AOP_TYPE(right) == AOP_LIT) &&
5683 (AOP_TYPE(result) == AOP_CRY) &&
5684 (AOP_TYPE(left) != AOP_CRY)){
5686 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5689 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5691 continueIfTrue(ifx);
5694 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5695 // lit = 0, result = boolean(left)
5697 pic14_emitcode(";XXX setb","c");
5698 pic14_toBoolean(right);
5700 symbol *tlbl = newiTempLabel(NULL);
5701 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5703 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5705 genIfxJump (ifx,"a");
5709 pic14_outBitC(result);
5713 /* if left is same as result */
5714 if(pic14_sameRegs(AOP(result),AOP(left))){
5716 for(;size--; offset++,lit>>=8) {
5717 if(AOP_TYPE(right) == AOP_LIT){
5718 if((lit & 0xff) == 0)
5719 /* or'ing with 0 has no effect */
5722 int p = my_powof2(lit & 0xff);
5724 /* only one bit is set in the literal, so use a bsf instruction */
5726 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5728 if(know_W != (lit & 0xff))
5729 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5730 know_W = lit & 0xff;
5731 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5736 if (AOP_TYPE(left) == AOP_ACC) {
5737 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5738 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5740 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5741 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5743 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5744 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5750 // left & result in different registers
5751 if(AOP_TYPE(result) == AOP_CRY){
5753 // if(size), result in bit
5754 // if(!size && ifx), conditional oper: if(left | right)
5755 symbol *tlbl = newiTempLabel(NULL);
5756 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5757 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5761 pic14_emitcode(";XXX setb","c");
5763 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5764 pic14_emitcode(";XXX orl","a,%s",
5765 aopGet(AOP(left),offset,FALSE,FALSE));
5766 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5771 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5772 pic14_outBitC(result);
5774 jmpTrueOrFalse(ifx, tlbl);
5775 } else for(;(size--);offset++){
5777 // result = left & right
5778 if(AOP_TYPE(right) == AOP_LIT){
5779 int t = (lit >> (offset*8)) & 0x0FFL;
5782 if (AOP_TYPE(left) != AOP_ACC) {
5783 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5785 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5789 if (AOP_TYPE(left) == AOP_ACC) {
5790 emitpcode(POC_IORLW, popGetLit(t));
5792 emitpcode(POC_MOVLW, popGetLit(t));
5793 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5795 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5800 // faster than result <- left, anl result,right
5801 // and better if result is SFR
5802 if (AOP_TYPE(left) == AOP_ACC) {
5803 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5804 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5806 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5807 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5809 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5810 pic14_emitcode("iorwf","%s,w",
5811 aopGet(AOP(left),offset,FALSE,FALSE));
5813 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5814 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5819 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5820 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5821 freeAsmop(result,NULL,ic,TRUE);
5824 /*-----------------------------------------------------------------*/
5825 /* genXor - code for xclusive or */
5826 /*-----------------------------------------------------------------*/
5827 static void genXor (iCode *ic, iCode *ifx)
5829 operand *left, *right, *result;
5831 unsigned long lit = 0L;
5833 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5835 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5836 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5837 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5839 /* if left is a literal & right is not ||
5840 if left needs acc & right does not */
5841 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5842 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5843 operand *tmp = right ;
5848 /* if result = right then exchange them */
5849 if(pic14_sameRegs(AOP(result),AOP(right))){
5850 operand *tmp = right ;
5855 /* if right is bit then exchange them */
5856 if (AOP_TYPE(right) == AOP_CRY &&
5857 AOP_TYPE(left) != AOP_CRY){
5858 operand *tmp = right ;
5862 if(AOP_TYPE(right) == AOP_LIT)
5863 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5865 size = AOP_SIZE(result);
5869 if (AOP_TYPE(left) == AOP_CRY){
5870 if(AOP_TYPE(right) == AOP_LIT){
5871 // c = bit & literal;
5873 // lit>>1 != 0 => result = 1
5874 if(AOP_TYPE(result) == AOP_CRY){
5876 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5877 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5879 continueIfTrue(ifx);
5882 pic14_emitcode("setb","c");
5886 // lit == 0, result = left
5887 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5889 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5891 // lit == 1, result = not(left)
5892 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5893 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5894 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5895 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5898 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5899 pic14_emitcode("cpl","c");
5906 symbol *tlbl = newiTempLabel(NULL);
5907 if (AOP_TYPE(right) == AOP_CRY){
5909 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5912 int sizer = AOP_SIZE(right);
5914 // if val>>1 != 0, result = 1
5915 pic14_emitcode("setb","c");
5917 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5919 // test the msb of the lsb
5920 pic14_emitcode("anl","a,#0xfe");
5921 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5925 pic14_emitcode("rrc","a");
5927 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5928 pic14_emitcode("cpl","c");
5929 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5934 pic14_outBitC(result);
5936 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5937 genIfxJump(ifx, "c");
5941 if(pic14_sameRegs(AOP(result),AOP(left))){
5942 /* if left is same as result */
5943 for(;size--; offset++) {
5944 if(AOP_TYPE(right) == AOP_LIT){
5945 int t = (lit >> (offset*8)) & 0x0FFL;
5949 if (IS_AOP_PREG(left)) {
5950 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5951 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5952 aopPut(AOP(result),"a",offset);
5954 emitpcode(POC_MOVLW, popGetLit(t));
5955 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5956 pic14_emitcode("xrl","%s,%s",
5957 aopGet(AOP(left),offset,FALSE,TRUE),
5958 aopGet(AOP(right),offset,FALSE,FALSE));
5961 if (AOP_TYPE(left) == AOP_ACC)
5962 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5964 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5965 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5967 if (IS_AOP_PREG(left)) {
5968 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5969 aopPut(AOP(result),"a",offset);
5971 pic14_emitcode("xrl","%s,a",
5972 aopGet(AOP(left),offset,FALSE,TRUE));
5978 // left & result in different registers
5979 if(AOP_TYPE(result) == AOP_CRY){
5981 // if(size), result in bit
5982 // if(!size && ifx), conditional oper: if(left ^ right)
5983 symbol *tlbl = newiTempLabel(NULL);
5984 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5986 pic14_emitcode("setb","c");
5988 if((AOP_TYPE(right) == AOP_LIT) &&
5989 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5990 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5992 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5993 pic14_emitcode("xrl","a,%s",
5994 aopGet(AOP(left),offset,FALSE,FALSE));
5996 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6001 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6002 pic14_outBitC(result);
6004 jmpTrueOrFalse(ifx, tlbl);
6005 } else for(;(size--);offset++){
6007 // result = left & right
6008 if(AOP_TYPE(right) == AOP_LIT){
6009 int t = (lit >> (offset*8)) & 0x0FFL;
6012 if (AOP_TYPE(left) != AOP_ACC) {
6013 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6015 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6016 pic14_emitcode("movf","%s,w",
6017 aopGet(AOP(left),offset,FALSE,FALSE));
6018 pic14_emitcode("movwf","%s",
6019 aopGet(AOP(result),offset,FALSE,FALSE));
6022 if (AOP_TYPE(left) == AOP_ACC) {
6023 emitpcode(POC_XORLW, popGetLit(t));
6025 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6027 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6030 if (AOP_TYPE(left) == AOP_ACC) {
6031 emitpcode(POC_XORLW, popGetLit(t));
6033 emitpcode(POC_MOVLW, popGetLit(t));
6034 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6036 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6037 pic14_emitcode("movlw","0x%x",t);
6038 pic14_emitcode("xorwf","%s,w",
6039 aopGet(AOP(left),offset,FALSE,FALSE));
6040 pic14_emitcode("movwf","%s",
6041 aopGet(AOP(result),offset,FALSE,FALSE));
6047 // faster than result <- left, anl result,right
6048 // and better if result is SFR
6049 if (AOP_TYPE(left) == AOP_ACC) {
6050 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6051 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6053 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6054 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6055 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6056 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6058 if ( AOP_TYPE(result) != AOP_ACC){
6059 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6060 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6066 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6068 freeAsmop(result,NULL,ic,TRUE);
6071 /*-----------------------------------------------------------------*/
6072 /* genInline - write the inline code out */
6073 /*-----------------------------------------------------------------*/
6074 static void genInline (iCode *ic)
6076 char *buffer, *bp, *bp1;
6078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6080 _G.inLine += (!options.asmpeep);
6082 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6083 strcpy(buffer,IC_INLINE(ic));
6085 /* emit each line as a code */
6091 addpCode2pBlock(pb,AssembleLine(bp1));
6098 pic14_emitcode(bp1,"");
6104 if ((bp1 != bp) && *bp1)
6105 addpCode2pBlock(pb,AssembleLine(bp1));
6109 _G.inLine -= (!options.asmpeep);
6112 /*-----------------------------------------------------------------*/
6113 /* genRRC - rotate right with carry */
6114 /*-----------------------------------------------------------------*/
6115 static void genRRC (iCode *ic)
6117 operand *left , *result ;
6118 int size, offset = 0, same;
6120 /* rotate right with carry */
6122 result=IC_RESULT(ic);
6123 aopOp (left,ic,FALSE);
6124 aopOp (result,ic,FALSE);
6126 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6128 same = pic14_sameRegs(AOP(result),AOP(left));
6130 size = AOP_SIZE(result);
6132 /* get the lsb and put it into the carry */
6133 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6140 emitpcode(POC_RRF, popGet(AOP(left),offset));
6142 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6143 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6149 freeAsmop(left,NULL,ic,TRUE);
6150 freeAsmop(result,NULL,ic,TRUE);
6153 /*-----------------------------------------------------------------*/
6154 /* genRLC - generate code for rotate left with carry */
6155 /*-----------------------------------------------------------------*/
6156 static void genRLC (iCode *ic)
6158 operand *left , *result ;
6159 int size, offset = 0;
6162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6163 /* rotate right with carry */
6165 result=IC_RESULT(ic);
6166 aopOp (left,ic,FALSE);
6167 aopOp (result,ic,FALSE);
6169 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6171 same = pic14_sameRegs(AOP(result),AOP(left));
6173 /* move it to the result */
6174 size = AOP_SIZE(result);
6176 /* get the msb and put it into the carry */
6177 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6184 emitpcode(POC_RLF, popGet(AOP(left),offset));
6186 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6187 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6194 freeAsmop(left,NULL,ic,TRUE);
6195 freeAsmop(result,NULL,ic,TRUE);
6198 /*-----------------------------------------------------------------*/
6199 /* genGetHbit - generates code get highest order bit */
6200 /*-----------------------------------------------------------------*/
6201 static void genGetHbit (iCode *ic)
6203 operand *left, *result;
6205 result=IC_RESULT(ic);
6206 aopOp (left,ic,FALSE);
6207 aopOp (result,ic,FALSE);
6209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6210 /* get the highest order byte into a */
6211 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6212 if(AOP_TYPE(result) == AOP_CRY){
6213 pic14_emitcode("rlc","a");
6214 pic14_outBitC(result);
6217 pic14_emitcode("rl","a");
6218 pic14_emitcode("anl","a,#0x01");
6219 pic14_outAcc(result);
6223 freeAsmop(left,NULL,ic,TRUE);
6224 freeAsmop(result,NULL,ic,TRUE);
6227 /*-----------------------------------------------------------------*/
6228 /* AccRol - rotate left accumulator by known count */
6229 /*-----------------------------------------------------------------*/
6230 static void AccRol (int shCount)
6232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6233 shCount &= 0x0007; // shCount : 0..7
6238 pic14_emitcode("rl","a");
6241 pic14_emitcode("rl","a");
6242 pic14_emitcode("rl","a");
6245 pic14_emitcode("swap","a");
6246 pic14_emitcode("rr","a");
6249 pic14_emitcode("swap","a");
6252 pic14_emitcode("swap","a");
6253 pic14_emitcode("rl","a");
6256 pic14_emitcode("rr","a");
6257 pic14_emitcode("rr","a");
6260 pic14_emitcode("rr","a");
6265 /*-----------------------------------------------------------------*/
6266 /* AccLsh - left shift accumulator by known count */
6267 /*-----------------------------------------------------------------*/
6268 static void AccLsh (int shCount)
6270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6273 pic14_emitcode("add","a,acc");
6276 pic14_emitcode("add","a,acc");
6277 pic14_emitcode("add","a,acc");
6279 /* rotate left accumulator */
6281 /* and kill the lower order bits */
6282 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6287 /*-----------------------------------------------------------------*/
6288 /* AccRsh - right shift accumulator by known count */
6289 /*-----------------------------------------------------------------*/
6290 static void AccRsh (int shCount)
6292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6296 pic14_emitcode("rrc","a");
6298 /* rotate right accumulator */
6299 AccRol(8 - shCount);
6300 /* and kill the higher order bits */
6301 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6307 /*-----------------------------------------------------------------*/
6308 /* AccSRsh - signed right shift accumulator by known count */
6309 /*-----------------------------------------------------------------*/
6310 static void AccSRsh (int shCount)
6313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6316 pic14_emitcode("mov","c,acc.7");
6317 pic14_emitcode("rrc","a");
6318 } else if(shCount == 2){
6319 pic14_emitcode("mov","c,acc.7");
6320 pic14_emitcode("rrc","a");
6321 pic14_emitcode("mov","c,acc.7");
6322 pic14_emitcode("rrc","a");
6324 tlbl = newiTempLabel(NULL);
6325 /* rotate right accumulator */
6326 AccRol(8 - shCount);
6327 /* and kill the higher order bits */
6328 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6329 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6330 pic14_emitcode("orl","a,#0x%02x",
6331 (unsigned char)~SRMask[shCount]);
6332 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6337 /*-----------------------------------------------------------------*/
6338 /* shiftR1Left2Result - shift right one byte from left to result */
6339 /*-----------------------------------------------------------------*/
6340 static void shiftR1Left2ResultSigned (operand *left, int offl,
6341 operand *result, int offr,
6346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6348 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6352 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6354 emitpcode(POC_RRF, popGet(AOP(result),offr));
6356 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6357 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6363 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6365 emitpcode(POC_RRF, popGet(AOP(result),offr));
6367 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6368 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6370 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6371 emitpcode(POC_RRF, popGet(AOP(result),offr));
6377 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6379 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6380 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6383 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6384 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6385 emitpcode(POC_ANDLW, popGetLit(0x1f));
6387 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6388 emitpcode(POC_IORLW, popGetLit(0xe0));
6390 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6394 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6395 emitpcode(POC_ANDLW, popGetLit(0x0f));
6396 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6397 emitpcode(POC_IORLW, popGetLit(0xf0));
6398 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6402 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6404 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6405 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6407 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6408 emitpcode(POC_ANDLW, popGetLit(0x07));
6409 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6410 emitpcode(POC_IORLW, popGetLit(0xf8));
6411 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416 emitpcode(POC_MOVLW, popGetLit(0x00));
6417 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6418 emitpcode(POC_MOVLW, popGetLit(0xfe));
6419 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6420 emitpcode(POC_IORLW, popGetLit(0x01));
6421 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6424 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6425 emitpcode(POC_DECF, popGet(AOP(result),offr));
6426 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6427 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6433 emitpcode(POC_MOVLW, popGetLit(0x00));
6434 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6435 emitpcode(POC_MOVLW, popGetLit(0xff));
6436 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6439 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6440 emitpcode(POC_DECF, popGet(AOP(result),offr));
6448 /*-----------------------------------------------------------------*/
6449 /* shiftR1Left2Result - shift right one byte from left to result */
6450 /*-----------------------------------------------------------------*/
6451 static void shiftR1Left2Result (operand *left, int offl,
6452 operand *result, int offr,
6453 int shCount, int sign)
6457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6459 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6461 /* Copy the msb into the carry if signed. */
6463 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6473 emitpcode(POC_RRF, popGet(AOP(result),offr));
6475 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6476 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6482 emitpcode(POC_RRF, popGet(AOP(result),offr));
6484 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6485 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6488 emitpcode(POC_RRF, popGet(AOP(result),offr));
6493 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6495 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6496 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6499 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6500 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6501 emitpcode(POC_ANDLW, popGetLit(0x1f));
6502 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6506 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6507 emitpcode(POC_ANDLW, popGetLit(0x0f));
6508 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6512 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6513 emitpcode(POC_ANDLW, popGetLit(0x0f));
6514 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6516 emitpcode(POC_RRF, popGet(AOP(result),offr));
6521 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6522 emitpcode(POC_ANDLW, popGetLit(0x80));
6523 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6524 emitpcode(POC_RLF, popGet(AOP(result),offr));
6525 emitpcode(POC_RLF, popGet(AOP(result),offr));
6530 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6531 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6532 emitpcode(POC_RLF, popGet(AOP(result),offr));
6541 /*-----------------------------------------------------------------*/
6542 /* shiftL1Left2Result - shift left one byte from left to result */
6543 /*-----------------------------------------------------------------*/
6544 static void shiftL1Left2Result (operand *left, int offl,
6545 operand *result, int offr, int shCount)
6550 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6552 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6553 DEBUGpic14_emitcode ("; ***","same = %d",same);
6554 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6556 /* shift left accumulator */
6557 //AccLsh(shCount); // don't comment out just yet...
6558 // aopPut(AOP(result),"a",offr);
6562 /* Shift left 1 bit position */
6563 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6565 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6567 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6568 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6572 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6573 emitpcode(POC_ANDLW,popGetLit(0x7e));
6574 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6575 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6578 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6579 emitpcode(POC_ANDLW,popGetLit(0x3e));
6580 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6581 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6582 emitpcode(POC_RLF, popGet(AOP(result),offr));
6585 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6586 emitpcode(POC_ANDLW, popGetLit(0xf0));
6587 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6590 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6591 emitpcode(POC_ANDLW, popGetLit(0xf0));
6592 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6593 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6596 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6597 emitpcode(POC_ANDLW, popGetLit(0x30));
6598 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6599 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6600 emitpcode(POC_RLF, popGet(AOP(result),offr));
6603 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6604 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6605 emitpcode(POC_RRF, popGet(AOP(result),offr));
6609 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6614 /*-----------------------------------------------------------------*/
6615 /* movLeft2Result - move byte from left to result */
6616 /*-----------------------------------------------------------------*/
6617 static void movLeft2Result (operand *left, int offl,
6618 operand *result, int offr)
6621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6622 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6623 l = aopGet(AOP(left),offl,FALSE,FALSE);
6625 if (*l == '@' && (IS_AOP_PREG(result))) {
6626 pic14_emitcode("mov","a,%s",l);
6627 aopPut(AOP(result),"a",offr);
6629 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6630 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6635 /*-----------------------------------------------------------------*/
6636 /* shiftL2Left2Result - shift left two bytes from left to result */
6637 /*-----------------------------------------------------------------*/
6638 static void shiftL2Left2Result (operand *left, int offl,
6639 operand *result, int offr, int shCount)
6643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6645 if(pic14_sameRegs(AOP(result), AOP(left))) {
6653 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6654 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6655 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6659 emitpcode(POC_RLF, popGet(AOP(result),offr));
6660 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6666 emitpcode(POC_MOVLW, popGetLit(0x0f));
6667 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6669 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6670 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6671 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6672 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_RLF, popGet(AOP(result),offr));
6675 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6679 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_RRF, popGet(AOP(result),offr));
6681 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_RRF, popGet(AOP(result),offr));
6683 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_ANDLW,popGetLit(0xc0));
6685 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6686 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6687 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6688 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6691 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6693 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6694 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6695 emitpcode(POC_RRF, popGet(AOP(result),offr));
6705 /* note, use a mov/add for the shift since the mov has a
6706 chance of getting optimized out */
6707 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6708 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6709 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6710 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6711 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_RLF, popGet(AOP(result),offr));
6716 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6722 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6723 emitpcode(POC_ANDLW, popGetLit(0xF0));
6724 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6725 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6726 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6727 emitpcode(POC_ANDLW, popGetLit(0xF0));
6728 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6729 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6733 emitpcode(POC_RLF, popGet(AOP(result),offr));
6734 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6738 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6739 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6740 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6741 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6743 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_RRF, popGet(AOP(result),offr));
6745 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_ANDLW,popGetLit(0xc0));
6747 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6748 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6749 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6750 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6753 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6754 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6755 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6756 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6757 emitpcode(POC_RRF, popGet(AOP(result),offr));
6762 /*-----------------------------------------------------------------*/
6763 /* shiftR2Left2Result - shift right two bytes from left to result */
6764 /*-----------------------------------------------------------------*/
6765 static void shiftR2Left2Result (operand *left, int offl,
6766 operand *result, int offr,
6767 int shCount, int sign)
6771 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6772 same = pic14_sameRegs(AOP(result), AOP(left));
6774 if(same && ((offl + MSB16) == offr)){
6776 /* don't crash result[offr] */
6777 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6778 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6781 movLeft2Result(left,offl, result, offr);
6782 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6785 /* a:x >> shCount (x = lsb(result))*/
6788 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6790 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6799 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6804 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6805 emitpcode(POC_RRF,popGet(AOP(result),offr));
6807 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6808 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6815 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6818 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6819 emitpcode(POC_RRF,popGet(AOP(result),offr));
6826 emitpcode(POC_MOVLW, popGetLit(0xf0));
6827 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6828 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6830 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6832 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6835 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6836 emitpcode(POC_ANDLW, popGetLit(0x0f));
6837 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6839 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6840 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6841 emitpcode(POC_ANDLW, popGetLit(0xf0));
6842 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6843 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6847 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6848 emitpcode(POC_RRF, popGet(AOP(result),offr));
6852 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6853 emitpcode(POC_BTFSC,
6854 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6855 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6863 emitpcode(POC_RLF, popGet(AOP(result),offr));
6864 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6866 emitpcode(POC_RLF, popGet(AOP(result),offr));
6867 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6868 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6869 emitpcode(POC_ANDLW,popGetLit(0x03));
6871 emitpcode(POC_BTFSC,
6872 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6873 emitpcode(POC_IORLW,popGetLit(0xfc));
6875 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6876 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6878 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6880 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6881 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6882 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6883 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6884 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6885 emitpcode(POC_RLF, popGet(AOP(result),offr));
6886 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6887 emitpcode(POC_ANDLW,popGetLit(0x03));
6889 emitpcode(POC_BTFSC,
6890 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6891 emitpcode(POC_IORLW,popGetLit(0xfc));
6893 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6894 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6901 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6902 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6903 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6904 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6907 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6909 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6914 /*-----------------------------------------------------------------*/
6915 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6916 /*-----------------------------------------------------------------*/
6917 static void shiftLLeftOrResult (operand *left, int offl,
6918 operand *result, int offr, int shCount)
6920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6921 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6922 /* shift left accumulator */
6924 /* or with result */
6925 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6926 /* back to result */
6927 aopPut(AOP(result),"a",offr);
6930 /*-----------------------------------------------------------------*/
6931 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6932 /*-----------------------------------------------------------------*/
6933 static void shiftRLeftOrResult (operand *left, int offl,
6934 operand *result, int offr, int shCount)
6936 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6937 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6938 /* shift right accumulator */
6940 /* or with result */
6941 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6942 /* back to result */
6943 aopPut(AOP(result),"a",offr);
6946 /*-----------------------------------------------------------------*/
6947 /* genlshOne - left shift a one byte quantity by known count */
6948 /*-----------------------------------------------------------------*/
6949 static void genlshOne (operand *result, operand *left, int shCount)
6951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6952 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6955 /*-----------------------------------------------------------------*/
6956 /* genlshTwo - left shift two bytes by known amount != 0 */
6957 /*-----------------------------------------------------------------*/
6958 static void genlshTwo (operand *result,operand *left, int shCount)
6962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6963 size = pic14_getDataSize(result);
6965 /* if shCount >= 8 */
6971 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6973 movLeft2Result(left, LSB, result, MSB16);
6975 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6978 /* 1 <= shCount <= 7 */
6981 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6983 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6987 /*-----------------------------------------------------------------*/
6988 /* shiftLLong - shift left one long from left to result */
6989 /* offl = LSB or MSB16 */
6990 /*-----------------------------------------------------------------*/
6991 static void shiftLLong (operand *left, operand *result, int offr )
6994 int size = AOP_SIZE(result);
6996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6997 if(size >= LSB+offr){
6998 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7000 pic14_emitcode("add","a,acc");
7001 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7002 size >= MSB16+offr && offr != LSB )
7003 pic14_emitcode("xch","a,%s",
7004 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7006 aopPut(AOP(result),"a",LSB+offr);
7009 if(size >= MSB16+offr){
7010 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7011 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7014 pic14_emitcode("rlc","a");
7015 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7016 size >= MSB24+offr && offr != LSB)
7017 pic14_emitcode("xch","a,%s",
7018 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7020 aopPut(AOP(result),"a",MSB16+offr);
7023 if(size >= MSB24+offr){
7024 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7025 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7028 pic14_emitcode("rlc","a");
7029 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7030 size >= MSB32+offr && offr != LSB )
7031 pic14_emitcode("xch","a,%s",
7032 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7034 aopPut(AOP(result),"a",MSB24+offr);
7037 if(size > MSB32+offr){
7038 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7039 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7042 pic14_emitcode("rlc","a");
7043 aopPut(AOP(result),"a",MSB32+offr);
7046 aopPut(AOP(result),zero,LSB);
7049 /*-----------------------------------------------------------------*/
7050 /* genlshFour - shift four byte by a known amount != 0 */
7051 /*-----------------------------------------------------------------*/
7052 static void genlshFour (operand *result, operand *left, int shCount)
7056 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7057 size = AOP_SIZE(result);
7059 /* if shifting more that 3 bytes */
7060 if (shCount >= 24 ) {
7063 /* lowest order of left goes to the highest
7064 order of the destination */
7065 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7067 movLeft2Result(left, LSB, result, MSB32);
7068 aopPut(AOP(result),zero,LSB);
7069 aopPut(AOP(result),zero,MSB16);
7070 aopPut(AOP(result),zero,MSB32);
7074 /* more than two bytes */
7075 else if ( shCount >= 16 ) {
7076 /* lower order two bytes goes to higher order two bytes */
7078 /* if some more remaining */
7080 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7082 movLeft2Result(left, MSB16, result, MSB32);
7083 movLeft2Result(left, LSB, result, MSB24);
7085 aopPut(AOP(result),zero,MSB16);
7086 aopPut(AOP(result),zero,LSB);
7090 /* if more than 1 byte */
7091 else if ( shCount >= 8 ) {
7092 /* lower order three bytes goes to higher order three bytes */
7096 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7098 movLeft2Result(left, LSB, result, MSB16);
7100 else{ /* size = 4 */
7102 movLeft2Result(left, MSB24, result, MSB32);
7103 movLeft2Result(left, MSB16, result, MSB24);
7104 movLeft2Result(left, LSB, result, MSB16);
7105 aopPut(AOP(result),zero,LSB);
7107 else if(shCount == 1)
7108 shiftLLong(left, result, MSB16);
7110 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7111 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7112 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7113 aopPut(AOP(result),zero,LSB);
7118 /* 1 <= shCount <= 7 */
7119 else if(shCount <= 2){
7120 shiftLLong(left, result, LSB);
7122 shiftLLong(result, result, LSB);
7124 /* 3 <= shCount <= 7, optimize */
7126 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7127 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7128 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7132 /*-----------------------------------------------------------------*/
7133 /* genLeftShiftLiteral - left shifting by known count */
7134 /*-----------------------------------------------------------------*/
7135 static void genLeftShiftLiteral (operand *left,
7140 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7144 freeAsmop(right,NULL,ic,TRUE);
7146 aopOp(left,ic,FALSE);
7147 aopOp(result,ic,FALSE);
7149 size = getSize(operandType(result));
7152 pic14_emitcode("; shift left ","result %d, left %d",size,
7156 /* I suppose that the left size >= result size */
7159 movLeft2Result(left, size, result, size);
7163 else if(shCount >= (size * 8))
7165 aopPut(AOP(result),zero,size);
7169 genlshOne (result,left,shCount);
7174 genlshTwo (result,left,shCount);
7178 genlshFour (result,left,shCount);
7182 freeAsmop(left,NULL,ic,TRUE);
7183 freeAsmop(result,NULL,ic,TRUE);
7186 /*-----------------------------------------------------------------*
7187 * genMultiAsm - repeat assembly instruction for size of register.
7188 * if endian == 1, then the high byte (i.e base address + size of
7189 * register) is used first else the low byte is used first;
7190 *-----------------------------------------------------------------*/
7191 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7209 emitpcode(poc, popGet(AOP(reg),offset));
7214 /*-----------------------------------------------------------------*/
7215 /* genLeftShift - generates code for left shifting */
7216 /*-----------------------------------------------------------------*/
7217 static void genLeftShift (iCode *ic)
7219 operand *left,*right, *result;
7222 symbol *tlbl , *tlbl1;
7225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7227 right = IC_RIGHT(ic);
7229 result = IC_RESULT(ic);
7231 aopOp(right,ic,FALSE);
7233 /* if the shift count is known then do it
7234 as efficiently as possible */
7235 if (AOP_TYPE(right) == AOP_LIT) {
7236 genLeftShiftLiteral (left,right,result,ic);
7240 /* shift count is unknown then we have to form
7241 a loop get the loop count in B : Note: we take
7242 only the lower order byte since shifting
7243 more that 32 bits make no sense anyway, ( the
7244 largest size of an object can be only 32 bits ) */
7247 aopOp(left,ic,FALSE);
7248 aopOp(result,ic,FALSE);
7250 /* now move the left to the result if they are not the
7252 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7253 AOP_SIZE(result) > 1) {
7255 size = AOP_SIZE(result);
7258 l = aopGet(AOP(left),offset,FALSE,TRUE);
7259 if (*l == '@' && (IS_AOP_PREG(result))) {
7261 pic14_emitcode("mov","a,%s",l);
7262 aopPut(AOP(result),"a",offset);
7264 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7265 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7266 //aopPut(AOP(result),l,offset);
7272 size = AOP_SIZE(result);
7274 /* if it is only one byte then */
7276 if(optimized_for_speed) {
7277 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7278 emitpcode(POC_ANDLW, popGetLit(0xf0));
7279 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7280 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7281 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7282 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7283 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7284 emitpcode(POC_RLFW, popGet(AOP(result),0));
7285 emitpcode(POC_ANDLW, popGetLit(0xfe));
7286 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7287 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7288 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7291 tlbl = newiTempLabel(NULL);
7292 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7293 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7294 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7297 emitpcode(POC_COMFW, popGet(AOP(right),0));
7298 emitpcode(POC_RRF, popGet(AOP(result),0));
7299 emitpLabel(tlbl->key);
7300 emitpcode(POC_RLF, popGet(AOP(result),0));
7301 emitpcode(POC_ADDLW, popGetLit(1));
7303 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7308 if (pic14_sameRegs(AOP(left),AOP(result))) {
7310 tlbl = newiTempLabel(NULL);
7311 emitpcode(POC_COMFW, popGet(AOP(right),0));
7312 genMultiAsm(POC_RRF, result, size,1);
7313 emitpLabel(tlbl->key);
7314 genMultiAsm(POC_RLF, result, size,0);
7315 emitpcode(POC_ADDLW, popGetLit(1));
7317 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7321 //tlbl = newiTempLabel(NULL);
7323 //tlbl1 = newiTempLabel(NULL);
7325 //reAdjustPreg(AOP(result));
7327 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7328 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7329 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7331 //pic14_emitcode("add","a,acc");
7332 //aopPut(AOP(result),"a",offset++);
7334 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7336 // pic14_emitcode("rlc","a");
7337 // aopPut(AOP(result),"a",offset++);
7339 //reAdjustPreg(AOP(result));
7341 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7342 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7345 tlbl = newiTempLabel(NULL);
7346 tlbl1= newiTempLabel(NULL);
7348 size = AOP_SIZE(result);
7351 pctemp = popGetTempReg(); /* grab a temporary working register. */
7353 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7355 /* offset should be 0, 1 or 3 */
7356 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7358 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7360 emitpcode(POC_MOVWF, pctemp);
7363 emitpLabel(tlbl->key);
7366 emitpcode(POC_RLF, popGet(AOP(result),0));
7368 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7370 emitpcode(POC_DECFSZ, pctemp);
7371 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7372 emitpLabel(tlbl1->key);
7374 popReleaseTempReg(pctemp);
7378 freeAsmop (right,NULL,ic,TRUE);
7379 freeAsmop(left,NULL,ic,TRUE);
7380 freeAsmop(result,NULL,ic,TRUE);
7383 /*-----------------------------------------------------------------*/
7384 /* genrshOne - right shift a one byte quantity by known count */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshOne (operand *result, operand *left,
7387 int shCount, int sign)
7389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7390 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7393 /*-----------------------------------------------------------------*/
7394 /* genrshTwo - right shift two bytes by known amount != 0 */
7395 /*-----------------------------------------------------------------*/
7396 static void genrshTwo (operand *result,operand *left,
7397 int shCount, int sign)
7399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7400 /* if shCount >= 8 */
7404 shiftR1Left2Result(left, MSB16, result, LSB,
7407 movLeft2Result(left, MSB16, result, LSB);
7409 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7412 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7413 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7417 /* 1 <= shCount <= 7 */
7419 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7422 /*-----------------------------------------------------------------*/
7423 /* shiftRLong - shift right one long from left to result */
7424 /* offl = LSB or MSB16 */
7425 /*-----------------------------------------------------------------*/
7426 static void shiftRLong (operand *left, int offl,
7427 operand *result, int sign)
7429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7431 pic14_emitcode("clr","c");
7432 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7434 pic14_emitcode("mov","c,acc.7");
7435 pic14_emitcode("rrc","a");
7436 aopPut(AOP(result),"a",MSB32-offl);
7438 /* add sign of "a" */
7439 addSign(result, MSB32, sign);
7441 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7442 pic14_emitcode("rrc","a");
7443 aopPut(AOP(result),"a",MSB24-offl);
7445 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7446 pic14_emitcode("rrc","a");
7447 aopPut(AOP(result),"a",MSB16-offl);
7450 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7451 pic14_emitcode("rrc","a");
7452 aopPut(AOP(result),"a",LSB);
7456 /*-----------------------------------------------------------------*/
7457 /* genrshFour - shift four byte by a known amount != 0 */
7458 /*-----------------------------------------------------------------*/
7459 static void genrshFour (operand *result, operand *left,
7460 int shCount, int sign)
7462 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7463 /* if shifting more that 3 bytes */
7464 if(shCount >= 24 ) {
7467 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7469 movLeft2Result(left, MSB32, result, LSB);
7471 addSign(result, MSB16, sign);
7473 else if(shCount >= 16){
7476 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7478 movLeft2Result(left, MSB24, result, LSB);
7479 movLeft2Result(left, MSB32, result, MSB16);
7481 addSign(result, MSB24, sign);
7483 else if(shCount >= 8){
7486 shiftRLong(left, MSB16, result, sign);
7487 else if(shCount == 0){
7488 movLeft2Result(left, MSB16, result, LSB);
7489 movLeft2Result(left, MSB24, result, MSB16);
7490 movLeft2Result(left, MSB32, result, MSB24);
7491 addSign(result, MSB32, sign);
7494 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7495 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7496 /* the last shift is signed */
7497 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7498 addSign(result, MSB32, sign);
7501 else{ /* 1 <= shCount <= 7 */
7503 shiftRLong(left, LSB, result, sign);
7505 shiftRLong(result, LSB, result, sign);
7508 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7509 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7510 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7515 /*-----------------------------------------------------------------*/
7516 /* genRightShiftLiteral - right shifting by known count */
7517 /*-----------------------------------------------------------------*/
7518 static void genRightShiftLiteral (operand *left,
7524 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7528 freeAsmop(right,NULL,ic,TRUE);
7530 aopOp(left,ic,FALSE);
7531 aopOp(result,ic,FALSE);
7534 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7538 lsize = pic14_getDataSize(left);
7539 res_size = pic14_getDataSize(result);
7540 /* test the LEFT size !!! */
7542 /* I suppose that the left size >= result size */
7545 movLeft2Result(left, lsize, result, res_size);
7548 else if(shCount >= (lsize * 8)){
7551 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7553 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7554 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7559 emitpcode(POC_MOVLW, popGetLit(0));
7560 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7561 emitpcode(POC_MOVLW, popGetLit(0xff));
7563 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7568 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7575 genrshOne (result,left,shCount,sign);
7579 genrshTwo (result,left,shCount,sign);
7583 genrshFour (result,left,shCount,sign);
7591 freeAsmop(left,NULL,ic,TRUE);
7592 freeAsmop(result,NULL,ic,TRUE);
7595 /*-----------------------------------------------------------------*/
7596 /* genSignedRightShift - right shift of signed number */
7597 /*-----------------------------------------------------------------*/
7598 static void genSignedRightShift (iCode *ic)
7600 operand *right, *left, *result;
7603 symbol *tlbl, *tlbl1 ;
7606 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7608 /* we do it the hard way put the shift count in b
7609 and loop thru preserving the sign */
7610 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7612 right = IC_RIGHT(ic);
7614 result = IC_RESULT(ic);
7616 aopOp(right,ic,FALSE);
7617 aopOp(left,ic,FALSE);
7618 aopOp(result,ic,FALSE);
7621 if ( AOP_TYPE(right) == AOP_LIT) {
7622 genRightShiftLiteral (left,right,result,ic,1);
7625 /* shift count is unknown then we have to form
7626 a loop get the loop count in B : Note: we take
7627 only the lower order byte since shifting
7628 more that 32 bits make no sense anyway, ( the
7629 largest size of an object can be only 32 bits ) */
7631 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7632 //pic14_emitcode("inc","b");
7633 //freeAsmop (right,NULL,ic,TRUE);
7634 //aopOp(left,ic,FALSE);
7635 //aopOp(result,ic,FALSE);
7637 /* now move the left to the result if they are not the
7639 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7640 AOP_SIZE(result) > 1) {
7642 size = AOP_SIZE(result);
7646 l = aopGet(AOP(left),offset,FALSE,TRUE);
7647 if (*l == '@' && IS_AOP_PREG(result)) {
7649 pic14_emitcode("mov","a,%s",l);
7650 aopPut(AOP(result),"a",offset);
7652 aopPut(AOP(result),l,offset);
7654 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7655 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7661 /* mov the highest order bit to OVR */
7662 tlbl = newiTempLabel(NULL);
7663 tlbl1= newiTempLabel(NULL);
7665 size = AOP_SIZE(result);
7668 pctemp = popGetTempReg(); /* grab a temporary working register. */
7670 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7672 /* offset should be 0, 1 or 3 */
7673 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7675 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7677 emitpcode(POC_MOVWF, pctemp);
7680 emitpLabel(tlbl->key);
7682 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7683 emitpcode(POC_RRF, popGet(AOP(result),offset));
7686 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7689 emitpcode(POC_DECFSZ, pctemp);
7690 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7691 emitpLabel(tlbl1->key);
7693 popReleaseTempReg(pctemp);
7695 size = AOP_SIZE(result);
7697 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7698 pic14_emitcode("rlc","a");
7699 pic14_emitcode("mov","ov,c");
7700 /* if it is only one byte then */
7702 l = aopGet(AOP(left),0,FALSE,FALSE);
7704 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7706 pic14_emitcode("mov","c,ov");
7707 pic14_emitcode("rrc","a");
7708 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7709 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7710 aopPut(AOP(result),"a",0);
7714 reAdjustPreg(AOP(result));
7715 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7716 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7717 pic14_emitcode("mov","c,ov");
7719 l = aopGet(AOP(result),offset,FALSE,FALSE);
7721 pic14_emitcode("rrc","a");
7722 aopPut(AOP(result),"a",offset--);
7724 reAdjustPreg(AOP(result));
7725 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7726 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7731 freeAsmop(left,NULL,ic,TRUE);
7732 freeAsmop(result,NULL,ic,TRUE);
7733 freeAsmop(right,NULL,ic,TRUE);
7736 /*-----------------------------------------------------------------*/
7737 /* genRightShift - generate code for right shifting */
7738 /*-----------------------------------------------------------------*/
7739 static void genRightShift (iCode *ic)
7741 operand *right, *left, *result;
7745 symbol *tlbl, *tlbl1 ;
7747 /* if signed then we do it the hard way preserve the
7748 sign bit moving it inwards */
7749 retype = getSpec(operandType(IC_RESULT(ic)));
7750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7752 if (!SPEC_USIGN(retype)) {
7753 genSignedRightShift (ic);
7757 /* signed & unsigned types are treated the same : i.e. the
7758 signed is NOT propagated inwards : quoting from the
7759 ANSI - standard : "for E1 >> E2, is equivalent to division
7760 by 2**E2 if unsigned or if it has a non-negative value,
7761 otherwise the result is implementation defined ", MY definition
7762 is that the sign does not get propagated */
7764 right = IC_RIGHT(ic);
7766 result = IC_RESULT(ic);
7768 aopOp(right,ic,FALSE);
7770 /* if the shift count is known then do it
7771 as efficiently as possible */
7772 if (AOP_TYPE(right) == AOP_LIT) {
7773 genRightShiftLiteral (left,right,result,ic, 0);
7777 /* shift count is unknown then we have to form
7778 a loop get the loop count in B : Note: we take
7779 only the lower order byte since shifting
7780 more that 32 bits make no sense anyway, ( the
7781 largest size of an object can be only 32 bits ) */
7783 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7784 pic14_emitcode("inc","b");
7785 aopOp(left,ic,FALSE);
7786 aopOp(result,ic,FALSE);
7788 /* now move the left to the result if they are not the
7790 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7791 AOP_SIZE(result) > 1) {
7793 size = AOP_SIZE(result);
7796 l = aopGet(AOP(left),offset,FALSE,TRUE);
7797 if (*l == '@' && IS_AOP_PREG(result)) {
7799 pic14_emitcode("mov","a,%s",l);
7800 aopPut(AOP(result),"a",offset);
7802 aopPut(AOP(result),l,offset);
7807 tlbl = newiTempLabel(NULL);
7808 tlbl1= newiTempLabel(NULL);
7809 size = AOP_SIZE(result);
7812 /* if it is only one byte then */
7815 tlbl = newiTempLabel(NULL);
7816 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7817 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7818 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7821 emitpcode(POC_COMFW, popGet(AOP(right),0));
7822 emitpcode(POC_RLF, popGet(AOP(result),0));
7823 emitpLabel(tlbl->key);
7824 emitpcode(POC_RRF, popGet(AOP(result),0));
7825 emitpcode(POC_ADDLW, popGetLit(1));
7827 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7832 reAdjustPreg(AOP(result));
7833 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7834 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7837 l = aopGet(AOP(result),offset,FALSE,FALSE);
7839 pic14_emitcode("rrc","a");
7840 aopPut(AOP(result),"a",offset--);
7842 reAdjustPreg(AOP(result));
7844 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7845 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7848 freeAsmop(left,NULL,ic,TRUE);
7849 freeAsmop (right,NULL,ic,TRUE);
7850 freeAsmop(result,NULL,ic,TRUE);
7853 /*-----------------------------------------------------------------*/
7854 /* genUnpackBits - generates code for unpacking bits */
7855 /*-----------------------------------------------------------------*/
7856 static void genUnpackBits (operand *result, char *rname, int ptype)
7863 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7864 etype = getSpec(operandType(result));
7866 /* read the first byte */
7871 pic14_emitcode("mov","a,@%s",rname);
7875 pic14_emitcode("movx","a,@%s",rname);
7879 pic14_emitcode("movx","a,@dptr");
7883 pic14_emitcode("clr","a");
7884 pic14_emitcode("movc","a","@a+dptr");
7888 pic14_emitcode("lcall","__gptrget");
7892 /* if we have bitdisplacement then it fits */
7893 /* into this byte completely or if length is */
7894 /* less than a byte */
7895 if ((shCnt = SPEC_BSTR(etype)) ||
7896 (SPEC_BLEN(etype) <= 8)) {
7898 /* shift right acc */
7901 pic14_emitcode("anl","a,#0x%02x",
7902 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7903 aopPut(AOP(result),"a",offset);
7907 /* bit field did not fit in a byte */
7908 rlen = SPEC_BLEN(etype) - 8;
7909 aopPut(AOP(result),"a",offset++);
7916 pic14_emitcode("inc","%s",rname);
7917 pic14_emitcode("mov","a,@%s",rname);
7921 pic14_emitcode("inc","%s",rname);
7922 pic14_emitcode("movx","a,@%s",rname);
7926 pic14_emitcode("inc","dptr");
7927 pic14_emitcode("movx","a,@dptr");
7931 pic14_emitcode("clr","a");
7932 pic14_emitcode("inc","dptr");
7933 pic14_emitcode("movc","a","@a+dptr");
7937 pic14_emitcode("inc","dptr");
7938 pic14_emitcode("lcall","__gptrget");
7943 /* if we are done */
7947 aopPut(AOP(result),"a",offset++);
7952 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7953 aopPut(AOP(result),"a",offset);
7960 /*-----------------------------------------------------------------*/
7961 /* genDataPointerGet - generates code when ptr offset is known */
7962 /*-----------------------------------------------------------------*/
7963 static void genDataPointerGet (operand *left,
7967 int size , offset = 0;
7970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7973 /* optimization - most of the time, left and result are the same
7974 * address, but different types. for the pic code, we could omit
7978 aopOp(result,ic,TRUE);
7980 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7982 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7984 size = AOP_SIZE(result);
7987 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7991 freeAsmop(left,NULL,ic,TRUE);
7992 freeAsmop(result,NULL,ic,TRUE);
7995 /*-----------------------------------------------------------------*/
7996 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7997 /*-----------------------------------------------------------------*/
7998 static void genNearPointerGet (operand *left,
8003 //regs *preg = NULL ;
8005 sym_link *rtype, *retype;
8006 sym_link *ltype = operandType(left);
8009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8011 rtype = operandType(result);
8012 retype= getSpec(rtype);
8014 aopOp(left,ic,FALSE);
8016 /* if left is rematerialisable and
8017 result is not bit variable type and
8018 the left is pointer to data space i.e
8019 lower 128 bytes of space */
8020 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8021 !IS_BITVAR(retype) &&
8022 DCL_TYPE(ltype) == POINTER) {
8023 //genDataPointerGet (left,result,ic);
8027 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8029 /* if the value is already in a pointer register
8030 then don't need anything more */
8031 if (!AOP_INPREG(AOP(left))) {
8032 /* otherwise get a free pointer register */
8033 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8036 preg = getFreePtr(ic,&aop,FALSE);
8037 pic14_emitcode("mov","%s,%s",
8039 aopGet(AOP(left),0,FALSE,TRUE));
8040 rname = preg->name ;
8044 rname = aopGet(AOP(left),0,FALSE,FALSE);
8046 aopOp (result,ic,FALSE);
8048 /* if bitfield then unpack the bits */
8049 if (IS_BITVAR(retype))
8050 genUnpackBits (result,rname,POINTER);
8052 /* we have can just get the values */
8053 int size = AOP_SIZE(result);
8056 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8058 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8059 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8061 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8062 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8064 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8068 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8070 pic14_emitcode("mov","a,@%s",rname);
8071 aopPut(AOP(result),"a",offset);
8073 sprintf(buffer,"@%s",rname);
8074 aopPut(AOP(result),buffer,offset);
8078 pic14_emitcode("inc","%s",rname);
8083 /* now some housekeeping stuff */
8085 /* we had to allocate for this iCode */
8086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8087 freeAsmop(NULL,aop,ic,TRUE);
8089 /* we did not allocate which means left
8090 already in a pointer register, then
8091 if size > 0 && this could be used again
8092 we have to point it back to where it
8094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8095 if (AOP_SIZE(result) > 1 &&
8096 !OP_SYMBOL(left)->remat &&
8097 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8099 int size = AOP_SIZE(result) - 1;
8101 pic14_emitcode("dec","%s",rname);
8106 freeAsmop(left,NULL,ic,TRUE);
8107 freeAsmop(result,NULL,ic,TRUE);
8111 /*-----------------------------------------------------------------*/
8112 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8113 /*-----------------------------------------------------------------*/
8114 static void genPagedPointerGet (operand *left,
8121 sym_link *rtype, *retype;
8123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8125 rtype = operandType(result);
8126 retype= getSpec(rtype);
8128 aopOp(left,ic,FALSE);
8130 /* if the value is already in a pointer register
8131 then don't need anything more */
8132 if (!AOP_INPREG(AOP(left))) {
8133 /* otherwise get a free pointer register */
8135 preg = getFreePtr(ic,&aop,FALSE);
8136 pic14_emitcode("mov","%s,%s",
8138 aopGet(AOP(left),0,FALSE,TRUE));
8139 rname = preg->name ;
8141 rname = aopGet(AOP(left),0,FALSE,FALSE);
8143 freeAsmop(left,NULL,ic,TRUE);
8144 aopOp (result,ic,FALSE);
8146 /* if bitfield then unpack the bits */
8147 if (IS_BITVAR(retype))
8148 genUnpackBits (result,rname,PPOINTER);
8150 /* we have can just get the values */
8151 int size = AOP_SIZE(result);
8156 pic14_emitcode("movx","a,@%s",rname);
8157 aopPut(AOP(result),"a",offset);
8162 pic14_emitcode("inc","%s",rname);
8166 /* now some housekeeping stuff */
8168 /* we had to allocate for this iCode */
8169 freeAsmop(NULL,aop,ic,TRUE);
8171 /* we did not allocate which means left
8172 already in a pointer register, then
8173 if size > 0 && this could be used again
8174 we have to point it back to where it
8176 if (AOP_SIZE(result) > 1 &&
8177 !OP_SYMBOL(left)->remat &&
8178 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8180 int size = AOP_SIZE(result) - 1;
8182 pic14_emitcode("dec","%s",rname);
8187 freeAsmop(result,NULL,ic,TRUE);
8192 /*-----------------------------------------------------------------*/
8193 /* genFarPointerGet - gget value from far space */
8194 /*-----------------------------------------------------------------*/
8195 static void genFarPointerGet (operand *left,
8196 operand *result, iCode *ic)
8199 sym_link *retype = getSpec(operandType(result));
8201 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8203 aopOp(left,ic,FALSE);
8205 /* if the operand is already in dptr
8206 then we do nothing else we move the value to dptr */
8207 if (AOP_TYPE(left) != AOP_STR) {
8208 /* if this is remateriazable */
8209 if (AOP_TYPE(left) == AOP_IMMD)
8210 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8211 else { /* we need to get it byte by byte */
8212 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8213 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8214 if (options.model == MODEL_FLAT24)
8216 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8220 /* so dptr know contains the address */
8221 freeAsmop(left,NULL,ic,TRUE);
8222 aopOp(result,ic,FALSE);
8224 /* if bit then unpack */
8225 if (IS_BITVAR(retype))
8226 genUnpackBits(result,"dptr",FPOINTER);
8228 size = AOP_SIZE(result);
8232 pic14_emitcode("movx","a,@dptr");
8233 aopPut(AOP(result),"a",offset++);
8235 pic14_emitcode("inc","dptr");
8239 freeAsmop(result,NULL,ic,TRUE);
8242 /*-----------------------------------------------------------------*/
8243 /* genCodePointerGet - get value from code space */
8244 /*-----------------------------------------------------------------*/
8245 static void genCodePointerGet (operand *left,
8246 operand *result, iCode *ic)
8249 sym_link *retype = getSpec(operandType(result));
8251 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8253 aopOp(left,ic,FALSE);
8255 /* if the operand is already in dptr
8256 then we do nothing else we move the value to dptr */
8257 if (AOP_TYPE(left) != AOP_STR) {
8258 /* if this is remateriazable */
8259 if (AOP_TYPE(left) == AOP_IMMD)
8260 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8261 else { /* we need to get it byte by byte */
8262 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8263 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8264 if (options.model == MODEL_FLAT24)
8266 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8270 /* so dptr know contains the address */
8271 freeAsmop(left,NULL,ic,TRUE);
8272 aopOp(result,ic,FALSE);
8274 /* if bit then unpack */
8275 if (IS_BITVAR(retype))
8276 genUnpackBits(result,"dptr",CPOINTER);
8278 size = AOP_SIZE(result);
8282 pic14_emitcode("clr","a");
8283 pic14_emitcode("movc","a,@a+dptr");
8284 aopPut(AOP(result),"a",offset++);
8286 pic14_emitcode("inc","dptr");
8290 freeAsmop(result,NULL,ic,TRUE);
8293 /*-----------------------------------------------------------------*/
8294 /* genGenPointerGet - gget value from generic pointer space */
8295 /*-----------------------------------------------------------------*/
8296 static void genGenPointerGet (operand *left,
8297 operand *result, iCode *ic)
8300 sym_link *retype = getSpec(operandType(result));
8302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8303 aopOp(left,ic,FALSE);
8304 aopOp(result,ic,FALSE);
8307 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8309 /* if the operand is already in dptr
8310 then we do nothing else we move the value to dptr */
8311 // if (AOP_TYPE(left) != AOP_STR) {
8312 /* if this is remateriazable */
8313 if (AOP_TYPE(left) == AOP_IMMD) {
8314 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8315 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8317 else { /* we need to get it byte by byte */
8319 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8320 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8322 size = AOP_SIZE(result);
8326 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8327 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8329 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8334 /* so dptr know contains the address */
8336 /* if bit then unpack */
8337 //if (IS_BITVAR(retype))
8338 // genUnpackBits(result,"dptr",GPOINTER);
8341 freeAsmop(left,NULL,ic,TRUE);
8342 freeAsmop(result,NULL,ic,TRUE);
8346 /*-----------------------------------------------------------------*/
8347 /* genConstPointerGet - get value from const generic pointer space */
8348 /*-----------------------------------------------------------------*/
8349 static void genConstPointerGet (operand *left,
8350 operand *result, iCode *ic)
8352 //sym_link *retype = getSpec(operandType(result));
8353 symbol *albl = newiTempLabel(NULL);
8354 symbol *blbl = newiTempLabel(NULL);
8357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8358 aopOp(left,ic,FALSE);
8359 aopOp(result,ic,FALSE);
8362 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8364 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8366 emitpcode(POC_CALL,popGetLabel(albl->key));
8367 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8368 emitpLabel(albl->key);
8370 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8372 emitpcode(poc,popGet(AOP(left),1));
8373 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8374 emitpcode(poc,popGet(AOP(left),0));
8375 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8377 emitpLabel(blbl->key);
8379 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8382 freeAsmop(left,NULL,ic,TRUE);
8383 freeAsmop(result,NULL,ic,TRUE);
8386 /*-----------------------------------------------------------------*/
8387 /* genPointerGet - generate code for pointer get */
8388 /*-----------------------------------------------------------------*/
8389 static void genPointerGet (iCode *ic)
8391 operand *left, *result ;
8392 sym_link *type, *etype;
8395 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8398 result = IC_RESULT(ic) ;
8400 /* depending on the type of pointer we need to
8401 move it to the correct pointer register */
8402 type = operandType(left);
8403 etype = getSpec(type);
8405 if (IS_PTR_CONST(type))
8406 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8408 /* if left is of type of pointer then it is simple */
8409 if (IS_PTR(type) && !IS_FUNC(type->next))
8410 p_type = DCL_TYPE(type);
8412 /* we have to go by the storage class */
8413 p_type = PTR_TYPE(SPEC_OCLS(etype));
8415 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8417 if (SPEC_OCLS(etype)->codesp ) {
8418 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8419 //p_type = CPOINTER ;
8422 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8423 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8424 /*p_type = FPOINTER ;*/
8426 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8427 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8428 /* p_type = PPOINTER; */
8430 if (SPEC_OCLS(etype) == idata )
8431 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8432 /* p_type = IPOINTER; */
8434 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8435 /* p_type = POINTER ; */
8438 /* now that we have the pointer type we assign
8439 the pointer values */
8444 genNearPointerGet (left,result,ic);
8448 genPagedPointerGet(left,result,ic);
8452 genFarPointerGet (left,result,ic);
8456 genConstPointerGet (left,result,ic);
8457 //pic14_emitcodePointerGet (left,result,ic);
8461 if (IS_PTR_CONST(type))
8462 genConstPointerGet (left,result,ic);
8464 genGenPointerGet (left,result,ic);
8470 /*-----------------------------------------------------------------*/
8471 /* genPackBits - generates code for packed bit storage */
8472 /*-----------------------------------------------------------------*/
8473 static void genPackBits (sym_link *etype ,
8475 char *rname, int p_type)
8483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8484 blen = SPEC_BLEN(etype);
8485 bstr = SPEC_BSTR(etype);
8487 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8490 /* if the bit lenth is less than or */
8491 /* it exactly fits a byte then */
8492 if (SPEC_BLEN(etype) <= 8 ) {
8493 shCount = SPEC_BSTR(etype) ;
8495 /* shift left acc */
8498 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8503 pic14_emitcode ("mov","b,a");
8504 pic14_emitcode("mov","a,@%s",rname);
8508 pic14_emitcode ("mov","b,a");
8509 pic14_emitcode("movx","a,@dptr");
8513 pic14_emitcode ("push","b");
8514 pic14_emitcode ("push","acc");
8515 pic14_emitcode ("lcall","__gptrget");
8516 pic14_emitcode ("pop","b");
8520 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8521 ((unsigned char)(0xFF << (blen+bstr)) |
8522 (unsigned char)(0xFF >> (8-bstr)) ) );
8523 pic14_emitcode ("orl","a,b");
8524 if (p_type == GPOINTER)
8525 pic14_emitcode("pop","b");
8531 pic14_emitcode("mov","@%s,a",rname);
8535 pic14_emitcode("movx","@dptr,a");
8539 DEBUGpic14_emitcode(";lcall","__gptrput");
8544 if ( SPEC_BLEN(etype) <= 8 )
8547 pic14_emitcode("inc","%s",rname);
8548 rLen = SPEC_BLEN(etype) ;
8550 /* now generate for lengths greater than one byte */
8553 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8563 pic14_emitcode("mov","@%s,a",rname);
8565 pic14_emitcode("mov","@%s,%s",rname,l);
8570 pic14_emitcode("movx","@dptr,a");
8575 DEBUGpic14_emitcode(";lcall","__gptrput");
8578 pic14_emitcode ("inc","%s",rname);
8583 /* last last was not complete */
8585 /* save the byte & read byte */
8588 pic14_emitcode ("mov","b,a");
8589 pic14_emitcode("mov","a,@%s",rname);
8593 pic14_emitcode ("mov","b,a");
8594 pic14_emitcode("movx","a,@dptr");
8598 pic14_emitcode ("push","b");
8599 pic14_emitcode ("push","acc");
8600 pic14_emitcode ("lcall","__gptrget");
8601 pic14_emitcode ("pop","b");
8605 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8606 pic14_emitcode ("orl","a,b");
8609 if (p_type == GPOINTER)
8610 pic14_emitcode("pop","b");
8615 pic14_emitcode("mov","@%s,a",rname);
8619 pic14_emitcode("movx","@dptr,a");
8623 DEBUGpic14_emitcode(";lcall","__gptrput");
8627 /*-----------------------------------------------------------------*/
8628 /* genDataPointerSet - remat pointer to data space */
8629 /*-----------------------------------------------------------------*/
8630 static void genDataPointerSet(operand *right,
8634 int size, offset = 0 ;
8635 char *l, buffer[256];
8637 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8638 aopOp(right,ic,FALSE);
8640 l = aopGet(AOP(result),0,FALSE,TRUE);
8641 size = AOP_SIZE(right);
8643 if ( AOP_TYPE(result) == AOP_PCODE) {
8644 fprintf(stderr,"genDataPointerSet %s, %d\n",
8645 AOP(result)->aopu.pcop->name,
8646 PCOI(AOP(result)->aopu.pcop)->offset);
8650 // tsd, was l+1 - the underline `_' prefix was being stripped
8653 sprintf(buffer,"(%s + %d)",l,offset);
8654 fprintf(stderr,"oops %s\n",buffer);
8656 sprintf(buffer,"%s",l);
8658 if (AOP_TYPE(right) == AOP_LIT) {
8659 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8660 lit = lit >> (8*offset);
8662 pic14_emitcode("movlw","%d",lit);
8663 pic14_emitcode("movwf","%s",buffer);
8665 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8666 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8667 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8670 pic14_emitcode("clrf","%s",buffer);
8671 //emitpcode(POC_CLRF, popRegFromString(buffer));
8672 emitpcode(POC_CLRF, popGet(AOP(result),0));
8675 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8676 pic14_emitcode("movwf","%s",buffer);
8678 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8679 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8680 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8687 freeAsmop(right,NULL,ic,TRUE);
8688 freeAsmop(result,NULL,ic,TRUE);
8691 /*-----------------------------------------------------------------*/
8692 /* genNearPointerSet - pic14_emitcode for near pointer put */
8693 /*-----------------------------------------------------------------*/
8694 static void genNearPointerSet (operand *right,
8701 sym_link *ptype = operandType(result);
8704 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8705 retype= getSpec(operandType(right));
8707 aopOp(result,ic,FALSE);
8710 /* if the result is rematerializable &
8711 in data space & not a bit variable */
8712 //if (AOP_TYPE(result) == AOP_IMMD &&
8713 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8714 DCL_TYPE(ptype) == POINTER &&
8715 !IS_BITVAR(retype)) {
8716 genDataPointerSet (right,result,ic);
8717 freeAsmop(result,NULL,ic,TRUE);
8721 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8722 aopOp(right,ic,FALSE);
8723 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8725 /* if the value is already in a pointer register
8726 then don't need anything more */
8727 if (!AOP_INPREG(AOP(result))) {
8728 /* otherwise get a free pointer register */
8729 //aop = newAsmop(0);
8730 //preg = getFreePtr(ic,&aop,FALSE);
8731 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8732 //pic14_emitcode("mov","%s,%s",
8734 // aopGet(AOP(result),0,FALSE,TRUE));
8735 //rname = preg->name ;
8736 //pic14_emitcode("movwf","fsr");
8737 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8738 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8739 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8740 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8744 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8747 /* if bitfield then unpack the bits */
8748 if (IS_BITVAR(retype)) {
8749 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8750 "The programmer is obviously confused");
8751 //genPackBits (retype,right,rname,POINTER);
8755 /* we have can just get the values */
8756 int size = AOP_SIZE(right);
8759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8761 l = aopGet(AOP(right),offset,FALSE,TRUE);
8764 //pic14_emitcode("mov","@%s,a",rname);
8765 pic14_emitcode("movf","indf,w ;1");
8768 if (AOP_TYPE(right) == AOP_LIT) {
8769 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8771 pic14_emitcode("movlw","%s",l);
8772 pic14_emitcode("movwf","indf ;2");
8774 pic14_emitcode("clrf","indf");
8776 pic14_emitcode("movf","%s,w",l);
8777 pic14_emitcode("movwf","indf ;2");
8779 //pic14_emitcode("mov","@%s,%s",rname,l);
8782 pic14_emitcode("incf","fsr,f ;3");
8783 //pic14_emitcode("inc","%s",rname);
8788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8789 /* now some housekeeping stuff */
8791 /* we had to allocate for this iCode */
8792 freeAsmop(NULL,aop,ic,TRUE);
8794 /* we did not allocate which means left
8795 already in a pointer register, then
8796 if size > 0 && this could be used again
8797 we have to point it back to where it
8799 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8800 if (AOP_SIZE(right) > 1 &&
8801 !OP_SYMBOL(result)->remat &&
8802 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8804 int size = AOP_SIZE(right) - 1;
8806 pic14_emitcode("decf","fsr,f");
8807 //pic14_emitcode("dec","%s",rname);
8811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8814 freeAsmop(right,NULL,ic,TRUE);
8815 freeAsmop(result,NULL,ic,TRUE);
8818 /*-----------------------------------------------------------------*/
8819 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8820 /*-----------------------------------------------------------------*/
8821 static void genPagedPointerSet (operand *right,
8830 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8832 retype= getSpec(operandType(right));
8834 aopOp(result,ic,FALSE);
8836 /* if the value is already in a pointer register
8837 then don't need anything more */
8838 if (!AOP_INPREG(AOP(result))) {
8839 /* otherwise get a free pointer register */
8841 preg = getFreePtr(ic,&aop,FALSE);
8842 pic14_emitcode("mov","%s,%s",
8844 aopGet(AOP(result),0,FALSE,TRUE));
8845 rname = preg->name ;
8847 rname = aopGet(AOP(result),0,FALSE,FALSE);
8849 freeAsmop(result,NULL,ic,TRUE);
8850 aopOp (right,ic,FALSE);
8852 /* if bitfield then unpack the bits */
8853 if (IS_BITVAR(retype))
8854 genPackBits (retype,right,rname,PPOINTER);
8856 /* we have can just get the values */
8857 int size = AOP_SIZE(right);
8861 l = aopGet(AOP(right),offset,FALSE,TRUE);
8864 pic14_emitcode("movx","@%s,a",rname);
8867 pic14_emitcode("inc","%s",rname);
8873 /* now some housekeeping stuff */
8875 /* we had to allocate for this iCode */
8876 freeAsmop(NULL,aop,ic,TRUE);
8878 /* we did not allocate which means left
8879 already in a pointer register, then
8880 if size > 0 && this could be used again
8881 we have to point it back to where it
8883 if (AOP_SIZE(right) > 1 &&
8884 !OP_SYMBOL(result)->remat &&
8885 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8887 int size = AOP_SIZE(right) - 1;
8889 pic14_emitcode("dec","%s",rname);
8894 freeAsmop(right,NULL,ic,TRUE);
8899 /*-----------------------------------------------------------------*/
8900 /* genFarPointerSet - set value from far space */
8901 /*-----------------------------------------------------------------*/
8902 static void genFarPointerSet (operand *right,
8903 operand *result, iCode *ic)
8906 sym_link *retype = getSpec(operandType(right));
8908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8909 aopOp(result,ic,FALSE);
8911 /* if the operand is already in dptr
8912 then we do nothing else we move the value to dptr */
8913 if (AOP_TYPE(result) != AOP_STR) {
8914 /* if this is remateriazable */
8915 if (AOP_TYPE(result) == AOP_IMMD)
8916 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8917 else { /* we need to get it byte by byte */
8918 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8919 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8920 if (options.model == MODEL_FLAT24)
8922 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8926 /* so dptr know contains the address */
8927 freeAsmop(result,NULL,ic,TRUE);
8928 aopOp(right,ic,FALSE);
8930 /* if bit then unpack */
8931 if (IS_BITVAR(retype))
8932 genPackBits(retype,right,"dptr",FPOINTER);
8934 size = AOP_SIZE(right);
8938 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8940 pic14_emitcode("movx","@dptr,a");
8942 pic14_emitcode("inc","dptr");
8946 freeAsmop(right,NULL,ic,TRUE);
8949 /*-----------------------------------------------------------------*/
8950 /* genGenPointerSet - set value from generic pointer space */
8951 /*-----------------------------------------------------------------*/
8952 static void genGenPointerSet (operand *right,
8953 operand *result, iCode *ic)
8956 sym_link *retype = getSpec(operandType(right));
8958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8960 aopOp(result,ic,FALSE);
8961 aopOp(right,ic,FALSE);
8962 size = AOP_SIZE(right);
8964 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8966 /* if the operand is already in dptr
8967 then we do nothing else we move the value to dptr */
8968 if (AOP_TYPE(result) != AOP_STR) {
8969 /* if this is remateriazable */
8970 if (AOP_TYPE(result) == AOP_IMMD) {
8971 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8972 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8974 else { /* we need to get it byte by byte */
8975 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8976 size = AOP_SIZE(right);
8979 /* hack hack! see if this the FSR. If so don't load W */
8980 if(AOP_TYPE(right) != AOP_ACC) {
8983 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8984 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8986 if(AOP_SIZE(result) > 1) {
8987 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8988 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8989 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8994 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8996 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8997 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9001 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9002 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9005 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9012 if(aopIdx(AOP(result),0) != 4) {
9014 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9018 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9023 /* so dptr know contains the address */
9026 /* if bit then unpack */
9027 if (IS_BITVAR(retype))
9028 genPackBits(retype,right,"dptr",GPOINTER);
9030 size = AOP_SIZE(right);
9033 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9037 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9038 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9040 if (AOP_TYPE(right) == AOP_LIT)
9041 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9043 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9045 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9052 freeAsmop(right,NULL,ic,TRUE);
9053 freeAsmop(result,NULL,ic,TRUE);
9056 /*-----------------------------------------------------------------*/
9057 /* genPointerSet - stores the value into a pointer location */
9058 /*-----------------------------------------------------------------*/
9059 static void genPointerSet (iCode *ic)
9061 operand *right, *result ;
9062 sym_link *type, *etype;
9065 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9067 right = IC_RIGHT(ic);
9068 result = IC_RESULT(ic) ;
9070 /* depending on the type of pointer we need to
9071 move it to the correct pointer register */
9072 type = operandType(result);
9073 etype = getSpec(type);
9074 /* if left is of type of pointer then it is simple */
9075 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9076 p_type = DCL_TYPE(type);
9079 /* we have to go by the storage class */
9080 p_type = PTR_TYPE(SPEC_OCLS(etype));
9082 /* if (SPEC_OCLS(etype)->codesp ) { */
9083 /* p_type = CPOINTER ; */
9086 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9087 /* p_type = FPOINTER ; */
9089 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9090 /* p_type = PPOINTER ; */
9092 /* if (SPEC_OCLS(etype) == idata ) */
9093 /* p_type = IPOINTER ; */
9095 /* p_type = POINTER ; */
9098 /* now that we have the pointer type we assign
9099 the pointer values */
9104 genNearPointerSet (right,result,ic);
9108 genPagedPointerSet (right,result,ic);
9112 genFarPointerSet (right,result,ic);
9116 genGenPointerSet (right,result,ic);
9120 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9121 "genPointerSet: illegal pointer type");
9125 /*-----------------------------------------------------------------*/
9126 /* genIfx - generate code for Ifx statement */
9127 /*-----------------------------------------------------------------*/
9128 static void genIfx (iCode *ic, iCode *popIc)
9130 operand *cond = IC_COND(ic);
9133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9135 aopOp(cond,ic,FALSE);
9137 /* get the value into acc */
9138 if (AOP_TYPE(cond) != AOP_CRY)
9139 pic14_toBoolean(cond);
9142 /* the result is now in the accumulator */
9143 freeAsmop(cond,NULL,ic,TRUE);
9145 /* if there was something to be popped then do it */
9149 /* if the condition is a bit variable */
9150 if (isbit && IS_ITEMP(cond) &&
9152 genIfxJump(ic,SPIL_LOC(cond)->rname);
9153 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9156 if (isbit && !IS_ITEMP(cond))
9157 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9165 /*-----------------------------------------------------------------*/
9166 /* genAddrOf - generates code for address of */
9167 /*-----------------------------------------------------------------*/
9168 static void genAddrOf (iCode *ic)
9170 operand *right, *result, *left;
9173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9176 //aopOp(IC_RESULT(ic),ic,FALSE);
9178 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9179 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9180 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9182 DEBUGpic14_AopType(__LINE__,left,right,result);
9184 size = AOP_SIZE(IC_RESULT(ic));
9188 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9189 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9193 freeAsmop(left,NULL,ic,FALSE);
9194 freeAsmop(result,NULL,ic,TRUE);
9199 /*-----------------------------------------------------------------*/
9200 /* genFarFarAssign - assignment when both are in far space */
9201 /*-----------------------------------------------------------------*/
9202 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9204 int size = AOP_SIZE(right);
9207 /* first push the right side on to the stack */
9209 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9211 pic14_emitcode ("push","acc");
9214 freeAsmop(right,NULL,ic,FALSE);
9215 /* now assign DPTR to result */
9216 aopOp(result,ic,FALSE);
9217 size = AOP_SIZE(result);
9219 pic14_emitcode ("pop","acc");
9220 aopPut(AOP(result),"a",--offset);
9222 freeAsmop(result,NULL,ic,FALSE);
9227 /*-----------------------------------------------------------------*/
9228 /* genAssign - generate code for assignment */
9229 /*-----------------------------------------------------------------*/
9230 static void genAssign (iCode *ic)
9232 operand *result, *right;
9233 int size, offset,know_W;
9234 unsigned long lit = 0L;
9236 result = IC_RESULT(ic);
9237 right = IC_RIGHT(ic) ;
9239 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9241 /* if they are the same */
9242 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9245 aopOp(right,ic,FALSE);
9246 aopOp(result,ic,TRUE);
9248 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9250 /* if they are the same registers */
9251 if (pic14_sameRegs(AOP(right),AOP(result)))
9254 /* if the result is a bit */
9255 if (AOP_TYPE(result) == AOP_CRY) {
9257 /* if the right size is a literal then
9258 we know what the value is */
9259 if (AOP_TYPE(right) == AOP_LIT) {
9261 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9262 popGet(AOP(result),0));
9264 if (((int) operandLitValue(right)))
9265 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9266 AOP(result)->aopu.aop_dir,
9267 AOP(result)->aopu.aop_dir);
9269 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9270 AOP(result)->aopu.aop_dir,
9271 AOP(result)->aopu.aop_dir);
9275 /* the right is also a bit variable */
9276 if (AOP_TYPE(right) == AOP_CRY) {
9277 emitpcode(POC_BCF, popGet(AOP(result),0));
9278 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9279 emitpcode(POC_BSF, popGet(AOP(result),0));
9281 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9282 AOP(result)->aopu.aop_dir,
9283 AOP(result)->aopu.aop_dir);
9284 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9285 AOP(right)->aopu.aop_dir,
9286 AOP(right)->aopu.aop_dir);
9287 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9288 AOP(result)->aopu.aop_dir,
9289 AOP(result)->aopu.aop_dir);
9294 emitpcode(POC_BCF, popGet(AOP(result),0));
9295 pic14_toBoolean(right);
9297 emitpcode(POC_BSF, popGet(AOP(result),0));
9298 //aopPut(AOP(result),"a",0);
9302 /* bit variables done */
9304 size = AOP_SIZE(result);
9306 if(AOP_TYPE(right) == AOP_LIT)
9307 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9309 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9311 if(aopIdx(AOP(result),0) == 4) {
9312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9313 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9314 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9317 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9323 if(AOP_TYPE(right) == AOP_LIT) {
9325 if(know_W != (lit&0xff))
9326 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9328 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9330 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9334 } else if (AOP_TYPE(right) == AOP_CRY) {
9335 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9337 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9338 emitpcode(POC_INCF, popGet(AOP(result),0));
9341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9342 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9343 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9351 freeAsmop (right,NULL,ic,FALSE);
9352 freeAsmop (result,NULL,ic,TRUE);
9355 /*-----------------------------------------------------------------*/
9356 /* genJumpTab - genrates code for jump table */
9357 /*-----------------------------------------------------------------*/
9358 static void genJumpTab (iCode *ic)
9363 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9365 aopOp(IC_JTCOND(ic),ic,FALSE);
9366 /* get the condition into accumulator */
9367 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9369 /* multiply by three */
9370 pic14_emitcode("add","a,acc");
9371 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9373 jtab = newiTempLabel(NULL);
9374 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9375 pic14_emitcode("jmp","@a+dptr");
9376 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9378 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9379 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9381 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9382 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9383 emitpLabel(jtab->key);
9385 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9387 /* now generate the jump labels */
9388 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9389 jtab = setNextItem(IC_JTLABELS(ic))) {
9390 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9391 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9397 /*-----------------------------------------------------------------*/
9398 /* genMixedOperation - gen code for operators between mixed types */
9399 /*-----------------------------------------------------------------*/
9401 TSD - Written for the PIC port - but this unfortunately is buggy.
9402 This routine is good in that it is able to efficiently promote
9403 types to different (larger) sizes. Unfortunately, the temporary
9404 variables that are optimized out by this routine are sometimes
9405 used in other places. So until I know how to really parse the
9406 iCode tree, I'm going to not be using this routine :(.
9408 static int genMixedOperation (iCode *ic)
9411 operand *result = IC_RESULT(ic);
9412 sym_link *ctype = operandType(IC_LEFT(ic));
9413 operand *right = IC_RIGHT(ic);
9419 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9421 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9427 nextright = IC_RIGHT(nextic);
9428 nextleft = IC_LEFT(nextic);
9429 nextresult = IC_RESULT(nextic);
9431 aopOp(right,ic,FALSE);
9432 aopOp(result,ic,FALSE);
9433 aopOp(nextright, nextic, FALSE);
9434 aopOp(nextleft, nextic, FALSE);
9435 aopOp(nextresult, nextic, FALSE);
9437 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9443 pic14_emitcode(";remove right +","");
9445 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9451 pic14_emitcode(";remove left +","");
9455 big = AOP_SIZE(nextleft);
9456 small = AOP_SIZE(nextright);
9458 switch(nextic->op) {
9461 pic14_emitcode(";optimize a +","");
9462 /* if unsigned or not an integral type */
9463 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9464 pic14_emitcode(";add a bit to something","");
9467 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9469 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9470 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9471 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9473 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9481 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9482 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9483 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9486 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9488 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9489 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9490 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9491 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9492 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9495 pic14_emitcode("rlf","known_zero,w");
9502 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9503 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9504 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9506 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9516 freeAsmop(right,NULL,ic,TRUE);
9517 freeAsmop(result,NULL,ic,TRUE);
9518 freeAsmop(nextright,NULL,ic,TRUE);
9519 freeAsmop(nextleft,NULL,ic,TRUE);
9521 nextic->generated = 1;
9528 /*-----------------------------------------------------------------*/
9529 /* genCast - gen code for casting */
9530 /*-----------------------------------------------------------------*/
9531 static void genCast (iCode *ic)
9533 operand *result = IC_RESULT(ic);
9534 sym_link *ctype = operandType(IC_LEFT(ic));
9535 sym_link *rtype = operandType(IC_RIGHT(ic));
9536 operand *right = IC_RIGHT(ic);
9539 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9540 /* if they are equivalent then do nothing */
9541 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9544 aopOp(right,ic,FALSE) ;
9545 aopOp(result,ic,FALSE);
9547 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9549 /* if the result is a bit */
9550 if (AOP_TYPE(result) == AOP_CRY) {
9551 /* if the right size is a literal then
9552 we know what the value is */
9553 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9554 if (AOP_TYPE(right) == AOP_LIT) {
9556 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9557 popGet(AOP(result),0));
9559 if (((int) operandLitValue(right)))
9560 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9561 AOP(result)->aopu.aop_dir,
9562 AOP(result)->aopu.aop_dir);
9564 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9565 AOP(result)->aopu.aop_dir,
9566 AOP(result)->aopu.aop_dir);
9571 /* the right is also a bit variable */
9572 if (AOP_TYPE(right) == AOP_CRY) {
9575 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9577 pic14_emitcode("clrc","");
9578 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9579 AOP(right)->aopu.aop_dir,
9580 AOP(right)->aopu.aop_dir);
9581 aopPut(AOP(result),"c",0);
9586 if (AOP_TYPE(right) == AOP_REG) {
9587 emitpcode(POC_BCF, popGet(AOP(result),0));
9588 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9589 emitpcode(POC_BSF, popGet(AOP(result),0));
9591 pic14_toBoolean(right);
9592 aopPut(AOP(result),"a",0);
9596 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9598 size = AOP_SIZE(result);
9600 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9602 emitpcode(POC_CLRF, popGet(AOP(result),0));
9603 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9604 emitpcode(POC_INCF, popGet(AOP(result),0));
9607 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9612 /* if they are the same size : or less */
9613 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9615 /* if they are in the same place */
9616 if (pic14_sameRegs(AOP(right),AOP(result)))
9619 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9620 if (IS_PTR_CONST(rtype))
9621 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9622 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9623 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9625 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9626 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9627 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9628 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9629 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9630 if(AOP_SIZE(result) <2)
9631 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9635 /* if they in different places then copy */
9636 size = AOP_SIZE(result);
9639 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9640 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9642 //aopPut(AOP(result),
9643 // aopGet(AOP(right),offset,FALSE,FALSE),
9653 /* if the result is of type pointer */
9654 if (IS_PTR(ctype)) {
9657 sym_link *type = operandType(right);
9658 sym_link *etype = getSpec(type);
9659 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9661 /* pointer to generic pointer */
9662 if (IS_GENPTR(ctype)) {
9666 p_type = DCL_TYPE(type);
9668 /* we have to go by the storage class */
9669 p_type = PTR_TYPE(SPEC_OCLS(etype));
9671 /* if (SPEC_OCLS(etype)->codesp ) */
9672 /* p_type = CPOINTER ; */
9674 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9675 /* p_type = FPOINTER ; */
9677 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9678 /* p_type = PPOINTER; */
9680 /* if (SPEC_OCLS(etype) == idata ) */
9681 /* p_type = IPOINTER ; */
9683 /* p_type = POINTER ; */
9686 /* the first two bytes are known */
9687 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9688 size = GPTRSIZE - 1;
9691 if(offset < AOP_SIZE(right)) {
9692 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9693 if ((AOP_TYPE(right) == AOP_PCODE) &&
9694 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9695 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9696 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9699 aopGet(AOP(right),offset,FALSE,FALSE),
9703 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9706 /* the last byte depending on type */
9710 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9713 pic14_emitcode(";BUG!? ","%d",__LINE__);
9717 pic14_emitcode(";BUG!? ","%d",__LINE__);
9721 pic14_emitcode(";BUG!? ","%d",__LINE__);
9726 /* this should never happen */
9727 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9728 "got unknown pointer type");
9731 //aopPut(AOP(result),l, GPTRSIZE - 1);
9735 /* just copy the pointers */
9736 size = AOP_SIZE(result);
9740 aopGet(AOP(right),offset,FALSE,FALSE),
9749 /* so we now know that the size of destination is greater
9750 than the size of the source.
9751 Now, if the next iCode is an operator then we might be
9752 able to optimize the operation without performing a cast.
9754 if(genMixedOperation(ic))
9757 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9759 /* we move to result for the size of source */
9760 size = AOP_SIZE(right);
9763 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9764 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9768 /* now depending on the sign of the destination */
9769 size = AOP_SIZE(result) - AOP_SIZE(right);
9770 /* if unsigned or not an integral type */
9771 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9773 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9775 /* we need to extend the sign :{ */
9778 /* Save one instruction of casting char to int */
9779 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9780 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9781 emitpcode(POC_DECF, popGet(AOP(result),offset));
9783 emitpcodeNULLop(POC_CLRW);
9786 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9788 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9790 emitpcode(POC_MOVLW, popGetLit(0xff));
9793 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9798 freeAsmop(right,NULL,ic,TRUE);
9799 freeAsmop(result,NULL,ic,TRUE);
9803 /*-----------------------------------------------------------------*/
9804 /* genDjnz - generate decrement & jump if not zero instrucion */
9805 /*-----------------------------------------------------------------*/
9806 static int genDjnz (iCode *ic, iCode *ifx)
9809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9814 /* if the if condition has a false label
9815 then we cannot save */
9819 /* if the minus is not of the form
9821 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9822 !IS_OP_LITERAL(IC_RIGHT(ic)))
9825 if (operandLitValue(IC_RIGHT(ic)) != 1)
9828 /* if the size of this greater than one then no
9830 if (getSize(operandType(IC_RESULT(ic))) > 1)
9833 /* otherwise we can save BIG */
9834 lbl = newiTempLabel(NULL);
9835 lbl1= newiTempLabel(NULL);
9837 aopOp(IC_RESULT(ic),ic,FALSE);
9839 if (IS_AOP_PREG(IC_RESULT(ic))) {
9840 pic14_emitcode("dec","%s",
9841 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9842 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9847 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9848 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9850 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9851 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9854 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9855 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9856 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9857 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9860 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9865 /*-----------------------------------------------------------------*/
9866 /* genReceive - generate code for a receive iCode */
9867 /*-----------------------------------------------------------------*/
9868 static void genReceive (iCode *ic)
9870 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9872 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9873 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9874 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9876 int size = getSize(operandType(IC_RESULT(ic)));
9877 int offset = fReturnSizePic - size;
9879 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9880 fReturn[fReturnSizePic - offset - 1] : "acc"));
9883 aopOp(IC_RESULT(ic),ic,FALSE);
9884 size = AOP_SIZE(IC_RESULT(ic));
9887 pic14_emitcode ("pop","acc");
9888 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9893 aopOp(IC_RESULT(ic),ic,FALSE);
9895 assignResultValue(IC_RESULT(ic));
9898 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9901 /*-----------------------------------------------------------------*/
9902 /* genpic14Code - generate code for pic14 based controllers */
9903 /*-----------------------------------------------------------------*/
9905 * At this point, ralloc.c has gone through the iCode and attempted
9906 * to optimize in a way suitable for a PIC. Now we've got to generate
9907 * PIC instructions that correspond to the iCode.
9909 * Once the instructions are generated, we'll pass through both the
9910 * peep hole optimizer and the pCode optimizer.
9911 *-----------------------------------------------------------------*/
9913 void genpic14Code (iCode *lic)
9918 lineHead = lineCurr = NULL;
9920 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9923 /* if debug information required */
9924 if (options.debug && currFunc) {
9926 debugFile->writeFunction(currFunc);
9928 if (IS_STATIC(currFunc->etype)) {
9929 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9930 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9932 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9933 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9940 for (ic = lic ; ic ; ic = ic->next ) {
9942 DEBUGpic14_emitcode(";ic","");
9943 if ( cln != ic->lineno ) {
9944 if ( options.debug ) {
9946 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9947 FileBaseName(ic->filename),ic->lineno,
9948 ic->level,ic->block);
9952 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9953 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9954 printCLine(ic->filename, ic->lineno));
9956 if (!options.noCcodeInAsm) {
9958 newpCodeCSource(ic->lineno,
9960 printCLine(ic->filename, ic->lineno)));
9966 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9968 /* if the result is marked as
9969 spilt and rematerializable or code for
9970 this has already been generated then
9972 if (resultRemat(ic) || ic->generated )
9975 /* depending on the operation */
9994 /* IPOP happens only when trying to restore a
9995 spilt live range, if there is an ifx statement
9996 following this pop then the if statement might
9997 be using some of the registers being popped which
9998 would destory the contents of the register so
9999 we need to check for this condition and handle it */
10001 ic->next->op == IFX &&
10002 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10003 genIfx (ic->next,ic);
10021 genEndFunction (ic);
10041 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10058 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10062 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10069 /* note these two are xlated by algebraic equivalence
10070 during parsing SDCC.y */
10071 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10072 "got '>=' or '<=' shouldn't have come here");
10076 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10088 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10092 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10096 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10120 genRightShift (ic);
10123 case GET_VALUE_AT_ADDRESS:
10128 if (POINTER_SET(ic))
10155 addSet(&_G.sendSet,ic);
10164 /* now we are ready to call the
10165 peep hole optimizer */
10166 if (!options.nopeep) {
10167 peepHole (&lineHead);
10169 /* now do the actual printing */
10170 printLine (lineHead,codeOutFile);
10173 DFPRINTF((stderr,"printing pBlock\n\n"));
10174 printpBlock(stdout,pb);