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)
1899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1900 /* assign asmOps to operand & result */
1901 aopOp (IC_LEFT(ic),ic,FALSE);
1902 aopOp (IC_RESULT(ic),ic,TRUE);
1904 /* if both are in bit space then
1906 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1907 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1909 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1910 pic14_emitcode("cpl","c");
1911 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1915 size = AOP_SIZE(IC_RESULT(ic));
1917 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1919 pic14_emitcode("cpl","a");
1920 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1925 /* release the aops */
1926 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1927 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1930 /*-----------------------------------------------------------------*/
1931 /* genUminusFloat - unary minus for floating points */
1932 /*-----------------------------------------------------------------*/
1933 static void genUminusFloat(operand *op,operand *result)
1935 int size ,offset =0 ;
1938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1939 /* for this we just need to flip the
1940 first it then copy the rest in place */
1941 size = AOP_SIZE(op) - 1;
1942 l = aopGet(AOP(op),3,FALSE,FALSE);
1946 pic14_emitcode("cpl","acc.7");
1947 aopPut(AOP(result),"a",3);
1951 aopGet(AOP(op),offset,FALSE,FALSE),
1957 /*-----------------------------------------------------------------*/
1958 /* genUminus - unary minus code generation */
1959 /*-----------------------------------------------------------------*/
1960 static void genUminus (iCode *ic)
1963 sym_link *optype, *rtype;
1966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1968 aopOp(IC_LEFT(ic),ic,FALSE);
1969 aopOp(IC_RESULT(ic),ic,TRUE);
1971 /* if both in bit space then special
1973 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1974 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1976 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1977 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1978 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1983 optype = operandType(IC_LEFT(ic));
1984 rtype = operandType(IC_RESULT(ic));
1986 /* if float then do float stuff */
1987 if (IS_FLOAT(optype)) {
1988 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1992 /* otherwise subtract from zero by taking the 2's complement */
1993 size = AOP_SIZE(IC_LEFT(ic));
1995 for(i=0; i<size; i++) {
1996 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1997 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1999 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2000 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2004 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2005 for(i=1; i<size; i++) {
2007 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2011 /* release the aops */
2012 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2013 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2016 /*-----------------------------------------------------------------*/
2017 /* saveRegisters - will look for a call and save the registers */
2018 /*-----------------------------------------------------------------*/
2019 static void saveRegisters(iCode *lic)
2026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2028 for (ic = lic ; ic ; ic = ic->next)
2029 if (ic->op == CALL || ic->op == PCALL)
2033 fprintf(stderr,"found parameter push with no function call\n");
2037 /* if the registers have been saved already then
2039 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2042 /* find the registers in use at this time
2043 and push them away to safety */
2044 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2048 if (options.useXstack) {
2049 if (bitVectBitValue(rsave,R0_IDX))
2050 pic14_emitcode("mov","b,r0");
2051 pic14_emitcode("mov","r0,%s",spname);
2052 for (i = 0 ; i < pic14_nRegs ; i++) {
2053 if (bitVectBitValue(rsave,i)) {
2055 pic14_emitcode("mov","a,b");
2057 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2058 pic14_emitcode("movx","@r0,a");
2059 pic14_emitcode("inc","r0");
2062 pic14_emitcode("mov","%s,r0",spname);
2063 if (bitVectBitValue(rsave,R0_IDX))
2064 pic14_emitcode("mov","r0,b");
2066 //for (i = 0 ; i < pic14_nRegs ; i++) {
2067 // if (bitVectBitValue(rsave,i))
2068 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2071 dtype = operandType(IC_LEFT(ic));
2072 if (currFunc && dtype &&
2073 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2074 IFFUNC_ISISR(currFunc->type) &&
2077 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2080 /*-----------------------------------------------------------------*/
2081 /* unsaveRegisters - pop the pushed registers */
2082 /*-----------------------------------------------------------------*/
2083 static void unsaveRegisters (iCode *ic)
2088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2089 /* find the registers in use at this time
2090 and push them away to safety */
2091 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2094 if (options.useXstack) {
2095 pic14_emitcode("mov","r0,%s",spname);
2096 for (i = pic14_nRegs ; i >= 0 ; i--) {
2097 if (bitVectBitValue(rsave,i)) {
2098 pic14_emitcode("dec","r0");
2099 pic14_emitcode("movx","a,@r0");
2101 pic14_emitcode("mov","b,a");
2103 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2107 pic14_emitcode("mov","%s,r0",spname);
2108 if (bitVectBitValue(rsave,R0_IDX))
2109 pic14_emitcode("mov","r0,b");
2111 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2112 // if (bitVectBitValue(rsave,i))
2113 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2119 /*-----------------------------------------------------------------*/
2121 /*-----------------------------------------------------------------*/
2122 static void pushSide(operand * oper, int size)
2126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2128 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2129 if (AOP_TYPE(oper) != AOP_REG &&
2130 AOP_TYPE(oper) != AOP_DIR &&
2132 pic14_emitcode("mov","a,%s",l);
2133 pic14_emitcode("push","acc");
2135 pic14_emitcode("push","%s",l);
2140 /*-----------------------------------------------------------------*/
2141 /* assignResultValue - */
2142 /*-----------------------------------------------------------------*/
2143 static void assignResultValue(operand * oper)
2145 int size = AOP_SIZE(oper);
2147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2149 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2151 if(!GpsuedoStkPtr) {
2152 /* The last byte in the assignment is in W */
2154 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2159 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2161 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2166 /*-----------------------------------------------------------------*/
2167 /* genIpush - genrate code for pushing this gets a little complex */
2168 /*-----------------------------------------------------------------*/
2169 static void genIpush (iCode *ic)
2172 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2174 int size, offset = 0 ;
2178 /* if this is not a parm push : ie. it is spill push
2179 and spill push is always done on the local stack */
2180 if (!ic->parmPush) {
2182 /* and the item is spilt then do nothing */
2183 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2186 aopOp(IC_LEFT(ic),ic,FALSE);
2187 size = AOP_SIZE(IC_LEFT(ic));
2188 /* push it on the stack */
2190 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2195 pic14_emitcode("push","%s",l);
2200 /* this is a paramter push: in this case we call
2201 the routine to find the call and save those
2202 registers that need to be saved */
2205 /* then do the push */
2206 aopOp(IC_LEFT(ic),ic,FALSE);
2209 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2210 size = AOP_SIZE(IC_LEFT(ic));
2213 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2214 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2215 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2217 pic14_emitcode("mov","a,%s",l);
2218 pic14_emitcode("push","acc");
2220 pic14_emitcode("push","%s",l);
2223 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2227 /*-----------------------------------------------------------------*/
2228 /* genIpop - recover the registers: can happen only for spilling */
2229 /*-----------------------------------------------------------------*/
2230 static void genIpop (iCode *ic)
2232 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2237 /* if the temp was not pushed then */
2238 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2241 aopOp(IC_LEFT(ic),ic,FALSE);
2242 size = AOP_SIZE(IC_LEFT(ic));
2245 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2248 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2252 /*-----------------------------------------------------------------*/
2253 /* unsaverbank - restores the resgister bank from stack */
2254 /*-----------------------------------------------------------------*/
2255 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2257 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2265 if (options.useXstack) {
2267 r = getFreePtr(ic,&aop,FALSE);
2270 pic14_emitcode("mov","%s,_spx",r->name);
2271 pic14_emitcode("movx","a,@%s",r->name);
2272 pic14_emitcode("mov","psw,a");
2273 pic14_emitcode("dec","%s",r->name);
2276 pic14_emitcode ("pop","psw");
2279 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2280 if (options.useXstack) {
2281 pic14_emitcode("movx","a,@%s",r->name);
2282 //pic14_emitcode("mov","(%s+%d),a",
2283 // regspic14[i].base,8*bank+regspic14[i].offset);
2284 pic14_emitcode("dec","%s",r->name);
2287 pic14_emitcode("pop",""); //"(%s+%d)",
2288 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2291 if (options.useXstack) {
2293 pic14_emitcode("mov","_spx,%s",r->name);
2294 freeAsmop(NULL,aop,ic,TRUE);
2300 /*-----------------------------------------------------------------*/
2301 /* saverbank - saves an entire register bank on the stack */
2302 /*-----------------------------------------------------------------*/
2303 static void saverbank (int bank, iCode *ic, bool pushPsw)
2305 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2312 if (options.useXstack) {
2315 r = getFreePtr(ic,&aop,FALSE);
2316 pic14_emitcode("mov","%s,_spx",r->name);
2320 for (i = 0 ; i < pic14_nRegs ;i++) {
2321 if (options.useXstack) {
2322 pic14_emitcode("inc","%s",r->name);
2323 //pic14_emitcode("mov","a,(%s+%d)",
2324 // regspic14[i].base,8*bank+regspic14[i].offset);
2325 pic14_emitcode("movx","@%s,a",r->name);
2327 pic14_emitcode("push","");// "(%s+%d)",
2328 //regspic14[i].base,8*bank+regspic14[i].offset);
2332 if (options.useXstack) {
2333 pic14_emitcode("mov","a,psw");
2334 pic14_emitcode("movx","@%s,a",r->name);
2335 pic14_emitcode("inc","%s",r->name);
2336 pic14_emitcode("mov","_spx,%s",r->name);
2337 freeAsmop (NULL,aop,ic,TRUE);
2340 pic14_emitcode("push","psw");
2342 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2348 /*-----------------------------------------------------------------*/
2349 /* genCall - generates a call statement */
2350 /*-----------------------------------------------------------------*/
2351 static void genCall (iCode *ic)
2355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2357 /* if caller saves & we have not saved then */
2361 /* if we are calling a function that is not using
2362 the same register bank then we need to save the
2363 destination registers on the stack */
2364 dtype = operandType(IC_LEFT(ic));
2365 if (currFunc && dtype &&
2366 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2367 IFFUNC_ISISR(currFunc->type) &&
2370 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2372 /* if send set is not empty the assign */
2375 /* For the Pic port, there is no data stack.
2376 * So parameters passed to functions are stored
2377 * in registers. (The pCode optimizer will get
2378 * rid of most of these :).
2380 int psuedoStkPtr=-1;
2381 int firstTimeThruLoop = 1;
2383 _G.sendSet = reverseSet(_G.sendSet);
2385 /* First figure how many parameters are getting passed */
2386 for (sic = setFirstItem(_G.sendSet) ; sic ;
2387 sic = setNextItem(_G.sendSet)) {
2389 aopOp(IC_LEFT(sic),sic,FALSE);
2390 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2391 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2394 for (sic = setFirstItem(_G.sendSet) ; sic ;
2395 sic = setNextItem(_G.sendSet)) {
2396 int size, offset = 0;
2398 aopOp(IC_LEFT(sic),sic,FALSE);
2399 size = AOP_SIZE(IC_LEFT(sic));
2402 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2403 AopType(AOP_TYPE(IC_LEFT(sic))));
2405 if(!firstTimeThruLoop) {
2406 /* If this is not the first time we've been through the loop
2407 * then we need to save the parameter in a temporary
2408 * register. The last byte of the last parameter is
2410 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2413 firstTimeThruLoop=0;
2415 //if (strcmp(l,fReturn[offset])) {
2416 mov2w (AOP(IC_LEFT(sic)), offset);
2418 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2419 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2420 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2422 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2427 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2432 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2433 OP_SYMBOL(IC_LEFT(ic))->rname :
2434 OP_SYMBOL(IC_LEFT(ic))->name));
2437 /* if we need assign a result value */
2438 if ((IS_ITEMP(IC_RESULT(ic)) &&
2439 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2440 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2441 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2444 aopOp(IC_RESULT(ic),ic,FALSE);
2447 assignResultValue(IC_RESULT(ic));
2449 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2450 AopType(AOP_TYPE(IC_RESULT(ic))));
2452 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2455 /* adjust the stack for parameters if
2457 if (ic->parmBytes) {
2459 if (ic->parmBytes > 3) {
2460 pic14_emitcode("mov","a,%s",spname);
2461 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2462 pic14_emitcode("mov","%s,a",spname);
2464 for ( i = 0 ; i < ic->parmBytes ;i++)
2465 pic14_emitcode("dec","%s",spname);
2469 /* if register bank was saved then pop them */
2471 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2473 /* if we hade saved some registers then unsave them */
2474 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2475 unsaveRegisters (ic);
2480 /*-----------------------------------------------------------------*/
2481 /* genPcall - generates a call by pointer statement */
2482 /*-----------------------------------------------------------------*/
2483 static void genPcall (iCode *ic)
2486 symbol *rlbl = newiTempLabel(NULL);
2489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2490 /* if caller saves & we have not saved then */
2494 /* if we are calling a function that is not using
2495 the same register bank then we need to save the
2496 destination registers on the stack */
2497 dtype = operandType(IC_LEFT(ic));
2498 if (currFunc && dtype &&
2499 IFFUNC_ISISR(currFunc->type) &&
2500 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2501 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2504 /* push the return address on to the stack */
2505 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2506 pic14_emitcode("push","acc");
2507 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2508 pic14_emitcode("push","acc");
2510 if (options.model == MODEL_FLAT24)
2512 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2513 pic14_emitcode("push","acc");
2516 /* now push the calling address */
2517 aopOp(IC_LEFT(ic),ic,FALSE);
2519 pushSide(IC_LEFT(ic), FPTRSIZE);
2521 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2523 /* if send set is not empty the assign */
2527 for (sic = setFirstItem(_G.sendSet) ; sic ;
2528 sic = setNextItem(_G.sendSet)) {
2529 int size, offset = 0;
2530 aopOp(IC_LEFT(sic),sic,FALSE);
2531 size = AOP_SIZE(IC_LEFT(sic));
2533 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2535 if (strcmp(l,fReturn[offset]))
2536 pic14_emitcode("mov","%s,%s",
2541 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2546 pic14_emitcode("ret","");
2547 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2550 /* if we need assign a result value */
2551 if ((IS_ITEMP(IC_RESULT(ic)) &&
2552 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2553 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2554 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2557 aopOp(IC_RESULT(ic),ic,FALSE);
2560 assignResultValue(IC_RESULT(ic));
2562 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2565 /* adjust the stack for parameters if
2567 if (ic->parmBytes) {
2569 if (ic->parmBytes > 3) {
2570 pic14_emitcode("mov","a,%s",spname);
2571 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2572 pic14_emitcode("mov","%s,a",spname);
2574 for ( i = 0 ; i < ic->parmBytes ;i++)
2575 pic14_emitcode("dec","%s",spname);
2579 /* if register bank was saved then unsave them */
2580 if (currFunc && dtype &&
2581 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2582 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2584 /* if we hade saved some registers then
2587 unsaveRegisters (ic);
2591 /*-----------------------------------------------------------------*/
2592 /* resultRemat - result is rematerializable */
2593 /*-----------------------------------------------------------------*/
2594 static int resultRemat (iCode *ic)
2596 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2597 if (SKIP_IC(ic) || ic->op == IFX)
2600 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2601 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2602 if (sym->remat && !POINTER_SET(ic))
2609 #if defined(__BORLANDC__) || defined(_MSC_VER)
2610 #define STRCASECMP stricmp
2612 #define STRCASECMP strcasecmp
2616 /*-----------------------------------------------------------------*/
2617 /* inExcludeList - return 1 if the string is in exclude Reg list */
2618 /*-----------------------------------------------------------------*/
2619 static bool inExcludeList(char *s)
2621 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2625 if (options.excludeRegs[i] &&
2626 STRCASECMP(options.excludeRegs[i],"none") == 0)
2629 for ( i = 0 ; options.excludeRegs[i]; i++) {
2630 if (options.excludeRegs[i] &&
2631 STRCASECMP(s,options.excludeRegs[i]) == 0)
2638 /*-----------------------------------------------------------------*/
2639 /* genFunction - generated code for function entry */
2640 /*-----------------------------------------------------------------*/
2641 static void genFunction (iCode *ic)
2646 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2648 labelOffset += (max_key+4);
2652 /* create the function header */
2653 pic14_emitcode(";","-----------------------------------------");
2654 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2655 pic14_emitcode(";","-----------------------------------------");
2657 pic14_emitcode("","%s:",sym->rname);
2658 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2660 ftype = operandType(IC_LEFT(ic));
2662 /* if critical function then turn interrupts off */
2663 if (IFFUNC_ISCRITICAL(ftype))
2664 pic14_emitcode("clr","ea");
2666 /* here we need to generate the equates for the
2667 register bank if required */
2669 if (FUNC_REGBANK(ftype) != rbank) {
2672 rbank = FUNC_REGBANK(ftype);
2673 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2674 if (strcmp(regspic14[i].base,"0") == 0)
2675 pic14_emitcode("","%s = 0x%02x",
2677 8*rbank+regspic14[i].offset);
2679 pic14_emitcode ("","%s = %s + 0x%02x",
2682 8*rbank+regspic14[i].offset);
2687 /* if this is an interrupt service routine then
2688 save acc, b, dpl, dph */
2689 if (IFFUNC_ISISR(sym->type)) {
2690 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2691 emitpcodeNULLop(POC_NOP);
2692 emitpcodeNULLop(POC_NOP);
2693 emitpcodeNULLop(POC_NOP);
2694 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2695 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2696 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2697 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2699 pBlockConvert2ISR(pb);
2701 if (!inExcludeList("acc"))
2702 pic14_emitcode ("push","acc");
2703 if (!inExcludeList("b"))
2704 pic14_emitcode ("push","b");
2705 if (!inExcludeList("dpl"))
2706 pic14_emitcode ("push","dpl");
2707 if (!inExcludeList("dph"))
2708 pic14_emitcode ("push","dph");
2709 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2711 pic14_emitcode ("push", "dpx");
2712 /* Make sure we're using standard DPTR */
2713 pic14_emitcode ("push", "dps");
2714 pic14_emitcode ("mov", "dps, #0x00");
2715 if (options.stack10bit)
2717 /* This ISR could conceivably use DPTR2. Better save it. */
2718 pic14_emitcode ("push", "dpl1");
2719 pic14_emitcode ("push", "dph1");
2720 pic14_emitcode ("push", "dpx1");
2723 /* if this isr has no bank i.e. is going to
2724 run with bank 0 , then we need to save more
2726 if (!FUNC_REGBANK(sym->type)) {
2728 /* if this function does not call any other
2729 function then we can be economical and
2730 save only those registers that are used */
2731 if (! IFFUNC_HASFCALL(sym->type)) {
2734 /* if any registers used */
2735 if (sym->regsUsed) {
2736 /* save the registers used */
2737 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2738 if (bitVectBitValue(sym->regsUsed,i) ||
2739 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2740 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2745 /* this function has a function call cannot
2746 determines register usage so we will have the
2748 saverbank(0,ic,FALSE);
2753 /* if callee-save to be used for this function
2754 then save the registers being used in this function */
2755 if (IFFUNC_CALLEESAVES(sym->type)) {
2758 /* if any registers used */
2759 if (sym->regsUsed) {
2760 /* save the registers used */
2761 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2762 if (bitVectBitValue(sym->regsUsed,i) ||
2763 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2764 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2772 /* set the register bank to the desired value */
2773 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2774 pic14_emitcode("push","psw");
2775 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2778 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2780 if (options.useXstack) {
2781 pic14_emitcode("mov","r0,%s",spname);
2782 pic14_emitcode("mov","a,_bp");
2783 pic14_emitcode("movx","@r0,a");
2784 pic14_emitcode("inc","%s",spname);
2788 /* set up the stack */
2789 pic14_emitcode ("push","_bp"); /* save the callers stack */
2791 pic14_emitcode ("mov","_bp,%s",spname);
2794 /* adjust the stack for the function */
2799 werror(W_STACK_OVERFLOW,sym->name);
2801 if (i > 3 && sym->recvSize < 4) {
2803 pic14_emitcode ("mov","a,sp");
2804 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2805 pic14_emitcode ("mov","sp,a");
2810 pic14_emitcode("inc","sp");
2815 pic14_emitcode ("mov","a,_spx");
2816 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2817 pic14_emitcode ("mov","_spx,a");
2822 /*-----------------------------------------------------------------*/
2823 /* genEndFunction - generates epilogue for functions */
2824 /*-----------------------------------------------------------------*/
2825 static void genEndFunction (iCode *ic)
2827 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2831 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2833 pic14_emitcode ("mov","%s,_bp",spname);
2836 /* if use external stack but some variables were
2837 added to the local stack then decrement the
2839 if (options.useXstack && sym->stack) {
2840 pic14_emitcode("mov","a,sp");
2841 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2842 pic14_emitcode("mov","sp,a");
2846 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2847 if (options.useXstack) {
2848 pic14_emitcode("mov","r0,%s",spname);
2849 pic14_emitcode("movx","a,@r0");
2850 pic14_emitcode("mov","_bp,a");
2851 pic14_emitcode("dec","%s",spname);
2855 pic14_emitcode ("pop","_bp");
2859 /* restore the register bank */
2860 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2861 pic14_emitcode ("pop","psw");
2863 if (IFFUNC_ISISR(sym->type)) {
2865 /* now we need to restore the registers */
2866 /* if this isr has no bank i.e. is going to
2867 run with bank 0 , then we need to save more
2869 if (!FUNC_REGBANK(sym->type)) {
2871 /* if this function does not call any other
2872 function then we can be economical and
2873 save only those registers that are used */
2874 if (! IFFUNC_HASFCALL(sym->type)) {
2877 /* if any registers used */
2878 if (sym->regsUsed) {
2879 /* save the registers used */
2880 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2881 if (bitVectBitValue(sym->regsUsed,i) ||
2882 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2883 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2888 /* this function has a function call cannot
2889 determines register usage so we will have the
2891 unsaverbank(0,ic,FALSE);
2895 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2897 if (options.stack10bit)
2899 pic14_emitcode ("pop", "dpx1");
2900 pic14_emitcode ("pop", "dph1");
2901 pic14_emitcode ("pop", "dpl1");
2903 pic14_emitcode ("pop", "dps");
2904 pic14_emitcode ("pop", "dpx");
2906 if (!inExcludeList("dph"))
2907 pic14_emitcode ("pop","dph");
2908 if (!inExcludeList("dpl"))
2909 pic14_emitcode ("pop","dpl");
2910 if (!inExcludeList("b"))
2911 pic14_emitcode ("pop","b");
2912 if (!inExcludeList("acc"))
2913 pic14_emitcode ("pop","acc");
2915 if (IFFUNC_ISCRITICAL(sym->type))
2916 pic14_emitcode("setb","ea");
2919 /* if debug then send end of function */
2920 /* if (options.debug && currFunc) { */
2923 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2924 FileBaseName(ic->filename),currFunc->lastLine,
2925 ic->level,ic->block);
2926 if (IS_STATIC(currFunc->etype))
2927 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2929 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2933 pic14_emitcode ("reti","");
2935 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2936 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2937 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2938 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2939 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2940 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2942 emitpcodeNULLop(POC_RETFIE);
2946 if (IFFUNC_ISCRITICAL(sym->type))
2947 pic14_emitcode("setb","ea");
2949 if (IFFUNC_CALLEESAVES(sym->type)) {
2952 /* if any registers used */
2953 if (sym->regsUsed) {
2954 /* save the registers used */
2955 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2956 if (bitVectBitValue(sym->regsUsed,i) ||
2957 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2958 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2964 /* if debug then send end of function */
2967 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2968 FileBaseName(ic->filename),currFunc->lastLine,
2969 ic->level,ic->block);
2970 if (IS_STATIC(currFunc->etype))
2971 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2973 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2977 pic14_emitcode ("return","");
2978 emitpcodeNULLop(POC_RETURN);
2980 /* Mark the end of a function */
2981 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2986 /*-----------------------------------------------------------------*/
2987 /* genRet - generate code for return statement */
2988 /*-----------------------------------------------------------------*/
2989 static void genRet (iCode *ic)
2991 int size,offset = 0 , pushed = 0;
2993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2994 /* if we have no return value then
2995 just generate the "ret" */
2999 /* we have something to return then
3000 move the return value into place */
3001 aopOp(IC_LEFT(ic),ic,FALSE);
3002 size = AOP_SIZE(IC_LEFT(ic));
3006 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3008 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3010 pic14_emitcode("push","%s",l);
3013 l = aopGet(AOP(IC_LEFT(ic)),offset,
3015 if (strcmp(fReturn[offset],l)) {
3016 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3017 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3018 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3020 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3023 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3033 if (strcmp(fReturn[pushed],"a"))
3034 pic14_emitcode("pop",fReturn[pushed]);
3036 pic14_emitcode("pop","acc");
3039 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3042 /* generate a jump to the return label
3043 if the next is not the return statement */
3044 if (!(ic->next && ic->next->op == LABEL &&
3045 IC_LABEL(ic->next) == returnLabel)) {
3047 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3048 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3053 /*-----------------------------------------------------------------*/
3054 /* genLabel - generates a label */
3055 /*-----------------------------------------------------------------*/
3056 static void genLabel (iCode *ic)
3058 /* special case never generate */
3059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3060 if (IC_LABEL(ic) == entryLabel)
3063 emitpLabel(IC_LABEL(ic)->key);
3064 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3067 /*-----------------------------------------------------------------*/
3068 /* genGoto - generates a goto */
3069 /*-----------------------------------------------------------------*/
3071 static void genGoto (iCode *ic)
3073 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3074 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3078 /*-----------------------------------------------------------------*/
3079 /* genMultbits :- multiplication of bits */
3080 /*-----------------------------------------------------------------*/
3081 static void genMultbits (operand *left,
3085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3087 if(!pic14_sameRegs(AOP(result),AOP(right)))
3088 emitpcode(POC_BSF, popGet(AOP(result),0));
3090 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3091 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3092 emitpcode(POC_BCF, popGet(AOP(result),0));
3097 /*-----------------------------------------------------------------*/
3098 /* genMultOneByte : 8 bit multiplication & division */
3099 /*-----------------------------------------------------------------*/
3100 static void genMultOneByte (operand *left,
3104 sym_link *opetype = operandType(result);
3109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3110 DEBUGpic14_AopType(__LINE__,left,right,result);
3111 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3113 /* (if two literals, the value is computed before) */
3114 /* if one literal, literal on the right */
3115 if (AOP_TYPE(left) == AOP_LIT){
3121 size = AOP_SIZE(result);
3124 if (AOP_TYPE(right) == AOP_LIT){
3125 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3126 aopGet(AOP(right),0,FALSE,FALSE),
3127 aopGet(AOP(left),0,FALSE,FALSE),
3128 aopGet(AOP(result),0,FALSE,FALSE));
3129 pic14_emitcode("call","genMultLit");
3131 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3132 aopGet(AOP(right),0,FALSE,FALSE),
3133 aopGet(AOP(left),0,FALSE,FALSE),
3134 aopGet(AOP(result),0,FALSE,FALSE));
3135 pic14_emitcode("call","genMult8X8_8");
3138 genMult8X8_8 (left, right,result);
3141 /* signed or unsigned */
3142 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3143 //l = aopGet(AOP(left),0,FALSE,FALSE);
3145 //pic14_emitcode("mul","ab");
3146 /* if result size = 1, mul signed = mul unsigned */
3147 //aopPut(AOP(result),"a",0);
3149 } else { // (size > 1)
3151 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3152 aopGet(AOP(right),0,FALSE,FALSE),
3153 aopGet(AOP(left),0,FALSE,FALSE),
3154 aopGet(AOP(result),0,FALSE,FALSE));
3156 if (SPEC_USIGN(opetype)){
3157 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3158 genUMult8X8_16 (left, right, result, NULL);
3161 /* for filling the MSBs */
3162 emitpcode(POC_CLRF, popGet(AOP(result),2));
3163 emitpcode(POC_CLRF, popGet(AOP(result),3));
3167 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3169 pic14_emitcode("mov","a,b");
3171 /* adjust the MSB if left or right neg */
3173 /* if one literal */
3174 if (AOP_TYPE(right) == AOP_LIT){
3175 pic14_emitcode("multiply ","right is a lit");
3176 /* AND literal negative */
3177 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3178 /* adjust MSB (c==0 after mul) */
3179 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3183 genSMult8X8_16 (left, right, result, NULL);
3187 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3189 pic14_emitcode("rlc","a");
3190 pic14_emitcode("subb","a,acc");
3198 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3199 //aopPut(AOP(result),"a",offset++);
3203 /*-----------------------------------------------------------------*/
3204 /* genMult - generates code for multiplication */
3205 /*-----------------------------------------------------------------*/
3206 static void genMult (iCode *ic)
3208 operand *left = IC_LEFT(ic);
3209 operand *right = IC_RIGHT(ic);
3210 operand *result= IC_RESULT(ic);
3212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3213 /* assign the amsops */
3214 aopOp (left,ic,FALSE);
3215 aopOp (right,ic,FALSE);
3216 aopOp (result,ic,TRUE);
3218 DEBUGpic14_AopType(__LINE__,left,right,result);
3220 /* special cases first */
3222 if (AOP_TYPE(left) == AOP_CRY &&
3223 AOP_TYPE(right)== AOP_CRY) {
3224 genMultbits(left,right,result);
3228 /* if both are of size == 1 */
3229 if (AOP_SIZE(left) == 1 &&
3230 AOP_SIZE(right) == 1 ) {
3231 genMultOneByte(left,right,result);
3235 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3237 /* should have been converted to function call */
3241 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3242 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3243 freeAsmop(result,NULL,ic,TRUE);
3246 /*-----------------------------------------------------------------*/
3247 /* genDivbits :- division of bits */
3248 /*-----------------------------------------------------------------*/
3249 static void genDivbits (operand *left,
3256 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3257 /* the result must be bit */
3258 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3259 l = aopGet(AOP(left),0,FALSE,FALSE);
3263 pic14_emitcode("div","ab");
3264 pic14_emitcode("rrc","a");
3265 aopPut(AOP(result),"c",0);
3268 /*-----------------------------------------------------------------*/
3269 /* genDivOneByte : 8 bit division */
3270 /*-----------------------------------------------------------------*/
3271 static void genDivOneByte (operand *left,
3275 sym_link *opetype = operandType(result);
3280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3281 size = AOP_SIZE(result) - 1;
3283 /* signed or unsigned */
3284 if (SPEC_USIGN(opetype)) {
3285 /* unsigned is easy */
3286 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3287 l = aopGet(AOP(left),0,FALSE,FALSE);
3289 pic14_emitcode("div","ab");
3290 aopPut(AOP(result),"a",0);
3292 aopPut(AOP(result),zero,offset++);
3296 /* signed is a little bit more difficult */
3298 /* save the signs of the operands */
3299 l = aopGet(AOP(left),0,FALSE,FALSE);
3301 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3302 pic14_emitcode("push","acc"); /* save it on the stack */
3304 /* now sign adjust for both left & right */
3305 l = aopGet(AOP(right),0,FALSE,FALSE);
3307 lbl = newiTempLabel(NULL);
3308 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3309 pic14_emitcode("cpl","a");
3310 pic14_emitcode("inc","a");
3311 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3312 pic14_emitcode("mov","b,a");
3314 /* sign adjust left side */
3315 l = aopGet(AOP(left),0,FALSE,FALSE);
3318 lbl = newiTempLabel(NULL);
3319 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3320 pic14_emitcode("cpl","a");
3321 pic14_emitcode("inc","a");
3322 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3324 /* now the division */
3325 pic14_emitcode("div","ab");
3326 /* we are interested in the lower order
3328 pic14_emitcode("mov","b,a");
3329 lbl = newiTempLabel(NULL);
3330 pic14_emitcode("pop","acc");
3331 /* if there was an over flow we don't
3332 adjust the sign of the result */
3333 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3334 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3336 pic14_emitcode("clr","a");
3337 pic14_emitcode("subb","a,b");
3338 pic14_emitcode("mov","b,a");
3339 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3341 /* now we are done */
3342 aopPut(AOP(result),"b",0);
3344 pic14_emitcode("mov","c,b.7");
3345 pic14_emitcode("subb","a,acc");
3348 aopPut(AOP(result),"a",offset++);
3352 /*-----------------------------------------------------------------*/
3353 /* genDiv - generates code for division */
3354 /*-----------------------------------------------------------------*/
3355 static void genDiv (iCode *ic)
3357 operand *left = IC_LEFT(ic);
3358 operand *right = IC_RIGHT(ic);
3359 operand *result= IC_RESULT(ic);
3361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3362 /* assign the amsops */
3363 aopOp (left,ic,FALSE);
3364 aopOp (right,ic,FALSE);
3365 aopOp (result,ic,TRUE);
3367 /* special cases first */
3369 if (AOP_TYPE(left) == AOP_CRY &&
3370 AOP_TYPE(right)== AOP_CRY) {
3371 genDivbits(left,right,result);
3375 /* if both are of size == 1 */
3376 if (AOP_SIZE(left) == 1 &&
3377 AOP_SIZE(right) == 1 ) {
3378 genDivOneByte(left,right,result);
3382 /* should have been converted to function call */
3385 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3386 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3387 freeAsmop(result,NULL,ic,TRUE);
3390 /*-----------------------------------------------------------------*/
3391 /* genModbits :- modulus of bits */
3392 /*-----------------------------------------------------------------*/
3393 static void genModbits (operand *left,
3400 /* the result must be bit */
3401 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3402 l = aopGet(AOP(left),0,FALSE,FALSE);
3406 pic14_emitcode("div","ab");
3407 pic14_emitcode("mov","a,b");
3408 pic14_emitcode("rrc","a");
3409 aopPut(AOP(result),"c",0);
3412 /*-----------------------------------------------------------------*/
3413 /* genModOneByte : 8 bit modulus */
3414 /*-----------------------------------------------------------------*/
3415 static void genModOneByte (operand *left,
3419 sym_link *opetype = operandType(result);
3423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3424 /* signed or unsigned */
3425 if (SPEC_USIGN(opetype)) {
3426 /* unsigned is easy */
3427 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3428 l = aopGet(AOP(left),0,FALSE,FALSE);
3430 pic14_emitcode("div","ab");
3431 aopPut(AOP(result),"b",0);
3435 /* signed is a little bit more difficult */
3437 /* save the signs of the operands */
3438 l = aopGet(AOP(left),0,FALSE,FALSE);
3441 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3442 pic14_emitcode("push","acc"); /* save it on the stack */
3444 /* now sign adjust for both left & right */
3445 l = aopGet(AOP(right),0,FALSE,FALSE);
3448 lbl = newiTempLabel(NULL);
3449 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3450 pic14_emitcode("cpl","a");
3451 pic14_emitcode("inc","a");
3452 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3453 pic14_emitcode("mov","b,a");
3455 /* sign adjust left side */
3456 l = aopGet(AOP(left),0,FALSE,FALSE);
3459 lbl = newiTempLabel(NULL);
3460 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3461 pic14_emitcode("cpl","a");
3462 pic14_emitcode("inc","a");
3463 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3465 /* now the multiplication */
3466 pic14_emitcode("div","ab");
3467 /* we are interested in the lower order
3469 lbl = newiTempLabel(NULL);
3470 pic14_emitcode("pop","acc");
3471 /* if there was an over flow we don't
3472 adjust the sign of the result */
3473 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3474 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3476 pic14_emitcode("clr","a");
3477 pic14_emitcode("subb","a,b");
3478 pic14_emitcode("mov","b,a");
3479 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3481 /* now we are done */
3482 aopPut(AOP(result),"b",0);
3486 /*-----------------------------------------------------------------*/
3487 /* genMod - generates code for division */
3488 /*-----------------------------------------------------------------*/
3489 static void genMod (iCode *ic)
3491 operand *left = IC_LEFT(ic);
3492 operand *right = IC_RIGHT(ic);
3493 operand *result= IC_RESULT(ic);
3495 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3496 /* assign the amsops */
3497 aopOp (left,ic,FALSE);
3498 aopOp (right,ic,FALSE);
3499 aopOp (result,ic,TRUE);
3501 /* special cases first */
3503 if (AOP_TYPE(left) == AOP_CRY &&
3504 AOP_TYPE(right)== AOP_CRY) {
3505 genModbits(left,right,result);
3509 /* if both are of size == 1 */
3510 if (AOP_SIZE(left) == 1 &&
3511 AOP_SIZE(right) == 1 ) {
3512 genModOneByte(left,right,result);
3516 /* should have been converted to function call */
3520 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3521 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3522 freeAsmop(result,NULL,ic,TRUE);
3525 /*-----------------------------------------------------------------*/
3526 /* genIfxJump :- will create a jump depending on the ifx */
3527 /*-----------------------------------------------------------------*/
3529 note: May need to add parameter to indicate when a variable is in bit space.
3531 static void genIfxJump (iCode *ic, char *jval)
3534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3535 /* if true label then we jump if condition
3537 if ( IC_TRUE(ic) ) {
3539 if(strcmp(jval,"a") == 0)
3541 else if (strcmp(jval,"c") == 0)
3544 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3545 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3548 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3549 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3553 /* false label is present */
3554 if(strcmp(jval,"a") == 0)
3556 else if (strcmp(jval,"c") == 0)
3559 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3560 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3563 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3564 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3569 /* mark the icode as generated */
3573 /*-----------------------------------------------------------------*/
3575 /*-----------------------------------------------------------------*/
3576 static void genSkip(iCode *ifx,int status_bit)
3581 if ( IC_TRUE(ifx) ) {
3582 switch(status_bit) {
3597 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3598 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3602 switch(status_bit) {
3616 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3617 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3623 /*-----------------------------------------------------------------*/
3625 /*-----------------------------------------------------------------*/
3626 static void genSkipc(resolvedIfx *rifx)
3636 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3637 rifx->generated = 1;
3640 /*-----------------------------------------------------------------*/
3642 /*-----------------------------------------------------------------*/
3643 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3648 if( (rifx->condition ^ invert_condition) & 1)
3653 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3654 rifx->generated = 1;
3657 /*-----------------------------------------------------------------*/
3659 /*-----------------------------------------------------------------*/
3660 static void genSkipz(iCode *ifx, int condition)
3671 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3673 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3676 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3678 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3681 /*-----------------------------------------------------------------*/
3683 /*-----------------------------------------------------------------*/
3684 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3690 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3692 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3695 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3696 rifx->generated = 1;
3700 /*-----------------------------------------------------------------*/
3701 /* genChkZeroes :- greater or less than comparison */
3702 /* For each byte in a literal that is zero, inclusive or the */
3703 /* the corresponding byte in the operand with W */
3704 /* returns true if any of the bytes are zero */
3705 /*-----------------------------------------------------------------*/
3706 static int genChkZeroes(operand *op, int lit, int size)
3713 i = (lit >> (size*8)) & 0xff;
3717 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3719 emitpcode(POC_IORFW, popGet(AOP(op),size));
3728 /*-----------------------------------------------------------------*/
3729 /* genCmp :- greater or less than comparison */
3730 /*-----------------------------------------------------------------*/
3731 static void genCmp (operand *left,operand *right,
3732 operand *result, iCode *ifx, int sign)
3734 int size; //, offset = 0 ;
3735 unsigned long lit = 0L,i = 0;
3736 resolvedIfx rFalseIfx;
3737 // resolvedIfx rTrueIfx;
3739 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3742 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3743 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3747 resolveIfx(&rFalseIfx,ifx);
3748 truelbl = newiTempLabel(NULL);
3749 size = max(AOP_SIZE(left),AOP_SIZE(right));
3751 DEBUGpic14_AopType(__LINE__,left,right,result);
3755 /* if literal is on the right then swap with left */
3756 if ((AOP_TYPE(right) == AOP_LIT)) {
3757 operand *tmp = right ;
3758 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3759 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3762 lit = (lit - 1) & mask;
3765 rFalseIfx.condition ^= 1;
3768 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3769 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3773 //if(IC_TRUE(ifx) == NULL)
3774 /* if left & right are bit variables */
3775 if (AOP_TYPE(left) == AOP_CRY &&
3776 AOP_TYPE(right) == AOP_CRY ) {
3777 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3778 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3780 /* subtract right from left if at the
3781 end the carry flag is set then we know that
3782 left is greater than right */
3786 symbol *lbl = newiTempLabel(NULL);
3789 if(AOP_TYPE(right) == AOP_LIT) {
3791 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3793 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3800 genSkipCond(&rFalseIfx,left,size-1,7);
3802 /* no need to compare to 0...*/
3803 /* NOTE: this is a de-generate compare that most certainly
3804 * creates some dead code. */
3805 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3807 if(ifx) ifx->generated = 1;
3814 //i = (lit >> (size*8)) & 0xff;
3815 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3817 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3819 i = ((0-lit) & 0xff);
3822 /* lit is 0x7f, all signed chars are less than
3823 * this except for 0x7f itself */
3824 emitpcode(POC_XORLW, popGetLit(0x7f));
3825 genSkipz2(&rFalseIfx,0);
3827 emitpcode(POC_ADDLW, popGetLit(0x80));
3828 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3829 genSkipc(&rFalseIfx);
3834 genSkipz2(&rFalseIfx,1);
3836 emitpcode(POC_ADDLW, popGetLit(i));
3837 genSkipc(&rFalseIfx);
3841 if(ifx) ifx->generated = 1;
3845 /* chars are out of the way. now do ints and longs */
3848 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3855 genSkipCond(&rFalseIfx,left,size,7);
3856 if(ifx) ifx->generated = 1;
3861 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3863 //rFalseIfx.condition ^= 1;
3864 //genSkipCond(&rFalseIfx,left,size,7);
3865 //rFalseIfx.condition ^= 1;
3867 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3868 if(rFalseIfx.condition)
3869 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3871 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3873 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3874 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3875 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3878 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3880 if(rFalseIfx.condition) {
3882 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3888 genSkipc(&rFalseIfx);
3889 emitpLabel(truelbl->key);
3890 if(ifx) ifx->generated = 1;
3897 if( (lit & 0xff) == 0) {
3898 /* lower byte is zero */
3899 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3900 i = ((lit >> 8) & 0xff) ^0x80;
3901 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3902 emitpcode(POC_ADDLW, popGetLit( 0x80));
3903 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3904 genSkipc(&rFalseIfx);
3907 if(ifx) ifx->generated = 1;
3912 /* Special cases for signed longs */
3913 if( (lit & 0xffffff) == 0) {
3914 /* lower byte is zero */
3915 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3916 i = ((lit >> 8*3) & 0xff) ^0x80;
3917 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3918 emitpcode(POC_ADDLW, popGetLit( 0x80));
3919 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3920 genSkipc(&rFalseIfx);
3923 if(ifx) ifx->generated = 1;
3931 if(lit & (0x80 << (size*8))) {
3932 /* lit is negative */
3933 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3935 //genSkipCond(&rFalseIfx,left,size,7);
3937 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3939 if(rFalseIfx.condition)
3940 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3942 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3946 /* lit is positive */
3947 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3948 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3949 if(rFalseIfx.condition)
3950 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3952 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3957 This works, but is only good for ints.
3958 It also requires a "known zero" register.
3959 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3960 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3961 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3962 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3963 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3964 genSkipc(&rFalseIfx);
3966 emitpLabel(truelbl->key);
3967 if(ifx) ifx->generated = 1;
3971 /* There are no more special cases, so perform a general compare */
3973 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3974 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3978 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3980 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3982 //rFalseIfx.condition ^= 1;
3983 genSkipc(&rFalseIfx);
3985 emitpLabel(truelbl->key);
3987 if(ifx) ifx->generated = 1;
3994 /* sign is out of the way. So now do an unsigned compare */
3995 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3998 /* General case - compare to an unsigned literal on the right.*/
4000 i = (lit >> (size*8)) & 0xff;
4001 emitpcode(POC_MOVLW, popGetLit(i));
4002 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4004 i = (lit >> (size*8)) & 0xff;
4007 emitpcode(POC_MOVLW, popGetLit(i));
4009 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4011 /* this byte of the lit is zero,
4012 *if it's not the last then OR in the variable */
4014 emitpcode(POC_IORFW, popGet(AOP(left),size));
4019 emitpLabel(lbl->key);
4020 //if(emitFinalCheck)
4021 genSkipc(&rFalseIfx);
4023 emitpLabel(truelbl->key);
4025 if(ifx) ifx->generated = 1;
4032 if(AOP_TYPE(left) == AOP_LIT) {
4033 //symbol *lbl = newiTempLabel(NULL);
4035 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4038 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4041 if((lit == 0) && (sign == 0)){
4044 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4046 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4048 genSkipz2(&rFalseIfx,0);
4049 if(ifx) ifx->generated = 1;
4056 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4057 /* degenerate compare can never be true */
4058 if(rFalseIfx.condition == 0)
4059 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4061 if(ifx) ifx->generated = 1;
4066 /* signed comparisons to a literal byte */
4068 int lp1 = (lit+1) & 0xff;
4070 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4073 rFalseIfx.condition ^= 1;
4074 genSkipCond(&rFalseIfx,right,0,7);
4077 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4078 emitpcode(POC_XORLW, popGetLit(0x7f));
4079 genSkipz2(&rFalseIfx,1);
4082 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4083 emitpcode(POC_ADDLW, popGetLit(0x80));
4084 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4085 rFalseIfx.condition ^= 1;
4086 genSkipc(&rFalseIfx);
4089 if(ifx) ifx->generated = 1;
4091 /* unsigned comparisons to a literal byte */
4093 switch(lit & 0xff ) {
4095 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4096 genSkipz2(&rFalseIfx,0);
4097 if(ifx) ifx->generated = 1;
4100 rFalseIfx.condition ^= 1;
4101 genSkipCond(&rFalseIfx,right,0,7);
4102 if(ifx) ifx->generated = 1;
4106 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4107 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4109 rFalseIfx.condition ^= 1;
4110 if (AOP_TYPE(result) == AOP_CRY) {
4111 genSkipc(&rFalseIfx);
4112 if(ifx) ifx->generated = 1;
4114 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4115 emitpcode(POC_CLRF, popGet(AOP(result),0));
4116 emitpcode(POC_RLF, popGet(AOP(result),0));
4117 emitpcode(POC_MOVLW, popGetLit(0x01));
4118 emitpcode(POC_XORWF, popGet(AOP(result),0));
4129 /* Size is greater than 1 */
4137 /* this means lit = 0xffffffff, or -1 */
4140 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4141 rFalseIfx.condition ^= 1;
4142 genSkipCond(&rFalseIfx,right,size,7);
4143 if(ifx) ifx->generated = 1;
4150 if(rFalseIfx.condition) {
4151 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4155 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4157 emitpcode(POC_IORFW, popGet(AOP(right),size));
4161 if(rFalseIfx.condition) {
4162 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4163 emitpLabel(truelbl->key);
4165 rFalseIfx.condition ^= 1;
4166 genSkipCond(&rFalseIfx,right,s,7);
4169 if(ifx) ifx->generated = 1;
4173 if((size == 1) && (0 == (lp1&0xff))) {
4174 /* lower byte of signed word is zero */
4175 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4176 i = ((lp1 >> 8) & 0xff) ^0x80;
4177 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4178 emitpcode(POC_ADDLW, popGetLit( 0x80));
4179 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4180 rFalseIfx.condition ^= 1;
4181 genSkipc(&rFalseIfx);
4184 if(ifx) ifx->generated = 1;
4188 if(lit & (0x80 << (size*8))) {
4189 /* Lit is less than zero */
4190 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4191 //rFalseIfx.condition ^= 1;
4192 //genSkipCond(&rFalseIfx,left,size,7);
4193 //rFalseIfx.condition ^= 1;
4194 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4195 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4197 if(rFalseIfx.condition)
4198 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4200 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4204 /* Lit is greater than or equal to zero */
4205 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4206 //rFalseIfx.condition ^= 1;
4207 //genSkipCond(&rFalseIfx,right,size,7);
4208 //rFalseIfx.condition ^= 1;
4210 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4211 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4213 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214 if(rFalseIfx.condition)
4215 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4217 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4222 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4223 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4227 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4229 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4231 rFalseIfx.condition ^= 1;
4232 //rFalseIfx.condition = 1;
4233 genSkipc(&rFalseIfx);
4235 emitpLabel(truelbl->key);
4237 if(ifx) ifx->generated = 1;
4242 /* compare word or long to an unsigned literal on the right.*/
4247 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4250 break; /* handled above */
4253 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4255 emitpcode(POC_IORFW, popGet(AOP(right),size));
4256 genSkipz2(&rFalseIfx,0);
4260 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4262 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265 if(rFalseIfx.condition)
4266 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4268 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4271 emitpcode(POC_MOVLW, popGetLit(lit+1));
4272 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4274 rFalseIfx.condition ^= 1;
4275 genSkipc(&rFalseIfx);
4278 emitpLabel(truelbl->key);
4280 if(ifx) ifx->generated = 1;
4286 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4287 i = (lit >> (size*8)) & 0xff;
4289 emitpcode(POC_MOVLW, popGetLit(i));
4290 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4293 i = (lit >> (size*8)) & 0xff;
4296 emitpcode(POC_MOVLW, popGetLit(i));
4298 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4300 /* this byte of the lit is zero,
4301 *if it's not the last then OR in the variable */
4303 emitpcode(POC_IORFW, popGet(AOP(right),size));
4308 emitpLabel(lbl->key);
4310 rFalseIfx.condition ^= 1;
4311 genSkipc(&rFalseIfx);
4315 emitpLabel(truelbl->key);
4316 if(ifx) ifx->generated = 1;
4320 /* Compare two variables */
4322 DEBUGpic14_emitcode(";sign","%d",sign);
4326 /* Sigh. thus sucks... */
4328 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4329 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4330 emitpcode(POC_MOVLW, popGetLit(0x80));
4331 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4332 emitpcode(POC_XORFW, popGet(AOP(right),size));
4333 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4335 /* Signed char comparison */
4336 /* Special thanks to Nikolai Golovchenko for this snippet */
4337 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4338 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4339 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4340 emitpcode(POC_XORFW, popGet(AOP(left),0));
4341 emitpcode(POC_XORFW, popGet(AOP(right),0));
4342 emitpcode(POC_ADDLW, popGetLit(0x80));
4344 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4345 genSkipc(&rFalseIfx);
4347 if(ifx) ifx->generated = 1;
4353 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4354 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4358 /* The rest of the bytes of a multi-byte compare */
4362 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4365 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4366 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4371 emitpLabel(lbl->key);
4373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4374 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4375 (AOP_TYPE(result) == AOP_REG)) {
4376 emitpcode(POC_CLRF, popGet(AOP(result),0));
4377 emitpcode(POC_RLF, popGet(AOP(result),0));
4379 genSkipc(&rFalseIfx);
4381 //genSkipc(&rFalseIfx);
4382 if(ifx) ifx->generated = 1;
4389 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4391 pic14_outBitC(result);
4393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4394 /* if the result is used in the next
4395 ifx conditional branch then generate
4396 code a little differently */
4398 genIfxJump (ifx,"c");
4400 pic14_outBitC(result);
4401 /* leave the result in acc */
4406 /*-----------------------------------------------------------------*/
4407 /* genCmpGt :- greater than comparison */
4408 /*-----------------------------------------------------------------*/
4409 static void genCmpGt (iCode *ic, iCode *ifx)
4411 operand *left, *right, *result;
4412 sym_link *letype , *retype;
4415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4417 right= IC_RIGHT(ic);
4418 result = IC_RESULT(ic);
4420 letype = getSpec(operandType(left));
4421 retype =getSpec(operandType(right));
4422 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4423 /* assign the amsops */
4424 aopOp (left,ic,FALSE);
4425 aopOp (right,ic,FALSE);
4426 aopOp (result,ic,TRUE);
4428 genCmp(right, left, result, ifx, sign);
4430 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4431 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4432 freeAsmop(result,NULL,ic,TRUE);
4435 /*-----------------------------------------------------------------*/
4436 /* genCmpLt - less than comparisons */
4437 /*-----------------------------------------------------------------*/
4438 static void genCmpLt (iCode *ic, iCode *ifx)
4440 operand *left, *right, *result;
4441 sym_link *letype , *retype;
4444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4446 right= IC_RIGHT(ic);
4447 result = IC_RESULT(ic);
4449 letype = getSpec(operandType(left));
4450 retype =getSpec(operandType(right));
4451 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4453 /* assign the amsops */
4454 aopOp (left,ic,FALSE);
4455 aopOp (right,ic,FALSE);
4456 aopOp (result,ic,TRUE);
4458 genCmp(left, right, result, ifx, sign);
4460 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4461 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4462 freeAsmop(result,NULL,ic,TRUE);
4465 /*-----------------------------------------------------------------*/
4466 /* genc16bit2lit - compare a 16 bit value to a literal */
4467 /*-----------------------------------------------------------------*/
4468 static void genc16bit2lit(operand *op, int lit, int offset)
4472 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4473 if( (lit&0xff) == 0)
4478 switch( BYTEofLONG(lit,i)) {
4480 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4483 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4486 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4489 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4490 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4495 switch( BYTEofLONG(lit,i)) {
4497 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4501 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4505 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4508 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4510 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4516 /*-----------------------------------------------------------------*/
4517 /* gencjneshort - compare and jump if not equal */
4518 /*-----------------------------------------------------------------*/
4519 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4521 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4523 int res_offset = 0; /* the result may be a different size then left or right */
4524 int res_size = AOP_SIZE(result);
4528 unsigned long lit = 0L;
4529 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4530 DEBUGpic14_AopType(__LINE__,left,right,result);
4532 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4533 resolveIfx(&rIfx,ifx);
4534 lbl = newiTempLabel(NULL);
4537 /* if the left side is a literal or
4538 if the right is in a pointer register and left
4540 if ((AOP_TYPE(left) == AOP_LIT) ||
4541 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4546 if(AOP_TYPE(right) == AOP_LIT)
4547 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4549 /* if the right side is a literal then anything goes */
4550 if (AOP_TYPE(right) == AOP_LIT &&
4551 AOP_TYPE(left) != AOP_DIR ) {
4554 genc16bit2lit(left, lit, 0);
4556 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4561 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4562 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4564 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4568 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4570 if(res_offset < res_size-1)
4578 /* if the right side is in a register or in direct space or
4579 if the left is a pointer register & right is not */
4580 else if (AOP_TYPE(right) == AOP_REG ||
4581 AOP_TYPE(right) == AOP_DIR ||
4582 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4583 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4584 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4585 int lbl_key = lbl->key;
4588 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4589 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4591 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4592 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4593 __FUNCTION__,__LINE__);
4597 /* switch(size) { */
4599 /* genc16bit2lit(left, lit, 0); */
4601 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4606 if((AOP_TYPE(left) == AOP_DIR) &&
4607 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4609 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4610 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4612 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4614 switch (lit & 0xff) {
4616 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4620 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4621 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4625 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4626 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4627 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4628 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4632 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4633 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4638 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4641 if(AOP_TYPE(result) == AOP_CRY) {
4642 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4647 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4649 /* fix me. probably need to check result size too */
4650 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4655 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4656 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4663 if(res_offset < res_size-1)
4668 } else if(AOP_TYPE(right) == AOP_REG &&
4669 AOP_TYPE(left) != AOP_DIR){
4672 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4673 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4674 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4679 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4681 if(res_offset < res_size-1)
4686 /* right is a pointer reg need both a & b */
4688 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4690 pic14_emitcode("mov","b,%s",l);
4691 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4692 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4697 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4699 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4701 emitpLabel(lbl->key);
4703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4710 /*-----------------------------------------------------------------*/
4711 /* gencjne - compare and jump if not equal */
4712 /*-----------------------------------------------------------------*/
4713 static void gencjne(operand *left, operand *right, iCode *ifx)
4715 symbol *tlbl = newiTempLabel(NULL);
4717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4718 gencjneshort(left, right, lbl);
4720 pic14_emitcode("mov","a,%s",one);
4721 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4722 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4723 pic14_emitcode("clr","a");
4724 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4726 emitpLabel(lbl->key);
4727 emitpLabel(tlbl->key);
4732 /*-----------------------------------------------------------------*/
4733 /* genCmpEq - generates code for equal to */
4734 /*-----------------------------------------------------------------*/
4735 static void genCmpEq (iCode *ic, iCode *ifx)
4737 operand *left, *right, *result;
4738 unsigned long lit = 0L;
4741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4744 DEBUGpic14_emitcode ("; ifx is non-null","");
4746 DEBUGpic14_emitcode ("; ifx is null","");
4748 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4749 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4750 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4752 size = max(AOP_SIZE(left),AOP_SIZE(right));
4754 DEBUGpic14_AopType(__LINE__,left,right,result);
4756 /* if literal, literal on the right or
4757 if the right is in a pointer register and left
4759 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4760 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4761 operand *tmp = right ;
4767 if(ifx && !AOP_SIZE(result)){
4769 /* if they are both bit variables */
4770 if (AOP_TYPE(left) == AOP_CRY &&
4771 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4772 if(AOP_TYPE(right) == AOP_LIT){
4773 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4775 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4776 pic14_emitcode("cpl","c");
4777 } else if(lit == 1L) {
4778 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4780 pic14_emitcode("clr","c");
4782 /* AOP_TYPE(right) == AOP_CRY */
4784 symbol *lbl = newiTempLabel(NULL);
4785 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4786 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4787 pic14_emitcode("cpl","c");
4788 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4790 /* if true label then we jump if condition
4792 tlbl = newiTempLabel(NULL);
4793 if ( IC_TRUE(ifx) ) {
4794 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4795 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4797 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4798 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4800 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4803 /* left and right are both bit variables, result is carry */
4806 resolveIfx(&rIfx,ifx);
4808 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4809 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4810 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4811 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4816 /* They're not both bit variables. Is the right a literal? */
4817 if(AOP_TYPE(right) == AOP_LIT) {
4818 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4823 switch(lit & 0xff) {
4825 if ( IC_TRUE(ifx) ) {
4826 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4828 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4830 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4831 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4835 if ( IC_TRUE(ifx) ) {
4836 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4838 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4840 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4841 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4845 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4847 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4852 /* end of size == 1 */
4856 genc16bit2lit(left,lit,offset);
4859 /* end of size == 2 */
4864 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4865 emitpcode(POC_IORFW,popGet(AOP(left),1));
4866 emitpcode(POC_IORFW,popGet(AOP(left),2));
4867 emitpcode(POC_IORFW,popGet(AOP(left),3));
4871 /* search for patterns that can be optimized */
4873 genc16bit2lit(left,lit,0);
4876 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4878 genc16bit2lit(left,lit,2);
4880 emitpcode(POC_IORFW,popGet(AOP(left),2));
4881 emitpcode(POC_IORFW,popGet(AOP(left),3));
4894 } else if(AOP_TYPE(right) == AOP_CRY ) {
4895 /* we know the left is not a bit, but that the right is */
4896 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4897 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4898 popGet(AOP(right),offset));
4899 emitpcode(POC_XORLW,popGetLit(1));
4901 /* if the two are equal, then W will be 0 and the Z bit is set
4902 * we could test Z now, or go ahead and check the high order bytes if
4903 * the variable we're comparing is larger than a byte. */
4906 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4908 if ( IC_TRUE(ifx) ) {
4910 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4911 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4914 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4915 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4919 /* They're both variables that are larger than bits */
4922 tlbl = newiTempLabel(NULL);
4925 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4926 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4928 if ( IC_TRUE(ifx) ) {
4931 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4932 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4935 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4936 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4940 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4941 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4945 if(s>1 && IC_TRUE(ifx)) {
4946 emitpLabel(tlbl->key);
4947 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4951 /* mark the icode as generated */
4956 /* if they are both bit variables */
4957 if (AOP_TYPE(left) == AOP_CRY &&
4958 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4959 if(AOP_TYPE(right) == AOP_LIT){
4960 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4962 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4963 pic14_emitcode("cpl","c");
4964 } else if(lit == 1L) {
4965 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4967 pic14_emitcode("clr","c");
4969 /* AOP_TYPE(right) == AOP_CRY */
4971 symbol *lbl = newiTempLabel(NULL);
4972 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4973 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4974 pic14_emitcode("cpl","c");
4975 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4978 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4979 pic14_outBitC(result);
4983 genIfxJump (ifx,"c");
4986 /* if the result is used in an arithmetic operation
4987 then put the result in place */
4988 pic14_outBitC(result);
4991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4992 gencjne(left,right,result,ifx);
4995 gencjne(left,right,newiTempLabel(NULL));
4997 if(IC_TRUE(ifx)->key)
4998 gencjne(left,right,IC_TRUE(ifx)->key);
5000 gencjne(left,right,IC_FALSE(ifx)->key);
5004 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5005 aopPut(AOP(result),"a",0);
5010 genIfxJump (ifx,"a");
5014 /* if the result is used in an arithmetic operation
5015 then put the result in place */
5017 if (AOP_TYPE(result) != AOP_CRY)
5018 pic14_outAcc(result);
5020 /* leave the result in acc */
5024 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5025 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5026 freeAsmop(result,NULL,ic,TRUE);
5029 /*-----------------------------------------------------------------*/
5030 /* ifxForOp - returns the icode containing the ifx for operand */
5031 /*-----------------------------------------------------------------*/
5032 static iCode *ifxForOp ( operand *op, iCode *ic )
5034 /* if true symbol then needs to be assigned */
5035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5036 if (IS_TRUE_SYMOP(op))
5039 /* if this has register type condition and
5040 the next instruction is ifx with the same operand
5041 and live to of the operand is upto the ifx only then */
5043 ic->next->op == IFX &&
5044 IC_COND(ic->next)->key == op->key &&
5045 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5049 ic->next->op == IFX &&
5050 IC_COND(ic->next)->key == op->key) {
5051 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5055 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5057 ic->next->op == IFX)
5058 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5061 ic->next->op == IFX &&
5062 IC_COND(ic->next)->key == op->key) {
5063 DEBUGpic14_emitcode ("; "," key is okay");
5064 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5065 OP_SYMBOL(op)->liveTo,
5072 /*-----------------------------------------------------------------*/
5073 /* genAndOp - for && operation */
5074 /*-----------------------------------------------------------------*/
5075 static void genAndOp (iCode *ic)
5077 operand *left,*right, *result;
5080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5081 /* note here that && operations that are in an
5082 if statement are taken away by backPatchLabels
5083 only those used in arthmetic operations remain */
5084 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5085 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5086 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5088 DEBUGpic14_AopType(__LINE__,left,right,result);
5090 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5091 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5092 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5094 /* if both are bit variables */
5095 /* if (AOP_TYPE(left) == AOP_CRY && */
5096 /* AOP_TYPE(right) == AOP_CRY ) { */
5097 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5098 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5099 /* pic14_outBitC(result); */
5101 /* tlbl = newiTempLabel(NULL); */
5102 /* pic14_toBoolean(left); */
5103 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5104 /* pic14_toBoolean(right); */
5105 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5106 /* pic14_outBitAcc(result); */
5109 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5111 freeAsmop(result,NULL,ic,TRUE);
5115 /*-----------------------------------------------------------------*/
5116 /* genOrOp - for || operation */
5117 /*-----------------------------------------------------------------*/
5120 modified this code, but it doesn't appear to ever get called
5123 static void genOrOp (iCode *ic)
5125 operand *left,*right, *result;
5128 /* note here that || operations that are in an
5129 if statement are taken away by backPatchLabels
5130 only those used in arthmetic operations remain */
5131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5132 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5133 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5134 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5136 DEBUGpic14_AopType(__LINE__,left,right,result);
5138 /* if both are bit variables */
5139 if (AOP_TYPE(left) == AOP_CRY &&
5140 AOP_TYPE(right) == AOP_CRY ) {
5141 pic14_emitcode("clrc","");
5142 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5143 AOP(left)->aopu.aop_dir,
5144 AOP(left)->aopu.aop_dir);
5145 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5146 AOP(right)->aopu.aop_dir,
5147 AOP(right)->aopu.aop_dir);
5148 pic14_emitcode("setc","");
5151 tlbl = newiTempLabel(NULL);
5152 pic14_toBoolean(left);
5154 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5155 pic14_toBoolean(right);
5156 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5158 pic14_outBitAcc(result);
5161 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5162 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5163 freeAsmop(result,NULL,ic,TRUE);
5166 /*-----------------------------------------------------------------*/
5167 /* isLiteralBit - test if lit == 2^n */
5168 /*-----------------------------------------------------------------*/
5169 static int isLiteralBit(unsigned long lit)
5171 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5172 0x100L,0x200L,0x400L,0x800L,
5173 0x1000L,0x2000L,0x4000L,0x8000L,
5174 0x10000L,0x20000L,0x40000L,0x80000L,
5175 0x100000L,0x200000L,0x400000L,0x800000L,
5176 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5177 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5181 for(idx = 0; idx < 32; idx++)
5187 /*-----------------------------------------------------------------*/
5188 /* continueIfTrue - */
5189 /*-----------------------------------------------------------------*/
5190 static void continueIfTrue (iCode *ic)
5192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5194 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5198 /*-----------------------------------------------------------------*/
5200 /*-----------------------------------------------------------------*/
5201 static void jumpIfTrue (iCode *ic)
5203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5205 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5209 /*-----------------------------------------------------------------*/
5210 /* jmpTrueOrFalse - */
5211 /*-----------------------------------------------------------------*/
5212 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5214 // ugly but optimized by peephole
5215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5217 symbol *nlbl = newiTempLabel(NULL);
5218 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5219 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5220 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5221 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5224 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5225 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5230 /*-----------------------------------------------------------------*/
5231 /* genAnd - code for and */
5232 /*-----------------------------------------------------------------*/
5233 static void genAnd (iCode *ic, iCode *ifx)
5235 operand *left, *right, *result;
5237 unsigned long lit = 0L;
5242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5243 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5244 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5245 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5247 resolveIfx(&rIfx,ifx);
5249 /* if left is a literal & right is not then exchange them */
5250 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5251 AOP_NEEDSACC(left)) {
5252 operand *tmp = right ;
5257 /* if result = right then exchange them */
5258 if(pic14_sameRegs(AOP(result),AOP(right))){
5259 operand *tmp = right ;
5264 /* if right is bit then exchange them */
5265 if (AOP_TYPE(right) == AOP_CRY &&
5266 AOP_TYPE(left) != AOP_CRY){
5267 operand *tmp = right ;
5271 if(AOP_TYPE(right) == AOP_LIT)
5272 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5274 size = AOP_SIZE(result);
5276 DEBUGpic14_AopType(__LINE__,left,right,result);
5279 // result = bit & yy;
5280 if (AOP_TYPE(left) == AOP_CRY){
5281 // c = bit & literal;
5282 if(AOP_TYPE(right) == AOP_LIT){
5284 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5287 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5290 if(size && (AOP_TYPE(result) == AOP_CRY)){
5291 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5294 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5298 pic14_emitcode("clr","c");
5301 if (AOP_TYPE(right) == AOP_CRY){
5303 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5304 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5307 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5309 pic14_emitcode("rrc","a");
5310 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5316 pic14_outBitC(result);
5318 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5319 genIfxJump(ifx, "c");
5323 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5324 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5325 if((AOP_TYPE(right) == AOP_LIT) &&
5326 (AOP_TYPE(result) == AOP_CRY) &&
5327 (AOP_TYPE(left) != AOP_CRY)){
5328 int posbit = isLiteralBit(lit);
5332 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5335 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5341 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5342 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5344 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5345 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5348 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5349 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5350 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5357 symbol *tlbl = newiTempLabel(NULL);
5358 int sizel = AOP_SIZE(left);
5360 pic14_emitcode("setb","c");
5362 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5363 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5365 if((posbit = isLiteralBit(bytelit)) != 0)
5366 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5368 if(bytelit != 0x0FFL)
5369 pic14_emitcode("anl","a,%s",
5370 aopGet(AOP(right),offset,FALSE,TRUE));
5371 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5376 // bit = left & literal
5378 pic14_emitcode("clr","c");
5379 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5381 // if(left & literal)
5384 jmpTrueOrFalse(ifx, tlbl);
5388 pic14_outBitC(result);
5392 /* if left is same as result */
5393 if(pic14_sameRegs(AOP(result),AOP(left))){
5395 for(;size--; offset++,lit>>=8) {
5396 if(AOP_TYPE(right) == AOP_LIT){
5397 switch(lit & 0xff) {
5399 /* and'ing with 0 has clears the result */
5400 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5401 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5404 /* and'ing with 0xff is a nop when the result and left are the same */
5409 int p = my_powof2( (~lit) & 0xff );
5411 /* only one bit is set in the literal, so use a bcf instruction */
5412 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5413 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5416 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5417 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5418 if(know_W != (lit&0xff))
5419 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5421 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5426 if (AOP_TYPE(left) == AOP_ACC) {
5427 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5429 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5430 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5437 // left & result in different registers
5438 if(AOP_TYPE(result) == AOP_CRY){
5440 // if(size), result in bit
5441 // if(!size && ifx), conditional oper: if(left & right)
5442 symbol *tlbl = newiTempLabel(NULL);
5443 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5445 pic14_emitcode("setb","c");
5447 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5448 pic14_emitcode("anl","a,%s",
5449 aopGet(AOP(left),offset,FALSE,FALSE));
5450 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5455 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5456 pic14_outBitC(result);
5458 jmpTrueOrFalse(ifx, tlbl);
5460 for(;(size--);offset++) {
5462 // result = left & right
5463 if(AOP_TYPE(right) == AOP_LIT){
5464 int t = (lit >> (offset*8)) & 0x0FFL;
5467 pic14_emitcode("clrf","%s",
5468 aopGet(AOP(result),offset,FALSE,FALSE));
5469 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5472 pic14_emitcode("movf","%s,w",
5473 aopGet(AOP(left),offset,FALSE,FALSE));
5474 pic14_emitcode("movwf","%s",
5475 aopGet(AOP(result),offset,FALSE,FALSE));
5476 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5477 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5480 pic14_emitcode("movlw","0x%x",t);
5481 pic14_emitcode("andwf","%s,w",
5482 aopGet(AOP(left),offset,FALSE,FALSE));
5483 pic14_emitcode("movwf","%s",
5484 aopGet(AOP(result),offset,FALSE,FALSE));
5486 emitpcode(POC_MOVLW, popGetLit(t));
5487 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5488 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5493 if (AOP_TYPE(left) == AOP_ACC) {
5494 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5495 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5497 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5498 pic14_emitcode("andwf","%s,w",
5499 aopGet(AOP(left),offset,FALSE,FALSE));
5500 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5501 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5503 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5504 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5510 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5511 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5512 freeAsmop(result,NULL,ic,TRUE);
5515 /*-----------------------------------------------------------------*/
5516 /* genOr - code for or */
5517 /*-----------------------------------------------------------------*/
5518 static void genOr (iCode *ic, iCode *ifx)
5520 operand *left, *right, *result;
5522 unsigned long lit = 0L;
5524 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5526 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5527 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5528 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5530 DEBUGpic14_AopType(__LINE__,left,right,result);
5532 /* if left is a literal & right is not then exchange them */
5533 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5534 AOP_NEEDSACC(left)) {
5535 operand *tmp = right ;
5540 /* if result = right then exchange them */
5541 if(pic14_sameRegs(AOP(result),AOP(right))){
5542 operand *tmp = right ;
5547 /* if right is bit then exchange them */
5548 if (AOP_TYPE(right) == AOP_CRY &&
5549 AOP_TYPE(left) != AOP_CRY){
5550 operand *tmp = right ;
5555 DEBUGpic14_AopType(__LINE__,left,right,result);
5557 if(AOP_TYPE(right) == AOP_LIT)
5558 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5560 size = AOP_SIZE(result);
5564 if (AOP_TYPE(left) == AOP_CRY){
5565 if(AOP_TYPE(right) == AOP_LIT){
5566 // c = bit & literal;
5568 // lit != 0 => result = 1
5569 if(AOP_TYPE(result) == AOP_CRY){
5571 emitpcode(POC_BSF, popGet(AOP(result),0));
5572 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5573 // AOP(result)->aopu.aop_dir,
5574 // AOP(result)->aopu.aop_dir);
5576 continueIfTrue(ifx);
5580 // lit == 0 => result = left
5581 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5583 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5586 if (AOP_TYPE(right) == AOP_CRY){
5587 if(pic14_sameRegs(AOP(result),AOP(left))){
5589 emitpcode(POC_BCF, popGet(AOP(result),0));
5590 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5591 emitpcode(POC_BSF, popGet(AOP(result),0));
5593 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5594 AOP(result)->aopu.aop_dir,
5595 AOP(result)->aopu.aop_dir);
5596 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5597 AOP(right)->aopu.aop_dir,
5598 AOP(right)->aopu.aop_dir);
5599 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5600 AOP(result)->aopu.aop_dir,
5601 AOP(result)->aopu.aop_dir);
5603 if( AOP_TYPE(result) == AOP_ACC) {
5604 emitpcode(POC_MOVLW, popGetLit(0));
5605 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5606 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5607 emitpcode(POC_MOVLW, popGetLit(1));
5611 emitpcode(POC_BCF, popGet(AOP(result),0));
5612 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5613 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5614 emitpcode(POC_BSF, popGet(AOP(result),0));
5616 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5617 AOP(result)->aopu.aop_dir,
5618 AOP(result)->aopu.aop_dir);
5619 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5620 AOP(right)->aopu.aop_dir,
5621 AOP(right)->aopu.aop_dir);
5622 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5623 AOP(left)->aopu.aop_dir,
5624 AOP(left)->aopu.aop_dir);
5625 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5626 AOP(result)->aopu.aop_dir,
5627 AOP(result)->aopu.aop_dir);
5632 symbol *tlbl = newiTempLabel(NULL);
5633 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5636 emitpcode(POC_BCF, popGet(AOP(result),0));
5637 if( AOP_TYPE(right) == AOP_ACC) {
5638 emitpcode(POC_IORLW, popGetLit(0));
5640 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5641 emitpcode(POC_BSF, popGet(AOP(result),0));
5646 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5647 pic14_emitcode(";XXX setb","c");
5648 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5649 AOP(left)->aopu.aop_dir,tlbl->key+100);
5650 pic14_toBoolean(right);
5651 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5652 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5653 jmpTrueOrFalse(ifx, tlbl);
5657 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5664 pic14_outBitC(result);
5666 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5667 genIfxJump(ifx, "c");
5671 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5672 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5673 if((AOP_TYPE(right) == AOP_LIT) &&
5674 (AOP_TYPE(result) == AOP_CRY) &&
5675 (AOP_TYPE(left) != AOP_CRY)){
5677 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5680 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5682 continueIfTrue(ifx);
5685 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5686 // lit = 0, result = boolean(left)
5688 pic14_emitcode(";XXX setb","c");
5689 pic14_toBoolean(right);
5691 symbol *tlbl = newiTempLabel(NULL);
5692 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5694 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5696 genIfxJump (ifx,"a");
5700 pic14_outBitC(result);
5704 /* if left is same as result */
5705 if(pic14_sameRegs(AOP(result),AOP(left))){
5707 for(;size--; offset++,lit>>=8) {
5708 if(AOP_TYPE(right) == AOP_LIT){
5709 if((lit & 0xff) == 0)
5710 /* or'ing with 0 has no effect */
5713 int p = my_powof2(lit & 0xff);
5715 /* only one bit is set in the literal, so use a bsf instruction */
5717 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5719 if(know_W != (lit & 0xff))
5720 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5721 know_W = lit & 0xff;
5722 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5727 if (AOP_TYPE(left) == AOP_ACC) {
5728 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5729 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5731 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5732 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5734 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5735 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5741 // left & result in different registers
5742 if(AOP_TYPE(result) == AOP_CRY){
5744 // if(size), result in bit
5745 // if(!size && ifx), conditional oper: if(left | right)
5746 symbol *tlbl = newiTempLabel(NULL);
5747 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5748 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5752 pic14_emitcode(";XXX setb","c");
5754 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5755 pic14_emitcode(";XXX orl","a,%s",
5756 aopGet(AOP(left),offset,FALSE,FALSE));
5757 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5762 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5763 pic14_outBitC(result);
5765 jmpTrueOrFalse(ifx, tlbl);
5766 } else for(;(size--);offset++){
5768 // result = left & right
5769 if(AOP_TYPE(right) == AOP_LIT){
5770 int t = (lit >> (offset*8)) & 0x0FFL;
5773 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5774 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5776 pic14_emitcode("movf","%s,w",
5777 aopGet(AOP(left),offset,FALSE,FALSE));
5778 pic14_emitcode("movwf","%s",
5779 aopGet(AOP(result),offset,FALSE,FALSE));
5782 emitpcode(POC_MOVLW, popGetLit(t));
5783 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5784 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5786 pic14_emitcode("movlw","0x%x",t);
5787 pic14_emitcode("iorwf","%s,w",
5788 aopGet(AOP(left),offset,FALSE,FALSE));
5789 pic14_emitcode("movwf","%s",
5790 aopGet(AOP(result),offset,FALSE,FALSE));
5796 // faster than result <- left, anl result,right
5797 // and better if result is SFR
5798 if (AOP_TYPE(left) == AOP_ACC) {
5799 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5800 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5802 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5803 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5805 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5806 pic14_emitcode("iorwf","%s,w",
5807 aopGet(AOP(left),offset,FALSE,FALSE));
5809 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5810 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5815 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5816 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5817 freeAsmop(result,NULL,ic,TRUE);
5820 /*-----------------------------------------------------------------*/
5821 /* genXor - code for xclusive or */
5822 /*-----------------------------------------------------------------*/
5823 static void genXor (iCode *ic, iCode *ifx)
5825 operand *left, *right, *result;
5827 unsigned long lit = 0L;
5829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5831 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5832 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5833 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5835 /* if left is a literal & right is not ||
5836 if left needs acc & right does not */
5837 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5838 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5839 operand *tmp = right ;
5844 /* if result = right then exchange them */
5845 if(pic14_sameRegs(AOP(result),AOP(right))){
5846 operand *tmp = right ;
5851 /* if right is bit then exchange them */
5852 if (AOP_TYPE(right) == AOP_CRY &&
5853 AOP_TYPE(left) != AOP_CRY){
5854 operand *tmp = right ;
5858 if(AOP_TYPE(right) == AOP_LIT)
5859 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5861 size = AOP_SIZE(result);
5865 if (AOP_TYPE(left) == AOP_CRY){
5866 if(AOP_TYPE(right) == AOP_LIT){
5867 // c = bit & literal;
5869 // lit>>1 != 0 => result = 1
5870 if(AOP_TYPE(result) == AOP_CRY){
5872 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5873 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5875 continueIfTrue(ifx);
5878 pic14_emitcode("setb","c");
5882 // lit == 0, result = left
5883 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5885 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5887 // lit == 1, result = not(left)
5888 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5889 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5890 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5891 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5894 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5895 pic14_emitcode("cpl","c");
5902 symbol *tlbl = newiTempLabel(NULL);
5903 if (AOP_TYPE(right) == AOP_CRY){
5905 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5908 int sizer = AOP_SIZE(right);
5910 // if val>>1 != 0, result = 1
5911 pic14_emitcode("setb","c");
5913 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5915 // test the msb of the lsb
5916 pic14_emitcode("anl","a,#0xfe");
5917 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5921 pic14_emitcode("rrc","a");
5923 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5924 pic14_emitcode("cpl","c");
5925 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5930 pic14_outBitC(result);
5932 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5933 genIfxJump(ifx, "c");
5937 if(pic14_sameRegs(AOP(result),AOP(left))){
5938 /* if left is same as result */
5939 for(;size--; offset++) {
5940 if(AOP_TYPE(right) == AOP_LIT){
5941 int t = (lit >> (offset*8)) & 0x0FFL;
5945 if (IS_AOP_PREG(left)) {
5946 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5947 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5948 aopPut(AOP(result),"a",offset);
5950 emitpcode(POC_MOVLW, popGetLit(t));
5951 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5952 pic14_emitcode("xrl","%s,%s",
5953 aopGet(AOP(left),offset,FALSE,TRUE),
5954 aopGet(AOP(right),offset,FALSE,FALSE));
5957 if (AOP_TYPE(left) == AOP_ACC)
5958 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5960 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5961 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5963 if (IS_AOP_PREG(left)) {
5964 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5965 aopPut(AOP(result),"a",offset);
5967 pic14_emitcode("xrl","%s,a",
5968 aopGet(AOP(left),offset,FALSE,TRUE));
5974 // left & result in different registers
5975 if(AOP_TYPE(result) == AOP_CRY){
5977 // if(size), result in bit
5978 // if(!size && ifx), conditional oper: if(left ^ right)
5979 symbol *tlbl = newiTempLabel(NULL);
5980 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5982 pic14_emitcode("setb","c");
5984 if((AOP_TYPE(right) == AOP_LIT) &&
5985 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5986 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5988 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5989 pic14_emitcode("xrl","a,%s",
5990 aopGet(AOP(left),offset,FALSE,FALSE));
5992 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5997 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5998 pic14_outBitC(result);
6000 jmpTrueOrFalse(ifx, tlbl);
6001 } else for(;(size--);offset++){
6003 // result = left & right
6004 if(AOP_TYPE(right) == AOP_LIT){
6005 int t = (lit >> (offset*8)) & 0x0FFL;
6008 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6009 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6010 pic14_emitcode("movf","%s,w",
6011 aopGet(AOP(left),offset,FALSE,FALSE));
6012 pic14_emitcode("movwf","%s",
6013 aopGet(AOP(result),offset,FALSE,FALSE));
6016 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6017 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6018 pic14_emitcode("comf","%s,w",
6019 aopGet(AOP(left),offset,FALSE,FALSE));
6020 pic14_emitcode("movwf","%s",
6021 aopGet(AOP(result),offset,FALSE,FALSE));
6024 emitpcode(POC_MOVLW, popGetLit(t));
6025 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6026 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027 pic14_emitcode("movlw","0x%x",t);
6028 pic14_emitcode("xorwf","%s,w",
6029 aopGet(AOP(left),offset,FALSE,FALSE));
6030 pic14_emitcode("movwf","%s",
6031 aopGet(AOP(result),offset,FALSE,FALSE));
6037 // faster than result <- left, anl result,right
6038 // and better if result is SFR
6039 if (AOP_TYPE(left) == AOP_ACC) {
6040 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6041 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6043 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6044 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6045 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6046 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6048 if ( AOP_TYPE(result) != AOP_ACC){
6049 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6050 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6056 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6057 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6058 freeAsmop(result,NULL,ic,TRUE);
6061 /*-----------------------------------------------------------------*/
6062 /* genInline - write the inline code out */
6063 /*-----------------------------------------------------------------*/
6064 static void genInline (iCode *ic)
6066 char *buffer, *bp, *bp1;
6068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6070 _G.inLine += (!options.asmpeep);
6072 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6073 strcpy(buffer,IC_INLINE(ic));
6075 /* emit each line as a code */
6081 addpCode2pBlock(pb,AssembleLine(bp1));
6088 pic14_emitcode(bp1,"");
6094 if ((bp1 != bp) && *bp1)
6095 addpCode2pBlock(pb,AssembleLine(bp1));
6099 _G.inLine -= (!options.asmpeep);
6102 /*-----------------------------------------------------------------*/
6103 /* genRRC - rotate right with carry */
6104 /*-----------------------------------------------------------------*/
6105 static void genRRC (iCode *ic)
6107 operand *left , *result ;
6108 int size, offset = 0, same;
6110 /* rotate right with carry */
6112 result=IC_RESULT(ic);
6113 aopOp (left,ic,FALSE);
6114 aopOp (result,ic,FALSE);
6116 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6118 same = pic14_sameRegs(AOP(result),AOP(left));
6120 size = AOP_SIZE(result);
6122 /* get the lsb and put it into the carry */
6123 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6130 emitpcode(POC_RRF, popGet(AOP(left),offset));
6132 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6133 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6139 freeAsmop(left,NULL,ic,TRUE);
6140 freeAsmop(result,NULL,ic,TRUE);
6143 /*-----------------------------------------------------------------*/
6144 /* genRLC - generate code for rotate left with carry */
6145 /*-----------------------------------------------------------------*/
6146 static void genRLC (iCode *ic)
6148 operand *left , *result ;
6149 int size, offset = 0;
6152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6153 /* rotate right with carry */
6155 result=IC_RESULT(ic);
6156 aopOp (left,ic,FALSE);
6157 aopOp (result,ic,FALSE);
6159 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6161 same = pic14_sameRegs(AOP(result),AOP(left));
6163 /* move it to the result */
6164 size = AOP_SIZE(result);
6166 /* get the msb and put it into the carry */
6167 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6174 emitpcode(POC_RLF, popGet(AOP(left),offset));
6176 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6177 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6184 freeAsmop(left,NULL,ic,TRUE);
6185 freeAsmop(result,NULL,ic,TRUE);
6188 /*-----------------------------------------------------------------*/
6189 /* genGetHbit - generates code get highest order bit */
6190 /*-----------------------------------------------------------------*/
6191 static void genGetHbit (iCode *ic)
6193 operand *left, *result;
6195 result=IC_RESULT(ic);
6196 aopOp (left,ic,FALSE);
6197 aopOp (result,ic,FALSE);
6199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6200 /* get the highest order byte into a */
6201 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6202 if(AOP_TYPE(result) == AOP_CRY){
6203 pic14_emitcode("rlc","a");
6204 pic14_outBitC(result);
6207 pic14_emitcode("rl","a");
6208 pic14_emitcode("anl","a,#0x01");
6209 pic14_outAcc(result);
6213 freeAsmop(left,NULL,ic,TRUE);
6214 freeAsmop(result,NULL,ic,TRUE);
6217 /*-----------------------------------------------------------------*/
6218 /* AccRol - rotate left accumulator by known count */
6219 /*-----------------------------------------------------------------*/
6220 static void AccRol (int shCount)
6222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6223 shCount &= 0x0007; // shCount : 0..7
6228 pic14_emitcode("rl","a");
6231 pic14_emitcode("rl","a");
6232 pic14_emitcode("rl","a");
6235 pic14_emitcode("swap","a");
6236 pic14_emitcode("rr","a");
6239 pic14_emitcode("swap","a");
6242 pic14_emitcode("swap","a");
6243 pic14_emitcode("rl","a");
6246 pic14_emitcode("rr","a");
6247 pic14_emitcode("rr","a");
6250 pic14_emitcode("rr","a");
6255 /*-----------------------------------------------------------------*/
6256 /* AccLsh - left shift accumulator by known count */
6257 /*-----------------------------------------------------------------*/
6258 static void AccLsh (int shCount)
6260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6263 pic14_emitcode("add","a,acc");
6266 pic14_emitcode("add","a,acc");
6267 pic14_emitcode("add","a,acc");
6269 /* rotate left accumulator */
6271 /* and kill the lower order bits */
6272 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6277 /*-----------------------------------------------------------------*/
6278 /* AccRsh - right shift accumulator by known count */
6279 /*-----------------------------------------------------------------*/
6280 static void AccRsh (int shCount)
6282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6286 pic14_emitcode("rrc","a");
6288 /* rotate right accumulator */
6289 AccRol(8 - shCount);
6290 /* and kill the higher order bits */
6291 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6297 /*-----------------------------------------------------------------*/
6298 /* AccSRsh - signed right shift accumulator by known count */
6299 /*-----------------------------------------------------------------*/
6300 static void AccSRsh (int shCount)
6303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6306 pic14_emitcode("mov","c,acc.7");
6307 pic14_emitcode("rrc","a");
6308 } else if(shCount == 2){
6309 pic14_emitcode("mov","c,acc.7");
6310 pic14_emitcode("rrc","a");
6311 pic14_emitcode("mov","c,acc.7");
6312 pic14_emitcode("rrc","a");
6314 tlbl = newiTempLabel(NULL);
6315 /* rotate right accumulator */
6316 AccRol(8 - shCount);
6317 /* and kill the higher order bits */
6318 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6319 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6320 pic14_emitcode("orl","a,#0x%02x",
6321 (unsigned char)~SRMask[shCount]);
6322 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6327 /*-----------------------------------------------------------------*/
6328 /* shiftR1Left2Result - shift right one byte from left to result */
6329 /*-----------------------------------------------------------------*/
6330 static void shiftR1Left2ResultSigned (operand *left, int offl,
6331 operand *result, int offr,
6336 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6338 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6342 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6344 emitpcode(POC_RRF, popGet(AOP(result),offr));
6346 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6347 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6353 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6355 emitpcode(POC_RRF, popGet(AOP(result),offr));
6357 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6358 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6360 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6361 emitpcode(POC_RRF, popGet(AOP(result),offr));
6367 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6369 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6370 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6373 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6374 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6375 emitpcode(POC_ANDLW, popGetLit(0x1f));
6377 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6378 emitpcode(POC_IORLW, popGetLit(0xe0));
6380 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6384 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6385 emitpcode(POC_ANDLW, popGetLit(0x0f));
6386 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6387 emitpcode(POC_IORLW, popGetLit(0xf0));
6388 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6394 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6395 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6397 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6398 emitpcode(POC_ANDLW, popGetLit(0x07));
6399 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6400 emitpcode(POC_IORLW, popGetLit(0xf8));
6401 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406 emitpcode(POC_MOVLW, popGetLit(0x00));
6407 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6408 emitpcode(POC_MOVLW, popGetLit(0xfe));
6409 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6410 emitpcode(POC_IORLW, popGetLit(0x01));
6411 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6414 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6415 emitpcode(POC_DECF, popGet(AOP(result),offr));
6416 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6417 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6423 emitpcode(POC_MOVLW, popGetLit(0x00));
6424 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6425 emitpcode(POC_MOVLW, popGetLit(0xff));
6426 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6428 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6429 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6430 emitpcode(POC_DECF, popGet(AOP(result),offr));
6438 /*-----------------------------------------------------------------*/
6439 /* shiftR1Left2Result - shift right one byte from left to result */
6440 /*-----------------------------------------------------------------*/
6441 static void shiftR1Left2Result (operand *left, int offl,
6442 operand *result, int offr,
6443 int shCount, int sign)
6447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6449 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6451 /* Copy the msb into the carry if signed. */
6453 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6463 emitpcode(POC_RRF, popGet(AOP(result),offr));
6465 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6466 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6472 emitpcode(POC_RRF, popGet(AOP(result),offr));
6474 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6478 emitpcode(POC_RRF, popGet(AOP(result),offr));
6483 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6485 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6486 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6489 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6490 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6491 emitpcode(POC_ANDLW, popGetLit(0x1f));
6492 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6496 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6497 emitpcode(POC_ANDLW, popGetLit(0x0f));
6498 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6502 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6503 emitpcode(POC_ANDLW, popGetLit(0x0f));
6504 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6506 emitpcode(POC_RRF, popGet(AOP(result),offr));
6511 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW, popGetLit(0x80));
6513 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514 emitpcode(POC_RLF, popGet(AOP(result),offr));
6515 emitpcode(POC_RLF, popGet(AOP(result),offr));
6520 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6521 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6522 emitpcode(POC_RLF, popGet(AOP(result),offr));
6531 /*-----------------------------------------------------------------*/
6532 /* shiftL1Left2Result - shift left one byte from left to result */
6533 /*-----------------------------------------------------------------*/
6534 static void shiftL1Left2Result (operand *left, int offl,
6535 operand *result, int offr, int shCount)
6540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6542 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6543 DEBUGpic14_emitcode ("; ***","same = %d",same);
6544 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6546 /* shift left accumulator */
6547 //AccLsh(shCount); // don't comment out just yet...
6548 // aopPut(AOP(result),"a",offr);
6552 /* Shift left 1 bit position */
6553 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6555 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6557 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6558 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6562 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6563 emitpcode(POC_ANDLW,popGetLit(0x7e));
6564 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6565 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6568 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6569 emitpcode(POC_ANDLW,popGetLit(0x3e));
6570 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6571 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6572 emitpcode(POC_RLF, popGet(AOP(result),offr));
6575 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6576 emitpcode(POC_ANDLW, popGetLit(0xf0));
6577 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6580 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6581 emitpcode(POC_ANDLW, popGetLit(0xf0));
6582 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6583 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6586 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6587 emitpcode(POC_ANDLW, popGetLit(0x30));
6588 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6590 emitpcode(POC_RLF, popGet(AOP(result),offr));
6593 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6594 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6595 emitpcode(POC_RRF, popGet(AOP(result),offr));
6599 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6604 /*-----------------------------------------------------------------*/
6605 /* movLeft2Result - move byte from left to result */
6606 /*-----------------------------------------------------------------*/
6607 static void movLeft2Result (operand *left, int offl,
6608 operand *result, int offr)
6611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6612 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6613 l = aopGet(AOP(left),offl,FALSE,FALSE);
6615 if (*l == '@' && (IS_AOP_PREG(result))) {
6616 pic14_emitcode("mov","a,%s",l);
6617 aopPut(AOP(result),"a",offr);
6619 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6620 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6625 /*-----------------------------------------------------------------*/
6626 /* shiftL2Left2Result - shift left two bytes from left to result */
6627 /*-----------------------------------------------------------------*/
6628 static void shiftL2Left2Result (operand *left, int offl,
6629 operand *result, int offr, int shCount)
6633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6635 if(pic14_sameRegs(AOP(result), AOP(left))) {
6643 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6644 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6645 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_RLF, popGet(AOP(result),offr));
6650 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6656 emitpcode(POC_MOVLW, popGetLit(0x0f));
6657 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6659 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6660 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6661 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6662 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RLF, popGet(AOP(result),offr));
6665 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6669 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRF, popGet(AOP(result),offr));
6671 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_RRF, popGet(AOP(result),offr));
6673 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_ANDLW,popGetLit(0xc0));
6675 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6676 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6677 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6678 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6683 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6685 emitpcode(POC_RRF, popGet(AOP(result),offr));
6695 /* note, use a mov/add for the shift since the mov has a
6696 chance of getting optimized out */
6697 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6698 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6699 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6700 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6701 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6705 emitpcode(POC_RLF, popGet(AOP(result),offr));
6706 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6712 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6713 emitpcode(POC_ANDLW, popGetLit(0xF0));
6714 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6716 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6717 emitpcode(POC_ANDLW, popGetLit(0xF0));
6718 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6719 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6723 emitpcode(POC_RLF, popGet(AOP(result),offr));
6724 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6728 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6729 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6730 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6731 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6733 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6734 emitpcode(POC_RRF, popGet(AOP(result),offr));
6735 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_ANDLW,popGetLit(0xc0));
6737 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6738 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6739 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6740 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6744 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6745 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6747 emitpcode(POC_RRF, popGet(AOP(result),offr));
6752 /*-----------------------------------------------------------------*/
6753 /* shiftR2Left2Result - shift right two bytes from left to result */
6754 /*-----------------------------------------------------------------*/
6755 static void shiftR2Left2Result (operand *left, int offl,
6756 operand *result, int offr,
6757 int shCount, int sign)
6761 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6762 same = pic14_sameRegs(AOP(result), AOP(left));
6764 if(same && ((offl + MSB16) == offr)){
6766 /* don't crash result[offr] */
6767 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6768 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6771 movLeft2Result(left,offl, result, offr);
6772 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6775 /* a:x >> shCount (x = lsb(result))*/
6778 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6780 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6789 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_RRF,popGet(AOP(result),offr));
6797 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6798 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6799 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6800 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6805 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_RRF,popGet(AOP(result),offr));
6816 emitpcode(POC_MOVLW, popGetLit(0xf0));
6817 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6818 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6820 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6821 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6822 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6823 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6825 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6826 emitpcode(POC_ANDLW, popGetLit(0x0f));
6827 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6829 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6830 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_ANDLW, popGetLit(0xf0));
6832 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6837 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6838 emitpcode(POC_RRF, popGet(AOP(result),offr));
6842 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6843 emitpcode(POC_BTFSC,
6844 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6845 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6853 emitpcode(POC_RLF, popGet(AOP(result),offr));
6854 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6856 emitpcode(POC_RLF, popGet(AOP(result),offr));
6857 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6858 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6859 emitpcode(POC_ANDLW,popGetLit(0x03));
6861 emitpcode(POC_BTFSC,
6862 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6863 emitpcode(POC_IORLW,popGetLit(0xfc));
6865 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6866 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6867 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6868 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6870 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6871 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6872 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6873 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6874 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6875 emitpcode(POC_RLF, popGet(AOP(result),offr));
6876 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_ANDLW,popGetLit(0x03));
6879 emitpcode(POC_BTFSC,
6880 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6881 emitpcode(POC_IORLW,popGetLit(0xfc));
6883 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6884 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6891 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6892 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6893 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6894 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6897 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6899 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6904 /*-----------------------------------------------------------------*/
6905 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6906 /*-----------------------------------------------------------------*/
6907 static void shiftLLeftOrResult (operand *left, int offl,
6908 operand *result, int offr, int shCount)
6910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6911 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6912 /* shift left accumulator */
6914 /* or with result */
6915 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6916 /* back to result */
6917 aopPut(AOP(result),"a",offr);
6920 /*-----------------------------------------------------------------*/
6921 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftRLeftOrResult (operand *left, int offl,
6924 operand *result, int offr, int shCount)
6926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6928 /* shift right accumulator */
6930 /* or with result */
6931 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6932 /* back to result */
6933 aopPut(AOP(result),"a",offr);
6936 /*-----------------------------------------------------------------*/
6937 /* genlshOne - left shift a one byte quantity by known count */
6938 /*-----------------------------------------------------------------*/
6939 static void genlshOne (operand *result, operand *left, int shCount)
6941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6942 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6945 /*-----------------------------------------------------------------*/
6946 /* genlshTwo - left shift two bytes by known amount != 0 */
6947 /*-----------------------------------------------------------------*/
6948 static void genlshTwo (operand *result,operand *left, int shCount)
6952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6953 size = pic14_getDataSize(result);
6955 /* if shCount >= 8 */
6961 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6963 movLeft2Result(left, LSB, result, MSB16);
6965 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6968 /* 1 <= shCount <= 7 */
6971 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6973 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6977 /*-----------------------------------------------------------------*/
6978 /* shiftLLong - shift left one long from left to result */
6979 /* offl = LSB or MSB16 */
6980 /*-----------------------------------------------------------------*/
6981 static void shiftLLong (operand *left, operand *result, int offr )
6984 int size = AOP_SIZE(result);
6986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 if(size >= LSB+offr){
6988 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6990 pic14_emitcode("add","a,acc");
6991 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6992 size >= MSB16+offr && offr != LSB )
6993 pic14_emitcode("xch","a,%s",
6994 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6996 aopPut(AOP(result),"a",LSB+offr);
6999 if(size >= MSB16+offr){
7000 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7001 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7004 pic14_emitcode("rlc","a");
7005 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7006 size >= MSB24+offr && offr != LSB)
7007 pic14_emitcode("xch","a,%s",
7008 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7010 aopPut(AOP(result),"a",MSB16+offr);
7013 if(size >= MSB24+offr){
7014 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7015 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7018 pic14_emitcode("rlc","a");
7019 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7020 size >= MSB32+offr && offr != LSB )
7021 pic14_emitcode("xch","a,%s",
7022 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7024 aopPut(AOP(result),"a",MSB24+offr);
7027 if(size > MSB32+offr){
7028 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7029 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7032 pic14_emitcode("rlc","a");
7033 aopPut(AOP(result),"a",MSB32+offr);
7036 aopPut(AOP(result),zero,LSB);
7039 /*-----------------------------------------------------------------*/
7040 /* genlshFour - shift four byte by a known amount != 0 */
7041 /*-----------------------------------------------------------------*/
7042 static void genlshFour (operand *result, operand *left, int shCount)
7046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7047 size = AOP_SIZE(result);
7049 /* if shifting more that 3 bytes */
7050 if (shCount >= 24 ) {
7053 /* lowest order of left goes to the highest
7054 order of the destination */
7055 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7057 movLeft2Result(left, LSB, result, MSB32);
7058 aopPut(AOP(result),zero,LSB);
7059 aopPut(AOP(result),zero,MSB16);
7060 aopPut(AOP(result),zero,MSB32);
7064 /* more than two bytes */
7065 else if ( shCount >= 16 ) {
7066 /* lower order two bytes goes to higher order two bytes */
7068 /* if some more remaining */
7070 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7072 movLeft2Result(left, MSB16, result, MSB32);
7073 movLeft2Result(left, LSB, result, MSB24);
7075 aopPut(AOP(result),zero,MSB16);
7076 aopPut(AOP(result),zero,LSB);
7080 /* if more than 1 byte */
7081 else if ( shCount >= 8 ) {
7082 /* lower order three bytes goes to higher order three bytes */
7086 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7088 movLeft2Result(left, LSB, result, MSB16);
7090 else{ /* size = 4 */
7092 movLeft2Result(left, MSB24, result, MSB32);
7093 movLeft2Result(left, MSB16, result, MSB24);
7094 movLeft2Result(left, LSB, result, MSB16);
7095 aopPut(AOP(result),zero,LSB);
7097 else if(shCount == 1)
7098 shiftLLong(left, result, MSB16);
7100 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7101 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7102 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7103 aopPut(AOP(result),zero,LSB);
7108 /* 1 <= shCount <= 7 */
7109 else if(shCount <= 2){
7110 shiftLLong(left, result, LSB);
7112 shiftLLong(result, result, LSB);
7114 /* 3 <= shCount <= 7, optimize */
7116 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7117 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7118 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7122 /*-----------------------------------------------------------------*/
7123 /* genLeftShiftLiteral - left shifting by known count */
7124 /*-----------------------------------------------------------------*/
7125 static void genLeftShiftLiteral (operand *left,
7130 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7134 freeAsmop(right,NULL,ic,TRUE);
7136 aopOp(left,ic,FALSE);
7137 aopOp(result,ic,FALSE);
7139 size = getSize(operandType(result));
7142 pic14_emitcode("; shift left ","result %d, left %d",size,
7146 /* I suppose that the left size >= result size */
7149 movLeft2Result(left, size, result, size);
7153 else if(shCount >= (size * 8))
7155 aopPut(AOP(result),zero,size);
7159 genlshOne (result,left,shCount);
7164 genlshTwo (result,left,shCount);
7168 genlshFour (result,left,shCount);
7172 freeAsmop(left,NULL,ic,TRUE);
7173 freeAsmop(result,NULL,ic,TRUE);
7176 /*-----------------------------------------------------------------*
7177 * genMultiAsm - repeat assembly instruction for size of register.
7178 * if endian == 1, then the high byte (i.e base address + size of
7179 * register) is used first else the low byte is used first;
7180 *-----------------------------------------------------------------*/
7181 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7199 emitpcode(poc, popGet(AOP(reg),offset));
7204 /*-----------------------------------------------------------------*/
7205 /* genLeftShift - generates code for left shifting */
7206 /*-----------------------------------------------------------------*/
7207 static void genLeftShift (iCode *ic)
7209 operand *left,*right, *result;
7212 symbol *tlbl , *tlbl1;
7215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7217 right = IC_RIGHT(ic);
7219 result = IC_RESULT(ic);
7221 aopOp(right,ic,FALSE);
7223 /* if the shift count is known then do it
7224 as efficiently as possible */
7225 if (AOP_TYPE(right) == AOP_LIT) {
7226 genLeftShiftLiteral (left,right,result,ic);
7230 /* shift count is unknown then we have to form
7231 a loop get the loop count in B : Note: we take
7232 only the lower order byte since shifting
7233 more that 32 bits make no sense anyway, ( the
7234 largest size of an object can be only 32 bits ) */
7237 aopOp(left,ic,FALSE);
7238 aopOp(result,ic,FALSE);
7240 /* now move the left to the result if they are not the
7242 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7243 AOP_SIZE(result) > 1) {
7245 size = AOP_SIZE(result);
7248 l = aopGet(AOP(left),offset,FALSE,TRUE);
7249 if (*l == '@' && (IS_AOP_PREG(result))) {
7251 pic14_emitcode("mov","a,%s",l);
7252 aopPut(AOP(result),"a",offset);
7254 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7255 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7256 //aopPut(AOP(result),l,offset);
7262 size = AOP_SIZE(result);
7264 /* if it is only one byte then */
7266 if(optimized_for_speed) {
7267 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7268 emitpcode(POC_ANDLW, popGetLit(0xf0));
7269 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7270 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7271 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7272 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7273 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7274 emitpcode(POC_RLFW, popGet(AOP(result),0));
7275 emitpcode(POC_ANDLW, popGetLit(0xfe));
7276 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7277 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7278 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7281 tlbl = newiTempLabel(NULL);
7282 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7283 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7284 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7287 emitpcode(POC_COMFW, popGet(AOP(right),0));
7288 emitpcode(POC_RRF, popGet(AOP(result),0));
7289 emitpLabel(tlbl->key);
7290 emitpcode(POC_RLF, popGet(AOP(result),0));
7291 emitpcode(POC_ADDLW, popGetLit(1));
7293 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7298 if (pic14_sameRegs(AOP(left),AOP(result))) {
7300 tlbl = newiTempLabel(NULL);
7301 emitpcode(POC_COMFW, popGet(AOP(right),0));
7302 genMultiAsm(POC_RRF, result, size,1);
7303 emitpLabel(tlbl->key);
7304 genMultiAsm(POC_RLF, result, size,0);
7305 emitpcode(POC_ADDLW, popGetLit(1));
7307 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7311 //tlbl = newiTempLabel(NULL);
7313 //tlbl1 = newiTempLabel(NULL);
7315 //reAdjustPreg(AOP(result));
7317 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7318 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7319 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7321 //pic14_emitcode("add","a,acc");
7322 //aopPut(AOP(result),"a",offset++);
7324 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7326 // pic14_emitcode("rlc","a");
7327 // aopPut(AOP(result),"a",offset++);
7329 //reAdjustPreg(AOP(result));
7331 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7332 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7335 tlbl = newiTempLabel(NULL);
7336 tlbl1= newiTempLabel(NULL);
7338 size = AOP_SIZE(result);
7341 pctemp = popGetTempReg(); /* grab a temporary working register. */
7343 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7345 /* offset should be 0, 1 or 3 */
7346 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7348 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7350 emitpcode(POC_MOVWF, pctemp);
7353 emitpLabel(tlbl->key);
7356 emitpcode(POC_RLF, popGet(AOP(result),0));
7358 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7360 emitpcode(POC_DECFSZ, pctemp);
7361 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7362 emitpLabel(tlbl1->key);
7364 popReleaseTempReg(pctemp);
7368 freeAsmop (right,NULL,ic,TRUE);
7369 freeAsmop(left,NULL,ic,TRUE);
7370 freeAsmop(result,NULL,ic,TRUE);
7373 /*-----------------------------------------------------------------*/
7374 /* genrshOne - right shift a one byte quantity by known count */
7375 /*-----------------------------------------------------------------*/
7376 static void genrshOne (operand *result, operand *left,
7377 int shCount, int sign)
7379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7380 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7383 /*-----------------------------------------------------------------*/
7384 /* genrshTwo - right shift two bytes by known amount != 0 */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshTwo (operand *result,operand *left,
7387 int shCount, int sign)
7389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7390 /* if shCount >= 8 */
7394 shiftR1Left2Result(left, MSB16, result, LSB,
7397 movLeft2Result(left, MSB16, result, LSB);
7399 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7402 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7403 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7407 /* 1 <= shCount <= 7 */
7409 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7412 /*-----------------------------------------------------------------*/
7413 /* shiftRLong - shift right one long from left to result */
7414 /* offl = LSB or MSB16 */
7415 /*-----------------------------------------------------------------*/
7416 static void shiftRLong (operand *left, int offl,
7417 operand *result, int sign)
7419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7421 pic14_emitcode("clr","c");
7422 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7424 pic14_emitcode("mov","c,acc.7");
7425 pic14_emitcode("rrc","a");
7426 aopPut(AOP(result),"a",MSB32-offl);
7428 /* add sign of "a" */
7429 addSign(result, MSB32, sign);
7431 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7432 pic14_emitcode("rrc","a");
7433 aopPut(AOP(result),"a",MSB24-offl);
7435 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7436 pic14_emitcode("rrc","a");
7437 aopPut(AOP(result),"a",MSB16-offl);
7440 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7441 pic14_emitcode("rrc","a");
7442 aopPut(AOP(result),"a",LSB);
7446 /*-----------------------------------------------------------------*/
7447 /* genrshFour - shift four byte by a known amount != 0 */
7448 /*-----------------------------------------------------------------*/
7449 static void genrshFour (operand *result, operand *left,
7450 int shCount, int sign)
7452 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7453 /* if shifting more that 3 bytes */
7454 if(shCount >= 24 ) {
7457 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7459 movLeft2Result(left, MSB32, result, LSB);
7461 addSign(result, MSB16, sign);
7463 else if(shCount >= 16){
7466 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7468 movLeft2Result(left, MSB24, result, LSB);
7469 movLeft2Result(left, MSB32, result, MSB16);
7471 addSign(result, MSB24, sign);
7473 else if(shCount >= 8){
7476 shiftRLong(left, MSB16, result, sign);
7477 else if(shCount == 0){
7478 movLeft2Result(left, MSB16, result, LSB);
7479 movLeft2Result(left, MSB24, result, MSB16);
7480 movLeft2Result(left, MSB32, result, MSB24);
7481 addSign(result, MSB32, sign);
7484 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7485 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7486 /* the last shift is signed */
7487 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7488 addSign(result, MSB32, sign);
7491 else{ /* 1 <= shCount <= 7 */
7493 shiftRLong(left, LSB, result, sign);
7495 shiftRLong(result, LSB, result, sign);
7498 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7499 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7500 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7505 /*-----------------------------------------------------------------*/
7506 /* genRightShiftLiteral - right shifting by known count */
7507 /*-----------------------------------------------------------------*/
7508 static void genRightShiftLiteral (operand *left,
7514 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7518 freeAsmop(right,NULL,ic,TRUE);
7520 aopOp(left,ic,FALSE);
7521 aopOp(result,ic,FALSE);
7524 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7528 lsize = pic14_getDataSize(left);
7529 res_size = pic14_getDataSize(result);
7530 /* test the LEFT size !!! */
7532 /* I suppose that the left size >= result size */
7535 movLeft2Result(left, lsize, result, res_size);
7538 else if(shCount >= (lsize * 8)){
7541 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7543 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7544 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7549 emitpcode(POC_MOVLW, popGetLit(0));
7550 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7551 emitpcode(POC_MOVLW, popGetLit(0xff));
7553 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7558 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7565 genrshOne (result,left,shCount,sign);
7569 genrshTwo (result,left,shCount,sign);
7573 genrshFour (result,left,shCount,sign);
7581 freeAsmop(left,NULL,ic,TRUE);
7582 freeAsmop(result,NULL,ic,TRUE);
7585 /*-----------------------------------------------------------------*/
7586 /* genSignedRightShift - right shift of signed number */
7587 /*-----------------------------------------------------------------*/
7588 static void genSignedRightShift (iCode *ic)
7590 operand *right, *left, *result;
7593 symbol *tlbl, *tlbl1 ;
7596 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7598 /* we do it the hard way put the shift count in b
7599 and loop thru preserving the sign */
7600 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7602 right = IC_RIGHT(ic);
7604 result = IC_RESULT(ic);
7606 aopOp(right,ic,FALSE);
7607 aopOp(left,ic,FALSE);
7608 aopOp(result,ic,FALSE);
7611 if ( AOP_TYPE(right) == AOP_LIT) {
7612 genRightShiftLiteral (left,right,result,ic,1);
7615 /* shift count is unknown then we have to form
7616 a loop get the loop count in B : Note: we take
7617 only the lower order byte since shifting
7618 more that 32 bits make no sense anyway, ( the
7619 largest size of an object can be only 32 bits ) */
7621 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7622 //pic14_emitcode("inc","b");
7623 //freeAsmop (right,NULL,ic,TRUE);
7624 //aopOp(left,ic,FALSE);
7625 //aopOp(result,ic,FALSE);
7627 /* now move the left to the result if they are not the
7629 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7630 AOP_SIZE(result) > 1) {
7632 size = AOP_SIZE(result);
7636 l = aopGet(AOP(left),offset,FALSE,TRUE);
7637 if (*l == '@' && IS_AOP_PREG(result)) {
7639 pic14_emitcode("mov","a,%s",l);
7640 aopPut(AOP(result),"a",offset);
7642 aopPut(AOP(result),l,offset);
7644 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7645 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7651 /* mov the highest order bit to OVR */
7652 tlbl = newiTempLabel(NULL);
7653 tlbl1= newiTempLabel(NULL);
7655 size = AOP_SIZE(result);
7658 pctemp = popGetTempReg(); /* grab a temporary working register. */
7660 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7662 /* offset should be 0, 1 or 3 */
7663 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7665 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7667 emitpcode(POC_MOVWF, pctemp);
7670 emitpLabel(tlbl->key);
7672 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7673 emitpcode(POC_RRF, popGet(AOP(result),offset));
7676 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7679 emitpcode(POC_DECFSZ, pctemp);
7680 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7681 emitpLabel(tlbl1->key);
7683 popReleaseTempReg(pctemp);
7685 size = AOP_SIZE(result);
7687 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7688 pic14_emitcode("rlc","a");
7689 pic14_emitcode("mov","ov,c");
7690 /* if it is only one byte then */
7692 l = aopGet(AOP(left),0,FALSE,FALSE);
7694 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7695 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7696 pic14_emitcode("mov","c,ov");
7697 pic14_emitcode("rrc","a");
7698 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7699 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7700 aopPut(AOP(result),"a",0);
7704 reAdjustPreg(AOP(result));
7705 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7706 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7707 pic14_emitcode("mov","c,ov");
7709 l = aopGet(AOP(result),offset,FALSE,FALSE);
7711 pic14_emitcode("rrc","a");
7712 aopPut(AOP(result),"a",offset--);
7714 reAdjustPreg(AOP(result));
7715 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7716 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7721 freeAsmop(left,NULL,ic,TRUE);
7722 freeAsmop(result,NULL,ic,TRUE);
7723 freeAsmop(right,NULL,ic,TRUE);
7726 /*-----------------------------------------------------------------*/
7727 /* genRightShift - generate code for right shifting */
7728 /*-----------------------------------------------------------------*/
7729 static void genRightShift (iCode *ic)
7731 operand *right, *left, *result;
7735 symbol *tlbl, *tlbl1 ;
7737 /* if signed then we do it the hard way preserve the
7738 sign bit moving it inwards */
7739 retype = getSpec(operandType(IC_RESULT(ic)));
7740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7742 if (!SPEC_USIGN(retype)) {
7743 genSignedRightShift (ic);
7747 /* signed & unsigned types are treated the same : i.e. the
7748 signed is NOT propagated inwards : quoting from the
7749 ANSI - standard : "for E1 >> E2, is equivalent to division
7750 by 2**E2 if unsigned or if it has a non-negative value,
7751 otherwise the result is implementation defined ", MY definition
7752 is that the sign does not get propagated */
7754 right = IC_RIGHT(ic);
7756 result = IC_RESULT(ic);
7758 aopOp(right,ic,FALSE);
7760 /* if the shift count is known then do it
7761 as efficiently as possible */
7762 if (AOP_TYPE(right) == AOP_LIT) {
7763 genRightShiftLiteral (left,right,result,ic, 0);
7767 /* shift count is unknown then we have to form
7768 a loop get the loop count in B : Note: we take
7769 only the lower order byte since shifting
7770 more that 32 bits make no sense anyway, ( the
7771 largest size of an object can be only 32 bits ) */
7773 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7774 pic14_emitcode("inc","b");
7775 aopOp(left,ic,FALSE);
7776 aopOp(result,ic,FALSE);
7778 /* now move the left to the result if they are not the
7780 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7781 AOP_SIZE(result) > 1) {
7783 size = AOP_SIZE(result);
7786 l = aopGet(AOP(left),offset,FALSE,TRUE);
7787 if (*l == '@' && IS_AOP_PREG(result)) {
7789 pic14_emitcode("mov","a,%s",l);
7790 aopPut(AOP(result),"a",offset);
7792 aopPut(AOP(result),l,offset);
7797 tlbl = newiTempLabel(NULL);
7798 tlbl1= newiTempLabel(NULL);
7799 size = AOP_SIZE(result);
7802 /* if it is only one byte then */
7805 tlbl = newiTempLabel(NULL);
7806 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7807 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7808 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7811 emitpcode(POC_COMFW, popGet(AOP(right),0));
7812 emitpcode(POC_RLF, popGet(AOP(result),0));
7813 emitpLabel(tlbl->key);
7814 emitpcode(POC_RRF, popGet(AOP(result),0));
7815 emitpcode(POC_ADDLW, popGetLit(1));
7817 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7822 reAdjustPreg(AOP(result));
7823 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7824 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7827 l = aopGet(AOP(result),offset,FALSE,FALSE);
7829 pic14_emitcode("rrc","a");
7830 aopPut(AOP(result),"a",offset--);
7832 reAdjustPreg(AOP(result));
7834 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7835 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7838 freeAsmop(left,NULL,ic,TRUE);
7839 freeAsmop (right,NULL,ic,TRUE);
7840 freeAsmop(result,NULL,ic,TRUE);
7843 /*-----------------------------------------------------------------*/
7844 /* genUnpackBits - generates code for unpacking bits */
7845 /*-----------------------------------------------------------------*/
7846 static void genUnpackBits (operand *result, char *rname, int ptype)
7853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7854 etype = getSpec(operandType(result));
7856 /* read the first byte */
7861 pic14_emitcode("mov","a,@%s",rname);
7865 pic14_emitcode("movx","a,@%s",rname);
7869 pic14_emitcode("movx","a,@dptr");
7873 pic14_emitcode("clr","a");
7874 pic14_emitcode("movc","a","@a+dptr");
7878 pic14_emitcode("lcall","__gptrget");
7882 /* if we have bitdisplacement then it fits */
7883 /* into this byte completely or if length is */
7884 /* less than a byte */
7885 if ((shCnt = SPEC_BSTR(etype)) ||
7886 (SPEC_BLEN(etype) <= 8)) {
7888 /* shift right acc */
7891 pic14_emitcode("anl","a,#0x%02x",
7892 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7893 aopPut(AOP(result),"a",offset);
7897 /* bit field did not fit in a byte */
7898 rlen = SPEC_BLEN(etype) - 8;
7899 aopPut(AOP(result),"a",offset++);
7906 pic14_emitcode("inc","%s",rname);
7907 pic14_emitcode("mov","a,@%s",rname);
7911 pic14_emitcode("inc","%s",rname);
7912 pic14_emitcode("movx","a,@%s",rname);
7916 pic14_emitcode("inc","dptr");
7917 pic14_emitcode("movx","a,@dptr");
7921 pic14_emitcode("clr","a");
7922 pic14_emitcode("inc","dptr");
7923 pic14_emitcode("movc","a","@a+dptr");
7927 pic14_emitcode("inc","dptr");
7928 pic14_emitcode("lcall","__gptrget");
7933 /* if we are done */
7937 aopPut(AOP(result),"a",offset++);
7942 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7943 aopPut(AOP(result),"a",offset);
7950 /*-----------------------------------------------------------------*/
7951 /* genDataPointerGet - generates code when ptr offset is known */
7952 /*-----------------------------------------------------------------*/
7953 static void genDataPointerGet (operand *left,
7957 int size , offset = 0;
7960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 /* optimization - most of the time, left and result are the same
7964 * address, but different types. for the pic code, we could omit
7968 aopOp(result,ic,TRUE);
7970 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7972 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7974 size = AOP_SIZE(result);
7977 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7981 freeAsmop(left,NULL,ic,TRUE);
7982 freeAsmop(result,NULL,ic,TRUE);
7985 /*-----------------------------------------------------------------*/
7986 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7987 /*-----------------------------------------------------------------*/
7988 static void genNearPointerGet (operand *left,
7993 //regs *preg = NULL ;
7995 sym_link *rtype, *retype;
7996 sym_link *ltype = operandType(left);
7999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8001 rtype = operandType(result);
8002 retype= getSpec(rtype);
8004 aopOp(left,ic,FALSE);
8006 /* if left is rematerialisable and
8007 result is not bit variable type and
8008 the left is pointer to data space i.e
8009 lower 128 bytes of space */
8010 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8011 !IS_BITVAR(retype) &&
8012 DCL_TYPE(ltype) == POINTER) {
8013 //genDataPointerGet (left,result,ic);
8017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 /* if the value is already in a pointer register
8020 then don't need anything more */
8021 if (!AOP_INPREG(AOP(left))) {
8022 /* otherwise get a free pointer register */
8023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8026 preg = getFreePtr(ic,&aop,FALSE);
8027 pic14_emitcode("mov","%s,%s",
8029 aopGet(AOP(left),0,FALSE,TRUE));
8030 rname = preg->name ;
8034 rname = aopGet(AOP(left),0,FALSE,FALSE);
8036 aopOp (result,ic,FALSE);
8038 /* if bitfield then unpack the bits */
8039 if (IS_BITVAR(retype))
8040 genUnpackBits (result,rname,POINTER);
8042 /* we have can just get the values */
8043 int size = AOP_SIZE(result);
8046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8048 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8049 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8051 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8052 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8054 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8058 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8060 pic14_emitcode("mov","a,@%s",rname);
8061 aopPut(AOP(result),"a",offset);
8063 sprintf(buffer,"@%s",rname);
8064 aopPut(AOP(result),buffer,offset);
8068 pic14_emitcode("inc","%s",rname);
8073 /* now some housekeeping stuff */
8075 /* we had to allocate for this iCode */
8076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8077 freeAsmop(NULL,aop,ic,TRUE);
8079 /* we did not allocate which means left
8080 already in a pointer register, then
8081 if size > 0 && this could be used again
8082 we have to point it back to where it
8084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8085 if (AOP_SIZE(result) > 1 &&
8086 !OP_SYMBOL(left)->remat &&
8087 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8089 int size = AOP_SIZE(result) - 1;
8091 pic14_emitcode("dec","%s",rname);
8096 freeAsmop(left,NULL,ic,TRUE);
8097 freeAsmop(result,NULL,ic,TRUE);
8101 /*-----------------------------------------------------------------*/
8102 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8103 /*-----------------------------------------------------------------*/
8104 static void genPagedPointerGet (operand *left,
8111 sym_link *rtype, *retype;
8113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8115 rtype = operandType(result);
8116 retype= getSpec(rtype);
8118 aopOp(left,ic,FALSE);
8120 /* if the value is already in a pointer register
8121 then don't need anything more */
8122 if (!AOP_INPREG(AOP(left))) {
8123 /* otherwise get a free pointer register */
8125 preg = getFreePtr(ic,&aop,FALSE);
8126 pic14_emitcode("mov","%s,%s",
8128 aopGet(AOP(left),0,FALSE,TRUE));
8129 rname = preg->name ;
8131 rname = aopGet(AOP(left),0,FALSE,FALSE);
8133 freeAsmop(left,NULL,ic,TRUE);
8134 aopOp (result,ic,FALSE);
8136 /* if bitfield then unpack the bits */
8137 if (IS_BITVAR(retype))
8138 genUnpackBits (result,rname,PPOINTER);
8140 /* we have can just get the values */
8141 int size = AOP_SIZE(result);
8146 pic14_emitcode("movx","a,@%s",rname);
8147 aopPut(AOP(result),"a",offset);
8152 pic14_emitcode("inc","%s",rname);
8156 /* now some housekeeping stuff */
8158 /* we had to allocate for this iCode */
8159 freeAsmop(NULL,aop,ic,TRUE);
8161 /* we did not allocate which means left
8162 already in a pointer register, then
8163 if size > 0 && this could be used again
8164 we have to point it back to where it
8166 if (AOP_SIZE(result) > 1 &&
8167 !OP_SYMBOL(left)->remat &&
8168 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8170 int size = AOP_SIZE(result) - 1;
8172 pic14_emitcode("dec","%s",rname);
8177 freeAsmop(result,NULL,ic,TRUE);
8182 /*-----------------------------------------------------------------*/
8183 /* genFarPointerGet - gget value from far space */
8184 /*-----------------------------------------------------------------*/
8185 static void genFarPointerGet (operand *left,
8186 operand *result, iCode *ic)
8189 sym_link *retype = getSpec(operandType(result));
8191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8193 aopOp(left,ic,FALSE);
8195 /* if the operand is already in dptr
8196 then we do nothing else we move the value to dptr */
8197 if (AOP_TYPE(left) != AOP_STR) {
8198 /* if this is remateriazable */
8199 if (AOP_TYPE(left) == AOP_IMMD)
8200 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8201 else { /* we need to get it byte by byte */
8202 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8203 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8204 if (options.model == MODEL_FLAT24)
8206 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8210 /* so dptr know contains the address */
8211 freeAsmop(left,NULL,ic,TRUE);
8212 aopOp(result,ic,FALSE);
8214 /* if bit then unpack */
8215 if (IS_BITVAR(retype))
8216 genUnpackBits(result,"dptr",FPOINTER);
8218 size = AOP_SIZE(result);
8222 pic14_emitcode("movx","a,@dptr");
8223 aopPut(AOP(result),"a",offset++);
8225 pic14_emitcode("inc","dptr");
8229 freeAsmop(result,NULL,ic,TRUE);
8232 /*-----------------------------------------------------------------*/
8233 /* genCodePointerGet - get value from code space */
8234 /*-----------------------------------------------------------------*/
8235 static void genCodePointerGet (operand *left,
8236 operand *result, iCode *ic)
8239 sym_link *retype = getSpec(operandType(result));
8241 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8243 aopOp(left,ic,FALSE);
8245 /* if the operand is already in dptr
8246 then we do nothing else we move the value to dptr */
8247 if (AOP_TYPE(left) != AOP_STR) {
8248 /* if this is remateriazable */
8249 if (AOP_TYPE(left) == AOP_IMMD)
8250 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8251 else { /* we need to get it byte by byte */
8252 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8253 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8254 if (options.model == MODEL_FLAT24)
8256 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8260 /* so dptr know contains the address */
8261 freeAsmop(left,NULL,ic,TRUE);
8262 aopOp(result,ic,FALSE);
8264 /* if bit then unpack */
8265 if (IS_BITVAR(retype))
8266 genUnpackBits(result,"dptr",CPOINTER);
8268 size = AOP_SIZE(result);
8272 pic14_emitcode("clr","a");
8273 pic14_emitcode("movc","a,@a+dptr");
8274 aopPut(AOP(result),"a",offset++);
8276 pic14_emitcode("inc","dptr");
8280 freeAsmop(result,NULL,ic,TRUE);
8283 /*-----------------------------------------------------------------*/
8284 /* genGenPointerGet - gget value from generic pointer space */
8285 /*-----------------------------------------------------------------*/
8286 static void genGenPointerGet (operand *left,
8287 operand *result, iCode *ic)
8290 sym_link *retype = getSpec(operandType(result));
8292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8293 aopOp(left,ic,FALSE);
8294 aopOp(result,ic,FALSE);
8297 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8299 /* if the operand is already in dptr
8300 then we do nothing else we move the value to dptr */
8301 // if (AOP_TYPE(left) != AOP_STR) {
8302 /* if this is remateriazable */
8303 if (AOP_TYPE(left) == AOP_IMMD) {
8304 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8305 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8307 else { /* we need to get it byte by byte */
8309 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8310 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8312 size = AOP_SIZE(result);
8316 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8317 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8319 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8324 /* so dptr know contains the address */
8326 /* if bit then unpack */
8327 //if (IS_BITVAR(retype))
8328 // genUnpackBits(result,"dptr",GPOINTER);
8331 freeAsmop(left,NULL,ic,TRUE);
8332 freeAsmop(result,NULL,ic,TRUE);
8336 /*-----------------------------------------------------------------*/
8337 /* genConstPointerGet - get value from const generic pointer space */
8338 /*-----------------------------------------------------------------*/
8339 static void genConstPointerGet (operand *left,
8340 operand *result, iCode *ic)
8342 //sym_link *retype = getSpec(operandType(result));
8343 symbol *albl = newiTempLabel(NULL);
8344 symbol *blbl = newiTempLabel(NULL);
8347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8348 aopOp(left,ic,FALSE);
8349 aopOp(result,ic,FALSE);
8352 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8354 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8356 emitpcode(POC_CALL,popGetLabel(albl->key));
8357 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8358 emitpLabel(albl->key);
8360 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8362 emitpcode(poc,popGet(AOP(left),1));
8363 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8364 emitpcode(poc,popGet(AOP(left),0));
8365 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8367 emitpLabel(blbl->key);
8369 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8372 freeAsmop(left,NULL,ic,TRUE);
8373 freeAsmop(result,NULL,ic,TRUE);
8376 /*-----------------------------------------------------------------*/
8377 /* genPointerGet - generate code for pointer get */
8378 /*-----------------------------------------------------------------*/
8379 static void genPointerGet (iCode *ic)
8381 operand *left, *result ;
8382 sym_link *type, *etype;
8385 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8388 result = IC_RESULT(ic) ;
8390 /* depending on the type of pointer we need to
8391 move it to the correct pointer register */
8392 type = operandType(left);
8393 etype = getSpec(type);
8395 if (IS_PTR_CONST(type))
8396 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8398 /* if left is of type of pointer then it is simple */
8399 if (IS_PTR(type) && !IS_FUNC(type->next))
8400 p_type = DCL_TYPE(type);
8402 /* we have to go by the storage class */
8403 p_type = PTR_TYPE(SPEC_OCLS(etype));
8405 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8407 if (SPEC_OCLS(etype)->codesp ) {
8408 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8409 //p_type = CPOINTER ;
8412 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8413 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8414 /*p_type = FPOINTER ;*/
8416 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8417 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8418 /* p_type = PPOINTER; */
8420 if (SPEC_OCLS(etype) == idata )
8421 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8422 /* p_type = IPOINTER; */
8424 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8425 /* p_type = POINTER ; */
8428 /* now that we have the pointer type we assign
8429 the pointer values */
8434 genNearPointerGet (left,result,ic);
8438 genPagedPointerGet(left,result,ic);
8442 genFarPointerGet (left,result,ic);
8446 genConstPointerGet (left,result,ic);
8447 //pic14_emitcodePointerGet (left,result,ic);
8451 if (IS_PTR_CONST(type))
8452 genConstPointerGet (left,result,ic);
8454 genGenPointerGet (left,result,ic);
8460 /*-----------------------------------------------------------------*/
8461 /* genPackBits - generates code for packed bit storage */
8462 /*-----------------------------------------------------------------*/
8463 static void genPackBits (sym_link *etype ,
8465 char *rname, int p_type)
8473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8474 blen = SPEC_BLEN(etype);
8475 bstr = SPEC_BSTR(etype);
8477 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8480 /* if the bit lenth is less than or */
8481 /* it exactly fits a byte then */
8482 if (SPEC_BLEN(etype) <= 8 ) {
8483 shCount = SPEC_BSTR(etype) ;
8485 /* shift left acc */
8488 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8493 pic14_emitcode ("mov","b,a");
8494 pic14_emitcode("mov","a,@%s",rname);
8498 pic14_emitcode ("mov","b,a");
8499 pic14_emitcode("movx","a,@dptr");
8503 pic14_emitcode ("push","b");
8504 pic14_emitcode ("push","acc");
8505 pic14_emitcode ("lcall","__gptrget");
8506 pic14_emitcode ("pop","b");
8510 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8511 ((unsigned char)(0xFF << (blen+bstr)) |
8512 (unsigned char)(0xFF >> (8-bstr)) ) );
8513 pic14_emitcode ("orl","a,b");
8514 if (p_type == GPOINTER)
8515 pic14_emitcode("pop","b");
8521 pic14_emitcode("mov","@%s,a",rname);
8525 pic14_emitcode("movx","@dptr,a");
8529 DEBUGpic14_emitcode(";lcall","__gptrput");
8534 if ( SPEC_BLEN(etype) <= 8 )
8537 pic14_emitcode("inc","%s",rname);
8538 rLen = SPEC_BLEN(etype) ;
8540 /* now generate for lengths greater than one byte */
8543 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8553 pic14_emitcode("mov","@%s,a",rname);
8555 pic14_emitcode("mov","@%s,%s",rname,l);
8560 pic14_emitcode("movx","@dptr,a");
8565 DEBUGpic14_emitcode(";lcall","__gptrput");
8568 pic14_emitcode ("inc","%s",rname);
8573 /* last last was not complete */
8575 /* save the byte & read byte */
8578 pic14_emitcode ("mov","b,a");
8579 pic14_emitcode("mov","a,@%s",rname);
8583 pic14_emitcode ("mov","b,a");
8584 pic14_emitcode("movx","a,@dptr");
8588 pic14_emitcode ("push","b");
8589 pic14_emitcode ("push","acc");
8590 pic14_emitcode ("lcall","__gptrget");
8591 pic14_emitcode ("pop","b");
8595 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8596 pic14_emitcode ("orl","a,b");
8599 if (p_type == GPOINTER)
8600 pic14_emitcode("pop","b");
8605 pic14_emitcode("mov","@%s,a",rname);
8609 pic14_emitcode("movx","@dptr,a");
8613 DEBUGpic14_emitcode(";lcall","__gptrput");
8617 /*-----------------------------------------------------------------*/
8618 /* genDataPointerSet - remat pointer to data space */
8619 /*-----------------------------------------------------------------*/
8620 static void genDataPointerSet(operand *right,
8624 int size, offset = 0 ;
8625 char *l, buffer[256];
8627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8628 aopOp(right,ic,FALSE);
8630 l = aopGet(AOP(result),0,FALSE,TRUE);
8631 size = AOP_SIZE(right);
8633 if ( AOP_TYPE(result) == AOP_PCODE) {
8634 fprintf(stderr,"genDataPointerSet %s, %d\n",
8635 AOP(result)->aopu.pcop->name,
8636 PCOI(AOP(result)->aopu.pcop)->offset);
8640 // tsd, was l+1 - the underline `_' prefix was being stripped
8643 sprintf(buffer,"(%s + %d)",l,offset);
8644 fprintf(stderr,"oops %s\n",buffer);
8646 sprintf(buffer,"%s",l);
8648 if (AOP_TYPE(right) == AOP_LIT) {
8649 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8650 lit = lit >> (8*offset);
8652 pic14_emitcode("movlw","%d",lit);
8653 pic14_emitcode("movwf","%s",buffer);
8655 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8656 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8657 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8660 pic14_emitcode("clrf","%s",buffer);
8661 //emitpcode(POC_CLRF, popRegFromString(buffer));
8662 emitpcode(POC_CLRF, popGet(AOP(result),0));
8665 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8666 pic14_emitcode("movwf","%s",buffer);
8668 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8669 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8670 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8677 freeAsmop(right,NULL,ic,TRUE);
8678 freeAsmop(result,NULL,ic,TRUE);
8681 /*-----------------------------------------------------------------*/
8682 /* genNearPointerSet - pic14_emitcode for near pointer put */
8683 /*-----------------------------------------------------------------*/
8684 static void genNearPointerSet (operand *right,
8691 sym_link *ptype = operandType(result);
8694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8695 retype= getSpec(operandType(right));
8697 aopOp(result,ic,FALSE);
8700 /* if the result is rematerializable &
8701 in data space & not a bit variable */
8702 //if (AOP_TYPE(result) == AOP_IMMD &&
8703 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8704 DCL_TYPE(ptype) == POINTER &&
8705 !IS_BITVAR(retype)) {
8706 genDataPointerSet (right,result,ic);
8707 freeAsmop(result,NULL,ic,TRUE);
8711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8712 aopOp(right,ic,FALSE);
8713 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8715 /* if the value is already in a pointer register
8716 then don't need anything more */
8717 if (!AOP_INPREG(AOP(result))) {
8718 /* otherwise get a free pointer register */
8719 //aop = newAsmop(0);
8720 //preg = getFreePtr(ic,&aop,FALSE);
8721 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8722 //pic14_emitcode("mov","%s,%s",
8724 // aopGet(AOP(result),0,FALSE,TRUE));
8725 //rname = preg->name ;
8726 //pic14_emitcode("movwf","fsr");
8727 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8728 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8729 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8730 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8734 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8737 /* if bitfield then unpack the bits */
8738 if (IS_BITVAR(retype)) {
8739 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8740 "The programmer is obviously confused");
8741 //genPackBits (retype,right,rname,POINTER);
8745 /* we have can just get the values */
8746 int size = AOP_SIZE(right);
8749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8751 l = aopGet(AOP(right),offset,FALSE,TRUE);
8754 //pic14_emitcode("mov","@%s,a",rname);
8755 pic14_emitcode("movf","indf,w ;1");
8758 if (AOP_TYPE(right) == AOP_LIT) {
8759 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8761 pic14_emitcode("movlw","%s",l);
8762 pic14_emitcode("movwf","indf ;2");
8764 pic14_emitcode("clrf","indf");
8766 pic14_emitcode("movf","%s,w",l);
8767 pic14_emitcode("movwf","indf ;2");
8769 //pic14_emitcode("mov","@%s,%s",rname,l);
8772 pic14_emitcode("incf","fsr,f ;3");
8773 //pic14_emitcode("inc","%s",rname);
8778 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8779 /* now some housekeeping stuff */
8781 /* we had to allocate for this iCode */
8782 freeAsmop(NULL,aop,ic,TRUE);
8784 /* we did not allocate which means left
8785 already in a pointer register, then
8786 if size > 0 && this could be used again
8787 we have to point it back to where it
8789 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8790 if (AOP_SIZE(right) > 1 &&
8791 !OP_SYMBOL(result)->remat &&
8792 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8794 int size = AOP_SIZE(right) - 1;
8796 pic14_emitcode("decf","fsr,f");
8797 //pic14_emitcode("dec","%s",rname);
8801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8804 freeAsmop(right,NULL,ic,TRUE);
8805 freeAsmop(result,NULL,ic,TRUE);
8808 /*-----------------------------------------------------------------*/
8809 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8810 /*-----------------------------------------------------------------*/
8811 static void genPagedPointerSet (operand *right,
8820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8822 retype= getSpec(operandType(right));
8824 aopOp(result,ic,FALSE);
8826 /* if the value is already in a pointer register
8827 then don't need anything more */
8828 if (!AOP_INPREG(AOP(result))) {
8829 /* otherwise get a free pointer register */
8831 preg = getFreePtr(ic,&aop,FALSE);
8832 pic14_emitcode("mov","%s,%s",
8834 aopGet(AOP(result),0,FALSE,TRUE));
8835 rname = preg->name ;
8837 rname = aopGet(AOP(result),0,FALSE,FALSE);
8839 freeAsmop(result,NULL,ic,TRUE);
8840 aopOp (right,ic,FALSE);
8842 /* if bitfield then unpack the bits */
8843 if (IS_BITVAR(retype))
8844 genPackBits (retype,right,rname,PPOINTER);
8846 /* we have can just get the values */
8847 int size = AOP_SIZE(right);
8851 l = aopGet(AOP(right),offset,FALSE,TRUE);
8854 pic14_emitcode("movx","@%s,a",rname);
8857 pic14_emitcode("inc","%s",rname);
8863 /* now some housekeeping stuff */
8865 /* we had to allocate for this iCode */
8866 freeAsmop(NULL,aop,ic,TRUE);
8868 /* we did not allocate which means left
8869 already in a pointer register, then
8870 if size > 0 && this could be used again
8871 we have to point it back to where it
8873 if (AOP_SIZE(right) > 1 &&
8874 !OP_SYMBOL(result)->remat &&
8875 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8877 int size = AOP_SIZE(right) - 1;
8879 pic14_emitcode("dec","%s",rname);
8884 freeAsmop(right,NULL,ic,TRUE);
8889 /*-----------------------------------------------------------------*/
8890 /* genFarPointerSet - set value from far space */
8891 /*-----------------------------------------------------------------*/
8892 static void genFarPointerSet (operand *right,
8893 operand *result, iCode *ic)
8896 sym_link *retype = getSpec(operandType(right));
8898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8899 aopOp(result,ic,FALSE);
8901 /* if the operand is already in dptr
8902 then we do nothing else we move the value to dptr */
8903 if (AOP_TYPE(result) != AOP_STR) {
8904 /* if this is remateriazable */
8905 if (AOP_TYPE(result) == AOP_IMMD)
8906 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8907 else { /* we need to get it byte by byte */
8908 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8909 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8910 if (options.model == MODEL_FLAT24)
8912 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8916 /* so dptr know contains the address */
8917 freeAsmop(result,NULL,ic,TRUE);
8918 aopOp(right,ic,FALSE);
8920 /* if bit then unpack */
8921 if (IS_BITVAR(retype))
8922 genPackBits(retype,right,"dptr",FPOINTER);
8924 size = AOP_SIZE(right);
8928 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8930 pic14_emitcode("movx","@dptr,a");
8932 pic14_emitcode("inc","dptr");
8936 freeAsmop(right,NULL,ic,TRUE);
8939 /*-----------------------------------------------------------------*/
8940 /* genGenPointerSet - set value from generic pointer space */
8941 /*-----------------------------------------------------------------*/
8942 static void genGenPointerSet (operand *right,
8943 operand *result, iCode *ic)
8946 sym_link *retype = getSpec(operandType(right));
8948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8950 aopOp(result,ic,FALSE);
8951 aopOp(right,ic,FALSE);
8952 size = AOP_SIZE(right);
8954 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8956 /* if the operand is already in dptr
8957 then we do nothing else we move the value to dptr */
8958 if (AOP_TYPE(result) != AOP_STR) {
8959 /* if this is remateriazable */
8960 if (AOP_TYPE(result) == AOP_IMMD) {
8961 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8962 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8964 else { /* we need to get it byte by byte */
8965 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8966 size = AOP_SIZE(right);
8969 /* hack hack! see if this the FSR. If so don't load W */
8970 if(AOP_TYPE(right) != AOP_ACC) {
8973 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8974 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8976 if(AOP_SIZE(result) > 1) {
8977 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8978 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8979 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8984 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8986 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8987 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8991 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8992 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8995 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9002 if(aopIdx(AOP(result),0) != 4) {
9004 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9008 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9013 /* so dptr know contains the address */
9016 /* if bit then unpack */
9017 if (IS_BITVAR(retype))
9018 genPackBits(retype,right,"dptr",GPOINTER);
9020 size = AOP_SIZE(right);
9023 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9027 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9028 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9030 if (AOP_TYPE(right) == AOP_LIT)
9031 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9033 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9035 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9042 freeAsmop(right,NULL,ic,TRUE);
9043 freeAsmop(result,NULL,ic,TRUE);
9046 /*-----------------------------------------------------------------*/
9047 /* genPointerSet - stores the value into a pointer location */
9048 /*-----------------------------------------------------------------*/
9049 static void genPointerSet (iCode *ic)
9051 operand *right, *result ;
9052 sym_link *type, *etype;
9055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9057 right = IC_RIGHT(ic);
9058 result = IC_RESULT(ic) ;
9060 /* depending on the type of pointer we need to
9061 move it to the correct pointer register */
9062 type = operandType(result);
9063 etype = getSpec(type);
9064 /* if left is of type of pointer then it is simple */
9065 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9066 p_type = DCL_TYPE(type);
9069 /* we have to go by the storage class */
9070 p_type = PTR_TYPE(SPEC_OCLS(etype));
9072 /* if (SPEC_OCLS(etype)->codesp ) { */
9073 /* p_type = CPOINTER ; */
9076 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9077 /* p_type = FPOINTER ; */
9079 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9080 /* p_type = PPOINTER ; */
9082 /* if (SPEC_OCLS(etype) == idata ) */
9083 /* p_type = IPOINTER ; */
9085 /* p_type = POINTER ; */
9088 /* now that we have the pointer type we assign
9089 the pointer values */
9094 genNearPointerSet (right,result,ic);
9098 genPagedPointerSet (right,result,ic);
9102 genFarPointerSet (right,result,ic);
9106 genGenPointerSet (right,result,ic);
9110 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9111 "genPointerSet: illegal pointer type");
9115 /*-----------------------------------------------------------------*/
9116 /* genIfx - generate code for Ifx statement */
9117 /*-----------------------------------------------------------------*/
9118 static void genIfx (iCode *ic, iCode *popIc)
9120 operand *cond = IC_COND(ic);
9123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9125 aopOp(cond,ic,FALSE);
9127 /* get the value into acc */
9128 if (AOP_TYPE(cond) != AOP_CRY)
9129 pic14_toBoolean(cond);
9132 /* the result is now in the accumulator */
9133 freeAsmop(cond,NULL,ic,TRUE);
9135 /* if there was something to be popped then do it */
9139 /* if the condition is a bit variable */
9140 if (isbit && IS_ITEMP(cond) &&
9142 genIfxJump(ic,SPIL_LOC(cond)->rname);
9143 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9146 if (isbit && !IS_ITEMP(cond))
9147 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9155 /*-----------------------------------------------------------------*/
9156 /* genAddrOf - generates code for address of */
9157 /*-----------------------------------------------------------------*/
9158 static void genAddrOf (iCode *ic)
9160 operand *right, *result, *left;
9163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9166 //aopOp(IC_RESULT(ic),ic,FALSE);
9168 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9169 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9170 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9172 DEBUGpic14_AopType(__LINE__,left,right,result);
9174 size = AOP_SIZE(IC_RESULT(ic));
9178 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9179 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9183 freeAsmop(left,NULL,ic,FALSE);
9184 freeAsmop(result,NULL,ic,TRUE);
9189 /*-----------------------------------------------------------------*/
9190 /* genFarFarAssign - assignment when both are in far space */
9191 /*-----------------------------------------------------------------*/
9192 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9194 int size = AOP_SIZE(right);
9197 /* first push the right side on to the stack */
9199 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9201 pic14_emitcode ("push","acc");
9204 freeAsmop(right,NULL,ic,FALSE);
9205 /* now assign DPTR to result */
9206 aopOp(result,ic,FALSE);
9207 size = AOP_SIZE(result);
9209 pic14_emitcode ("pop","acc");
9210 aopPut(AOP(result),"a",--offset);
9212 freeAsmop(result,NULL,ic,FALSE);
9217 /*-----------------------------------------------------------------*/
9218 /* genAssign - generate code for assignment */
9219 /*-----------------------------------------------------------------*/
9220 static void genAssign (iCode *ic)
9222 operand *result, *right;
9223 int size, offset,know_W;
9224 unsigned long lit = 0L;
9226 result = IC_RESULT(ic);
9227 right = IC_RIGHT(ic) ;
9229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9231 /* if they are the same */
9232 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9235 aopOp(right,ic,FALSE);
9236 aopOp(result,ic,TRUE);
9238 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9240 /* if they are the same registers */
9241 if (pic14_sameRegs(AOP(right),AOP(result)))
9244 /* if the result is a bit */
9245 if (AOP_TYPE(result) == AOP_CRY) {
9247 /* if the right size is a literal then
9248 we know what the value is */
9249 if (AOP_TYPE(right) == AOP_LIT) {
9251 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9252 popGet(AOP(result),0));
9254 if (((int) operandLitValue(right)))
9255 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9256 AOP(result)->aopu.aop_dir,
9257 AOP(result)->aopu.aop_dir);
9259 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9260 AOP(result)->aopu.aop_dir,
9261 AOP(result)->aopu.aop_dir);
9265 /* the right is also a bit variable */
9266 if (AOP_TYPE(right) == AOP_CRY) {
9267 emitpcode(POC_BCF, popGet(AOP(result),0));
9268 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9269 emitpcode(POC_BSF, popGet(AOP(result),0));
9271 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9272 AOP(result)->aopu.aop_dir,
9273 AOP(result)->aopu.aop_dir);
9274 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9275 AOP(right)->aopu.aop_dir,
9276 AOP(right)->aopu.aop_dir);
9277 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9278 AOP(result)->aopu.aop_dir,
9279 AOP(result)->aopu.aop_dir);
9284 emitpcode(POC_BCF, popGet(AOP(result),0));
9285 pic14_toBoolean(right);
9287 emitpcode(POC_BSF, popGet(AOP(result),0));
9288 //aopPut(AOP(result),"a",0);
9292 /* bit variables done */
9294 size = AOP_SIZE(result);
9296 if(AOP_TYPE(right) == AOP_LIT)
9297 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9299 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9301 if(aopIdx(AOP(result),0) == 4) {
9302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9303 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9304 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9307 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9313 if(AOP_TYPE(right) == AOP_LIT) {
9315 if(know_W != (lit&0xff))
9316 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9318 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9320 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9324 } else if (AOP_TYPE(right) == AOP_CRY) {
9325 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9327 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9328 emitpcode(POC_INCF, popGet(AOP(result),0));
9331 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9332 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9333 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9341 freeAsmop (right,NULL,ic,FALSE);
9342 freeAsmop (result,NULL,ic,TRUE);
9345 /*-----------------------------------------------------------------*/
9346 /* genJumpTab - genrates code for jump table */
9347 /*-----------------------------------------------------------------*/
9348 static void genJumpTab (iCode *ic)
9353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9355 aopOp(IC_JTCOND(ic),ic,FALSE);
9356 /* get the condition into accumulator */
9357 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9359 /* multiply by three */
9360 pic14_emitcode("add","a,acc");
9361 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9363 jtab = newiTempLabel(NULL);
9364 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9365 pic14_emitcode("jmp","@a+dptr");
9366 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9368 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9369 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9371 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9372 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9373 emitpLabel(jtab->key);
9375 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9377 /* now generate the jump labels */
9378 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9379 jtab = setNextItem(IC_JTLABELS(ic))) {
9380 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9381 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9387 /*-----------------------------------------------------------------*/
9388 /* genMixedOperation - gen code for operators between mixed types */
9389 /*-----------------------------------------------------------------*/
9391 TSD - Written for the PIC port - but this unfortunately is buggy.
9392 This routine is good in that it is able to efficiently promote
9393 types to different (larger) sizes. Unfortunately, the temporary
9394 variables that are optimized out by this routine are sometimes
9395 used in other places. So until I know how to really parse the
9396 iCode tree, I'm going to not be using this routine :(.
9398 static int genMixedOperation (iCode *ic)
9401 operand *result = IC_RESULT(ic);
9402 sym_link *ctype = operandType(IC_LEFT(ic));
9403 operand *right = IC_RIGHT(ic);
9409 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9411 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9417 nextright = IC_RIGHT(nextic);
9418 nextleft = IC_LEFT(nextic);
9419 nextresult = IC_RESULT(nextic);
9421 aopOp(right,ic,FALSE);
9422 aopOp(result,ic,FALSE);
9423 aopOp(nextright, nextic, FALSE);
9424 aopOp(nextleft, nextic, FALSE);
9425 aopOp(nextresult, nextic, FALSE);
9427 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9433 pic14_emitcode(";remove right +","");
9435 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9441 pic14_emitcode(";remove left +","");
9445 big = AOP_SIZE(nextleft);
9446 small = AOP_SIZE(nextright);
9448 switch(nextic->op) {
9451 pic14_emitcode(";optimize a +","");
9452 /* if unsigned or not an integral type */
9453 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9454 pic14_emitcode(";add a bit to something","");
9457 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9459 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9460 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9461 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9463 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9471 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9472 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9473 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9476 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9478 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9479 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9480 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9481 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9482 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9485 pic14_emitcode("rlf","known_zero,w");
9492 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9493 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9494 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9496 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9506 freeAsmop(right,NULL,ic,TRUE);
9507 freeAsmop(result,NULL,ic,TRUE);
9508 freeAsmop(nextright,NULL,ic,TRUE);
9509 freeAsmop(nextleft,NULL,ic,TRUE);
9511 nextic->generated = 1;
9518 /*-----------------------------------------------------------------*/
9519 /* genCast - gen code for casting */
9520 /*-----------------------------------------------------------------*/
9521 static void genCast (iCode *ic)
9523 operand *result = IC_RESULT(ic);
9524 sym_link *ctype = operandType(IC_LEFT(ic));
9525 sym_link *rtype = operandType(IC_RIGHT(ic));
9526 operand *right = IC_RIGHT(ic);
9529 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9530 /* if they are equivalent then do nothing */
9531 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9534 aopOp(right,ic,FALSE) ;
9535 aopOp(result,ic,FALSE);
9537 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9539 /* if the result is a bit */
9540 if (AOP_TYPE(result) == AOP_CRY) {
9541 /* if the right size is a literal then
9542 we know what the value is */
9543 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9544 if (AOP_TYPE(right) == AOP_LIT) {
9546 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9547 popGet(AOP(result),0));
9549 if (((int) operandLitValue(right)))
9550 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9551 AOP(result)->aopu.aop_dir,
9552 AOP(result)->aopu.aop_dir);
9554 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9555 AOP(result)->aopu.aop_dir,
9556 AOP(result)->aopu.aop_dir);
9561 /* the right is also a bit variable */
9562 if (AOP_TYPE(right) == AOP_CRY) {
9565 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9567 pic14_emitcode("clrc","");
9568 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9569 AOP(right)->aopu.aop_dir,
9570 AOP(right)->aopu.aop_dir);
9571 aopPut(AOP(result),"c",0);
9576 if (AOP_TYPE(right) == AOP_REG) {
9577 emitpcode(POC_BCF, popGet(AOP(result),0));
9578 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9579 emitpcode(POC_BSF, popGet(AOP(result),0));
9581 pic14_toBoolean(right);
9582 aopPut(AOP(result),"a",0);
9586 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9588 size = AOP_SIZE(result);
9590 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9592 emitpcode(POC_CLRF, popGet(AOP(result),0));
9593 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9594 emitpcode(POC_INCF, popGet(AOP(result),0));
9597 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9602 /* if they are the same size : or less */
9603 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9605 /* if they are in the same place */
9606 if (pic14_sameRegs(AOP(right),AOP(result)))
9609 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9610 if (IS_PTR_CONST(rtype))
9611 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9612 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9613 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9615 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9616 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9617 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9618 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9619 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9620 if(AOP_SIZE(result) <2)
9621 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9625 /* if they in different places then copy */
9626 size = AOP_SIZE(result);
9629 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9630 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9632 //aopPut(AOP(result),
9633 // aopGet(AOP(right),offset,FALSE,FALSE),
9643 /* if the result is of type pointer */
9644 if (IS_PTR(ctype)) {
9647 sym_link *type = operandType(right);
9648 sym_link *etype = getSpec(type);
9649 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9651 /* pointer to generic pointer */
9652 if (IS_GENPTR(ctype)) {
9656 p_type = DCL_TYPE(type);
9658 /* we have to go by the storage class */
9659 p_type = PTR_TYPE(SPEC_OCLS(etype));
9661 /* if (SPEC_OCLS(etype)->codesp ) */
9662 /* p_type = CPOINTER ; */
9664 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9665 /* p_type = FPOINTER ; */
9667 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9668 /* p_type = PPOINTER; */
9670 /* if (SPEC_OCLS(etype) == idata ) */
9671 /* p_type = IPOINTER ; */
9673 /* p_type = POINTER ; */
9676 /* the first two bytes are known */
9677 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9678 size = GPTRSIZE - 1;
9681 if(offset < AOP_SIZE(right)) {
9682 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9683 if ((AOP_TYPE(right) == AOP_PCODE) &&
9684 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9685 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9686 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9689 aopGet(AOP(right),offset,FALSE,FALSE),
9693 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9696 /* the last byte depending on type */
9700 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9703 pic14_emitcode(";BUG!? ","%d",__LINE__);
9707 pic14_emitcode(";BUG!? ","%d",__LINE__);
9711 pic14_emitcode(";BUG!? ","%d",__LINE__);
9716 /* this should never happen */
9717 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9718 "got unknown pointer type");
9721 //aopPut(AOP(result),l, GPTRSIZE - 1);
9725 /* just copy the pointers */
9726 size = AOP_SIZE(result);
9730 aopGet(AOP(right),offset,FALSE,FALSE),
9739 /* so we now know that the size of destination is greater
9740 than the size of the source.
9741 Now, if the next iCode is an operator then we might be
9742 able to optimize the operation without performing a cast.
9744 if(genMixedOperation(ic))
9747 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9749 /* we move to result for the size of source */
9750 size = AOP_SIZE(right);
9753 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9754 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9758 /* now depending on the sign of the destination */
9759 size = AOP_SIZE(result) - AOP_SIZE(right);
9760 /* if unsigned or not an integral type */
9761 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9763 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9765 /* we need to extend the sign :{ */
9768 /* Save one instruction of casting char to int */
9769 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9770 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9771 emitpcode(POC_DECF, popGet(AOP(result),offset));
9773 emitpcodeNULLop(POC_CLRW);
9776 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9778 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9780 emitpcode(POC_MOVLW, popGetLit(0xff));
9783 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9788 freeAsmop(right,NULL,ic,TRUE);
9789 freeAsmop(result,NULL,ic,TRUE);
9793 /*-----------------------------------------------------------------*/
9794 /* genDjnz - generate decrement & jump if not zero instrucion */
9795 /*-----------------------------------------------------------------*/
9796 static int genDjnz (iCode *ic, iCode *ifx)
9799 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9804 /* if the if condition has a false label
9805 then we cannot save */
9809 /* if the minus is not of the form
9811 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9812 !IS_OP_LITERAL(IC_RIGHT(ic)))
9815 if (operandLitValue(IC_RIGHT(ic)) != 1)
9818 /* if the size of this greater than one then no
9820 if (getSize(operandType(IC_RESULT(ic))) > 1)
9823 /* otherwise we can save BIG */
9824 lbl = newiTempLabel(NULL);
9825 lbl1= newiTempLabel(NULL);
9827 aopOp(IC_RESULT(ic),ic,FALSE);
9829 if (IS_AOP_PREG(IC_RESULT(ic))) {
9830 pic14_emitcode("dec","%s",
9831 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9832 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9833 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9837 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9838 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9840 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9841 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9844 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9845 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9846 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9847 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9850 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9855 /*-----------------------------------------------------------------*/
9856 /* genReceive - generate code for a receive iCode */
9857 /*-----------------------------------------------------------------*/
9858 static void genReceive (iCode *ic)
9860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9862 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9863 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9864 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9866 int size = getSize(operandType(IC_RESULT(ic)));
9867 int offset = fReturnSizePic - size;
9869 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9870 fReturn[fReturnSizePic - offset - 1] : "acc"));
9873 aopOp(IC_RESULT(ic),ic,FALSE);
9874 size = AOP_SIZE(IC_RESULT(ic));
9877 pic14_emitcode ("pop","acc");
9878 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9883 aopOp(IC_RESULT(ic),ic,FALSE);
9885 assignResultValue(IC_RESULT(ic));
9888 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9891 /*-----------------------------------------------------------------*/
9892 /* genpic14Code - generate code for pic14 based controllers */
9893 /*-----------------------------------------------------------------*/
9895 * At this point, ralloc.c has gone through the iCode and attempted
9896 * to optimize in a way suitable for a PIC. Now we've got to generate
9897 * PIC instructions that correspond to the iCode.
9899 * Once the instructions are generated, we'll pass through both the
9900 * peep hole optimizer and the pCode optimizer.
9901 *-----------------------------------------------------------------*/
9903 void genpic14Code (iCode *lic)
9908 lineHead = lineCurr = NULL;
9910 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9913 /* if debug information required */
9914 if (options.debug && currFunc) {
9916 debugFile->writeFunction(currFunc);
9918 if (IS_STATIC(currFunc->etype)) {
9919 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9920 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9922 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9923 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9930 for (ic = lic ; ic ; ic = ic->next ) {
9932 DEBUGpic14_emitcode(";ic","");
9933 if ( cln != ic->lineno ) {
9934 if ( options.debug ) {
9936 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9937 FileBaseName(ic->filename),ic->lineno,
9938 ic->level,ic->block);
9942 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9943 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9944 printCLine(ic->filename, ic->lineno));
9946 if (!options.noCcodeInAsm) {
9948 newpCodeCSource(ic->lineno,
9950 printCLine(ic->filename, ic->lineno)));
9956 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9958 /* if the result is marked as
9959 spilt and rematerializable or code for
9960 this has already been generated then
9962 if (resultRemat(ic) || ic->generated )
9965 /* depending on the operation */
9984 /* IPOP happens only when trying to restore a
9985 spilt live range, if there is an ifx statement
9986 following this pop then the if statement might
9987 be using some of the registers being popped which
9988 would destory the contents of the register so
9989 we need to check for this condition and handle it */
9991 ic->next->op == IFX &&
9992 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9993 genIfx (ic->next,ic);
10011 genEndFunction (ic);
10031 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10048 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10052 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10059 /* note these two are xlated by algebraic equivalence
10060 during parsing SDCC.y */
10061 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10062 "got '>=' or '<=' shouldn't have come here");
10066 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10078 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10082 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10086 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10110 genRightShift (ic);
10113 case GET_VALUE_AT_ADDRESS:
10118 if (POINTER_SET(ic))
10145 addSet(&_G.sendSet,ic);
10154 /* now we are ready to call the
10155 peep hole optimizer */
10156 if (!options.nopeep) {
10157 peepHole (&lineHead);
10159 /* now do the actual printing */
10160 printLine (lineHead,codeOutFile);
10163 DFPRINTF((stderr,"printing pBlock\n\n"));
10164 printpBlock(stdout,pb);