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);
4090 /* unsigned comparisons to a literal byte */
4092 switch(lit & 0xff ) {
4094 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4095 genSkipz2(&rFalseIfx,0);
4098 rFalseIfx.condition ^= 1;
4099 genSkipCond(&rFalseIfx,right,0,7);
4103 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4104 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4105 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4106 rFalseIfx.condition ^= 1;
4107 if (AOP_TYPE(result) == AOP_CRY)
4108 genSkipc(&rFalseIfx);
4110 emitpcode(POC_CLRF, popGet(AOP(result),0));
4111 emitpcode(POC_RLF, popGet(AOP(result),0));
4117 if(ifx) ifx->generated = 1;
4123 /* Size is greater than 1 */
4131 /* this means lit = 0xffffffff, or -1 */
4134 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4135 rFalseIfx.condition ^= 1;
4136 genSkipCond(&rFalseIfx,right,size,7);
4137 if(ifx) ifx->generated = 1;
4144 if(rFalseIfx.condition) {
4145 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4146 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4149 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4151 emitpcode(POC_IORFW, popGet(AOP(right),size));
4155 if(rFalseIfx.condition) {
4156 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4157 emitpLabel(truelbl->key);
4159 rFalseIfx.condition ^= 1;
4160 genSkipCond(&rFalseIfx,right,s,7);
4163 if(ifx) ifx->generated = 1;
4167 if((size == 1) && (0 == (lp1&0xff))) {
4168 /* lower byte of signed word is zero */
4169 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4170 i = ((lp1 >> 8) & 0xff) ^0x80;
4171 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4172 emitpcode(POC_ADDLW, popGetLit( 0x80));
4173 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4174 rFalseIfx.condition ^= 1;
4175 genSkipc(&rFalseIfx);
4178 if(ifx) ifx->generated = 1;
4182 if(lit & (0x80 << (size*8))) {
4183 /* Lit is less than zero */
4184 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4185 //rFalseIfx.condition ^= 1;
4186 //genSkipCond(&rFalseIfx,left,size,7);
4187 //rFalseIfx.condition ^= 1;
4188 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4189 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4191 if(rFalseIfx.condition)
4192 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4194 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4198 /* Lit is greater than or equal to zero */
4199 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4200 //rFalseIfx.condition ^= 1;
4201 //genSkipCond(&rFalseIfx,right,size,7);
4202 //rFalseIfx.condition ^= 1;
4204 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4205 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4207 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4208 if(rFalseIfx.condition)
4209 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4211 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4216 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4217 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4221 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4223 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4225 rFalseIfx.condition ^= 1;
4226 //rFalseIfx.condition = 1;
4227 genSkipc(&rFalseIfx);
4229 emitpLabel(truelbl->key);
4231 if(ifx) ifx->generated = 1;
4236 /* compare word or long to an unsigned literal on the right.*/
4241 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4244 break; /* handled above */
4247 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4249 emitpcode(POC_IORFW, popGet(AOP(right),size));
4250 genSkipz2(&rFalseIfx,0);
4254 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4256 emitpcode(POC_IORFW, popGet(AOP(right),size));
4259 if(rFalseIfx.condition)
4260 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4262 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4265 emitpcode(POC_MOVLW, popGetLit(lit+1));
4266 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4268 rFalseIfx.condition ^= 1;
4269 genSkipc(&rFalseIfx);
4272 emitpLabel(truelbl->key);
4274 if(ifx) ifx->generated = 1;
4280 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4281 i = (lit >> (size*8)) & 0xff;
4283 emitpcode(POC_MOVLW, popGetLit(i));
4284 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4287 i = (lit >> (size*8)) & 0xff;
4290 emitpcode(POC_MOVLW, popGetLit(i));
4292 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4294 /* this byte of the lit is zero,
4295 *if it's not the last then OR in the variable */
4297 emitpcode(POC_IORFW, popGet(AOP(right),size));
4302 emitpLabel(lbl->key);
4304 rFalseIfx.condition ^= 1;
4305 genSkipc(&rFalseIfx);
4309 emitpLabel(truelbl->key);
4310 if(ifx) ifx->generated = 1;
4314 /* Compare two variables */
4316 DEBUGpic14_emitcode(";sign","%d",sign);
4320 /* Sigh. thus sucks... */
4322 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4323 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4324 emitpcode(POC_MOVLW, popGetLit(0x80));
4325 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4326 emitpcode(POC_XORFW, popGet(AOP(right),size));
4327 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4329 /* Signed char comparison */
4330 /* Special thanks to Nikolai Golovchenko for this snippet */
4331 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4332 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4333 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4334 emitpcode(POC_XORFW, popGet(AOP(left),0));
4335 emitpcode(POC_XORFW, popGet(AOP(right),0));
4336 emitpcode(POC_ADDLW, popGetLit(0x80));
4338 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4339 genSkipc(&rFalseIfx);
4341 if(ifx) ifx->generated = 1;
4347 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4348 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4352 /* The rest of the bytes of a multi-byte compare */
4356 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4359 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4360 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4365 emitpLabel(lbl->key);
4367 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4368 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4369 (AOP_TYPE(result) == AOP_REG)) {
4370 emitpcode(POC_CLRF, popGet(AOP(result),0));
4371 emitpcode(POC_RLF, popGet(AOP(result),0));
4373 genSkipc(&rFalseIfx);
4375 //genSkipc(&rFalseIfx);
4376 if(ifx) ifx->generated = 1;
4383 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4385 pic14_outBitC(result);
4387 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4388 /* if the result is used in the next
4389 ifx conditional branch then generate
4390 code a little differently */
4392 genIfxJump (ifx,"c");
4394 pic14_outBitC(result);
4395 /* leave the result in acc */
4400 /*-----------------------------------------------------------------*/
4401 /* genCmpGt :- greater than comparison */
4402 /*-----------------------------------------------------------------*/
4403 static void genCmpGt (iCode *ic, iCode *ifx)
4405 operand *left, *right, *result;
4406 sym_link *letype , *retype;
4409 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4411 right= IC_RIGHT(ic);
4412 result = IC_RESULT(ic);
4414 letype = getSpec(operandType(left));
4415 retype =getSpec(operandType(right));
4416 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4417 /* assign the amsops */
4418 aopOp (left,ic,FALSE);
4419 aopOp (right,ic,FALSE);
4420 aopOp (result,ic,TRUE);
4422 genCmp(right, left, result, ifx, sign);
4424 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4425 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4426 freeAsmop(result,NULL,ic,TRUE);
4429 /*-----------------------------------------------------------------*/
4430 /* genCmpLt - less than comparisons */
4431 /*-----------------------------------------------------------------*/
4432 static void genCmpLt (iCode *ic, iCode *ifx)
4434 operand *left, *right, *result;
4435 sym_link *letype , *retype;
4438 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4440 right= IC_RIGHT(ic);
4441 result = IC_RESULT(ic);
4443 letype = getSpec(operandType(left));
4444 retype =getSpec(operandType(right));
4445 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4447 /* assign the amsops */
4448 aopOp (left,ic,FALSE);
4449 aopOp (right,ic,FALSE);
4450 aopOp (result,ic,TRUE);
4452 genCmp(left, right, result, ifx, sign);
4454 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4455 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4456 freeAsmop(result,NULL,ic,TRUE);
4459 /*-----------------------------------------------------------------*/
4460 /* genc16bit2lit - compare a 16 bit value to a literal */
4461 /*-----------------------------------------------------------------*/
4462 static void genc16bit2lit(operand *op, int lit, int offset)
4466 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4467 if( (lit&0xff) == 0)
4472 switch( BYTEofLONG(lit,i)) {
4474 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4477 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4480 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4483 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4484 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4489 switch( BYTEofLONG(lit,i)) {
4491 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4495 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4499 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4502 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4504 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4510 /*-----------------------------------------------------------------*/
4511 /* gencjneshort - compare and jump if not equal */
4512 /*-----------------------------------------------------------------*/
4513 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4515 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4517 int res_offset = 0; /* the result may be a different size then left or right */
4518 int res_size = AOP_SIZE(result);
4522 unsigned long lit = 0L;
4523 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4524 DEBUGpic14_AopType(__LINE__,left,right,result);
4526 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4527 resolveIfx(&rIfx,ifx);
4528 lbl = newiTempLabel(NULL);
4531 /* if the left side is a literal or
4532 if the right is in a pointer register and left
4534 if ((AOP_TYPE(left) == AOP_LIT) ||
4535 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4540 if(AOP_TYPE(right) == AOP_LIT)
4541 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4543 /* if the right side is a literal then anything goes */
4544 if (AOP_TYPE(right) == AOP_LIT &&
4545 AOP_TYPE(left) != AOP_DIR ) {
4548 genc16bit2lit(left, lit, 0);
4550 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4555 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4556 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4558 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4562 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4564 if(res_offset < res_size-1)
4572 /* if the right side is in a register or in direct space or
4573 if the left is a pointer register & right is not */
4574 else if (AOP_TYPE(right) == AOP_REG ||
4575 AOP_TYPE(right) == AOP_DIR ||
4576 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4577 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4578 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4579 int lbl_key = lbl->key;
4582 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4583 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4585 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4586 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4587 __FUNCTION__,__LINE__);
4591 /* switch(size) { */
4593 /* genc16bit2lit(left, lit, 0); */
4595 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4600 if((AOP_TYPE(left) == AOP_DIR) &&
4601 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4603 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4604 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4606 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4608 switch (lit & 0xff) {
4610 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4613 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4614 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4615 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4619 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4620 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4621 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4622 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4626 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4627 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4632 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4635 if(AOP_TYPE(result) == AOP_CRY) {
4636 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4641 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4643 /* fix me. probably need to check result size too */
4644 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4649 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4650 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4657 if(res_offset < res_size-1)
4662 } else if(AOP_TYPE(right) == AOP_REG &&
4663 AOP_TYPE(left) != AOP_DIR){
4666 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4667 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4668 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4673 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4675 if(res_offset < res_size-1)
4680 /* right is a pointer reg need both a & b */
4682 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4684 pic14_emitcode("mov","b,%s",l);
4685 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4686 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4691 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4693 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4695 emitpLabel(lbl->key);
4697 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4704 /*-----------------------------------------------------------------*/
4705 /* gencjne - compare and jump if not equal */
4706 /*-----------------------------------------------------------------*/
4707 static void gencjne(operand *left, operand *right, iCode *ifx)
4709 symbol *tlbl = newiTempLabel(NULL);
4711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4712 gencjneshort(left, right, lbl);
4714 pic14_emitcode("mov","a,%s",one);
4715 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4716 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4717 pic14_emitcode("clr","a");
4718 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4720 emitpLabel(lbl->key);
4721 emitpLabel(tlbl->key);
4726 /*-----------------------------------------------------------------*/
4727 /* genCmpEq - generates code for equal to */
4728 /*-----------------------------------------------------------------*/
4729 static void genCmpEq (iCode *ic, iCode *ifx)
4731 operand *left, *right, *result;
4732 unsigned long lit = 0L;
4735 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4738 DEBUGpic14_emitcode ("; ifx is non-null","");
4740 DEBUGpic14_emitcode ("; ifx is null","");
4742 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4743 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4744 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4746 size = max(AOP_SIZE(left),AOP_SIZE(right));
4748 DEBUGpic14_AopType(__LINE__,left,right,result);
4750 /* if literal, literal on the right or
4751 if the right is in a pointer register and left
4753 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4754 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4755 operand *tmp = right ;
4761 if(ifx && !AOP_SIZE(result)){
4763 /* if they are both bit variables */
4764 if (AOP_TYPE(left) == AOP_CRY &&
4765 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4766 if(AOP_TYPE(right) == AOP_LIT){
4767 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4769 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4770 pic14_emitcode("cpl","c");
4771 } else if(lit == 1L) {
4772 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4774 pic14_emitcode("clr","c");
4776 /* AOP_TYPE(right) == AOP_CRY */
4778 symbol *lbl = newiTempLabel(NULL);
4779 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4780 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4781 pic14_emitcode("cpl","c");
4782 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4784 /* if true label then we jump if condition
4786 tlbl = newiTempLabel(NULL);
4787 if ( IC_TRUE(ifx) ) {
4788 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4789 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4791 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4792 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4794 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4797 /* left and right are both bit variables, result is carry */
4800 resolveIfx(&rIfx,ifx);
4802 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4803 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4804 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4805 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4810 /* They're not both bit variables. Is the right a literal? */
4811 if(AOP_TYPE(right) == AOP_LIT) {
4812 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4817 switch(lit & 0xff) {
4819 if ( IC_TRUE(ifx) ) {
4820 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4822 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4824 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4825 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4829 if ( IC_TRUE(ifx) ) {
4830 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4832 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4834 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4835 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4839 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4841 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4846 /* end of size == 1 */
4850 genc16bit2lit(left,lit,offset);
4853 /* end of size == 2 */
4858 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4859 emitpcode(POC_IORFW,popGet(AOP(left),1));
4860 emitpcode(POC_IORFW,popGet(AOP(left),2));
4861 emitpcode(POC_IORFW,popGet(AOP(left),3));
4865 /* search for patterns that can be optimized */
4867 genc16bit2lit(left,lit,0);
4870 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4872 genc16bit2lit(left,lit,2);
4874 emitpcode(POC_IORFW,popGet(AOP(left),2));
4875 emitpcode(POC_IORFW,popGet(AOP(left),3));
4888 } else if(AOP_TYPE(right) == AOP_CRY ) {
4889 /* we know the left is not a bit, but that the right is */
4890 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4891 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4892 popGet(AOP(right),offset));
4893 emitpcode(POC_XORLW,popGetLit(1));
4895 /* if the two are equal, then W will be 0 and the Z bit is set
4896 * we could test Z now, or go ahead and check the high order bytes if
4897 * the variable we're comparing is larger than a byte. */
4900 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4902 if ( IC_TRUE(ifx) ) {
4904 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4905 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4908 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4909 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4913 /* They're both variables that are larger than bits */
4916 tlbl = newiTempLabel(NULL);
4919 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4920 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4922 if ( IC_TRUE(ifx) ) {
4925 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4926 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4929 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4930 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4934 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4935 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4939 if(s>1 && IC_TRUE(ifx)) {
4940 emitpLabel(tlbl->key);
4941 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4945 /* mark the icode as generated */
4950 /* if they are both bit variables */
4951 if (AOP_TYPE(left) == AOP_CRY &&
4952 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4953 if(AOP_TYPE(right) == AOP_LIT){
4954 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4956 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4957 pic14_emitcode("cpl","c");
4958 } else if(lit == 1L) {
4959 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4961 pic14_emitcode("clr","c");
4963 /* AOP_TYPE(right) == AOP_CRY */
4965 symbol *lbl = newiTempLabel(NULL);
4966 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4967 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4968 pic14_emitcode("cpl","c");
4969 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4972 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4973 pic14_outBitC(result);
4977 genIfxJump (ifx,"c");
4980 /* if the result is used in an arithmetic operation
4981 then put the result in place */
4982 pic14_outBitC(result);
4985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4986 gencjne(left,right,result,ifx);
4989 gencjne(left,right,newiTempLabel(NULL));
4991 if(IC_TRUE(ifx)->key)
4992 gencjne(left,right,IC_TRUE(ifx)->key);
4994 gencjne(left,right,IC_FALSE(ifx)->key);
4998 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4999 aopPut(AOP(result),"a",0);
5004 genIfxJump (ifx,"a");
5008 /* if the result is used in an arithmetic operation
5009 then put the result in place */
5011 if (AOP_TYPE(result) != AOP_CRY)
5012 pic14_outAcc(result);
5014 /* leave the result in acc */
5018 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5019 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5020 freeAsmop(result,NULL,ic,TRUE);
5023 /*-----------------------------------------------------------------*/
5024 /* ifxForOp - returns the icode containing the ifx for operand */
5025 /*-----------------------------------------------------------------*/
5026 static iCode *ifxForOp ( operand *op, iCode *ic )
5028 /* if true symbol then needs to be assigned */
5029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5030 if (IS_TRUE_SYMOP(op))
5033 /* if this has register type condition and
5034 the next instruction is ifx with the same operand
5035 and live to of the operand is upto the ifx only then */
5037 ic->next->op == IFX &&
5038 IC_COND(ic->next)->key == op->key &&
5039 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5043 ic->next->op == IFX &&
5044 IC_COND(ic->next)->key == op->key) {
5045 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5049 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5051 ic->next->op == IFX)
5052 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5055 ic->next->op == IFX &&
5056 IC_COND(ic->next)->key == op->key) {
5057 DEBUGpic14_emitcode ("; "," key is okay");
5058 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5059 OP_SYMBOL(op)->liveTo,
5066 /*-----------------------------------------------------------------*/
5067 /* genAndOp - for && operation */
5068 /*-----------------------------------------------------------------*/
5069 static void genAndOp (iCode *ic)
5071 operand *left,*right, *result;
5074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5075 /* note here that && operations that are in an
5076 if statement are taken away by backPatchLabels
5077 only those used in arthmetic operations remain */
5078 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5079 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5080 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5082 DEBUGpic14_AopType(__LINE__,left,right,result);
5084 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5085 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5086 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5088 /* if both are bit variables */
5089 /* if (AOP_TYPE(left) == AOP_CRY && */
5090 /* AOP_TYPE(right) == AOP_CRY ) { */
5091 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5092 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5093 /* pic14_outBitC(result); */
5095 /* tlbl = newiTempLabel(NULL); */
5096 /* pic14_toBoolean(left); */
5097 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5098 /* pic14_toBoolean(right); */
5099 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5100 /* pic14_outBitAcc(result); */
5103 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5104 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5105 freeAsmop(result,NULL,ic,TRUE);
5109 /*-----------------------------------------------------------------*/
5110 /* genOrOp - for || operation */
5111 /*-----------------------------------------------------------------*/
5114 modified this code, but it doesn't appear to ever get called
5117 static void genOrOp (iCode *ic)
5119 operand *left,*right, *result;
5122 /* note here that || operations that are in an
5123 if statement are taken away by backPatchLabels
5124 only those used in arthmetic operations remain */
5125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5126 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5127 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5128 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5130 DEBUGpic14_AopType(__LINE__,left,right,result);
5132 /* if both are bit variables */
5133 if (AOP_TYPE(left) == AOP_CRY &&
5134 AOP_TYPE(right) == AOP_CRY ) {
5135 pic14_emitcode("clrc","");
5136 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5137 AOP(left)->aopu.aop_dir,
5138 AOP(left)->aopu.aop_dir);
5139 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5140 AOP(right)->aopu.aop_dir,
5141 AOP(right)->aopu.aop_dir);
5142 pic14_emitcode("setc","");
5145 tlbl = newiTempLabel(NULL);
5146 pic14_toBoolean(left);
5148 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5149 pic14_toBoolean(right);
5150 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5152 pic14_outBitAcc(result);
5155 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5156 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5157 freeAsmop(result,NULL,ic,TRUE);
5160 /*-----------------------------------------------------------------*/
5161 /* isLiteralBit - test if lit == 2^n */
5162 /*-----------------------------------------------------------------*/
5163 static int isLiteralBit(unsigned long lit)
5165 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5166 0x100L,0x200L,0x400L,0x800L,
5167 0x1000L,0x2000L,0x4000L,0x8000L,
5168 0x10000L,0x20000L,0x40000L,0x80000L,
5169 0x100000L,0x200000L,0x400000L,0x800000L,
5170 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5171 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5175 for(idx = 0; idx < 32; idx++)
5181 /*-----------------------------------------------------------------*/
5182 /* continueIfTrue - */
5183 /*-----------------------------------------------------------------*/
5184 static void continueIfTrue (iCode *ic)
5186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5188 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5192 /*-----------------------------------------------------------------*/
5194 /*-----------------------------------------------------------------*/
5195 static void jumpIfTrue (iCode *ic)
5197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5199 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5203 /*-----------------------------------------------------------------*/
5204 /* jmpTrueOrFalse - */
5205 /*-----------------------------------------------------------------*/
5206 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5208 // ugly but optimized by peephole
5209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5211 symbol *nlbl = newiTempLabel(NULL);
5212 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5213 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5214 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5215 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5218 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5219 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5224 /*-----------------------------------------------------------------*/
5225 /* genAnd - code for and */
5226 /*-----------------------------------------------------------------*/
5227 static void genAnd (iCode *ic, iCode *ifx)
5229 operand *left, *right, *result;
5231 unsigned long lit = 0L;
5236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5237 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5238 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5239 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5241 resolveIfx(&rIfx,ifx);
5243 /* if left is a literal & right is not then exchange them */
5244 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5245 AOP_NEEDSACC(left)) {
5246 operand *tmp = right ;
5251 /* if result = right then exchange them */
5252 if(pic14_sameRegs(AOP(result),AOP(right))){
5253 operand *tmp = right ;
5258 /* if right is bit then exchange them */
5259 if (AOP_TYPE(right) == AOP_CRY &&
5260 AOP_TYPE(left) != AOP_CRY){
5261 operand *tmp = right ;
5265 if(AOP_TYPE(right) == AOP_LIT)
5266 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5268 size = AOP_SIZE(result);
5270 DEBUGpic14_AopType(__LINE__,left,right,result);
5273 // result = bit & yy;
5274 if (AOP_TYPE(left) == AOP_CRY){
5275 // c = bit & literal;
5276 if(AOP_TYPE(right) == AOP_LIT){
5278 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5281 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5284 if(size && (AOP_TYPE(result) == AOP_CRY)){
5285 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5288 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5292 pic14_emitcode("clr","c");
5295 if (AOP_TYPE(right) == AOP_CRY){
5297 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5298 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5301 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5303 pic14_emitcode("rrc","a");
5304 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5310 pic14_outBitC(result);
5312 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5313 genIfxJump(ifx, "c");
5317 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5318 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5319 if((AOP_TYPE(right) == AOP_LIT) &&
5320 (AOP_TYPE(result) == AOP_CRY) &&
5321 (AOP_TYPE(left) != AOP_CRY)){
5322 int posbit = isLiteralBit(lit);
5326 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5329 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5335 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5336 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5338 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5339 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5342 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5343 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5344 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5351 symbol *tlbl = newiTempLabel(NULL);
5352 int sizel = AOP_SIZE(left);
5354 pic14_emitcode("setb","c");
5356 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5357 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5359 if((posbit = isLiteralBit(bytelit)) != 0)
5360 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5362 if(bytelit != 0x0FFL)
5363 pic14_emitcode("anl","a,%s",
5364 aopGet(AOP(right),offset,FALSE,TRUE));
5365 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5370 // bit = left & literal
5372 pic14_emitcode("clr","c");
5373 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5375 // if(left & literal)
5378 jmpTrueOrFalse(ifx, tlbl);
5382 pic14_outBitC(result);
5386 /* if left is same as result */
5387 if(pic14_sameRegs(AOP(result),AOP(left))){
5389 for(;size--; offset++,lit>>=8) {
5390 if(AOP_TYPE(right) == AOP_LIT){
5391 switch(lit & 0xff) {
5393 /* and'ing with 0 has clears the result */
5394 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5395 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5398 /* and'ing with 0xff is a nop when the result and left are the same */
5403 int p = my_powof2( (~lit) & 0xff );
5405 /* only one bit is set in the literal, so use a bcf instruction */
5406 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5407 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5410 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5411 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5412 if(know_W != (lit&0xff))
5413 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5415 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5420 if (AOP_TYPE(left) == AOP_ACC) {
5421 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5423 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5424 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5431 // left & result in different registers
5432 if(AOP_TYPE(result) == AOP_CRY){
5434 // if(size), result in bit
5435 // if(!size && ifx), conditional oper: if(left & right)
5436 symbol *tlbl = newiTempLabel(NULL);
5437 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5439 pic14_emitcode("setb","c");
5441 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5442 pic14_emitcode("anl","a,%s",
5443 aopGet(AOP(left),offset,FALSE,FALSE));
5444 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5449 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5450 pic14_outBitC(result);
5452 jmpTrueOrFalse(ifx, tlbl);
5454 for(;(size--);offset++) {
5456 // result = left & right
5457 if(AOP_TYPE(right) == AOP_LIT){
5458 int t = (lit >> (offset*8)) & 0x0FFL;
5461 pic14_emitcode("clrf","%s",
5462 aopGet(AOP(result),offset,FALSE,FALSE));
5463 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5466 pic14_emitcode("movf","%s,w",
5467 aopGet(AOP(left),offset,FALSE,FALSE));
5468 pic14_emitcode("movwf","%s",
5469 aopGet(AOP(result),offset,FALSE,FALSE));
5470 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5471 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5474 pic14_emitcode("movlw","0x%x",t);
5475 pic14_emitcode("andwf","%s,w",
5476 aopGet(AOP(left),offset,FALSE,FALSE));
5477 pic14_emitcode("movwf","%s",
5478 aopGet(AOP(result),offset,FALSE,FALSE));
5480 emitpcode(POC_MOVLW, popGetLit(t));
5481 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5482 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5487 if (AOP_TYPE(left) == AOP_ACC) {
5488 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5489 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5491 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5492 pic14_emitcode("andwf","%s,w",
5493 aopGet(AOP(left),offset,FALSE,FALSE));
5494 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5495 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5497 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5498 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5504 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5505 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5506 freeAsmop(result,NULL,ic,TRUE);
5509 /*-----------------------------------------------------------------*/
5510 /* genOr - code for or */
5511 /*-----------------------------------------------------------------*/
5512 static void genOr (iCode *ic, iCode *ifx)
5514 operand *left, *right, *result;
5516 unsigned long lit = 0L;
5518 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5520 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5521 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5522 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5524 DEBUGpic14_AopType(__LINE__,left,right,result);
5526 /* if left is a literal & right is not then exchange them */
5527 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5528 AOP_NEEDSACC(left)) {
5529 operand *tmp = right ;
5534 /* if result = right then exchange them */
5535 if(pic14_sameRegs(AOP(result),AOP(right))){
5536 operand *tmp = right ;
5541 /* if right is bit then exchange them */
5542 if (AOP_TYPE(right) == AOP_CRY &&
5543 AOP_TYPE(left) != AOP_CRY){
5544 operand *tmp = right ;
5549 DEBUGpic14_AopType(__LINE__,left,right,result);
5551 if(AOP_TYPE(right) == AOP_LIT)
5552 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5554 size = AOP_SIZE(result);
5558 if (AOP_TYPE(left) == AOP_CRY){
5559 if(AOP_TYPE(right) == AOP_LIT){
5560 // c = bit & literal;
5562 // lit != 0 => result = 1
5563 if(AOP_TYPE(result) == AOP_CRY){
5565 emitpcode(POC_BSF, popGet(AOP(result),0));
5566 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5567 // AOP(result)->aopu.aop_dir,
5568 // AOP(result)->aopu.aop_dir);
5570 continueIfTrue(ifx);
5574 // lit == 0 => result = left
5575 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5577 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5580 if (AOP_TYPE(right) == AOP_CRY){
5581 if(pic14_sameRegs(AOP(result),AOP(left))){
5583 emitpcode(POC_BCF, popGet(AOP(result),0));
5584 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5585 emitpcode(POC_BSF, popGet(AOP(result),0));
5587 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5588 AOP(result)->aopu.aop_dir,
5589 AOP(result)->aopu.aop_dir);
5590 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5591 AOP(right)->aopu.aop_dir,
5592 AOP(right)->aopu.aop_dir);
5593 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5594 AOP(result)->aopu.aop_dir,
5595 AOP(result)->aopu.aop_dir);
5597 if( AOP_TYPE(result) == AOP_ACC) {
5598 emitpcode(POC_MOVLW, popGetLit(0));
5599 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5600 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5601 emitpcode(POC_MOVLW, popGetLit(1));
5605 emitpcode(POC_BCF, popGet(AOP(result),0));
5606 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5607 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5608 emitpcode(POC_BSF, popGet(AOP(result),0));
5610 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5611 AOP(result)->aopu.aop_dir,
5612 AOP(result)->aopu.aop_dir);
5613 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5614 AOP(right)->aopu.aop_dir,
5615 AOP(right)->aopu.aop_dir);
5616 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5617 AOP(left)->aopu.aop_dir,
5618 AOP(left)->aopu.aop_dir);
5619 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5620 AOP(result)->aopu.aop_dir,
5621 AOP(result)->aopu.aop_dir);
5626 symbol *tlbl = newiTempLabel(NULL);
5627 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5630 emitpcode(POC_BCF, popGet(AOP(result),0));
5631 if( AOP_TYPE(right) == AOP_ACC) {
5632 emitpcode(POC_IORLW, popGetLit(0));
5634 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5635 emitpcode(POC_BSF, popGet(AOP(result),0));
5640 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5641 pic14_emitcode(";XXX setb","c");
5642 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5643 AOP(left)->aopu.aop_dir,tlbl->key+100);
5644 pic14_toBoolean(right);
5645 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5646 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5647 jmpTrueOrFalse(ifx, tlbl);
5651 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5658 pic14_outBitC(result);
5660 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5661 genIfxJump(ifx, "c");
5665 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5666 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5667 if((AOP_TYPE(right) == AOP_LIT) &&
5668 (AOP_TYPE(result) == AOP_CRY) &&
5669 (AOP_TYPE(left) != AOP_CRY)){
5671 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5674 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5676 continueIfTrue(ifx);
5679 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5680 // lit = 0, result = boolean(left)
5682 pic14_emitcode(";XXX setb","c");
5683 pic14_toBoolean(right);
5685 symbol *tlbl = newiTempLabel(NULL);
5686 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5688 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5690 genIfxJump (ifx,"a");
5694 pic14_outBitC(result);
5698 /* if left is same as result */
5699 if(pic14_sameRegs(AOP(result),AOP(left))){
5701 for(;size--; offset++,lit>>=8) {
5702 if(AOP_TYPE(right) == AOP_LIT){
5703 if((lit & 0xff) == 0)
5704 /* or'ing with 0 has no effect */
5707 int p = my_powof2(lit & 0xff);
5709 /* only one bit is set in the literal, so use a bsf instruction */
5711 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5713 if(know_W != (lit & 0xff))
5714 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5715 know_W = lit & 0xff;
5716 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5721 if (AOP_TYPE(left) == AOP_ACC) {
5722 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5723 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5725 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5726 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5728 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5729 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5735 // left & result in different registers
5736 if(AOP_TYPE(result) == AOP_CRY){
5738 // if(size), result in bit
5739 // if(!size && ifx), conditional oper: if(left | right)
5740 symbol *tlbl = newiTempLabel(NULL);
5741 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5742 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5746 pic14_emitcode(";XXX setb","c");
5748 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5749 pic14_emitcode(";XXX orl","a,%s",
5750 aopGet(AOP(left),offset,FALSE,FALSE));
5751 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5756 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5757 pic14_outBitC(result);
5759 jmpTrueOrFalse(ifx, tlbl);
5760 } else for(;(size--);offset++){
5762 // result = left & right
5763 if(AOP_TYPE(right) == AOP_LIT){
5764 int t = (lit >> (offset*8)) & 0x0FFL;
5767 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5768 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5770 pic14_emitcode("movf","%s,w",
5771 aopGet(AOP(left),offset,FALSE,FALSE));
5772 pic14_emitcode("movwf","%s",
5773 aopGet(AOP(result),offset,FALSE,FALSE));
5776 emitpcode(POC_MOVLW, popGetLit(t));
5777 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5778 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5780 pic14_emitcode("movlw","0x%x",t);
5781 pic14_emitcode("iorwf","%s,w",
5782 aopGet(AOP(left),offset,FALSE,FALSE));
5783 pic14_emitcode("movwf","%s",
5784 aopGet(AOP(result),offset,FALSE,FALSE));
5790 // faster than result <- left, anl result,right
5791 // and better if result is SFR
5792 if (AOP_TYPE(left) == AOP_ACC) {
5793 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5794 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5796 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5797 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5799 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5800 pic14_emitcode("iorwf","%s,w",
5801 aopGet(AOP(left),offset,FALSE,FALSE));
5803 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5804 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5809 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5810 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5811 freeAsmop(result,NULL,ic,TRUE);
5814 /*-----------------------------------------------------------------*/
5815 /* genXor - code for xclusive or */
5816 /*-----------------------------------------------------------------*/
5817 static void genXor (iCode *ic, iCode *ifx)
5819 operand *left, *right, *result;
5821 unsigned long lit = 0L;
5823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5825 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5826 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5827 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5829 /* if left is a literal & right is not ||
5830 if left needs acc & right does not */
5831 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5832 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5833 operand *tmp = right ;
5838 /* if result = right then exchange them */
5839 if(pic14_sameRegs(AOP(result),AOP(right))){
5840 operand *tmp = right ;
5845 /* if right is bit then exchange them */
5846 if (AOP_TYPE(right) == AOP_CRY &&
5847 AOP_TYPE(left) != AOP_CRY){
5848 operand *tmp = right ;
5852 if(AOP_TYPE(right) == AOP_LIT)
5853 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5855 size = AOP_SIZE(result);
5859 if (AOP_TYPE(left) == AOP_CRY){
5860 if(AOP_TYPE(right) == AOP_LIT){
5861 // c = bit & literal;
5863 // lit>>1 != 0 => result = 1
5864 if(AOP_TYPE(result) == AOP_CRY){
5866 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5867 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5869 continueIfTrue(ifx);
5872 pic14_emitcode("setb","c");
5876 // lit == 0, result = left
5877 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5879 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5881 // lit == 1, result = not(left)
5882 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5883 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5884 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5885 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5888 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5889 pic14_emitcode("cpl","c");
5896 symbol *tlbl = newiTempLabel(NULL);
5897 if (AOP_TYPE(right) == AOP_CRY){
5899 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5902 int sizer = AOP_SIZE(right);
5904 // if val>>1 != 0, result = 1
5905 pic14_emitcode("setb","c");
5907 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5909 // test the msb of the lsb
5910 pic14_emitcode("anl","a,#0xfe");
5911 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5915 pic14_emitcode("rrc","a");
5917 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5918 pic14_emitcode("cpl","c");
5919 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5924 pic14_outBitC(result);
5926 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5927 genIfxJump(ifx, "c");
5931 if(pic14_sameRegs(AOP(result),AOP(left))){
5932 /* if left is same as result */
5933 for(;size--; offset++) {
5934 if(AOP_TYPE(right) == AOP_LIT){
5935 int t = (lit >> (offset*8)) & 0x0FFL;
5939 if (IS_AOP_PREG(left)) {
5940 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5941 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5942 aopPut(AOP(result),"a",offset);
5944 emitpcode(POC_MOVLW, popGetLit(t));
5945 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5946 pic14_emitcode("xrl","%s,%s",
5947 aopGet(AOP(left),offset,FALSE,TRUE),
5948 aopGet(AOP(right),offset,FALSE,FALSE));
5951 if (AOP_TYPE(left) == AOP_ACC)
5952 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5954 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5955 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5957 if (IS_AOP_PREG(left)) {
5958 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5959 aopPut(AOP(result),"a",offset);
5961 pic14_emitcode("xrl","%s,a",
5962 aopGet(AOP(left),offset,FALSE,TRUE));
5968 // left & result in different registers
5969 if(AOP_TYPE(result) == AOP_CRY){
5971 // if(size), result in bit
5972 // if(!size && ifx), conditional oper: if(left ^ right)
5973 symbol *tlbl = newiTempLabel(NULL);
5974 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5976 pic14_emitcode("setb","c");
5978 if((AOP_TYPE(right) == AOP_LIT) &&
5979 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5980 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5982 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5983 pic14_emitcode("xrl","a,%s",
5984 aopGet(AOP(left),offset,FALSE,FALSE));
5986 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5991 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5992 pic14_outBitC(result);
5994 jmpTrueOrFalse(ifx, tlbl);
5995 } else for(;(size--);offset++){
5997 // result = left & right
5998 if(AOP_TYPE(right) == AOP_LIT){
5999 int t = (lit >> (offset*8)) & 0x0FFL;
6002 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6003 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6004 pic14_emitcode("movf","%s,w",
6005 aopGet(AOP(left),offset,FALSE,FALSE));
6006 pic14_emitcode("movwf","%s",
6007 aopGet(AOP(result),offset,FALSE,FALSE));
6010 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6011 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6012 pic14_emitcode("comf","%s,w",
6013 aopGet(AOP(left),offset,FALSE,FALSE));
6014 pic14_emitcode("movwf","%s",
6015 aopGet(AOP(result),offset,FALSE,FALSE));
6018 emitpcode(POC_MOVLW, popGetLit(t));
6019 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6020 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6021 pic14_emitcode("movlw","0x%x",t);
6022 pic14_emitcode("xorwf","%s,w",
6023 aopGet(AOP(left),offset,FALSE,FALSE));
6024 pic14_emitcode("movwf","%s",
6025 aopGet(AOP(result),offset,FALSE,FALSE));
6031 // faster than result <- left, anl result,right
6032 // and better if result is SFR
6033 if (AOP_TYPE(left) == AOP_ACC) {
6034 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6035 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6037 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6038 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6039 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6040 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6042 if ( AOP_TYPE(result) != AOP_ACC){
6043 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6044 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6050 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6051 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6052 freeAsmop(result,NULL,ic,TRUE);
6055 /*-----------------------------------------------------------------*/
6056 /* genInline - write the inline code out */
6057 /*-----------------------------------------------------------------*/
6058 static void genInline (iCode *ic)
6060 char *buffer, *bp, *bp1;
6062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6064 _G.inLine += (!options.asmpeep);
6066 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6067 strcpy(buffer,IC_INLINE(ic));
6069 /* emit each line as a code */
6075 addpCode2pBlock(pb,AssembleLine(bp1));
6082 pic14_emitcode(bp1,"");
6088 if ((bp1 != bp) && *bp1)
6089 addpCode2pBlock(pb,AssembleLine(bp1));
6093 _G.inLine -= (!options.asmpeep);
6096 /*-----------------------------------------------------------------*/
6097 /* genRRC - rotate right with carry */
6098 /*-----------------------------------------------------------------*/
6099 static void genRRC (iCode *ic)
6101 operand *left , *result ;
6102 int size, offset = 0, same;
6104 /* rotate right with carry */
6106 result=IC_RESULT(ic);
6107 aopOp (left,ic,FALSE);
6108 aopOp (result,ic,FALSE);
6110 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6112 same = pic14_sameRegs(AOP(result),AOP(left));
6114 size = AOP_SIZE(result);
6116 /* get the lsb and put it into the carry */
6117 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6124 emitpcode(POC_RRF, popGet(AOP(left),offset));
6126 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6127 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6133 freeAsmop(left,NULL,ic,TRUE);
6134 freeAsmop(result,NULL,ic,TRUE);
6137 /*-----------------------------------------------------------------*/
6138 /* genRLC - generate code for rotate left with carry */
6139 /*-----------------------------------------------------------------*/
6140 static void genRLC (iCode *ic)
6142 operand *left , *result ;
6143 int size, offset = 0;
6146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6147 /* rotate right with carry */
6149 result=IC_RESULT(ic);
6150 aopOp (left,ic,FALSE);
6151 aopOp (result,ic,FALSE);
6153 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6155 same = pic14_sameRegs(AOP(result),AOP(left));
6157 /* move it to the result */
6158 size = AOP_SIZE(result);
6160 /* get the msb and put it into the carry */
6161 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6168 emitpcode(POC_RLF, popGet(AOP(left),offset));
6170 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6171 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6178 freeAsmop(left,NULL,ic,TRUE);
6179 freeAsmop(result,NULL,ic,TRUE);
6182 /*-----------------------------------------------------------------*/
6183 /* genGetHbit - generates code get highest order bit */
6184 /*-----------------------------------------------------------------*/
6185 static void genGetHbit (iCode *ic)
6187 operand *left, *result;
6189 result=IC_RESULT(ic);
6190 aopOp (left,ic,FALSE);
6191 aopOp (result,ic,FALSE);
6193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6194 /* get the highest order byte into a */
6195 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6196 if(AOP_TYPE(result) == AOP_CRY){
6197 pic14_emitcode("rlc","a");
6198 pic14_outBitC(result);
6201 pic14_emitcode("rl","a");
6202 pic14_emitcode("anl","a,#0x01");
6203 pic14_outAcc(result);
6207 freeAsmop(left,NULL,ic,TRUE);
6208 freeAsmop(result,NULL,ic,TRUE);
6211 /*-----------------------------------------------------------------*/
6212 /* AccRol - rotate left accumulator by known count */
6213 /*-----------------------------------------------------------------*/
6214 static void AccRol (int shCount)
6216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6217 shCount &= 0x0007; // shCount : 0..7
6222 pic14_emitcode("rl","a");
6225 pic14_emitcode("rl","a");
6226 pic14_emitcode("rl","a");
6229 pic14_emitcode("swap","a");
6230 pic14_emitcode("rr","a");
6233 pic14_emitcode("swap","a");
6236 pic14_emitcode("swap","a");
6237 pic14_emitcode("rl","a");
6240 pic14_emitcode("rr","a");
6241 pic14_emitcode("rr","a");
6244 pic14_emitcode("rr","a");
6249 /*-----------------------------------------------------------------*/
6250 /* AccLsh - left shift accumulator by known count */
6251 /*-----------------------------------------------------------------*/
6252 static void AccLsh (int shCount)
6254 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6257 pic14_emitcode("add","a,acc");
6260 pic14_emitcode("add","a,acc");
6261 pic14_emitcode("add","a,acc");
6263 /* rotate left accumulator */
6265 /* and kill the lower order bits */
6266 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6271 /*-----------------------------------------------------------------*/
6272 /* AccRsh - right shift accumulator by known count */
6273 /*-----------------------------------------------------------------*/
6274 static void AccRsh (int shCount)
6276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6280 pic14_emitcode("rrc","a");
6282 /* rotate right accumulator */
6283 AccRol(8 - shCount);
6284 /* and kill the higher order bits */
6285 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6291 /*-----------------------------------------------------------------*/
6292 /* AccSRsh - signed right shift accumulator by known count */
6293 /*-----------------------------------------------------------------*/
6294 static void AccSRsh (int shCount)
6297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6300 pic14_emitcode("mov","c,acc.7");
6301 pic14_emitcode("rrc","a");
6302 } else if(shCount == 2){
6303 pic14_emitcode("mov","c,acc.7");
6304 pic14_emitcode("rrc","a");
6305 pic14_emitcode("mov","c,acc.7");
6306 pic14_emitcode("rrc","a");
6308 tlbl = newiTempLabel(NULL);
6309 /* rotate right accumulator */
6310 AccRol(8 - shCount);
6311 /* and kill the higher order bits */
6312 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6313 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6314 pic14_emitcode("orl","a,#0x%02x",
6315 (unsigned char)~SRMask[shCount]);
6316 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6321 /*-----------------------------------------------------------------*/
6322 /* shiftR1Left2Result - shift right one byte from left to result */
6323 /*-----------------------------------------------------------------*/
6324 static void shiftR1Left2ResultSigned (operand *left, int offl,
6325 operand *result, int offr,
6330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6332 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6336 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6338 emitpcode(POC_RRF, popGet(AOP(result),offr));
6340 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6341 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6347 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6349 emitpcode(POC_RRF, popGet(AOP(result),offr));
6351 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6352 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6354 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6355 emitpcode(POC_RRF, popGet(AOP(result),offr));
6361 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6363 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6364 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6367 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6368 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6369 emitpcode(POC_ANDLW, popGetLit(0x1f));
6371 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6372 emitpcode(POC_IORLW, popGetLit(0xe0));
6374 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6378 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6379 emitpcode(POC_ANDLW, popGetLit(0x0f));
6380 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6381 emitpcode(POC_IORLW, popGetLit(0xf0));
6382 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6386 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6388 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6389 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6391 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6392 emitpcode(POC_ANDLW, popGetLit(0x07));
6393 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6394 emitpcode(POC_IORLW, popGetLit(0xf8));
6395 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6400 emitpcode(POC_MOVLW, popGetLit(0x00));
6401 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6402 emitpcode(POC_MOVLW, popGetLit(0xfe));
6403 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6404 emitpcode(POC_IORLW, popGetLit(0x01));
6405 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6407 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6408 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6409 emitpcode(POC_DECF, popGet(AOP(result),offr));
6410 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6411 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6417 emitpcode(POC_MOVLW, popGetLit(0x00));
6418 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6419 emitpcode(POC_MOVLW, popGetLit(0xff));
6420 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6423 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6424 emitpcode(POC_DECF, popGet(AOP(result),offr));
6432 /*-----------------------------------------------------------------*/
6433 /* shiftR1Left2Result - shift right one byte from left to result */
6434 /*-----------------------------------------------------------------*/
6435 static void shiftR1Left2Result (operand *left, int offl,
6436 operand *result, int offr,
6437 int shCount, int sign)
6441 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6443 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6445 /* Copy the msb into the carry if signed. */
6447 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6457 emitpcode(POC_RRF, popGet(AOP(result),offr));
6459 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6460 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6466 emitpcode(POC_RRF, popGet(AOP(result),offr));
6468 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6469 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6472 emitpcode(POC_RRF, popGet(AOP(result),offr));
6477 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6479 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6480 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6484 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6485 emitpcode(POC_ANDLW, popGetLit(0x1f));
6486 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6490 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6491 emitpcode(POC_ANDLW, popGetLit(0x0f));
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));
6500 emitpcode(POC_RRF, popGet(AOP(result),offr));
6505 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6506 emitpcode(POC_ANDLW, popGetLit(0x80));
6507 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6508 emitpcode(POC_RLF, popGet(AOP(result),offr));
6509 emitpcode(POC_RLF, popGet(AOP(result),offr));
6514 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6515 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6516 emitpcode(POC_RLF, popGet(AOP(result),offr));
6525 /*-----------------------------------------------------------------*/
6526 /* shiftL1Left2Result - shift left one byte from left to result */
6527 /*-----------------------------------------------------------------*/
6528 static void shiftL1Left2Result (operand *left, int offl,
6529 operand *result, int offr, int shCount)
6534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6536 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6537 DEBUGpic14_emitcode ("; ***","same = %d",same);
6538 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6540 /* shift left accumulator */
6541 //AccLsh(shCount); // don't comment out just yet...
6542 // aopPut(AOP(result),"a",offr);
6546 /* Shift left 1 bit position */
6547 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6549 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6551 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6552 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6556 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6557 emitpcode(POC_ANDLW,popGetLit(0x7e));
6558 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6559 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6562 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6563 emitpcode(POC_ANDLW,popGetLit(0x3e));
6564 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6565 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6566 emitpcode(POC_RLF, popGet(AOP(result),offr));
6569 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6570 emitpcode(POC_ANDLW, popGetLit(0xf0));
6571 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6574 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6575 emitpcode(POC_ANDLW, popGetLit(0xf0));
6576 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6577 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6580 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6581 emitpcode(POC_ANDLW, popGetLit(0x30));
6582 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6583 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6584 emitpcode(POC_RLF, popGet(AOP(result),offr));
6587 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6588 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6589 emitpcode(POC_RRF, popGet(AOP(result),offr));
6593 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6598 /*-----------------------------------------------------------------*/
6599 /* movLeft2Result - move byte from left to result */
6600 /*-----------------------------------------------------------------*/
6601 static void movLeft2Result (operand *left, int offl,
6602 operand *result, int offr)
6605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6606 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6607 l = aopGet(AOP(left),offl,FALSE,FALSE);
6609 if (*l == '@' && (IS_AOP_PREG(result))) {
6610 pic14_emitcode("mov","a,%s",l);
6611 aopPut(AOP(result),"a",offr);
6613 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6614 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6619 /*-----------------------------------------------------------------*/
6620 /* shiftL2Left2Result - shift left two bytes from left to result */
6621 /*-----------------------------------------------------------------*/
6622 static void shiftL2Left2Result (operand *left, int offl,
6623 operand *result, int offr, int shCount)
6627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6629 if(pic14_sameRegs(AOP(result), AOP(left))) {
6637 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6638 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6639 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6643 emitpcode(POC_RLF, popGet(AOP(result),offr));
6644 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6650 emitpcode(POC_MOVLW, popGetLit(0x0f));
6651 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6652 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6653 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6654 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6655 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6656 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_RLF, popGet(AOP(result),offr));
6659 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6663 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RRF, popGet(AOP(result),offr));
6665 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6666 emitpcode(POC_RRF, popGet(AOP(result),offr));
6667 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_ANDLW,popGetLit(0xc0));
6669 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6670 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6671 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6672 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6675 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6676 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6677 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6679 emitpcode(POC_RRF, popGet(AOP(result),offr));
6689 /* note, use a mov/add for the shift since the mov has a
6690 chance of getting optimized out */
6691 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6692 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6693 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6694 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6695 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6699 emitpcode(POC_RLF, popGet(AOP(result),offr));
6700 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6706 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6707 emitpcode(POC_ANDLW, popGetLit(0xF0));
6708 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6709 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6710 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6711 emitpcode(POC_ANDLW, popGetLit(0xF0));
6712 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6713 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6717 emitpcode(POC_RLF, popGet(AOP(result),offr));
6718 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6722 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6723 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6724 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6725 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6727 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6728 emitpcode(POC_RRF, popGet(AOP(result),offr));
6729 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6730 emitpcode(POC_ANDLW,popGetLit(0xc0));
6731 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6732 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6733 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6734 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6737 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6738 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6739 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6740 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6741 emitpcode(POC_RRF, popGet(AOP(result),offr));
6746 /*-----------------------------------------------------------------*/
6747 /* shiftR2Left2Result - shift right two bytes from left to result */
6748 /*-----------------------------------------------------------------*/
6749 static void shiftR2Left2Result (operand *left, int offl,
6750 operand *result, int offr,
6751 int shCount, int sign)
6755 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6756 same = pic14_sameRegs(AOP(result), AOP(left));
6758 if(same && ((offl + MSB16) == offr)){
6760 /* don't crash result[offr] */
6761 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6762 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6765 movLeft2Result(left,offl, result, offr);
6766 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6769 /* a:x >> shCount (x = lsb(result))*/
6772 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6774 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6783 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6788 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6789 emitpcode(POC_RRF,popGet(AOP(result),offr));
6791 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6792 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6793 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6794 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6799 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_RRF,popGet(AOP(result),offr));
6810 emitpcode(POC_MOVLW, popGetLit(0xf0));
6811 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6812 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6814 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6815 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6819 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6820 emitpcode(POC_ANDLW, popGetLit(0x0f));
6821 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6823 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6824 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6825 emitpcode(POC_ANDLW, popGetLit(0xf0));
6826 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6827 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6831 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6832 emitpcode(POC_RRF, popGet(AOP(result),offr));
6836 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6837 emitpcode(POC_BTFSC,
6838 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6839 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6847 emitpcode(POC_RLF, popGet(AOP(result),offr));
6848 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6850 emitpcode(POC_RLF, popGet(AOP(result),offr));
6851 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6852 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6853 emitpcode(POC_ANDLW,popGetLit(0x03));
6855 emitpcode(POC_BTFSC,
6856 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6857 emitpcode(POC_IORLW,popGetLit(0xfc));
6859 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6860 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6861 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6862 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6864 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6865 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6866 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6867 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6868 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6869 emitpcode(POC_RLF, popGet(AOP(result),offr));
6870 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6871 emitpcode(POC_ANDLW,popGetLit(0x03));
6873 emitpcode(POC_BTFSC,
6874 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6875 emitpcode(POC_IORLW,popGetLit(0xfc));
6877 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6878 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6885 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6886 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6887 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6888 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6891 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6893 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6898 /*-----------------------------------------------------------------*/
6899 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6900 /*-----------------------------------------------------------------*/
6901 static void shiftLLeftOrResult (operand *left, int offl,
6902 operand *result, int offr, int shCount)
6904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6905 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6906 /* shift left accumulator */
6908 /* or with result */
6909 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6910 /* back to result */
6911 aopPut(AOP(result),"a",offr);
6914 /*-----------------------------------------------------------------*/
6915 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6916 /*-----------------------------------------------------------------*/
6917 static void shiftRLeftOrResult (operand *left, int offl,
6918 operand *result, int offr, int shCount)
6920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6921 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6922 /* shift right accumulator */
6924 /* or with result */
6925 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6926 /* back to result */
6927 aopPut(AOP(result),"a",offr);
6930 /*-----------------------------------------------------------------*/
6931 /* genlshOne - left shift a one byte quantity by known count */
6932 /*-----------------------------------------------------------------*/
6933 static void genlshOne (operand *result, operand *left, int shCount)
6935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6936 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6939 /*-----------------------------------------------------------------*/
6940 /* genlshTwo - left shift two bytes by known amount != 0 */
6941 /*-----------------------------------------------------------------*/
6942 static void genlshTwo (operand *result,operand *left, int shCount)
6946 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6947 size = pic14_getDataSize(result);
6949 /* if shCount >= 8 */
6955 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6957 movLeft2Result(left, LSB, result, MSB16);
6959 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6962 /* 1 <= shCount <= 7 */
6965 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6967 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6971 /*-----------------------------------------------------------------*/
6972 /* shiftLLong - shift left one long from left to result */
6973 /* offl = LSB or MSB16 */
6974 /*-----------------------------------------------------------------*/
6975 static void shiftLLong (operand *left, operand *result, int offr )
6978 int size = AOP_SIZE(result);
6980 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6981 if(size >= LSB+offr){
6982 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6984 pic14_emitcode("add","a,acc");
6985 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6986 size >= MSB16+offr && offr != LSB )
6987 pic14_emitcode("xch","a,%s",
6988 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6990 aopPut(AOP(result),"a",LSB+offr);
6993 if(size >= MSB16+offr){
6994 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6995 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6998 pic14_emitcode("rlc","a");
6999 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7000 size >= MSB24+offr && offr != LSB)
7001 pic14_emitcode("xch","a,%s",
7002 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7004 aopPut(AOP(result),"a",MSB16+offr);
7007 if(size >= MSB24+offr){
7008 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7009 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7012 pic14_emitcode("rlc","a");
7013 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7014 size >= MSB32+offr && offr != LSB )
7015 pic14_emitcode("xch","a,%s",
7016 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7018 aopPut(AOP(result),"a",MSB24+offr);
7021 if(size > MSB32+offr){
7022 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7023 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7026 pic14_emitcode("rlc","a");
7027 aopPut(AOP(result),"a",MSB32+offr);
7030 aopPut(AOP(result),zero,LSB);
7033 /*-----------------------------------------------------------------*/
7034 /* genlshFour - shift four byte by a known amount != 0 */
7035 /*-----------------------------------------------------------------*/
7036 static void genlshFour (operand *result, operand *left, int shCount)
7040 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7041 size = AOP_SIZE(result);
7043 /* if shifting more that 3 bytes */
7044 if (shCount >= 24 ) {
7047 /* lowest order of left goes to the highest
7048 order of the destination */
7049 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7051 movLeft2Result(left, LSB, result, MSB32);
7052 aopPut(AOP(result),zero,LSB);
7053 aopPut(AOP(result),zero,MSB16);
7054 aopPut(AOP(result),zero,MSB32);
7058 /* more than two bytes */
7059 else if ( shCount >= 16 ) {
7060 /* lower order two bytes goes to higher order two bytes */
7062 /* if some more remaining */
7064 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7066 movLeft2Result(left, MSB16, result, MSB32);
7067 movLeft2Result(left, LSB, result, MSB24);
7069 aopPut(AOP(result),zero,MSB16);
7070 aopPut(AOP(result),zero,LSB);
7074 /* if more than 1 byte */
7075 else if ( shCount >= 8 ) {
7076 /* lower order three bytes goes to higher order three bytes */
7080 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7082 movLeft2Result(left, LSB, result, MSB16);
7084 else{ /* size = 4 */
7086 movLeft2Result(left, MSB24, result, MSB32);
7087 movLeft2Result(left, MSB16, result, MSB24);
7088 movLeft2Result(left, LSB, result, MSB16);
7089 aopPut(AOP(result),zero,LSB);
7091 else if(shCount == 1)
7092 shiftLLong(left, result, MSB16);
7094 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7095 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7096 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7097 aopPut(AOP(result),zero,LSB);
7102 /* 1 <= shCount <= 7 */
7103 else if(shCount <= 2){
7104 shiftLLong(left, result, LSB);
7106 shiftLLong(result, result, LSB);
7108 /* 3 <= shCount <= 7, optimize */
7110 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7111 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7112 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7116 /*-----------------------------------------------------------------*/
7117 /* genLeftShiftLiteral - left shifting by known count */
7118 /*-----------------------------------------------------------------*/
7119 static void genLeftShiftLiteral (operand *left,
7124 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7127 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7128 freeAsmop(right,NULL,ic,TRUE);
7130 aopOp(left,ic,FALSE);
7131 aopOp(result,ic,FALSE);
7133 size = getSize(operandType(result));
7136 pic14_emitcode("; shift left ","result %d, left %d",size,
7140 /* I suppose that the left size >= result size */
7143 movLeft2Result(left, size, result, size);
7147 else if(shCount >= (size * 8))
7149 aopPut(AOP(result),zero,size);
7153 genlshOne (result,left,shCount);
7158 genlshTwo (result,left,shCount);
7162 genlshFour (result,left,shCount);
7166 freeAsmop(left,NULL,ic,TRUE);
7167 freeAsmop(result,NULL,ic,TRUE);
7170 /*-----------------------------------------------------------------*
7171 * genMultiAsm - repeat assembly instruction for size of register.
7172 * if endian == 1, then the high byte (i.e base address + size of
7173 * register) is used first else the low byte is used first;
7174 *-----------------------------------------------------------------*/
7175 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7193 emitpcode(poc, popGet(AOP(reg),offset));
7198 /*-----------------------------------------------------------------*/
7199 /* genLeftShift - generates code for left shifting */
7200 /*-----------------------------------------------------------------*/
7201 static void genLeftShift (iCode *ic)
7203 operand *left,*right, *result;
7206 symbol *tlbl , *tlbl1;
7209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7211 right = IC_RIGHT(ic);
7213 result = IC_RESULT(ic);
7215 aopOp(right,ic,FALSE);
7217 /* if the shift count is known then do it
7218 as efficiently as possible */
7219 if (AOP_TYPE(right) == AOP_LIT) {
7220 genLeftShiftLiteral (left,right,result,ic);
7224 /* shift count is unknown then we have to form
7225 a loop get the loop count in B : Note: we take
7226 only the lower order byte since shifting
7227 more that 32 bits make no sense anyway, ( the
7228 largest size of an object can be only 32 bits ) */
7231 aopOp(left,ic,FALSE);
7232 aopOp(result,ic,FALSE);
7234 /* now move the left to the result if they are not the
7236 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7237 AOP_SIZE(result) > 1) {
7239 size = AOP_SIZE(result);
7242 l = aopGet(AOP(left),offset,FALSE,TRUE);
7243 if (*l == '@' && (IS_AOP_PREG(result))) {
7245 pic14_emitcode("mov","a,%s",l);
7246 aopPut(AOP(result),"a",offset);
7248 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7249 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7250 //aopPut(AOP(result),l,offset);
7256 size = AOP_SIZE(result);
7258 /* if it is only one byte then */
7260 if(optimized_for_speed) {
7261 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7262 emitpcode(POC_ANDLW, popGetLit(0xf0));
7263 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7264 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7265 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7266 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7267 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7268 emitpcode(POC_RLFW, popGet(AOP(result),0));
7269 emitpcode(POC_ANDLW, popGetLit(0xfe));
7270 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7271 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7272 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7275 tlbl = newiTempLabel(NULL);
7276 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7277 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7278 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7281 emitpcode(POC_COMFW, popGet(AOP(right),0));
7282 emitpcode(POC_RRF, popGet(AOP(result),0));
7283 emitpLabel(tlbl->key);
7284 emitpcode(POC_RLF, popGet(AOP(result),0));
7285 emitpcode(POC_ADDLW, popGetLit(1));
7287 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7292 if (pic14_sameRegs(AOP(left),AOP(result))) {
7294 tlbl = newiTempLabel(NULL);
7295 emitpcode(POC_COMFW, popGet(AOP(right),0));
7296 genMultiAsm(POC_RRF, result, size,1);
7297 emitpLabel(tlbl->key);
7298 genMultiAsm(POC_RLF, result, size,0);
7299 emitpcode(POC_ADDLW, popGetLit(1));
7301 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7305 //tlbl = newiTempLabel(NULL);
7307 //tlbl1 = newiTempLabel(NULL);
7309 //reAdjustPreg(AOP(result));
7311 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7312 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7313 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7315 //pic14_emitcode("add","a,acc");
7316 //aopPut(AOP(result),"a",offset++);
7318 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7320 // pic14_emitcode("rlc","a");
7321 // aopPut(AOP(result),"a",offset++);
7323 //reAdjustPreg(AOP(result));
7325 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7326 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7329 tlbl = newiTempLabel(NULL);
7330 tlbl1= newiTempLabel(NULL);
7332 size = AOP_SIZE(result);
7335 pctemp = popGetTempReg(); /* grab a temporary working register. */
7337 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7339 /* offset should be 0, 1 or 3 */
7340 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7342 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7344 emitpcode(POC_MOVWF, pctemp);
7347 emitpLabel(tlbl->key);
7350 emitpcode(POC_RLF, popGet(AOP(result),0));
7352 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7354 emitpcode(POC_DECFSZ, pctemp);
7355 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7356 emitpLabel(tlbl1->key);
7358 popReleaseTempReg(pctemp);
7362 freeAsmop (right,NULL,ic,TRUE);
7363 freeAsmop(left,NULL,ic,TRUE);
7364 freeAsmop(result,NULL,ic,TRUE);
7367 /*-----------------------------------------------------------------*/
7368 /* genrshOne - right shift a one byte quantity by known count */
7369 /*-----------------------------------------------------------------*/
7370 static void genrshOne (operand *result, operand *left,
7371 int shCount, int sign)
7373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7374 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7377 /*-----------------------------------------------------------------*/
7378 /* genrshTwo - right shift two bytes by known amount != 0 */
7379 /*-----------------------------------------------------------------*/
7380 static void genrshTwo (operand *result,operand *left,
7381 int shCount, int sign)
7383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7384 /* if shCount >= 8 */
7388 shiftR1Left2Result(left, MSB16, result, LSB,
7391 movLeft2Result(left, MSB16, result, LSB);
7393 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7396 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7397 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7401 /* 1 <= shCount <= 7 */
7403 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7406 /*-----------------------------------------------------------------*/
7407 /* shiftRLong - shift right one long from left to result */
7408 /* offl = LSB or MSB16 */
7409 /*-----------------------------------------------------------------*/
7410 static void shiftRLong (operand *left, int offl,
7411 operand *result, int sign)
7413 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7415 pic14_emitcode("clr","c");
7416 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7418 pic14_emitcode("mov","c,acc.7");
7419 pic14_emitcode("rrc","a");
7420 aopPut(AOP(result),"a",MSB32-offl);
7422 /* add sign of "a" */
7423 addSign(result, MSB32, sign);
7425 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7426 pic14_emitcode("rrc","a");
7427 aopPut(AOP(result),"a",MSB24-offl);
7429 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7430 pic14_emitcode("rrc","a");
7431 aopPut(AOP(result),"a",MSB16-offl);
7434 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7435 pic14_emitcode("rrc","a");
7436 aopPut(AOP(result),"a",LSB);
7440 /*-----------------------------------------------------------------*/
7441 /* genrshFour - shift four byte by a known amount != 0 */
7442 /*-----------------------------------------------------------------*/
7443 static void genrshFour (operand *result, operand *left,
7444 int shCount, int sign)
7446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7447 /* if shifting more that 3 bytes */
7448 if(shCount >= 24 ) {
7451 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7453 movLeft2Result(left, MSB32, result, LSB);
7455 addSign(result, MSB16, sign);
7457 else if(shCount >= 16){
7460 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7462 movLeft2Result(left, MSB24, result, LSB);
7463 movLeft2Result(left, MSB32, result, MSB16);
7465 addSign(result, MSB24, sign);
7467 else if(shCount >= 8){
7470 shiftRLong(left, MSB16, result, sign);
7471 else if(shCount == 0){
7472 movLeft2Result(left, MSB16, result, LSB);
7473 movLeft2Result(left, MSB24, result, MSB16);
7474 movLeft2Result(left, MSB32, result, MSB24);
7475 addSign(result, MSB32, sign);
7478 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7479 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7480 /* the last shift is signed */
7481 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7482 addSign(result, MSB32, sign);
7485 else{ /* 1 <= shCount <= 7 */
7487 shiftRLong(left, LSB, result, sign);
7489 shiftRLong(result, LSB, result, sign);
7492 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7493 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7494 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7499 /*-----------------------------------------------------------------*/
7500 /* genRightShiftLiteral - right shifting by known count */
7501 /*-----------------------------------------------------------------*/
7502 static void genRightShiftLiteral (operand *left,
7508 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7512 freeAsmop(right,NULL,ic,TRUE);
7514 aopOp(left,ic,FALSE);
7515 aopOp(result,ic,FALSE);
7518 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7522 lsize = pic14_getDataSize(left);
7523 res_size = pic14_getDataSize(result);
7524 /* test the LEFT size !!! */
7526 /* I suppose that the left size >= result size */
7529 movLeft2Result(left, lsize, result, res_size);
7532 else if(shCount >= (lsize * 8)){
7535 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7537 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7538 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7543 emitpcode(POC_MOVLW, popGetLit(0));
7544 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7545 emitpcode(POC_MOVLW, popGetLit(0xff));
7547 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7552 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7559 genrshOne (result,left,shCount,sign);
7563 genrshTwo (result,left,shCount,sign);
7567 genrshFour (result,left,shCount,sign);
7575 freeAsmop(left,NULL,ic,TRUE);
7576 freeAsmop(result,NULL,ic,TRUE);
7579 /*-----------------------------------------------------------------*/
7580 /* genSignedRightShift - right shift of signed number */
7581 /*-----------------------------------------------------------------*/
7582 static void genSignedRightShift (iCode *ic)
7584 operand *right, *left, *result;
7587 symbol *tlbl, *tlbl1 ;
7590 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7592 /* we do it the hard way put the shift count in b
7593 and loop thru preserving the sign */
7594 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7596 right = IC_RIGHT(ic);
7598 result = IC_RESULT(ic);
7600 aopOp(right,ic,FALSE);
7601 aopOp(left,ic,FALSE);
7602 aopOp(result,ic,FALSE);
7605 if ( AOP_TYPE(right) == AOP_LIT) {
7606 genRightShiftLiteral (left,right,result,ic,1);
7609 /* shift count is unknown then we have to form
7610 a loop get the loop count in B : Note: we take
7611 only the lower order byte since shifting
7612 more that 32 bits make no sense anyway, ( the
7613 largest size of an object can be only 32 bits ) */
7615 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7616 //pic14_emitcode("inc","b");
7617 //freeAsmop (right,NULL,ic,TRUE);
7618 //aopOp(left,ic,FALSE);
7619 //aopOp(result,ic,FALSE);
7621 /* now move the left to the result if they are not the
7623 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7624 AOP_SIZE(result) > 1) {
7626 size = AOP_SIZE(result);
7630 l = aopGet(AOP(left),offset,FALSE,TRUE);
7631 if (*l == '@' && IS_AOP_PREG(result)) {
7633 pic14_emitcode("mov","a,%s",l);
7634 aopPut(AOP(result),"a",offset);
7636 aopPut(AOP(result),l,offset);
7638 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7639 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7645 /* mov the highest order bit to OVR */
7646 tlbl = newiTempLabel(NULL);
7647 tlbl1= newiTempLabel(NULL);
7649 size = AOP_SIZE(result);
7652 pctemp = popGetTempReg(); /* grab a temporary working register. */
7654 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7656 /* offset should be 0, 1 or 3 */
7657 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7659 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7661 emitpcode(POC_MOVWF, pctemp);
7664 emitpLabel(tlbl->key);
7666 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7667 emitpcode(POC_RRF, popGet(AOP(result),offset));
7670 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7673 emitpcode(POC_DECFSZ, pctemp);
7674 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7675 emitpLabel(tlbl1->key);
7677 popReleaseTempReg(pctemp);
7679 size = AOP_SIZE(result);
7681 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7682 pic14_emitcode("rlc","a");
7683 pic14_emitcode("mov","ov,c");
7684 /* if it is only one byte then */
7686 l = aopGet(AOP(left),0,FALSE,FALSE);
7688 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7689 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7690 pic14_emitcode("mov","c,ov");
7691 pic14_emitcode("rrc","a");
7692 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7693 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7694 aopPut(AOP(result),"a",0);
7698 reAdjustPreg(AOP(result));
7699 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7700 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7701 pic14_emitcode("mov","c,ov");
7703 l = aopGet(AOP(result),offset,FALSE,FALSE);
7705 pic14_emitcode("rrc","a");
7706 aopPut(AOP(result),"a",offset--);
7708 reAdjustPreg(AOP(result));
7709 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7710 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7715 freeAsmop(left,NULL,ic,TRUE);
7716 freeAsmop(result,NULL,ic,TRUE);
7717 freeAsmop(right,NULL,ic,TRUE);
7720 /*-----------------------------------------------------------------*/
7721 /* genRightShift - generate code for right shifting */
7722 /*-----------------------------------------------------------------*/
7723 static void genRightShift (iCode *ic)
7725 operand *right, *left, *result;
7729 symbol *tlbl, *tlbl1 ;
7731 /* if signed then we do it the hard way preserve the
7732 sign bit moving it inwards */
7733 retype = getSpec(operandType(IC_RESULT(ic)));
7734 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7736 if (!SPEC_USIGN(retype)) {
7737 genSignedRightShift (ic);
7741 /* signed & unsigned types are treated the same : i.e. the
7742 signed is NOT propagated inwards : quoting from the
7743 ANSI - standard : "for E1 >> E2, is equivalent to division
7744 by 2**E2 if unsigned or if it has a non-negative value,
7745 otherwise the result is implementation defined ", MY definition
7746 is that the sign does not get propagated */
7748 right = IC_RIGHT(ic);
7750 result = IC_RESULT(ic);
7752 aopOp(right,ic,FALSE);
7754 /* if the shift count is known then do it
7755 as efficiently as possible */
7756 if (AOP_TYPE(right) == AOP_LIT) {
7757 genRightShiftLiteral (left,right,result,ic, 0);
7761 /* shift count is unknown then we have to form
7762 a loop get the loop count in B : Note: we take
7763 only the lower order byte since shifting
7764 more that 32 bits make no sense anyway, ( the
7765 largest size of an object can be only 32 bits ) */
7767 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7768 pic14_emitcode("inc","b");
7769 aopOp(left,ic,FALSE);
7770 aopOp(result,ic,FALSE);
7772 /* now move the left to the result if they are not the
7774 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7775 AOP_SIZE(result) > 1) {
7777 size = AOP_SIZE(result);
7780 l = aopGet(AOP(left),offset,FALSE,TRUE);
7781 if (*l == '@' && IS_AOP_PREG(result)) {
7783 pic14_emitcode("mov","a,%s",l);
7784 aopPut(AOP(result),"a",offset);
7786 aopPut(AOP(result),l,offset);
7791 tlbl = newiTempLabel(NULL);
7792 tlbl1= newiTempLabel(NULL);
7793 size = AOP_SIZE(result);
7796 /* if it is only one byte then */
7799 tlbl = newiTempLabel(NULL);
7800 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7801 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7802 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7805 emitpcode(POC_COMFW, popGet(AOP(right),0));
7806 emitpcode(POC_RLF, popGet(AOP(result),0));
7807 emitpLabel(tlbl->key);
7808 emitpcode(POC_RRF, popGet(AOP(result),0));
7809 emitpcode(POC_ADDLW, popGetLit(1));
7811 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7816 reAdjustPreg(AOP(result));
7817 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7818 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7821 l = aopGet(AOP(result),offset,FALSE,FALSE);
7823 pic14_emitcode("rrc","a");
7824 aopPut(AOP(result),"a",offset--);
7826 reAdjustPreg(AOP(result));
7828 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7829 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7832 freeAsmop(left,NULL,ic,TRUE);
7833 freeAsmop (right,NULL,ic,TRUE);
7834 freeAsmop(result,NULL,ic,TRUE);
7837 /*-----------------------------------------------------------------*/
7838 /* genUnpackBits - generates code for unpacking bits */
7839 /*-----------------------------------------------------------------*/
7840 static void genUnpackBits (operand *result, char *rname, int ptype)
7847 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7848 etype = getSpec(operandType(result));
7850 /* read the first byte */
7855 pic14_emitcode("mov","a,@%s",rname);
7859 pic14_emitcode("movx","a,@%s",rname);
7863 pic14_emitcode("movx","a,@dptr");
7867 pic14_emitcode("clr","a");
7868 pic14_emitcode("movc","a","@a+dptr");
7872 pic14_emitcode("lcall","__gptrget");
7876 /* if we have bitdisplacement then it fits */
7877 /* into this byte completely or if length is */
7878 /* less than a byte */
7879 if ((shCnt = SPEC_BSTR(etype)) ||
7880 (SPEC_BLEN(etype) <= 8)) {
7882 /* shift right acc */
7885 pic14_emitcode("anl","a,#0x%02x",
7886 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7887 aopPut(AOP(result),"a",offset);
7891 /* bit field did not fit in a byte */
7892 rlen = SPEC_BLEN(etype) - 8;
7893 aopPut(AOP(result),"a",offset++);
7900 pic14_emitcode("inc","%s",rname);
7901 pic14_emitcode("mov","a,@%s",rname);
7905 pic14_emitcode("inc","%s",rname);
7906 pic14_emitcode("movx","a,@%s",rname);
7910 pic14_emitcode("inc","dptr");
7911 pic14_emitcode("movx","a,@dptr");
7915 pic14_emitcode("clr","a");
7916 pic14_emitcode("inc","dptr");
7917 pic14_emitcode("movc","a","@a+dptr");
7921 pic14_emitcode("inc","dptr");
7922 pic14_emitcode("lcall","__gptrget");
7927 /* if we are done */
7931 aopPut(AOP(result),"a",offset++);
7936 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7937 aopPut(AOP(result),"a",offset);
7944 /*-----------------------------------------------------------------*/
7945 /* genDataPointerGet - generates code when ptr offset is known */
7946 /*-----------------------------------------------------------------*/
7947 static void genDataPointerGet (operand *left,
7951 int size , offset = 0;
7954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7957 /* optimization - most of the time, left and result are the same
7958 * address, but different types. for the pic code, we could omit
7962 aopOp(result,ic,TRUE);
7964 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7966 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7968 size = AOP_SIZE(result);
7971 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7975 freeAsmop(left,NULL,ic,TRUE);
7976 freeAsmop(result,NULL,ic,TRUE);
7979 /*-----------------------------------------------------------------*/
7980 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7981 /*-----------------------------------------------------------------*/
7982 static void genNearPointerGet (operand *left,
7987 //regs *preg = NULL ;
7989 sym_link *rtype, *retype;
7990 sym_link *ltype = operandType(left);
7993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7995 rtype = operandType(result);
7996 retype= getSpec(rtype);
7998 aopOp(left,ic,FALSE);
8000 /* if left is rematerialisable and
8001 result is not bit variable type and
8002 the left is pointer to data space i.e
8003 lower 128 bytes of space */
8004 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8005 !IS_BITVAR(retype) &&
8006 DCL_TYPE(ltype) == POINTER) {
8007 //genDataPointerGet (left,result,ic);
8011 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8013 /* if the value is already in a pointer register
8014 then don't need anything more */
8015 if (!AOP_INPREG(AOP(left))) {
8016 /* otherwise get a free pointer register */
8017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8020 preg = getFreePtr(ic,&aop,FALSE);
8021 pic14_emitcode("mov","%s,%s",
8023 aopGet(AOP(left),0,FALSE,TRUE));
8024 rname = preg->name ;
8028 rname = aopGet(AOP(left),0,FALSE,FALSE);
8030 aopOp (result,ic,FALSE);
8032 /* if bitfield then unpack the bits */
8033 if (IS_BITVAR(retype))
8034 genUnpackBits (result,rname,POINTER);
8036 /* we have can just get the values */
8037 int size = AOP_SIZE(result);
8040 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8042 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8043 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8045 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8046 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8048 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8052 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8054 pic14_emitcode("mov","a,@%s",rname);
8055 aopPut(AOP(result),"a",offset);
8057 sprintf(buffer,"@%s",rname);
8058 aopPut(AOP(result),buffer,offset);
8062 pic14_emitcode("inc","%s",rname);
8067 /* now some housekeeping stuff */
8069 /* we had to allocate for this iCode */
8070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8071 freeAsmop(NULL,aop,ic,TRUE);
8073 /* we did not allocate which means left
8074 already in a pointer register, then
8075 if size > 0 && this could be used again
8076 we have to point it back to where it
8078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8079 if (AOP_SIZE(result) > 1 &&
8080 !OP_SYMBOL(left)->remat &&
8081 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8083 int size = AOP_SIZE(result) - 1;
8085 pic14_emitcode("dec","%s",rname);
8090 freeAsmop(left,NULL,ic,TRUE);
8091 freeAsmop(result,NULL,ic,TRUE);
8095 /*-----------------------------------------------------------------*/
8096 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8097 /*-----------------------------------------------------------------*/
8098 static void genPagedPointerGet (operand *left,
8105 sym_link *rtype, *retype;
8107 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8109 rtype = operandType(result);
8110 retype= getSpec(rtype);
8112 aopOp(left,ic,FALSE);
8114 /* if the value is already in a pointer register
8115 then don't need anything more */
8116 if (!AOP_INPREG(AOP(left))) {
8117 /* otherwise get a free pointer register */
8119 preg = getFreePtr(ic,&aop,FALSE);
8120 pic14_emitcode("mov","%s,%s",
8122 aopGet(AOP(left),0,FALSE,TRUE));
8123 rname = preg->name ;
8125 rname = aopGet(AOP(left),0,FALSE,FALSE);
8127 freeAsmop(left,NULL,ic,TRUE);
8128 aopOp (result,ic,FALSE);
8130 /* if bitfield then unpack the bits */
8131 if (IS_BITVAR(retype))
8132 genUnpackBits (result,rname,PPOINTER);
8134 /* we have can just get the values */
8135 int size = AOP_SIZE(result);
8140 pic14_emitcode("movx","a,@%s",rname);
8141 aopPut(AOP(result),"a",offset);
8146 pic14_emitcode("inc","%s",rname);
8150 /* now some housekeeping stuff */
8152 /* we had to allocate for this iCode */
8153 freeAsmop(NULL,aop,ic,TRUE);
8155 /* we did not allocate which means left
8156 already in a pointer register, then
8157 if size > 0 && this could be used again
8158 we have to point it back to where it
8160 if (AOP_SIZE(result) > 1 &&
8161 !OP_SYMBOL(left)->remat &&
8162 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8164 int size = AOP_SIZE(result) - 1;
8166 pic14_emitcode("dec","%s",rname);
8171 freeAsmop(result,NULL,ic,TRUE);
8176 /*-----------------------------------------------------------------*/
8177 /* genFarPointerGet - gget value from far space */
8178 /*-----------------------------------------------------------------*/
8179 static void genFarPointerGet (operand *left,
8180 operand *result, iCode *ic)
8183 sym_link *retype = getSpec(operandType(result));
8185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8187 aopOp(left,ic,FALSE);
8189 /* if the operand is already in dptr
8190 then we do nothing else we move the value to dptr */
8191 if (AOP_TYPE(left) != AOP_STR) {
8192 /* if this is remateriazable */
8193 if (AOP_TYPE(left) == AOP_IMMD)
8194 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8195 else { /* we need to get it byte by byte */
8196 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8197 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8198 if (options.model == MODEL_FLAT24)
8200 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8204 /* so dptr know contains the address */
8205 freeAsmop(left,NULL,ic,TRUE);
8206 aopOp(result,ic,FALSE);
8208 /* if bit then unpack */
8209 if (IS_BITVAR(retype))
8210 genUnpackBits(result,"dptr",FPOINTER);
8212 size = AOP_SIZE(result);
8216 pic14_emitcode("movx","a,@dptr");
8217 aopPut(AOP(result),"a",offset++);
8219 pic14_emitcode("inc","dptr");
8223 freeAsmop(result,NULL,ic,TRUE);
8226 /*-----------------------------------------------------------------*/
8227 /* genCodePointerGet - get value from code space */
8228 /*-----------------------------------------------------------------*/
8229 static void genCodePointerGet (operand *left,
8230 operand *result, iCode *ic)
8233 sym_link *retype = getSpec(operandType(result));
8235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8237 aopOp(left,ic,FALSE);
8239 /* if the operand is already in dptr
8240 then we do nothing else we move the value to dptr */
8241 if (AOP_TYPE(left) != AOP_STR) {
8242 /* if this is remateriazable */
8243 if (AOP_TYPE(left) == AOP_IMMD)
8244 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8245 else { /* we need to get it byte by byte */
8246 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8247 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8248 if (options.model == MODEL_FLAT24)
8250 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8254 /* so dptr know contains the address */
8255 freeAsmop(left,NULL,ic,TRUE);
8256 aopOp(result,ic,FALSE);
8258 /* if bit then unpack */
8259 if (IS_BITVAR(retype))
8260 genUnpackBits(result,"dptr",CPOINTER);
8262 size = AOP_SIZE(result);
8266 pic14_emitcode("clr","a");
8267 pic14_emitcode("movc","a,@a+dptr");
8268 aopPut(AOP(result),"a",offset++);
8270 pic14_emitcode("inc","dptr");
8274 freeAsmop(result,NULL,ic,TRUE);
8277 /*-----------------------------------------------------------------*/
8278 /* genGenPointerGet - gget value from generic pointer space */
8279 /*-----------------------------------------------------------------*/
8280 static void genGenPointerGet (operand *left,
8281 operand *result, iCode *ic)
8284 sym_link *retype = getSpec(operandType(result));
8286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8287 aopOp(left,ic,FALSE);
8288 aopOp(result,ic,FALSE);
8291 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8293 /* if the operand is already in dptr
8294 then we do nothing else we move the value to dptr */
8295 // if (AOP_TYPE(left) != AOP_STR) {
8296 /* if this is remateriazable */
8297 if (AOP_TYPE(left) == AOP_IMMD) {
8298 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8299 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8301 else { /* we need to get it byte by byte */
8303 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8304 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8306 size = AOP_SIZE(result);
8310 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8311 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8313 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8318 /* so dptr know contains the address */
8320 /* if bit then unpack */
8321 //if (IS_BITVAR(retype))
8322 // genUnpackBits(result,"dptr",GPOINTER);
8325 freeAsmop(left,NULL,ic,TRUE);
8326 freeAsmop(result,NULL,ic,TRUE);
8330 /*-----------------------------------------------------------------*/
8331 /* genConstPointerGet - get value from const generic pointer space */
8332 /*-----------------------------------------------------------------*/
8333 static void genConstPointerGet (operand *left,
8334 operand *result, iCode *ic)
8336 //sym_link *retype = getSpec(operandType(result));
8337 symbol *albl = newiTempLabel(NULL);
8338 symbol *blbl = newiTempLabel(NULL);
8341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8342 aopOp(left,ic,FALSE);
8343 aopOp(result,ic,FALSE);
8346 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8348 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8350 emitpcode(POC_CALL,popGetLabel(albl->key));
8351 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8352 emitpLabel(albl->key);
8354 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8356 emitpcode(poc,popGet(AOP(left),1));
8357 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8358 emitpcode(poc,popGet(AOP(left),0));
8359 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8361 emitpLabel(blbl->key);
8363 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8366 freeAsmop(left,NULL,ic,TRUE);
8367 freeAsmop(result,NULL,ic,TRUE);
8370 /*-----------------------------------------------------------------*/
8371 /* genPointerGet - generate code for pointer get */
8372 /*-----------------------------------------------------------------*/
8373 static void genPointerGet (iCode *ic)
8375 operand *left, *result ;
8376 sym_link *type, *etype;
8379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8382 result = IC_RESULT(ic) ;
8384 /* depending on the type of pointer we need to
8385 move it to the correct pointer register */
8386 type = operandType(left);
8387 etype = getSpec(type);
8389 if (IS_PTR_CONST(type))
8390 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8392 /* if left is of type of pointer then it is simple */
8393 if (IS_PTR(type) && !IS_FUNC(type->next))
8394 p_type = DCL_TYPE(type);
8396 /* we have to go by the storage class */
8397 p_type = PTR_TYPE(SPEC_OCLS(etype));
8399 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8401 if (SPEC_OCLS(etype)->codesp ) {
8402 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8403 //p_type = CPOINTER ;
8406 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8407 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8408 /*p_type = FPOINTER ;*/
8410 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8411 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8412 /* p_type = PPOINTER; */
8414 if (SPEC_OCLS(etype) == idata )
8415 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8416 /* p_type = IPOINTER; */
8418 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8419 /* p_type = POINTER ; */
8422 /* now that we have the pointer type we assign
8423 the pointer values */
8428 genNearPointerGet (left,result,ic);
8432 genPagedPointerGet(left,result,ic);
8436 genFarPointerGet (left,result,ic);
8440 genConstPointerGet (left,result,ic);
8441 //pic14_emitcodePointerGet (left,result,ic);
8445 if (IS_PTR_CONST(type))
8446 genConstPointerGet (left,result,ic);
8448 genGenPointerGet (left,result,ic);
8454 /*-----------------------------------------------------------------*/
8455 /* genPackBits - generates code for packed bit storage */
8456 /*-----------------------------------------------------------------*/
8457 static void genPackBits (sym_link *etype ,
8459 char *rname, int p_type)
8467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8468 blen = SPEC_BLEN(etype);
8469 bstr = SPEC_BSTR(etype);
8471 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8474 /* if the bit lenth is less than or */
8475 /* it exactly fits a byte then */
8476 if (SPEC_BLEN(etype) <= 8 ) {
8477 shCount = SPEC_BSTR(etype) ;
8479 /* shift left acc */
8482 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8487 pic14_emitcode ("mov","b,a");
8488 pic14_emitcode("mov","a,@%s",rname);
8492 pic14_emitcode ("mov","b,a");
8493 pic14_emitcode("movx","a,@dptr");
8497 pic14_emitcode ("push","b");
8498 pic14_emitcode ("push","acc");
8499 pic14_emitcode ("lcall","__gptrget");
8500 pic14_emitcode ("pop","b");
8504 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8505 ((unsigned char)(0xFF << (blen+bstr)) |
8506 (unsigned char)(0xFF >> (8-bstr)) ) );
8507 pic14_emitcode ("orl","a,b");
8508 if (p_type == GPOINTER)
8509 pic14_emitcode("pop","b");
8515 pic14_emitcode("mov","@%s,a",rname);
8519 pic14_emitcode("movx","@dptr,a");
8523 DEBUGpic14_emitcode(";lcall","__gptrput");
8528 if ( SPEC_BLEN(etype) <= 8 )
8531 pic14_emitcode("inc","%s",rname);
8532 rLen = SPEC_BLEN(etype) ;
8534 /* now generate for lengths greater than one byte */
8537 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8547 pic14_emitcode("mov","@%s,a",rname);
8549 pic14_emitcode("mov","@%s,%s",rname,l);
8554 pic14_emitcode("movx","@dptr,a");
8559 DEBUGpic14_emitcode(";lcall","__gptrput");
8562 pic14_emitcode ("inc","%s",rname);
8567 /* last last was not complete */
8569 /* save the byte & read byte */
8572 pic14_emitcode ("mov","b,a");
8573 pic14_emitcode("mov","a,@%s",rname);
8577 pic14_emitcode ("mov","b,a");
8578 pic14_emitcode("movx","a,@dptr");
8582 pic14_emitcode ("push","b");
8583 pic14_emitcode ("push","acc");
8584 pic14_emitcode ("lcall","__gptrget");
8585 pic14_emitcode ("pop","b");
8589 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8590 pic14_emitcode ("orl","a,b");
8593 if (p_type == GPOINTER)
8594 pic14_emitcode("pop","b");
8599 pic14_emitcode("mov","@%s,a",rname);
8603 pic14_emitcode("movx","@dptr,a");
8607 DEBUGpic14_emitcode(";lcall","__gptrput");
8611 /*-----------------------------------------------------------------*/
8612 /* genDataPointerSet - remat pointer to data space */
8613 /*-----------------------------------------------------------------*/
8614 static void genDataPointerSet(operand *right,
8618 int size, offset = 0 ;
8619 char *l, buffer[256];
8621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8622 aopOp(right,ic,FALSE);
8624 l = aopGet(AOP(result),0,FALSE,TRUE);
8625 size = AOP_SIZE(right);
8627 if ( AOP_TYPE(result) == AOP_PCODE) {
8628 fprintf(stderr,"genDataPointerSet %s, %d\n",
8629 AOP(result)->aopu.pcop->name,
8630 PCOI(AOP(result)->aopu.pcop)->offset);
8634 // tsd, was l+1 - the underline `_' prefix was being stripped
8637 sprintf(buffer,"(%s + %d)",l,offset);
8638 fprintf(stderr,"oops %s\n",buffer);
8640 sprintf(buffer,"%s",l);
8642 if (AOP_TYPE(right) == AOP_LIT) {
8643 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8644 lit = lit >> (8*offset);
8646 pic14_emitcode("movlw","%d",lit);
8647 pic14_emitcode("movwf","%s",buffer);
8649 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8650 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8651 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8654 pic14_emitcode("clrf","%s",buffer);
8655 //emitpcode(POC_CLRF, popRegFromString(buffer));
8656 emitpcode(POC_CLRF, popGet(AOP(result),0));
8659 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8660 pic14_emitcode("movwf","%s",buffer);
8662 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8663 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8664 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8671 freeAsmop(right,NULL,ic,TRUE);
8672 freeAsmop(result,NULL,ic,TRUE);
8675 /*-----------------------------------------------------------------*/
8676 /* genNearPointerSet - pic14_emitcode for near pointer put */
8677 /*-----------------------------------------------------------------*/
8678 static void genNearPointerSet (operand *right,
8685 sym_link *ptype = operandType(result);
8688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8689 retype= getSpec(operandType(right));
8691 aopOp(result,ic,FALSE);
8694 /* if the result is rematerializable &
8695 in data space & not a bit variable */
8696 //if (AOP_TYPE(result) == AOP_IMMD &&
8697 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8698 DCL_TYPE(ptype) == POINTER &&
8699 !IS_BITVAR(retype)) {
8700 genDataPointerSet (right,result,ic);
8701 freeAsmop(result,NULL,ic,TRUE);
8705 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8706 aopOp(right,ic,FALSE);
8707 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8709 /* if the value is already in a pointer register
8710 then don't need anything more */
8711 if (!AOP_INPREG(AOP(result))) {
8712 /* otherwise get a free pointer register */
8713 //aop = newAsmop(0);
8714 //preg = getFreePtr(ic,&aop,FALSE);
8715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8716 //pic14_emitcode("mov","%s,%s",
8718 // aopGet(AOP(result),0,FALSE,TRUE));
8719 //rname = preg->name ;
8720 //pic14_emitcode("movwf","fsr");
8721 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8722 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8723 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8724 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8728 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8731 /* if bitfield then unpack the bits */
8732 if (IS_BITVAR(retype)) {
8733 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8734 "The programmer is obviously confused");
8735 //genPackBits (retype,right,rname,POINTER);
8739 /* we have can just get the values */
8740 int size = AOP_SIZE(right);
8743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8745 l = aopGet(AOP(right),offset,FALSE,TRUE);
8748 //pic14_emitcode("mov","@%s,a",rname);
8749 pic14_emitcode("movf","indf,w ;1");
8752 if (AOP_TYPE(right) == AOP_LIT) {
8753 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8755 pic14_emitcode("movlw","%s",l);
8756 pic14_emitcode("movwf","indf ;2");
8758 pic14_emitcode("clrf","indf");
8760 pic14_emitcode("movf","%s,w",l);
8761 pic14_emitcode("movwf","indf ;2");
8763 //pic14_emitcode("mov","@%s,%s",rname,l);
8766 pic14_emitcode("incf","fsr,f ;3");
8767 //pic14_emitcode("inc","%s",rname);
8772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8773 /* now some housekeeping stuff */
8775 /* we had to allocate for this iCode */
8776 freeAsmop(NULL,aop,ic,TRUE);
8778 /* we did not allocate which means left
8779 already in a pointer register, then
8780 if size > 0 && this could be used again
8781 we have to point it back to where it
8783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8784 if (AOP_SIZE(right) > 1 &&
8785 !OP_SYMBOL(result)->remat &&
8786 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8788 int size = AOP_SIZE(right) - 1;
8790 pic14_emitcode("decf","fsr,f");
8791 //pic14_emitcode("dec","%s",rname);
8795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8798 freeAsmop(right,NULL,ic,TRUE);
8799 freeAsmop(result,NULL,ic,TRUE);
8802 /*-----------------------------------------------------------------*/
8803 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8804 /*-----------------------------------------------------------------*/
8805 static void genPagedPointerSet (operand *right,
8814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8816 retype= getSpec(operandType(right));
8818 aopOp(result,ic,FALSE);
8820 /* if the value is already in a pointer register
8821 then don't need anything more */
8822 if (!AOP_INPREG(AOP(result))) {
8823 /* otherwise get a free pointer register */
8825 preg = getFreePtr(ic,&aop,FALSE);
8826 pic14_emitcode("mov","%s,%s",
8828 aopGet(AOP(result),0,FALSE,TRUE));
8829 rname = preg->name ;
8831 rname = aopGet(AOP(result),0,FALSE,FALSE);
8833 freeAsmop(result,NULL,ic,TRUE);
8834 aopOp (right,ic,FALSE);
8836 /* if bitfield then unpack the bits */
8837 if (IS_BITVAR(retype))
8838 genPackBits (retype,right,rname,PPOINTER);
8840 /* we have can just get the values */
8841 int size = AOP_SIZE(right);
8845 l = aopGet(AOP(right),offset,FALSE,TRUE);
8848 pic14_emitcode("movx","@%s,a",rname);
8851 pic14_emitcode("inc","%s",rname);
8857 /* now some housekeeping stuff */
8859 /* we had to allocate for this iCode */
8860 freeAsmop(NULL,aop,ic,TRUE);
8862 /* we did not allocate which means left
8863 already in a pointer register, then
8864 if size > 0 && this could be used again
8865 we have to point it back to where it
8867 if (AOP_SIZE(right) > 1 &&
8868 !OP_SYMBOL(result)->remat &&
8869 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8871 int size = AOP_SIZE(right) - 1;
8873 pic14_emitcode("dec","%s",rname);
8878 freeAsmop(right,NULL,ic,TRUE);
8883 /*-----------------------------------------------------------------*/
8884 /* genFarPointerSet - set value from far space */
8885 /*-----------------------------------------------------------------*/
8886 static void genFarPointerSet (operand *right,
8887 operand *result, iCode *ic)
8890 sym_link *retype = getSpec(operandType(right));
8892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8893 aopOp(result,ic,FALSE);
8895 /* if the operand is already in dptr
8896 then we do nothing else we move the value to dptr */
8897 if (AOP_TYPE(result) != AOP_STR) {
8898 /* if this is remateriazable */
8899 if (AOP_TYPE(result) == AOP_IMMD)
8900 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8901 else { /* we need to get it byte by byte */
8902 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8903 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8904 if (options.model == MODEL_FLAT24)
8906 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8910 /* so dptr know contains the address */
8911 freeAsmop(result,NULL,ic,TRUE);
8912 aopOp(right,ic,FALSE);
8914 /* if bit then unpack */
8915 if (IS_BITVAR(retype))
8916 genPackBits(retype,right,"dptr",FPOINTER);
8918 size = AOP_SIZE(right);
8922 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8924 pic14_emitcode("movx","@dptr,a");
8926 pic14_emitcode("inc","dptr");
8930 freeAsmop(right,NULL,ic,TRUE);
8933 /*-----------------------------------------------------------------*/
8934 /* genGenPointerSet - set value from generic pointer space */
8935 /*-----------------------------------------------------------------*/
8936 static void genGenPointerSet (operand *right,
8937 operand *result, iCode *ic)
8940 sym_link *retype = getSpec(operandType(right));
8942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8944 aopOp(result,ic,FALSE);
8945 aopOp(right,ic,FALSE);
8946 size = AOP_SIZE(right);
8948 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8950 /* if the operand is already in dptr
8951 then we do nothing else we move the value to dptr */
8952 if (AOP_TYPE(result) != AOP_STR) {
8953 /* if this is remateriazable */
8954 if (AOP_TYPE(result) == AOP_IMMD) {
8955 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8956 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8958 else { /* we need to get it byte by byte */
8959 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8960 size = AOP_SIZE(right);
8963 /* hack hack! see if this the FSR. If so don't load W */
8964 if(AOP_TYPE(right) != AOP_ACC) {
8967 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8968 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8970 if(AOP_SIZE(result) > 1) {
8971 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8972 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8973 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8978 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8980 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8981 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8985 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8986 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8989 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8996 if(aopIdx(AOP(result),0) != 4) {
8998 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9002 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9007 /* so dptr know contains the address */
9010 /* if bit then unpack */
9011 if (IS_BITVAR(retype))
9012 genPackBits(retype,right,"dptr",GPOINTER);
9014 size = AOP_SIZE(right);
9017 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9021 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9022 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9024 if (AOP_TYPE(right) == AOP_LIT)
9025 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9027 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9029 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9036 freeAsmop(right,NULL,ic,TRUE);
9037 freeAsmop(result,NULL,ic,TRUE);
9040 /*-----------------------------------------------------------------*/
9041 /* genPointerSet - stores the value into a pointer location */
9042 /*-----------------------------------------------------------------*/
9043 static void genPointerSet (iCode *ic)
9045 operand *right, *result ;
9046 sym_link *type, *etype;
9049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9051 right = IC_RIGHT(ic);
9052 result = IC_RESULT(ic) ;
9054 /* depending on the type of pointer we need to
9055 move it to the correct pointer register */
9056 type = operandType(result);
9057 etype = getSpec(type);
9058 /* if left is of type of pointer then it is simple */
9059 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9060 p_type = DCL_TYPE(type);
9063 /* we have to go by the storage class */
9064 p_type = PTR_TYPE(SPEC_OCLS(etype));
9066 /* if (SPEC_OCLS(etype)->codesp ) { */
9067 /* p_type = CPOINTER ; */
9070 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9071 /* p_type = FPOINTER ; */
9073 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9074 /* p_type = PPOINTER ; */
9076 /* if (SPEC_OCLS(etype) == idata ) */
9077 /* p_type = IPOINTER ; */
9079 /* p_type = POINTER ; */
9082 /* now that we have the pointer type we assign
9083 the pointer values */
9088 genNearPointerSet (right,result,ic);
9092 genPagedPointerSet (right,result,ic);
9096 genFarPointerSet (right,result,ic);
9100 genGenPointerSet (right,result,ic);
9104 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9105 "genPointerSet: illegal pointer type");
9109 /*-----------------------------------------------------------------*/
9110 /* genIfx - generate code for Ifx statement */
9111 /*-----------------------------------------------------------------*/
9112 static void genIfx (iCode *ic, iCode *popIc)
9114 operand *cond = IC_COND(ic);
9117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9119 aopOp(cond,ic,FALSE);
9121 /* get the value into acc */
9122 if (AOP_TYPE(cond) != AOP_CRY)
9123 pic14_toBoolean(cond);
9126 /* the result is now in the accumulator */
9127 freeAsmop(cond,NULL,ic,TRUE);
9129 /* if there was something to be popped then do it */
9133 /* if the condition is a bit variable */
9134 if (isbit && IS_ITEMP(cond) &&
9136 genIfxJump(ic,SPIL_LOC(cond)->rname);
9137 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9140 if (isbit && !IS_ITEMP(cond))
9141 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9149 /*-----------------------------------------------------------------*/
9150 /* genAddrOf - generates code for address of */
9151 /*-----------------------------------------------------------------*/
9152 static void genAddrOf (iCode *ic)
9154 operand *right, *result, *left;
9157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9160 //aopOp(IC_RESULT(ic),ic,FALSE);
9162 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9163 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9164 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9166 DEBUGpic14_AopType(__LINE__,left,right,result);
9168 size = AOP_SIZE(IC_RESULT(ic));
9172 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9173 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9177 freeAsmop(left,NULL,ic,FALSE);
9178 freeAsmop(result,NULL,ic,TRUE);
9183 /*-----------------------------------------------------------------*/
9184 /* genFarFarAssign - assignment when both are in far space */
9185 /*-----------------------------------------------------------------*/
9186 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9188 int size = AOP_SIZE(right);
9191 /* first push the right side on to the stack */
9193 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9195 pic14_emitcode ("push","acc");
9198 freeAsmop(right,NULL,ic,FALSE);
9199 /* now assign DPTR to result */
9200 aopOp(result,ic,FALSE);
9201 size = AOP_SIZE(result);
9203 pic14_emitcode ("pop","acc");
9204 aopPut(AOP(result),"a",--offset);
9206 freeAsmop(result,NULL,ic,FALSE);
9211 /*-----------------------------------------------------------------*/
9212 /* genAssign - generate code for assignment */
9213 /*-----------------------------------------------------------------*/
9214 static void genAssign (iCode *ic)
9216 operand *result, *right;
9217 int size, offset,know_W;
9218 unsigned long lit = 0L;
9220 result = IC_RESULT(ic);
9221 right = IC_RIGHT(ic) ;
9223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9225 /* if they are the same */
9226 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9229 aopOp(right,ic,FALSE);
9230 aopOp(result,ic,TRUE);
9232 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9234 /* if they are the same registers */
9235 if (pic14_sameRegs(AOP(right),AOP(result)))
9238 /* if the result is a bit */
9239 if (AOP_TYPE(result) == AOP_CRY) {
9241 /* if the right size is a literal then
9242 we know what the value is */
9243 if (AOP_TYPE(right) == AOP_LIT) {
9245 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9246 popGet(AOP(result),0));
9248 if (((int) operandLitValue(right)))
9249 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9250 AOP(result)->aopu.aop_dir,
9251 AOP(result)->aopu.aop_dir);
9253 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9254 AOP(result)->aopu.aop_dir,
9255 AOP(result)->aopu.aop_dir);
9259 /* the right is also a bit variable */
9260 if (AOP_TYPE(right) == AOP_CRY) {
9261 emitpcode(POC_BCF, popGet(AOP(result),0));
9262 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9263 emitpcode(POC_BSF, popGet(AOP(result),0));
9265 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9266 AOP(result)->aopu.aop_dir,
9267 AOP(result)->aopu.aop_dir);
9268 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9269 AOP(right)->aopu.aop_dir,
9270 AOP(right)->aopu.aop_dir);
9271 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9272 AOP(result)->aopu.aop_dir,
9273 AOP(result)->aopu.aop_dir);
9278 emitpcode(POC_BCF, popGet(AOP(result),0));
9279 pic14_toBoolean(right);
9281 emitpcode(POC_BSF, popGet(AOP(result),0));
9282 //aopPut(AOP(result),"a",0);
9286 /* bit variables done */
9288 size = AOP_SIZE(result);
9290 if(AOP_TYPE(right) == AOP_LIT)
9291 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9293 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9295 if(aopIdx(AOP(result),0) == 4) {
9296 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9297 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9298 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9301 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9307 if(AOP_TYPE(right) == AOP_LIT) {
9309 if(know_W != (lit&0xff))
9310 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9312 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9314 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9318 } else if (AOP_TYPE(right) == AOP_CRY) {
9319 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9321 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9322 emitpcode(POC_INCF, popGet(AOP(result),0));
9325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9326 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9327 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9335 freeAsmop (right,NULL,ic,FALSE);
9336 freeAsmop (result,NULL,ic,TRUE);
9339 /*-----------------------------------------------------------------*/
9340 /* genJumpTab - genrates code for jump table */
9341 /*-----------------------------------------------------------------*/
9342 static void genJumpTab (iCode *ic)
9347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9349 aopOp(IC_JTCOND(ic),ic,FALSE);
9350 /* get the condition into accumulator */
9351 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9353 /* multiply by three */
9354 pic14_emitcode("add","a,acc");
9355 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9357 jtab = newiTempLabel(NULL);
9358 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9359 pic14_emitcode("jmp","@a+dptr");
9360 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9362 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9363 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9365 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9366 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9367 emitpLabel(jtab->key);
9369 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9371 /* now generate the jump labels */
9372 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9373 jtab = setNextItem(IC_JTLABELS(ic))) {
9374 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9375 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9381 /*-----------------------------------------------------------------*/
9382 /* genMixedOperation - gen code for operators between mixed types */
9383 /*-----------------------------------------------------------------*/
9385 TSD - Written for the PIC port - but this unfortunately is buggy.
9386 This routine is good in that it is able to efficiently promote
9387 types to different (larger) sizes. Unfortunately, the temporary
9388 variables that are optimized out by this routine are sometimes
9389 used in other places. So until I know how to really parse the
9390 iCode tree, I'm going to not be using this routine :(.
9392 static int genMixedOperation (iCode *ic)
9395 operand *result = IC_RESULT(ic);
9396 sym_link *ctype = operandType(IC_LEFT(ic));
9397 operand *right = IC_RIGHT(ic);
9403 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9405 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9411 nextright = IC_RIGHT(nextic);
9412 nextleft = IC_LEFT(nextic);
9413 nextresult = IC_RESULT(nextic);
9415 aopOp(right,ic,FALSE);
9416 aopOp(result,ic,FALSE);
9417 aopOp(nextright, nextic, FALSE);
9418 aopOp(nextleft, nextic, FALSE);
9419 aopOp(nextresult, nextic, FALSE);
9421 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9427 pic14_emitcode(";remove right +","");
9429 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9435 pic14_emitcode(";remove left +","");
9439 big = AOP_SIZE(nextleft);
9440 small = AOP_SIZE(nextright);
9442 switch(nextic->op) {
9445 pic14_emitcode(";optimize a +","");
9446 /* if unsigned or not an integral type */
9447 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9448 pic14_emitcode(";add a bit to something","");
9451 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9453 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9454 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9455 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9457 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9465 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9466 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9467 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9470 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9472 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9473 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9474 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9475 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9476 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9479 pic14_emitcode("rlf","known_zero,w");
9486 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9487 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9488 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9490 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9500 freeAsmop(right,NULL,ic,TRUE);
9501 freeAsmop(result,NULL,ic,TRUE);
9502 freeAsmop(nextright,NULL,ic,TRUE);
9503 freeAsmop(nextleft,NULL,ic,TRUE);
9505 nextic->generated = 1;
9512 /*-----------------------------------------------------------------*/
9513 /* genCast - gen code for casting */
9514 /*-----------------------------------------------------------------*/
9515 static void genCast (iCode *ic)
9517 operand *result = IC_RESULT(ic);
9518 sym_link *ctype = operandType(IC_LEFT(ic));
9519 sym_link *rtype = operandType(IC_RIGHT(ic));
9520 operand *right = IC_RIGHT(ic);
9523 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9524 /* if they are equivalent then do nothing */
9525 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9528 aopOp(right,ic,FALSE) ;
9529 aopOp(result,ic,FALSE);
9531 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9533 /* if the result is a bit */
9534 if (AOP_TYPE(result) == AOP_CRY) {
9535 /* if the right size is a literal then
9536 we know what the value is */
9537 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9538 if (AOP_TYPE(right) == AOP_LIT) {
9540 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9541 popGet(AOP(result),0));
9543 if (((int) operandLitValue(right)))
9544 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9545 AOP(result)->aopu.aop_dir,
9546 AOP(result)->aopu.aop_dir);
9548 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9549 AOP(result)->aopu.aop_dir,
9550 AOP(result)->aopu.aop_dir);
9555 /* the right is also a bit variable */
9556 if (AOP_TYPE(right) == AOP_CRY) {
9559 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9561 pic14_emitcode("clrc","");
9562 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9563 AOP(right)->aopu.aop_dir,
9564 AOP(right)->aopu.aop_dir);
9565 aopPut(AOP(result),"c",0);
9570 if (AOP_TYPE(right) == AOP_REG) {
9571 emitpcode(POC_BCF, popGet(AOP(result),0));
9572 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9573 emitpcode(POC_BSF, popGet(AOP(result),0));
9575 pic14_toBoolean(right);
9576 aopPut(AOP(result),"a",0);
9580 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9582 size = AOP_SIZE(result);
9584 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9586 emitpcode(POC_CLRF, popGet(AOP(result),0));
9587 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9588 emitpcode(POC_INCF, popGet(AOP(result),0));
9591 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9596 /* if they are the same size : or less */
9597 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9599 /* if they are in the same place */
9600 if (pic14_sameRegs(AOP(right),AOP(result)))
9603 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9604 if (IS_PTR_CONST(rtype))
9605 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9606 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9607 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9609 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9610 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9611 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9612 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9613 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9614 if(AOP_SIZE(result) <2)
9615 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9619 /* if they in different places then copy */
9620 size = AOP_SIZE(result);
9623 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9624 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9626 //aopPut(AOP(result),
9627 // aopGet(AOP(right),offset,FALSE,FALSE),
9637 /* if the result is of type pointer */
9638 if (IS_PTR(ctype)) {
9641 sym_link *type = operandType(right);
9642 sym_link *etype = getSpec(type);
9643 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9645 /* pointer to generic pointer */
9646 if (IS_GENPTR(ctype)) {
9650 p_type = DCL_TYPE(type);
9652 /* we have to go by the storage class */
9653 p_type = PTR_TYPE(SPEC_OCLS(etype));
9655 /* if (SPEC_OCLS(etype)->codesp ) */
9656 /* p_type = CPOINTER ; */
9658 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9659 /* p_type = FPOINTER ; */
9661 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9662 /* p_type = PPOINTER; */
9664 /* if (SPEC_OCLS(etype) == idata ) */
9665 /* p_type = IPOINTER ; */
9667 /* p_type = POINTER ; */
9670 /* the first two bytes are known */
9671 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9672 size = GPTRSIZE - 1;
9675 if(offset < AOP_SIZE(right)) {
9676 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9677 if ((AOP_TYPE(right) == AOP_PCODE) &&
9678 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9679 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9680 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9683 aopGet(AOP(right),offset,FALSE,FALSE),
9687 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9690 /* the last byte depending on type */
9694 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9697 pic14_emitcode(";BUG!? ","%d",__LINE__);
9701 pic14_emitcode(";BUG!? ","%d",__LINE__);
9705 pic14_emitcode(";BUG!? ","%d",__LINE__);
9710 /* this should never happen */
9711 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9712 "got unknown pointer type");
9715 //aopPut(AOP(result),l, GPTRSIZE - 1);
9719 /* just copy the pointers */
9720 size = AOP_SIZE(result);
9724 aopGet(AOP(right),offset,FALSE,FALSE),
9733 /* so we now know that the size of destination is greater
9734 than the size of the source.
9735 Now, if the next iCode is an operator then we might be
9736 able to optimize the operation without performing a cast.
9738 if(genMixedOperation(ic))
9741 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9743 /* we move to result for the size of source */
9744 size = AOP_SIZE(right);
9747 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9748 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9752 /* now depending on the sign of the destination */
9753 size = AOP_SIZE(result) - AOP_SIZE(right);
9754 /* if unsigned or not an integral type */
9755 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9757 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9759 /* we need to extend the sign :{ */
9762 /* Save one instruction of casting char to int */
9763 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9764 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9765 emitpcode(POC_DECF, popGet(AOP(result),offset));
9767 emitpcodeNULLop(POC_CLRW);
9770 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9772 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9774 emitpcode(POC_MOVLW, popGetLit(0xff));
9777 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9782 freeAsmop(right,NULL,ic,TRUE);
9783 freeAsmop(result,NULL,ic,TRUE);
9787 /*-----------------------------------------------------------------*/
9788 /* genDjnz - generate decrement & jump if not zero instrucion */
9789 /*-----------------------------------------------------------------*/
9790 static int genDjnz (iCode *ic, iCode *ifx)
9793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9798 /* if the if condition has a false label
9799 then we cannot save */
9803 /* if the minus is not of the form
9805 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9806 !IS_OP_LITERAL(IC_RIGHT(ic)))
9809 if (operandLitValue(IC_RIGHT(ic)) != 1)
9812 /* if the size of this greater than one then no
9814 if (getSize(operandType(IC_RESULT(ic))) > 1)
9817 /* otherwise we can save BIG */
9818 lbl = newiTempLabel(NULL);
9819 lbl1= newiTempLabel(NULL);
9821 aopOp(IC_RESULT(ic),ic,FALSE);
9823 if (IS_AOP_PREG(IC_RESULT(ic))) {
9824 pic14_emitcode("dec","%s",
9825 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9826 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9827 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9831 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9832 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9834 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9835 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9838 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9839 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9840 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9841 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9844 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9849 /*-----------------------------------------------------------------*/
9850 /* genReceive - generate code for a receive iCode */
9851 /*-----------------------------------------------------------------*/
9852 static void genReceive (iCode *ic)
9854 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9856 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9857 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9858 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9860 int size = getSize(operandType(IC_RESULT(ic)));
9861 int offset = fReturnSizePic - size;
9863 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9864 fReturn[fReturnSizePic - offset - 1] : "acc"));
9867 aopOp(IC_RESULT(ic),ic,FALSE);
9868 size = AOP_SIZE(IC_RESULT(ic));
9871 pic14_emitcode ("pop","acc");
9872 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9877 aopOp(IC_RESULT(ic),ic,FALSE);
9879 assignResultValue(IC_RESULT(ic));
9882 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9885 /*-----------------------------------------------------------------*/
9886 /* genpic14Code - generate code for pic14 based controllers */
9887 /*-----------------------------------------------------------------*/
9889 * At this point, ralloc.c has gone through the iCode and attempted
9890 * to optimize in a way suitable for a PIC. Now we've got to generate
9891 * PIC instructions that correspond to the iCode.
9893 * Once the instructions are generated, we'll pass through both the
9894 * peep hole optimizer and the pCode optimizer.
9895 *-----------------------------------------------------------------*/
9897 void genpic14Code (iCode *lic)
9902 lineHead = lineCurr = NULL;
9904 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9907 /* if debug information required */
9908 if (options.debug && currFunc) {
9910 debugFile->writeFunction(currFunc);
9912 if (IS_STATIC(currFunc->etype)) {
9913 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9914 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9916 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9917 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9924 for (ic = lic ; ic ; ic = ic->next ) {
9926 DEBUGpic14_emitcode(";ic","");
9927 if ( cln != ic->lineno ) {
9928 if ( options.debug ) {
9930 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9931 FileBaseName(ic->filename),ic->lineno,
9932 ic->level,ic->block);
9936 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9937 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9938 printCLine(ic->filename, ic->lineno));
9940 if (!options.noCcodeInAsm) {
9942 newpCodeCSource(ic->lineno,
9944 printCLine(ic->filename, ic->lineno)));
9950 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9952 /* if the result is marked as
9953 spilt and rematerializable or code for
9954 this has already been generated then
9956 if (resultRemat(ic) || ic->generated )
9959 /* depending on the operation */
9978 /* IPOP happens only when trying to restore a
9979 spilt live range, if there is an ifx statement
9980 following this pop then the if statement might
9981 be using some of the registers being popped which
9982 would destory the contents of the register so
9983 we need to check for this condition and handle it */
9985 ic->next->op == IFX &&
9986 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9987 genIfx (ic->next,ic);
10005 genEndFunction (ic);
10025 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10042 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10046 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10053 /* note these two are xlated by algebraic equivalence
10054 during parsing SDCC.y */
10055 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10056 "got '>=' or '<=' shouldn't have come here");
10060 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10072 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10076 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10080 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10104 genRightShift (ic);
10107 case GET_VALUE_AT_ADDRESS:
10112 if (POINTER_SET(ic))
10139 addSet(&_G.sendSet,ic);
10148 /* now we are ready to call the
10149 peep hole optimizer */
10150 if (!options.nopeep) {
10151 peepHole (&lineHead);
10153 /* now do the actual printing */
10154 printLine (lineHead,codeOutFile);
10157 DFPRINTF((stderr,"printing pBlock\n\n"));
10158 printpBlock(stdout,pb);