1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
221 addpCode2pBlock(pb,newpCode(poc,pcop));
223 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
226 void emitpcodeNULLop(PIC_OPCODE poc)
229 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
274 bool r0iu = FALSE , r1iu = FALSE;
275 bool r0ou = FALSE , r1ou = FALSE;
277 /* the logic: if r0 & r1 used in the instruction
278 then we are in trouble otherwise */
280 /* first check if r0 & r1 are used by this
281 instruction, in which case we are in trouble */
282 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
288 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
291 /* if no usage of r0 then return it */
292 if (!r0iu && !r0ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294 (*aopp)->type = AOP_R0;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
299 /* if no usage of r1 then return it */
300 if (!r1iu && !r1ou) {
301 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302 (*aopp)->type = AOP_R1;
304 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
307 /* now we know they both have usage */
308 /* if r0 not used in this instruction */
310 /* push it if not already pushed */
312 //pic14_emitcode ("push","%s",
313 // pic14_regWithIdx(R0_IDX)->dname);
317 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318 (*aopp)->type = AOP_R0;
320 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
323 /* if r1 not used then */
326 /* push it if not already pushed */
328 //pic14_emitcode ("push","%s",
329 // pic14_regWithIdx(R1_IDX)->dname);
333 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334 (*aopp)->type = AOP_R1;
335 return pic14_regWithIdx(R1_IDX);
339 /* I said end of world but not quite end of world yet */
340 /* if this is a result then we can push it on the stack*/
342 (*aopp)->type = AOP_STK;
346 /* other wise this is true end of the world */
347 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348 "getFreePtr should never reach here");
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
359 aop = Safe_calloc(1,sizeof(asmop));
364 static void genSetDPTR(int n)
368 pic14_emitcode(";", "Select standard DPTR");
369 pic14_emitcode("mov", "dps, #0x00");
373 pic14_emitcode(";", "Select alternate DPTR");
374 pic14_emitcode("mov", "dps, #0x01");
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for */
380 /* generating code */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
387 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
389 resIfx->condition = 1; /* assume that the ifx is true */
390 resIfx->generated = 0; /* indicate that the ifx has not been used */
393 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
395 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396 __FUNCTION__,__LINE__,resIfx->lbl->key);
400 resIfx->lbl = IC_TRUE(ifx);
402 resIfx->lbl = IC_FALSE(ifx);
403 resIfx->condition = 0;
407 DEBUGpic14_emitcode("; ***","ifx true is non-null");
409 DEBUGpic14_emitcode("; ***","ifx false is non-null");
413 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
422 return PTR_TYPE(SPEC_OCLS(etype));
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
432 memmap *space= SPEC_OCLS(sym->etype);
434 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435 /* if already has one */
439 /* assign depending on the storage class */
440 /* if it is on the stack or indirectly addressable */
441 /* space we need to assign either r0 or r1 to it */
442 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443 sym->aop = aop = newAsmop(0);
444 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445 aop->size = getSize(sym->type);
447 /* now assign the address of the variable to
448 the pointer register */
449 if (aop->type != AOP_STK) {
453 pic14_emitcode("push","acc");
455 pic14_emitcode("mov","a,_bp");
456 pic14_emitcode("add","a,#0x%02x",
458 ((char)(sym->stack - _G.nRegsSaved )) :
459 ((char)sym->stack)) & 0xff);
460 pic14_emitcode("mov","%s,a",
461 aop->aopu.aop_ptr->name);
464 pic14_emitcode("pop","acc");
466 pic14_emitcode("mov","%s,#%s",
467 aop->aopu.aop_ptr->name,
469 aop->paged = space->paged;
471 aop->aopu.aop_stk = sym->stack;
475 if (sym->onStack && options.stack10bit)
477 /* It's on the 10 bit stack, which is located in
481 //DEBUGpic14_emitcode(";","%d",__LINE__);
484 pic14_emitcode("push","acc");
486 pic14_emitcode("mov","a,_bp");
487 pic14_emitcode("add","a,#0x%02x",
489 ((char)(sym->stack - _G.nRegsSaved )) :
490 ((char)sym->stack)) & 0xff);
493 pic14_emitcode ("mov","dpx1,#0x40");
494 pic14_emitcode ("mov","dph1,#0x00");
495 pic14_emitcode ("mov","dpl1, a");
499 pic14_emitcode("pop","acc");
501 sym->aop = aop = newAsmop(AOP_DPTR2);
502 aop->size = getSize(sym->type);
506 //DEBUGpic14_emitcode(";","%d",__LINE__);
507 /* if in bit space */
508 if (IN_BITSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_CRY);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
515 /* if it is in direct space */
516 if (IN_DIRSPACE(space)) {
517 sym->aop = aop = newAsmop (AOP_DIR);
518 aop->aopu.aop_dir = sym->rname ;
519 aop->size = getSize(sym->type);
520 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524 /* special case for a function */
525 if (IS_FUNC(sym->type)) {
526 sym->aop = aop = newAsmop(AOP_IMMD);
527 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
528 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
529 strcpy(aop->aopu.aop_immd,sym->rname);
530 aop->size = FPTRSIZE;
531 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
536 /* only remaining is far space */
537 /* in which case DPTR gets the address */
538 sym->aop = aop = newAsmop(AOP_PCODE);
540 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
541 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542 PCOI(aop->aopu.pcop)->index = 0;
544 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
545 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
547 allocDirReg (IC_LEFT(ic));
549 aop->size = FPTRSIZE;
551 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552 sym->aop = aop = newAsmop(AOP_DPTR);
553 pic14_emitcode ("mov","dptr,#%s", sym->rname);
554 aop->size = getSize(sym->type);
556 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
559 /* if it is in code space */
560 if (IN_CODESPACE(space))
566 /*-----------------------------------------------------------------*/
567 /* aopForRemat - rematerialzes an object */
568 /*-----------------------------------------------------------------*/
569 static asmop *aopForRemat (operand *op) // x symbol *sym)
571 symbol *sym = OP_SYMBOL(op);
573 asmop *aop = newAsmop(AOP_PCODE);
577 ic = sym->rematiCode;
579 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
580 if(IS_OP_POINTER(op)) {
581 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
585 val += (int) operandLitValue(IC_RIGHT(ic));
586 } else if (ic->op == '-') {
587 val -= (int) operandLitValue(IC_RIGHT(ic));
591 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
594 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
595 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
596 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
597 PCOI(aop->aopu.pcop)->index = val;
599 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
600 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
601 val, IS_PTR_CONST(operandType(op)));
603 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
605 allocDirReg (IC_LEFT(ic));
610 int aopIdx (asmop *aop, int offset)
615 if(aop->type != AOP_REG)
618 return aop->aopu.aop_reg[offset]->rIdx;
621 /*-----------------------------------------------------------------*/
622 /* regsInCommon - two operands have some registers in common */
623 /*-----------------------------------------------------------------*/
624 static bool regsInCommon (operand *op1, operand *op2)
629 /* if they have registers in common */
630 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
633 sym1 = OP_SYMBOL(op1);
634 sym2 = OP_SYMBOL(op2);
636 if (sym1->nRegs == 0 || sym2->nRegs == 0)
639 for (i = 0 ; i < sym1->nRegs ; i++) {
644 for (j = 0 ; j < sym2->nRegs ;j++ ) {
648 if (sym2->regs[j] == sym1->regs[i])
656 /*-----------------------------------------------------------------*/
657 /* operandsEqu - equivalent */
658 /*-----------------------------------------------------------------*/
659 static bool operandsEqu ( operand *op1, operand *op2)
663 /* if they not symbols */
664 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
667 sym1 = OP_SYMBOL(op1);
668 sym2 = OP_SYMBOL(op2);
670 /* if both are itemps & one is spilt
671 and the other is not then false */
672 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
673 sym1->isspilt != sym2->isspilt )
676 /* if they are the same */
680 if (strcmp(sym1->rname,sym2->rname) == 0)
684 /* if left is a tmp & right is not */
688 (sym1->usl.spillLoc == sym2))
695 (sym2->usl.spillLoc == sym1))
701 /*-----------------------------------------------------------------*/
702 /* pic14_sameRegs - two asmops have the same registers */
703 /*-----------------------------------------------------------------*/
704 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
711 if (aop1->type != AOP_REG ||
712 aop2->type != AOP_REG )
715 if (aop1->size != aop2->size )
718 for (i = 0 ; i < aop1->size ; i++ )
719 if (aop1->aopu.aop_reg[i] !=
720 aop2->aopu.aop_reg[i] )
726 /*-----------------------------------------------------------------*/
727 /* aopOp - allocates an asmop for an operand : */
728 /*-----------------------------------------------------------------*/
729 void aopOp (operand *op, iCode *ic, bool result)
738 // DEBUGpic14_emitcode(";","%d",__LINE__);
739 /* if this a literal */
740 if (IS_OP_LITERAL(op)) {
741 op->aop = aop = newAsmop(AOP_LIT);
742 aop->aopu.aop_lit = op->operand.valOperand;
743 aop->size = getSize(operandType(op));
748 sym_link *type = operandType(op);
749 if(IS_PTR_CONST(type))
750 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
753 /* if already has a asmop then continue */
757 /* if the underlying symbol has a aop */
758 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
759 DEBUGpic14_emitcode(";","%d",__LINE__);
760 op->aop = OP_SYMBOL(op)->aop;
764 /* if this is a true symbol */
765 if (IS_TRUE_SYMOP(op)) {
766 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
767 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
771 /* this is a temporary : this has
777 e) can be a return use only */
782 /* if the type is a conditional */
783 if (sym->regType == REG_CND) {
784 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
789 /* if it is spilt then two situations
791 b) has a spill location */
792 if (sym->isspilt || sym->nRegs == 0) {
794 DEBUGpic14_emitcode(";","%d",__LINE__);
795 /* rematerialize it NOW */
798 sym->aop = op->aop = aop =
800 aop->size = getSize(sym->type);
801 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
807 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
808 aop->size = getSize(sym->type);
809 for ( i = 0 ; i < 2 ; i++ )
810 aop->aopu.aop_str[i] = accUse[i];
811 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
817 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
818 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
819 //allocDirReg (IC_LEFT(ic));
820 aop->size = getSize(sym->type);
825 aop = op->aop = sym->aop = newAsmop(AOP_STR);
826 aop->size = getSize(sym->type);
827 for ( i = 0 ; i < fReturnSizePic ; i++ )
828 aop->aopu.aop_str[i] = fReturn[i];
830 DEBUGpic14_emitcode(";","%d",__LINE__);
834 /* else spill location */
835 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
836 /* force a new aop if sizes differ */
837 sym->usl.spillLoc->aop = NULL;
839 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
840 __FUNCTION__,__LINE__,
841 sym->usl.spillLoc->rname,
842 sym->rname, sym->usl.spillLoc->offset);
844 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
845 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
846 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
848 sym->usl.spillLoc->offset);
849 aop->size = getSize(sym->type);
855 sym_link *type = operandType(op);
856 if(IS_PTR_CONST(type))
857 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
860 /* must be in a register */
861 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
862 sym->aop = op->aop = aop = newAsmop(AOP_REG);
863 aop->size = sym->nRegs;
864 for ( i = 0 ; i < sym->nRegs ;i++)
865 aop->aopu.aop_reg[i] = sym->regs[i];
868 /*-----------------------------------------------------------------*/
869 /* freeAsmop - free up the asmop given to an operand */
870 /*----------------------------------------------------------------*/
871 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
888 /* depending on the asmop type only three cases need work AOP_RO
889 , AOP_R1 && AOP_STK */
895 pic14_emitcode ("pop","ar0");
899 bitVectUnSetBit(ic->rUsed,R0_IDX);
905 pic14_emitcode ("pop","ar1");
909 bitVectUnSetBit(ic->rUsed,R1_IDX);
915 int stk = aop->aopu.aop_stk + aop->size;
916 bitVectUnSetBit(ic->rUsed,R0_IDX);
917 bitVectUnSetBit(ic->rUsed,R1_IDX);
919 getFreePtr(ic,&aop,FALSE);
921 if (options.stack10bit)
923 /* I'm not sure what to do here yet... */
926 "*** Warning: probably generating bad code for "
927 "10 bit stack mode.\n");
931 pic14_emitcode ("mov","a,_bp");
932 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
933 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
935 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
939 pic14_emitcode("pop","acc");
940 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
942 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
945 freeAsmop(op,NULL,ic,TRUE);
947 pic14_emitcode("pop","ar0");
952 pic14_emitcode("pop","ar1");
960 /* all other cases just dealloc */
964 OP_SYMBOL(op)->aop = NULL;
965 /* if the symbol has a spill */
967 SPIL_LOC(op)->aop = NULL;
972 /*-----------------------------------------------------------------*/
973 /* aopGet - for fetching value of the aop */
974 /*-----------------------------------------------------------------*/
975 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
980 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
981 /* offset is greater than
983 if (offset > (aop->size - 1) &&
984 aop->type != AOP_LIT)
987 /* depending on type */
992 DEBUGpic14_emitcode(";","%d",__LINE__);
993 /* if we need to increment it */
994 while (offset > aop->coff) {
995 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
999 while (offset < aop->coff) {
1000 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1004 aop->coff = offset ;
1006 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1007 return (dname ? "acc" : "a");
1009 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1010 rs = Safe_calloc(1,strlen(s)+1);
1016 DEBUGpic14_emitcode(";","%d",__LINE__);
1017 if (aop->type == AOP_DPTR2)
1022 while (offset > aop->coff) {
1023 pic14_emitcode ("inc","dptr");
1027 while (offset < aop->coff) {
1028 pic14_emitcode("lcall","__decdptr");
1034 pic14_emitcode("clr","a");
1035 pic14_emitcode("movc","a,@a+dptr");
1038 pic14_emitcode("movx","a,@dptr");
1041 if (aop->type == AOP_DPTR2)
1046 return (dname ? "acc" : "a");
1051 sprintf (s,"%s",aop->aopu.aop_immd);
1054 sprintf(s,"(%s >> %d)",
1059 aop->aopu.aop_immd);
1060 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1061 rs = Safe_calloc(1,strlen(s)+1);
1067 sprintf(s,"(%s + %d)",
1070 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1072 sprintf(s,"%s",aop->aopu.aop_dir);
1073 rs = Safe_calloc(1,strlen(s)+1);
1079 // return aop->aopu.aop_reg[offset]->dname;
1081 return aop->aopu.aop_reg[offset]->name;
1084 //pic14_emitcode(";","%d",__LINE__);
1085 return aop->aopu.aop_dir;
1088 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1089 return "AOP_accumulator_bug";
1092 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1093 rs = Safe_calloc(1,strlen(s)+1);
1098 aop->coff = offset ;
1099 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1102 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1104 return aop->aopu.aop_str[offset];
1108 pCodeOp *pcop = aop->aopu.pcop;
1109 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1111 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1112 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1113 sprintf(s,"%s", pcop->name);
1115 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1118 rs = Safe_calloc(1,strlen(s)+1);
1124 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1125 "aopget got unsupported aop->type");
1130 /*-----------------------------------------------------------------*/
1131 /* popGetTempReg - create a new temporary pCodeOp */
1132 /*-----------------------------------------------------------------*/
1133 pCodeOp *popGetTempReg(void)
1138 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1139 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1140 PCOR(pcop)->r->wasUsed=1;
1141 PCOR(pcop)->r->isFree=0;
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp */
1149 /*-----------------------------------------------------------------*/
1150 void popReleaseTempReg(pCodeOp *pcop)
1153 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1154 PCOR(pcop)->r->isFree = 1;
1157 /*-----------------------------------------------------------------*/
1158 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1159 /*-----------------------------------------------------------------*/
1160 pCodeOp *popGetLabel(unsigned int key)
1163 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1168 return newpCodeOpLabel(NULL,key+100+labelOffset);
1171 /*-----------------------------------------------------------------*/
1172 /* popCopyReg - copy a pcode operator */
1173 /*-----------------------------------------------------------------*/
1174 pCodeOp *popCopyReg(pCodeOpReg *pc)
1178 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1179 pcor->pcop.type = pc->pcop.type;
1181 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1182 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1184 pcor->pcop.name = NULL;
1187 pcor->rIdx = pc->rIdx;
1190 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1194 /*-----------------------------------------------------------------*/
1195 /* popGet - asm operator to pcode operator conversion */
1196 /*-----------------------------------------------------------------*/
1197 pCodeOp *popGetLit(unsigned int lit)
1200 return newpCodeOpLit(lit);
1204 /*-----------------------------------------------------------------*/
1205 /* popGetImmd - asm operator to pcode immediate conversion */
1206 /*-----------------------------------------------------------------*/
1207 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1210 return newpCodeOpImmd(name, offset,index, 0);
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetWithString(char *str)
1223 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1227 pcop = newpCodeOp(str,PO_STR);
1232 /*-----------------------------------------------------------------*/
1233 /* popRegFromString - */
1234 /*-----------------------------------------------------------------*/
1235 pCodeOp *popRegFromString(char *str, int size, int offset)
1238 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1239 pcop->type = PO_DIR;
1241 DEBUGpic14_emitcode(";","%d",__LINE__);
1246 pcop->name = Safe_calloc(1,strlen(str)+1);
1247 strcpy(pcop->name,str);
1249 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1251 PCOR(pcop)->r = dirregWithName(pcop->name);
1252 if(PCOR(pcop)->r == NULL) {
1253 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1254 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1255 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1257 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1259 PCOR(pcop)->instance = offset;
1264 pCodeOp *popRegFromIdx(int rIdx)
1268 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1269 __FUNCTION__,__LINE__,rIdx);
1271 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1273 PCOR(pcop)->rIdx = rIdx;
1274 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1275 PCOR(pcop)->r->isFree = 0;
1276 PCOR(pcop)->r->wasUsed = 1;
1278 pcop->type = PCOR(pcop)->r->pc_type;
1283 /*-----------------------------------------------------------------*/
1284 /* popGet - asm operator to pcode operator conversion */
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1288 //char *s = buffer ;
1293 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1294 /* offset is greater than
1297 if (offset > (aop->size - 1) &&
1298 aop->type != AOP_LIT)
1299 return NULL; //zero;
1301 /* depending on type */
1302 switch (aop->type) {
1309 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1313 DEBUGpic14_emitcode(";","%d",__LINE__);
1314 return popGetImmd(aop->aopu.aop_immd,offset,0);
1317 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1319 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1320 pcop->type = PO_DIR;
1324 sprintf(s,"(%s + %d)",
1328 sprintf(s,"%s",aop->aopu.aop_dir);
1329 pcop->name = Safe_calloc(1,strlen(s)+1);
1330 strcpy(pcop->name,s);
1332 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1333 strcpy(pcop->name,aop->aopu.aop_dir);
1334 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1335 if(PCOR(pcop)->r == NULL) {
1336 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1337 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1338 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1340 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1342 PCOR(pcop)->instance = offset;
1349 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1351 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1352 PCOR(pcop)->rIdx = rIdx;
1353 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1354 PCOR(pcop)->r->wasUsed=1;
1355 PCOR(pcop)->r->isFree=0;
1357 PCOR(pcop)->instance = offset;
1358 pcop->type = PCOR(pcop)->r->pc_type;
1359 //rs = aop->aopu.aop_reg[offset]->name;
1360 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1365 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1366 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1367 //if(PCOR(pcop)->r == NULL)
1368 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1372 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1375 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1376 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1378 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1379 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1380 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1381 pcop->type = PCOR(pcop)->r->pc_type;
1382 pcop->name = PCOR(pcop)->r->name;
1388 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1390 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1391 pcop = pCodeOpCopy(aop->aopu.pcop);
1392 PCOI(pcop)->offset = offset;
1396 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1397 "popGet got unsupported aop->type");
1400 /*-----------------------------------------------------------------*/
1401 /* aopPut - puts a string for a aop */
1402 /*-----------------------------------------------------------------*/
1403 void aopPut (asmop *aop, char *s, int offset)
1408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1410 if (aop->size && offset > ( aop->size - 1)) {
1411 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1412 "aopPut got offset > aop->size");
1416 /* will assign value to value */
1417 /* depending on where it is ofcourse */
1418 switch (aop->type) {
1421 sprintf(d,"(%s + %d)",
1422 aop->aopu.aop_dir,offset);
1423 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1426 sprintf(d,"%s",aop->aopu.aop_dir);
1429 DEBUGpic14_emitcode(";","%d",__LINE__);
1431 pic14_emitcode("movf","%s,w",s);
1432 pic14_emitcode("movwf","%s",d);
1435 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1436 if(offset >= aop->size) {
1437 emitpcode(POC_CLRF,popGet(aop,offset));
1440 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1443 emitpcode(POC_MOVWF,popGet(aop,offset));
1450 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1451 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1454 strcmp(s,"r0") == 0 ||
1455 strcmp(s,"r1") == 0 ||
1456 strcmp(s,"r2") == 0 ||
1457 strcmp(s,"r3") == 0 ||
1458 strcmp(s,"r4") == 0 ||
1459 strcmp(s,"r5") == 0 ||
1460 strcmp(s,"r6") == 0 ||
1461 strcmp(s,"r7") == 0 )
1462 pic14_emitcode("mov","%s,%s ; %d",
1463 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1467 if(strcmp(s,"W")==0 )
1468 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1470 pic14_emitcode("movwf","%s",
1471 aop->aopu.aop_reg[offset]->name);
1473 if(strcmp(s,zero)==0) {
1474 emitpcode(POC_CLRF,popGet(aop,offset));
1476 } else if(strcmp(s,"W")==0) {
1477 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1478 pcop->type = PO_GPR_REGISTER;
1480 PCOR(pcop)->rIdx = -1;
1481 PCOR(pcop)->r = NULL;
1483 DEBUGpic14_emitcode(";","%d",__LINE__);
1484 pcop->name = Safe_strdup(s);
1485 emitpcode(POC_MOVFW,pcop);
1486 emitpcode(POC_MOVWF,popGet(aop,offset));
1487 } else if(strcmp(s,one)==0) {
1488 emitpcode(POC_CLRF,popGet(aop,offset));
1489 emitpcode(POC_INCF,popGet(aop,offset));
1491 emitpcode(POC_MOVWF,popGet(aop,offset));
1499 if (aop->type == AOP_DPTR2)
1505 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1506 "aopPut writting to code space");
1510 while (offset > aop->coff) {
1512 pic14_emitcode ("inc","dptr");
1515 while (offset < aop->coff) {
1517 pic14_emitcode("lcall","__decdptr");
1522 /* if not in accumulater */
1525 pic14_emitcode ("movx","@dptr,a");
1527 if (aop->type == AOP_DPTR2)
1535 while (offset > aop->coff) {
1537 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1539 while (offset < aop->coff) {
1541 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1547 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1552 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1554 if (strcmp(s,"r0") == 0 ||
1555 strcmp(s,"r1") == 0 ||
1556 strcmp(s,"r2") == 0 ||
1557 strcmp(s,"r3") == 0 ||
1558 strcmp(s,"r4") == 0 ||
1559 strcmp(s,"r5") == 0 ||
1560 strcmp(s,"r6") == 0 ||
1561 strcmp(s,"r7") == 0 ) {
1563 sprintf(buffer,"a%s",s);
1564 pic14_emitcode("mov","@%s,%s",
1565 aop->aopu.aop_ptr->name,buffer);
1567 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1572 if (strcmp(s,"a") == 0)
1573 pic14_emitcode("push","acc");
1575 pic14_emitcode("push","%s",s);
1580 /* if bit variable */
1581 if (!aop->aopu.aop_dir) {
1582 pic14_emitcode("clr","a");
1583 pic14_emitcode("rlc","a");
1586 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1589 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1592 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1594 lbl = newiTempLabel(NULL);
1596 if (strcmp(s,"a")) {
1599 pic14_emitcode("clr","c");
1600 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1601 pic14_emitcode("cpl","c");
1602 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1603 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1610 if (strcmp(aop->aopu.aop_str[offset],s))
1611 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1616 if (!offset && (strcmp(s,"acc") == 0))
1619 if (strcmp(aop->aopu.aop_str[offset],s))
1620 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1624 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1625 "aopPut got unsupported aop->type");
1631 /*-----------------------------------------------------------------*/
1632 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1633 /*-----------------------------------------------------------------*/
1634 void mov2w (asmop *aop, int offset)
1640 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1642 if ( aop->type == AOP_PCODE ||
1643 aop->type == AOP_LIT )
1644 emitpcode(POC_MOVLW,popGet(aop,offset));
1646 emitpcode(POC_MOVFW,popGet(aop,offset));
1650 /*-----------------------------------------------------------------*/
1651 /* reAdjustPreg - points a register back to where it should */
1652 /*-----------------------------------------------------------------*/
1653 static void reAdjustPreg (asmop *aop)
1657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 if ((size = aop->size) <= 1)
1662 switch (aop->type) {
1666 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1670 if (aop->type == AOP_DPTR2)
1676 pic14_emitcode("lcall","__decdptr");
1679 if (aop->type == AOP_DPTR2)
1689 /*-----------------------------------------------------------------*/
1690 /* genNotFloat - generates not for float operations */
1691 /*-----------------------------------------------------------------*/
1692 static void genNotFloat (operand *op, operand *res)
1698 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1699 /* we will put 127 in the first byte of
1701 aopPut(AOP(res),"#127",0);
1702 size = AOP_SIZE(op) - 1;
1705 l = aopGet(op->aop,offset++,FALSE,FALSE);
1709 pic14_emitcode("orl","a,%s",
1711 offset++,FALSE,FALSE));
1713 tlbl = newiTempLabel(NULL);
1715 tlbl = newiTempLabel(NULL);
1716 aopPut(res->aop,one,1);
1717 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1718 aopPut(res->aop,zero,1);
1719 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1721 size = res->aop->size - 2;
1723 /* put zeros in the rest */
1725 aopPut(res->aop,zero,offset++);
1729 /*-----------------------------------------------------------------*/
1730 /* opIsGptr: returns non-zero if the passed operand is */
1731 /* a generic pointer type. */
1732 /*-----------------------------------------------------------------*/
1733 static int opIsGptr(operand *op)
1735 sym_link *type = operandType(op);
1737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1738 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1746 /*-----------------------------------------------------------------*/
1747 /* pic14_getDataSize - get the operand data size */
1748 /*-----------------------------------------------------------------*/
1749 int pic14_getDataSize(operand *op)
1751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1754 return AOP_SIZE(op);
1756 // tsd- in the pic port, the genptr size is 1, so this code here
1757 // fails. ( in the 8051 port, the size was 4).
1760 size = AOP_SIZE(op);
1761 if (size == GPTRSIZE)
1763 sym_link *type = operandType(op);
1764 if (IS_GENPTR(type))
1766 /* generic pointer; arithmetic operations
1767 * should ignore the high byte (pointer type).
1770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1777 /*-----------------------------------------------------------------*/
1778 /* pic14_outAcc - output Acc */
1779 /*-----------------------------------------------------------------*/
1780 void pic14_outAcc(operand *result)
1783 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1784 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1787 size = pic14_getDataSize(result);
1789 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1792 /* unsigned or positive */
1794 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1799 /*-----------------------------------------------------------------*/
1800 /* pic14_outBitC - output a bit C */
1801 /*-----------------------------------------------------------------*/
1802 void pic14_outBitC(operand *result)
1805 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1806 /* if the result is bit */
1807 if (AOP_TYPE(result) == AOP_CRY)
1808 aopPut(AOP(result),"c",0);
1810 pic14_emitcode("clr","a ; %d", __LINE__);
1811 pic14_emitcode("rlc","a");
1812 pic14_outAcc(result);
1816 /*-----------------------------------------------------------------*/
1817 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1818 /*-----------------------------------------------------------------*/
1819 void pic14_toBoolean(operand *oper)
1821 int size = AOP_SIZE(oper) - 1;
1824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1826 if ( AOP_TYPE(oper) != AOP_ACC) {
1827 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1830 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1835 /*-----------------------------------------------------------------*/
1836 /* genNot - generate code for ! operation */
1837 /*-----------------------------------------------------------------*/
1838 static void genNot (iCode *ic)
1841 sym_link *optype = operandType(IC_LEFT(ic));
1844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1845 /* assign asmOps to operand & result */
1846 aopOp (IC_LEFT(ic),ic,FALSE);
1847 aopOp (IC_RESULT(ic),ic,TRUE);
1849 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1850 /* if in bit space then a special case */
1851 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1852 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1853 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1854 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1856 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1857 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1858 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1863 /* if type float then do float */
1864 if (IS_FLOAT(optype)) {
1865 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1869 size = AOP_SIZE(IC_RESULT(ic));
1871 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1872 emitpcode(POC_ANDLW,popGetLit(1));
1873 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1876 pic14_toBoolean(IC_LEFT(ic));
1878 tlbl = newiTempLabel(NULL);
1879 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1880 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1881 pic14_outBitC(IC_RESULT(ic));
1884 /* release the aops */
1885 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1886 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1890 /*-----------------------------------------------------------------*/
1891 /* genCpl - generate code for complement */
1892 /*-----------------------------------------------------------------*/
1893 static void genCpl (iCode *ic)
1899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1900 /* assign asmOps to operand & result */
1901 aopOp (IC_LEFT(ic),ic,FALSE);
1902 aopOp (IC_RESULT(ic),ic,TRUE);
1904 /* if both are in bit space then
1906 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1907 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1909 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1910 pic14_emitcode("cpl","c");
1911 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1915 size = AOP_SIZE(IC_RESULT(ic));
1917 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1919 pic14_emitcode("cpl","a");
1920 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1925 /* release the aops */
1926 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1927 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1930 /*-----------------------------------------------------------------*/
1931 /* genUminusFloat - unary minus for floating points */
1932 /*-----------------------------------------------------------------*/
1933 static void genUminusFloat(operand *op,operand *result)
1935 int size ,offset =0 ;
1938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1939 /* for this we just need to flip the
1940 first it then copy the rest in place */
1941 size = AOP_SIZE(op) - 1;
1942 l = aopGet(AOP(op),3,FALSE,FALSE);
1946 pic14_emitcode("cpl","acc.7");
1947 aopPut(AOP(result),"a",3);
1951 aopGet(AOP(op),offset,FALSE,FALSE),
1957 /*-----------------------------------------------------------------*/
1958 /* genUminus - unary minus code generation */
1959 /*-----------------------------------------------------------------*/
1960 static void genUminus (iCode *ic)
1963 sym_link *optype, *rtype;
1966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1968 aopOp(IC_LEFT(ic),ic,FALSE);
1969 aopOp(IC_RESULT(ic),ic,TRUE);
1971 /* if both in bit space then special
1973 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1974 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1976 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1977 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1978 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1983 optype = operandType(IC_LEFT(ic));
1984 rtype = operandType(IC_RESULT(ic));
1986 /* if float then do float stuff */
1987 if (IS_FLOAT(optype)) {
1988 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1992 /* otherwise subtract from zero by taking the 2's complement */
1993 size = AOP_SIZE(IC_LEFT(ic));
1995 for(i=0; i<size; i++) {
1996 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1997 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1999 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2000 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2004 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2005 for(i=1; i<size; i++) {
2007 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2011 /* release the aops */
2012 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2013 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2016 /*-----------------------------------------------------------------*/
2017 /* saveRegisters - will look for a call and save the registers */
2018 /*-----------------------------------------------------------------*/
2019 static void saveRegisters(iCode *lic)
2026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2028 for (ic = lic ; ic ; ic = ic->next)
2029 if (ic->op == CALL || ic->op == PCALL)
2033 fprintf(stderr,"found parameter push with no function call\n");
2037 /* if the registers have been saved already then
2039 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2042 /* find the registers in use at this time
2043 and push them away to safety */
2044 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2048 if (options.useXstack) {
2049 if (bitVectBitValue(rsave,R0_IDX))
2050 pic14_emitcode("mov","b,r0");
2051 pic14_emitcode("mov","r0,%s",spname);
2052 for (i = 0 ; i < pic14_nRegs ; i++) {
2053 if (bitVectBitValue(rsave,i)) {
2055 pic14_emitcode("mov","a,b");
2057 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2058 pic14_emitcode("movx","@r0,a");
2059 pic14_emitcode("inc","r0");
2062 pic14_emitcode("mov","%s,r0",spname);
2063 if (bitVectBitValue(rsave,R0_IDX))
2064 pic14_emitcode("mov","r0,b");
2066 //for (i = 0 ; i < pic14_nRegs ; i++) {
2067 // if (bitVectBitValue(rsave,i))
2068 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2071 dtype = operandType(IC_LEFT(ic));
2072 if (currFunc && dtype &&
2073 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2074 IFFUNC_ISISR(currFunc->type) &&
2077 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2080 /*-----------------------------------------------------------------*/
2081 /* unsaveRegisters - pop the pushed registers */
2082 /*-----------------------------------------------------------------*/
2083 static void unsaveRegisters (iCode *ic)
2088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2089 /* find the registers in use at this time
2090 and push them away to safety */
2091 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2094 if (options.useXstack) {
2095 pic14_emitcode("mov","r0,%s",spname);
2096 for (i = pic14_nRegs ; i >= 0 ; i--) {
2097 if (bitVectBitValue(rsave,i)) {
2098 pic14_emitcode("dec","r0");
2099 pic14_emitcode("movx","a,@r0");
2101 pic14_emitcode("mov","b,a");
2103 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2107 pic14_emitcode("mov","%s,r0",spname);
2108 if (bitVectBitValue(rsave,R0_IDX))
2109 pic14_emitcode("mov","r0,b");
2111 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2112 // if (bitVectBitValue(rsave,i))
2113 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2119 /*-----------------------------------------------------------------*/
2121 /*-----------------------------------------------------------------*/
2122 static void pushSide(operand * oper, int size)
2126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2128 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2129 if (AOP_TYPE(oper) != AOP_REG &&
2130 AOP_TYPE(oper) != AOP_DIR &&
2132 pic14_emitcode("mov","a,%s",l);
2133 pic14_emitcode("push","acc");
2135 pic14_emitcode("push","%s",l);
2140 /*-----------------------------------------------------------------*/
2141 /* assignResultValue - */
2142 /*-----------------------------------------------------------------*/
2143 static void assignResultValue(operand * oper)
2145 int size = AOP_SIZE(oper);
2147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2149 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2151 if(!GpsuedoStkPtr) {
2152 /* The last byte in the assignment is in W */
2154 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2159 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2161 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2166 /*-----------------------------------------------------------------*/
2167 /* genIpush - genrate code for pushing this gets a little complex */
2168 /*-----------------------------------------------------------------*/
2169 static void genIpush (iCode *ic)
2172 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2174 int size, offset = 0 ;
2178 /* if this is not a parm push : ie. it is spill push
2179 and spill push is always done on the local stack */
2180 if (!ic->parmPush) {
2182 /* and the item is spilt then do nothing */
2183 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2186 aopOp(IC_LEFT(ic),ic,FALSE);
2187 size = AOP_SIZE(IC_LEFT(ic));
2188 /* push it on the stack */
2190 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2195 pic14_emitcode("push","%s",l);
2200 /* this is a paramter push: in this case we call
2201 the routine to find the call and save those
2202 registers that need to be saved */
2205 /* then do the push */
2206 aopOp(IC_LEFT(ic),ic,FALSE);
2209 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2210 size = AOP_SIZE(IC_LEFT(ic));
2213 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2214 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2215 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2217 pic14_emitcode("mov","a,%s",l);
2218 pic14_emitcode("push","acc");
2220 pic14_emitcode("push","%s",l);
2223 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2227 /*-----------------------------------------------------------------*/
2228 /* genIpop - recover the registers: can happen only for spilling */
2229 /*-----------------------------------------------------------------*/
2230 static void genIpop (iCode *ic)
2232 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2237 /* if the temp was not pushed then */
2238 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2241 aopOp(IC_LEFT(ic),ic,FALSE);
2242 size = AOP_SIZE(IC_LEFT(ic));
2245 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2248 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2252 /*-----------------------------------------------------------------*/
2253 /* unsaverbank - restores the resgister bank from stack */
2254 /*-----------------------------------------------------------------*/
2255 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2257 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2265 if (options.useXstack) {
2267 r = getFreePtr(ic,&aop,FALSE);
2270 pic14_emitcode("mov","%s,_spx",r->name);
2271 pic14_emitcode("movx","a,@%s",r->name);
2272 pic14_emitcode("mov","psw,a");
2273 pic14_emitcode("dec","%s",r->name);
2276 pic14_emitcode ("pop","psw");
2279 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2280 if (options.useXstack) {
2281 pic14_emitcode("movx","a,@%s",r->name);
2282 //pic14_emitcode("mov","(%s+%d),a",
2283 // regspic14[i].base,8*bank+regspic14[i].offset);
2284 pic14_emitcode("dec","%s",r->name);
2287 pic14_emitcode("pop",""); //"(%s+%d)",
2288 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2291 if (options.useXstack) {
2293 pic14_emitcode("mov","_spx,%s",r->name);
2294 freeAsmop(NULL,aop,ic,TRUE);
2300 /*-----------------------------------------------------------------*/
2301 /* saverbank - saves an entire register bank on the stack */
2302 /*-----------------------------------------------------------------*/
2303 static void saverbank (int bank, iCode *ic, bool pushPsw)
2305 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2312 if (options.useXstack) {
2315 r = getFreePtr(ic,&aop,FALSE);
2316 pic14_emitcode("mov","%s,_spx",r->name);
2320 for (i = 0 ; i < pic14_nRegs ;i++) {
2321 if (options.useXstack) {
2322 pic14_emitcode("inc","%s",r->name);
2323 //pic14_emitcode("mov","a,(%s+%d)",
2324 // regspic14[i].base,8*bank+regspic14[i].offset);
2325 pic14_emitcode("movx","@%s,a",r->name);
2327 pic14_emitcode("push","");// "(%s+%d)",
2328 //regspic14[i].base,8*bank+regspic14[i].offset);
2332 if (options.useXstack) {
2333 pic14_emitcode("mov","a,psw");
2334 pic14_emitcode("movx","@%s,a",r->name);
2335 pic14_emitcode("inc","%s",r->name);
2336 pic14_emitcode("mov","_spx,%s",r->name);
2337 freeAsmop (NULL,aop,ic,TRUE);
2340 pic14_emitcode("push","psw");
2342 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2348 /*-----------------------------------------------------------------*/
2349 /* genCall - generates a call statement */
2350 /*-----------------------------------------------------------------*/
2351 static void genCall (iCode *ic)
2355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2357 /* if caller saves & we have not saved then */
2361 /* if we are calling a function that is not using
2362 the same register bank then we need to save the
2363 destination registers on the stack */
2364 dtype = operandType(IC_LEFT(ic));
2365 if (currFunc && dtype &&
2366 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2367 IFFUNC_ISISR(currFunc->type) &&
2370 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2372 /* if send set is not empty the assign */
2375 /* For the Pic port, there is no data stack.
2376 * So parameters passed to functions are stored
2377 * in registers. (The pCode optimizer will get
2378 * rid of most of these :).
2380 int psuedoStkPtr=-1;
2381 int firstTimeThruLoop = 1;
2383 _G.sendSet = reverseSet(_G.sendSet);
2385 /* First figure how many parameters are getting passed */
2386 for (sic = setFirstItem(_G.sendSet) ; sic ;
2387 sic = setNextItem(_G.sendSet)) {
2389 aopOp(IC_LEFT(sic),sic,FALSE);
2390 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2391 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2394 for (sic = setFirstItem(_G.sendSet) ; sic ;
2395 sic = setNextItem(_G.sendSet)) {
2396 int size, offset = 0;
2398 aopOp(IC_LEFT(sic),sic,FALSE);
2399 size = AOP_SIZE(IC_LEFT(sic));
2402 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2403 AopType(AOP_TYPE(IC_LEFT(sic))));
2405 if(!firstTimeThruLoop) {
2406 /* If this is not the first time we've been through the loop
2407 * then we need to save the parameter in a temporary
2408 * register. The last byte of the last parameter is
2410 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2413 firstTimeThruLoop=0;
2415 //if (strcmp(l,fReturn[offset])) {
2416 mov2w (AOP(IC_LEFT(sic)), offset);
2418 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2419 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2420 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2422 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2427 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2432 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2433 OP_SYMBOL(IC_LEFT(ic))->rname :
2434 OP_SYMBOL(IC_LEFT(ic))->name));
2437 /* if we need assign a result value */
2438 if ((IS_ITEMP(IC_RESULT(ic)) &&
2439 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2440 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2441 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2444 aopOp(IC_RESULT(ic),ic,FALSE);
2447 assignResultValue(IC_RESULT(ic));
2449 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2450 AopType(AOP_TYPE(IC_RESULT(ic))));
2452 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2455 /* adjust the stack for parameters if
2457 if (ic->parmBytes) {
2459 if (ic->parmBytes > 3) {
2460 pic14_emitcode("mov","a,%s",spname);
2461 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2462 pic14_emitcode("mov","%s,a",spname);
2464 for ( i = 0 ; i < ic->parmBytes ;i++)
2465 pic14_emitcode("dec","%s",spname);
2469 /* if register bank was saved then pop them */
2471 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2473 /* if we hade saved some registers then unsave them */
2474 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2475 unsaveRegisters (ic);
2480 /*-----------------------------------------------------------------*/
2481 /* genPcall - generates a call by pointer statement */
2482 /*-----------------------------------------------------------------*/
2483 static void genPcall (iCode *ic)
2486 symbol *rlbl = newiTempLabel(NULL);
2489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2490 /* if caller saves & we have not saved then */
2494 /* if we are calling a function that is not using
2495 the same register bank then we need to save the
2496 destination registers on the stack */
2497 dtype = operandType(IC_LEFT(ic));
2498 if (currFunc && dtype &&
2499 IFFUNC_ISISR(currFunc->type) &&
2500 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2501 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2504 /* push the return address on to the stack */
2505 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2506 pic14_emitcode("push","acc");
2507 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2508 pic14_emitcode("push","acc");
2510 if (options.model == MODEL_FLAT24)
2512 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2513 pic14_emitcode("push","acc");
2516 /* now push the calling address */
2517 aopOp(IC_LEFT(ic),ic,FALSE);
2519 pushSide(IC_LEFT(ic), FPTRSIZE);
2521 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2523 /* if send set is not empty the assign */
2527 for (sic = setFirstItem(_G.sendSet) ; sic ;
2528 sic = setNextItem(_G.sendSet)) {
2529 int size, offset = 0;
2530 aopOp(IC_LEFT(sic),sic,FALSE);
2531 size = AOP_SIZE(IC_LEFT(sic));
2533 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2535 if (strcmp(l,fReturn[offset]))
2536 pic14_emitcode("mov","%s,%s",
2541 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2546 pic14_emitcode("ret","");
2547 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2550 /* if we need assign a result value */
2551 if ((IS_ITEMP(IC_RESULT(ic)) &&
2552 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2553 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2554 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2557 aopOp(IC_RESULT(ic),ic,FALSE);
2560 assignResultValue(IC_RESULT(ic));
2562 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2565 /* adjust the stack for parameters if
2567 if (ic->parmBytes) {
2569 if (ic->parmBytes > 3) {
2570 pic14_emitcode("mov","a,%s",spname);
2571 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2572 pic14_emitcode("mov","%s,a",spname);
2574 for ( i = 0 ; i < ic->parmBytes ;i++)
2575 pic14_emitcode("dec","%s",spname);
2579 /* if register bank was saved then unsave them */
2580 if (currFunc && dtype &&
2581 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2582 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2584 /* if we hade saved some registers then
2587 unsaveRegisters (ic);
2591 /*-----------------------------------------------------------------*/
2592 /* resultRemat - result is rematerializable */
2593 /*-----------------------------------------------------------------*/
2594 static int resultRemat (iCode *ic)
2596 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2597 if (SKIP_IC(ic) || ic->op == IFX)
2600 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2601 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2602 if (sym->remat && !POINTER_SET(ic))
2609 #if defined(__BORLANDC__) || defined(_MSC_VER)
2610 #define STRCASECMP stricmp
2612 #define STRCASECMP strcasecmp
2616 /*-----------------------------------------------------------------*/
2617 /* inExcludeList - return 1 if the string is in exclude Reg list */
2618 /*-----------------------------------------------------------------*/
2619 static bool inExcludeList(char *s)
2621 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2625 if (options.excludeRegs[i] &&
2626 STRCASECMP(options.excludeRegs[i],"none") == 0)
2629 for ( i = 0 ; options.excludeRegs[i]; i++) {
2630 if (options.excludeRegs[i] &&
2631 STRCASECMP(s,options.excludeRegs[i]) == 0)
2638 /*-----------------------------------------------------------------*/
2639 /* genFunction - generated code for function entry */
2640 /*-----------------------------------------------------------------*/
2641 static void genFunction (iCode *ic)
2646 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2648 labelOffset += (max_key+4);
2652 /* create the function header */
2653 pic14_emitcode(";","-----------------------------------------");
2654 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2655 pic14_emitcode(";","-----------------------------------------");
2657 pic14_emitcode("","%s:",sym->rname);
2658 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2660 ftype = operandType(IC_LEFT(ic));
2662 /* if critical function then turn interrupts off */
2663 if (IFFUNC_ISCRITICAL(ftype))
2664 pic14_emitcode("clr","ea");
2666 /* here we need to generate the equates for the
2667 register bank if required */
2669 if (FUNC_REGBANK(ftype) != rbank) {
2672 rbank = FUNC_REGBANK(ftype);
2673 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2674 if (strcmp(regspic14[i].base,"0") == 0)
2675 pic14_emitcode("","%s = 0x%02x",
2677 8*rbank+regspic14[i].offset);
2679 pic14_emitcode ("","%s = %s + 0x%02x",
2682 8*rbank+regspic14[i].offset);
2687 /* if this is an interrupt service routine then
2688 save acc, b, dpl, dph */
2689 if (IFFUNC_ISISR(sym->type)) {
2690 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2691 emitpcodeNULLop(POC_NOP);
2692 emitpcodeNULLop(POC_NOP);
2693 emitpcodeNULLop(POC_NOP);
2694 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2695 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2696 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2697 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2699 pBlockConvert2ISR(pb);
2701 if (!inExcludeList("acc"))
2702 pic14_emitcode ("push","acc");
2703 if (!inExcludeList("b"))
2704 pic14_emitcode ("push","b");
2705 if (!inExcludeList("dpl"))
2706 pic14_emitcode ("push","dpl");
2707 if (!inExcludeList("dph"))
2708 pic14_emitcode ("push","dph");
2709 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2711 pic14_emitcode ("push", "dpx");
2712 /* Make sure we're using standard DPTR */
2713 pic14_emitcode ("push", "dps");
2714 pic14_emitcode ("mov", "dps, #0x00");
2715 if (options.stack10bit)
2717 /* This ISR could conceivably use DPTR2. Better save it. */
2718 pic14_emitcode ("push", "dpl1");
2719 pic14_emitcode ("push", "dph1");
2720 pic14_emitcode ("push", "dpx1");
2723 /* if this isr has no bank i.e. is going to
2724 run with bank 0 , then we need to save more
2726 if (!FUNC_REGBANK(sym->type)) {
2728 /* if this function does not call any other
2729 function then we can be economical and
2730 save only those registers that are used */
2731 if (! IFFUNC_HASFCALL(sym->type)) {
2734 /* if any registers used */
2735 if (sym->regsUsed) {
2736 /* save the registers used */
2737 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2738 if (bitVectBitValue(sym->regsUsed,i) ||
2739 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2740 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2745 /* this function has a function call cannot
2746 determines register usage so we will have the
2748 saverbank(0,ic,FALSE);
2753 /* if callee-save to be used for this function
2754 then save the registers being used in this function */
2755 if (IFFUNC_CALLEESAVES(sym->type)) {
2758 /* if any registers used */
2759 if (sym->regsUsed) {
2760 /* save the registers used */
2761 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2762 if (bitVectBitValue(sym->regsUsed,i) ||
2763 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2764 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2772 /* set the register bank to the desired value */
2773 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2774 pic14_emitcode("push","psw");
2775 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2778 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2780 if (options.useXstack) {
2781 pic14_emitcode("mov","r0,%s",spname);
2782 pic14_emitcode("mov","a,_bp");
2783 pic14_emitcode("movx","@r0,a");
2784 pic14_emitcode("inc","%s",spname);
2788 /* set up the stack */
2789 pic14_emitcode ("push","_bp"); /* save the callers stack */
2791 pic14_emitcode ("mov","_bp,%s",spname);
2794 /* adjust the stack for the function */
2799 werror(W_STACK_OVERFLOW,sym->name);
2801 if (i > 3 && sym->recvSize < 4) {
2803 pic14_emitcode ("mov","a,sp");
2804 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2805 pic14_emitcode ("mov","sp,a");
2810 pic14_emitcode("inc","sp");
2815 pic14_emitcode ("mov","a,_spx");
2816 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2817 pic14_emitcode ("mov","_spx,a");
2822 /*-----------------------------------------------------------------*/
2823 /* genEndFunction - generates epilogue for functions */
2824 /*-----------------------------------------------------------------*/
2825 static void genEndFunction (iCode *ic)
2827 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2831 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2833 pic14_emitcode ("mov","%s,_bp",spname);
2836 /* if use external stack but some variables were
2837 added to the local stack then decrement the
2839 if (options.useXstack && sym->stack) {
2840 pic14_emitcode("mov","a,sp");
2841 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2842 pic14_emitcode("mov","sp,a");
2846 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2847 if (options.useXstack) {
2848 pic14_emitcode("mov","r0,%s",spname);
2849 pic14_emitcode("movx","a,@r0");
2850 pic14_emitcode("mov","_bp,a");
2851 pic14_emitcode("dec","%s",spname);
2855 pic14_emitcode ("pop","_bp");
2859 /* restore the register bank */
2860 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2861 pic14_emitcode ("pop","psw");
2863 if (IFFUNC_ISISR(sym->type)) {
2865 /* now we need to restore the registers */
2866 /* if this isr has no bank i.e. is going to
2867 run with bank 0 , then we need to save more
2869 if (!FUNC_REGBANK(sym->type)) {
2871 /* if this function does not call any other
2872 function then we can be economical and
2873 save only those registers that are used */
2874 if (! IFFUNC_HASFCALL(sym->type)) {
2877 /* if any registers used */
2878 if (sym->regsUsed) {
2879 /* save the registers used */
2880 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2881 if (bitVectBitValue(sym->regsUsed,i) ||
2882 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2883 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2888 /* this function has a function call cannot
2889 determines register usage so we will have the
2891 unsaverbank(0,ic,FALSE);
2895 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2897 if (options.stack10bit)
2899 pic14_emitcode ("pop", "dpx1");
2900 pic14_emitcode ("pop", "dph1");
2901 pic14_emitcode ("pop", "dpl1");
2903 pic14_emitcode ("pop", "dps");
2904 pic14_emitcode ("pop", "dpx");
2906 if (!inExcludeList("dph"))
2907 pic14_emitcode ("pop","dph");
2908 if (!inExcludeList("dpl"))
2909 pic14_emitcode ("pop","dpl");
2910 if (!inExcludeList("b"))
2911 pic14_emitcode ("pop","b");
2912 if (!inExcludeList("acc"))
2913 pic14_emitcode ("pop","acc");
2915 if (IFFUNC_ISCRITICAL(sym->type))
2916 pic14_emitcode("setb","ea");
2919 /* if debug then send end of function */
2920 /* if (options.debug && currFunc) { */
2923 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2924 FileBaseName(ic->filename),currFunc->lastLine,
2925 ic->level,ic->block);
2926 if (IS_STATIC(currFunc->etype))
2927 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2929 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2933 pic14_emitcode ("reti","");
2935 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2936 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2937 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2938 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2939 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2940 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2942 emitpcodeNULLop(POC_RETFIE);
2946 if (IFFUNC_ISCRITICAL(sym->type))
2947 pic14_emitcode("setb","ea");
2949 if (IFFUNC_CALLEESAVES(sym->type)) {
2952 /* if any registers used */
2953 if (sym->regsUsed) {
2954 /* save the registers used */
2955 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2956 if (bitVectBitValue(sym->regsUsed,i) ||
2957 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2958 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2964 /* if debug then send end of function */
2967 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2968 FileBaseName(ic->filename),currFunc->lastLine,
2969 ic->level,ic->block);
2970 if (IS_STATIC(currFunc->etype))
2971 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2973 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2977 pic14_emitcode ("return","");
2978 emitpcodeNULLop(POC_RETURN);
2980 /* Mark the end of a function */
2981 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2986 /*-----------------------------------------------------------------*/
2987 /* genRet - generate code for return statement */
2988 /*-----------------------------------------------------------------*/
2989 static void genRet (iCode *ic)
2991 int size,offset = 0 , pushed = 0;
2993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2994 /* if we have no return value then
2995 just generate the "ret" */
2999 /* we have something to return then
3000 move the return value into place */
3001 aopOp(IC_LEFT(ic),ic,FALSE);
3002 size = AOP_SIZE(IC_LEFT(ic));
3006 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3008 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3010 pic14_emitcode("push","%s",l);
3013 l = aopGet(AOP(IC_LEFT(ic)),offset,
3015 if (strcmp(fReturn[offset],l)) {
3016 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3017 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3018 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3020 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3023 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3033 if (strcmp(fReturn[pushed],"a"))
3034 pic14_emitcode("pop",fReturn[pushed]);
3036 pic14_emitcode("pop","acc");
3039 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3042 /* generate a jump to the return label
3043 if the next is not the return statement */
3044 if (!(ic->next && ic->next->op == LABEL &&
3045 IC_LABEL(ic->next) == returnLabel)) {
3047 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3048 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3053 /*-----------------------------------------------------------------*/
3054 /* genLabel - generates a label */
3055 /*-----------------------------------------------------------------*/
3056 static void genLabel (iCode *ic)
3058 /* special case never generate */
3059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3060 if (IC_LABEL(ic) == entryLabel)
3063 emitpLabel(IC_LABEL(ic)->key);
3064 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3067 /*-----------------------------------------------------------------*/
3068 /* genGoto - generates a goto */
3069 /*-----------------------------------------------------------------*/
3071 static void genGoto (iCode *ic)
3073 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3074 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3078 /*-----------------------------------------------------------------*/
3079 /* genMultbits :- multiplication of bits */
3080 /*-----------------------------------------------------------------*/
3081 static void genMultbits (operand *left,
3085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3087 if(!pic14_sameRegs(AOP(result),AOP(right)))
3088 emitpcode(POC_BSF, popGet(AOP(result),0));
3090 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3091 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3092 emitpcode(POC_BCF, popGet(AOP(result),0));
3097 /*-----------------------------------------------------------------*/
3098 /* genMultOneByte : 8 bit multiplication & division */
3099 /*-----------------------------------------------------------------*/
3100 static void genMultOneByte (operand *left,
3104 sym_link *opetype = operandType(result);
3109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3110 DEBUGpic14_AopType(__LINE__,left,right,result);
3111 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3113 /* (if two literals, the value is computed before) */
3114 /* if one literal, literal on the right */
3115 if (AOP_TYPE(left) == AOP_LIT){
3121 size = AOP_SIZE(result);
3124 if (AOP_TYPE(right) == AOP_LIT){
3125 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3126 aopGet(AOP(right),0,FALSE,FALSE),
3127 aopGet(AOP(left),0,FALSE,FALSE),
3128 aopGet(AOP(result),0,FALSE,FALSE));
3129 pic14_emitcode("call","genMultLit");
3131 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3132 aopGet(AOP(right),0,FALSE,FALSE),
3133 aopGet(AOP(left),0,FALSE,FALSE),
3134 aopGet(AOP(result),0,FALSE,FALSE));
3135 pic14_emitcode("call","genMult8X8_8");
3138 genMult8X8_8 (left, right,result);
3141 /* signed or unsigned */
3142 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3143 //l = aopGet(AOP(left),0,FALSE,FALSE);
3145 //pic14_emitcode("mul","ab");
3146 /* if result size = 1, mul signed = mul unsigned */
3147 //aopPut(AOP(result),"a",0);
3149 } else { // (size > 1)
3151 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3152 aopGet(AOP(right),0,FALSE,FALSE),
3153 aopGet(AOP(left),0,FALSE,FALSE),
3154 aopGet(AOP(result),0,FALSE,FALSE));
3156 if (SPEC_USIGN(opetype)){
3157 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3158 genUMult8X8_16 (left, right, result, NULL);
3161 /* for filling the MSBs */
3162 emitpcode(POC_CLRF, popGet(AOP(result),2));
3163 emitpcode(POC_CLRF, popGet(AOP(result),3));
3167 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3169 pic14_emitcode("mov","a,b");
3171 /* adjust the MSB if left or right neg */
3173 /* if one literal */
3174 if (AOP_TYPE(right) == AOP_LIT){
3175 pic14_emitcode("multiply ","right is a lit");
3176 /* AND literal negative */
3177 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3178 /* adjust MSB (c==0 after mul) */
3179 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3183 genSMult8X8_16 (left, right, result, NULL);
3187 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3189 pic14_emitcode("rlc","a");
3190 pic14_emitcode("subb","a,acc");
3198 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3199 //aopPut(AOP(result),"a",offset++);
3203 /*-----------------------------------------------------------------*/
3204 /* genMult - generates code for multiplication */
3205 /*-----------------------------------------------------------------*/
3206 static void genMult (iCode *ic)
3208 operand *left = IC_LEFT(ic);
3209 operand *right = IC_RIGHT(ic);
3210 operand *result= IC_RESULT(ic);
3212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3213 /* assign the amsops */
3214 aopOp (left,ic,FALSE);
3215 aopOp (right,ic,FALSE);
3216 aopOp (result,ic,TRUE);
3218 DEBUGpic14_AopType(__LINE__,left,right,result);
3220 /* special cases first */
3222 if (AOP_TYPE(left) == AOP_CRY &&
3223 AOP_TYPE(right)== AOP_CRY) {
3224 genMultbits(left,right,result);
3228 /* if both are of size == 1 */
3229 if (AOP_SIZE(left) == 1 &&
3230 AOP_SIZE(right) == 1 ) {
3231 genMultOneByte(left,right,result);
3235 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3237 /* should have been converted to function call */
3241 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3242 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3243 freeAsmop(result,NULL,ic,TRUE);
3246 /*-----------------------------------------------------------------*/
3247 /* genDivbits :- division of bits */
3248 /*-----------------------------------------------------------------*/
3249 static void genDivbits (operand *left,
3256 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3257 /* the result must be bit */
3258 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3259 l = aopGet(AOP(left),0,FALSE,FALSE);
3263 pic14_emitcode("div","ab");
3264 pic14_emitcode("rrc","a");
3265 aopPut(AOP(result),"c",0);
3268 /*-----------------------------------------------------------------*/
3269 /* genDivOneByte : 8 bit division */
3270 /*-----------------------------------------------------------------*/
3271 static void genDivOneByte (operand *left,
3275 sym_link *opetype = operandType(result);
3280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3281 size = AOP_SIZE(result) - 1;
3283 /* signed or unsigned */
3284 if (SPEC_USIGN(opetype)) {
3285 /* unsigned is easy */
3286 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3287 l = aopGet(AOP(left),0,FALSE,FALSE);
3289 pic14_emitcode("div","ab");
3290 aopPut(AOP(result),"a",0);
3292 aopPut(AOP(result),zero,offset++);
3296 /* signed is a little bit more difficult */
3298 /* save the signs of the operands */
3299 l = aopGet(AOP(left),0,FALSE,FALSE);
3301 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3302 pic14_emitcode("push","acc"); /* save it on the stack */
3304 /* now sign adjust for both left & right */
3305 l = aopGet(AOP(right),0,FALSE,FALSE);
3307 lbl = newiTempLabel(NULL);
3308 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3309 pic14_emitcode("cpl","a");
3310 pic14_emitcode("inc","a");
3311 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3312 pic14_emitcode("mov","b,a");
3314 /* sign adjust left side */
3315 l = aopGet(AOP(left),0,FALSE,FALSE);
3318 lbl = newiTempLabel(NULL);
3319 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3320 pic14_emitcode("cpl","a");
3321 pic14_emitcode("inc","a");
3322 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3324 /* now the division */
3325 pic14_emitcode("div","ab");
3326 /* we are interested in the lower order
3328 pic14_emitcode("mov","b,a");
3329 lbl = newiTempLabel(NULL);
3330 pic14_emitcode("pop","acc");
3331 /* if there was an over flow we don't
3332 adjust the sign of the result */
3333 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3334 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3336 pic14_emitcode("clr","a");
3337 pic14_emitcode("subb","a,b");
3338 pic14_emitcode("mov","b,a");
3339 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3341 /* now we are done */
3342 aopPut(AOP(result),"b",0);
3344 pic14_emitcode("mov","c,b.7");
3345 pic14_emitcode("subb","a,acc");
3348 aopPut(AOP(result),"a",offset++);
3352 /*-----------------------------------------------------------------*/
3353 /* genDiv - generates code for division */
3354 /*-----------------------------------------------------------------*/
3355 static void genDiv (iCode *ic)
3357 operand *left = IC_LEFT(ic);
3358 operand *right = IC_RIGHT(ic);
3359 operand *result= IC_RESULT(ic);
3361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3362 /* assign the amsops */
3363 aopOp (left,ic,FALSE);
3364 aopOp (right,ic,FALSE);
3365 aopOp (result,ic,TRUE);
3367 /* special cases first */
3369 if (AOP_TYPE(left) == AOP_CRY &&
3370 AOP_TYPE(right)== AOP_CRY) {
3371 genDivbits(left,right,result);
3375 /* if both are of size == 1 */
3376 if (AOP_SIZE(left) == 1 &&
3377 AOP_SIZE(right) == 1 ) {
3378 genDivOneByte(left,right,result);
3382 /* should have been converted to function call */
3385 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3386 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3387 freeAsmop(result,NULL,ic,TRUE);
3390 /*-----------------------------------------------------------------*/
3391 /* genModbits :- modulus of bits */
3392 /*-----------------------------------------------------------------*/
3393 static void genModbits (operand *left,
3400 /* the result must be bit */
3401 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3402 l = aopGet(AOP(left),0,FALSE,FALSE);
3406 pic14_emitcode("div","ab");
3407 pic14_emitcode("mov","a,b");
3408 pic14_emitcode("rrc","a");
3409 aopPut(AOP(result),"c",0);
3412 /*-----------------------------------------------------------------*/
3413 /* genModOneByte : 8 bit modulus */
3414 /*-----------------------------------------------------------------*/
3415 static void genModOneByte (operand *left,
3419 sym_link *opetype = operandType(result);
3423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3424 /* signed or unsigned */
3425 if (SPEC_USIGN(opetype)) {
3426 /* unsigned is easy */
3427 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3428 l = aopGet(AOP(left),0,FALSE,FALSE);
3430 pic14_emitcode("div","ab");
3431 aopPut(AOP(result),"b",0);
3435 /* signed is a little bit more difficult */
3437 /* save the signs of the operands */
3438 l = aopGet(AOP(left),0,FALSE,FALSE);
3441 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3442 pic14_emitcode("push","acc"); /* save it on the stack */
3444 /* now sign adjust for both left & right */
3445 l = aopGet(AOP(right),0,FALSE,FALSE);
3448 lbl = newiTempLabel(NULL);
3449 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3450 pic14_emitcode("cpl","a");
3451 pic14_emitcode("inc","a");
3452 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3453 pic14_emitcode("mov","b,a");
3455 /* sign adjust left side */
3456 l = aopGet(AOP(left),0,FALSE,FALSE);
3459 lbl = newiTempLabel(NULL);
3460 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3461 pic14_emitcode("cpl","a");
3462 pic14_emitcode("inc","a");
3463 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3465 /* now the multiplication */
3466 pic14_emitcode("div","ab");
3467 /* we are interested in the lower order
3469 lbl = newiTempLabel(NULL);
3470 pic14_emitcode("pop","acc");
3471 /* if there was an over flow we don't
3472 adjust the sign of the result */
3473 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3474 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3476 pic14_emitcode("clr","a");
3477 pic14_emitcode("subb","a,b");
3478 pic14_emitcode("mov","b,a");
3479 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3481 /* now we are done */
3482 aopPut(AOP(result),"b",0);
3486 /*-----------------------------------------------------------------*/
3487 /* genMod - generates code for division */
3488 /*-----------------------------------------------------------------*/
3489 static void genMod (iCode *ic)
3491 operand *left = IC_LEFT(ic);
3492 operand *right = IC_RIGHT(ic);
3493 operand *result= IC_RESULT(ic);
3495 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3496 /* assign the amsops */
3497 aopOp (left,ic,FALSE);
3498 aopOp (right,ic,FALSE);
3499 aopOp (result,ic,TRUE);
3501 /* special cases first */
3503 if (AOP_TYPE(left) == AOP_CRY &&
3504 AOP_TYPE(right)== AOP_CRY) {
3505 genModbits(left,right,result);
3509 /* if both are of size == 1 */
3510 if (AOP_SIZE(left) == 1 &&
3511 AOP_SIZE(right) == 1 ) {
3512 genModOneByte(left,right,result);
3516 /* should have been converted to function call */
3520 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3521 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3522 freeAsmop(result,NULL,ic,TRUE);
3525 /*-----------------------------------------------------------------*/
3526 /* genIfxJump :- will create a jump depending on the ifx */
3527 /*-----------------------------------------------------------------*/
3529 note: May need to add parameter to indicate when a variable is in bit space.
3531 static void genIfxJump (iCode *ic, char *jval)
3534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3535 /* if true label then we jump if condition
3537 if ( IC_TRUE(ic) ) {
3539 if(strcmp(jval,"a") == 0)
3541 else if (strcmp(jval,"c") == 0)
3544 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3545 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3548 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3549 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3553 /* false label is present */
3554 if(strcmp(jval,"a") == 0)
3556 else if (strcmp(jval,"c") == 0)
3559 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3560 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3563 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3564 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3569 /* mark the icode as generated */
3573 /*-----------------------------------------------------------------*/
3575 /*-----------------------------------------------------------------*/
3576 static void genSkip(iCode *ifx,int status_bit)
3581 if ( IC_TRUE(ifx) ) {
3582 switch(status_bit) {
3597 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3598 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3602 switch(status_bit) {
3616 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3617 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3623 /*-----------------------------------------------------------------*/
3625 /*-----------------------------------------------------------------*/
3626 static void genSkipc(resolvedIfx *rifx)
3636 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3637 rifx->generated = 1;
3640 /*-----------------------------------------------------------------*/
3642 /*-----------------------------------------------------------------*/
3643 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3648 if( (rifx->condition ^ invert_condition) & 1)
3653 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3654 rifx->generated = 1;
3657 /*-----------------------------------------------------------------*/
3659 /*-----------------------------------------------------------------*/
3660 static void genSkipz(iCode *ifx, int condition)
3671 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3673 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3676 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3678 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3681 /*-----------------------------------------------------------------*/
3683 /*-----------------------------------------------------------------*/
3684 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3690 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3692 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3695 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3696 rifx->generated = 1;
3700 /*-----------------------------------------------------------------*/
3701 /* genChkZeroes :- greater or less than comparison */
3702 /* For each byte in a literal that is zero, inclusive or the */
3703 /* the corresponding byte in the operand with W */
3704 /* returns true if any of the bytes are zero */
3705 /*-----------------------------------------------------------------*/
3706 static int genChkZeroes(operand *op, int lit, int size)
3713 i = (lit >> (size*8)) & 0xff;
3717 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3719 emitpcode(POC_IORFW, popGet(AOP(op),size));
3728 /*-----------------------------------------------------------------*/
3729 /* genCmp :- greater or less than comparison */
3730 /*-----------------------------------------------------------------*/
3731 static void genCmp (operand *left,operand *right,
3732 operand *result, iCode *ifx, int sign)
3734 int size; //, offset = 0 ;
3735 unsigned long lit = 0L,i = 0;
3736 resolvedIfx rFalseIfx;
3737 // resolvedIfx rTrueIfx;
3739 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3742 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3743 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3747 resolveIfx(&rFalseIfx,ifx);
3748 truelbl = newiTempLabel(NULL);
3749 size = max(AOP_SIZE(left),AOP_SIZE(right));
3751 DEBUGpic14_AopType(__LINE__,left,right,result);
3755 /* if literal is on the right then swap with left */
3756 if ((AOP_TYPE(right) == AOP_LIT)) {
3757 operand *tmp = right ;
3758 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3759 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3762 lit = (lit - 1) & mask;
3765 rFalseIfx.condition ^= 1;
3768 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3769 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3773 //if(IC_TRUE(ifx) == NULL)
3774 /* if left & right are bit variables */
3775 if (AOP_TYPE(left) == AOP_CRY &&
3776 AOP_TYPE(right) == AOP_CRY ) {
3777 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3778 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3780 /* subtract right from left if at the
3781 end the carry flag is set then we know that
3782 left is greater than right */
3786 symbol *lbl = newiTempLabel(NULL);
3789 if(AOP_TYPE(right) == AOP_LIT) {
3791 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3793 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3800 genSkipCond(&rFalseIfx,left,size-1,7);
3802 /* no need to compare to 0...*/
3803 /* NOTE: this is a de-generate compare that most certainly
3804 * creates some dead code. */
3805 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3807 if(ifx) ifx->generated = 1;
3814 //i = (lit >> (size*8)) & 0xff;
3815 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3817 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3819 i = ((0-lit) & 0xff);
3822 /* lit is 0x7f, all signed chars are less than
3823 * this except for 0x7f itself */
3824 emitpcode(POC_XORLW, popGetLit(0x7f));
3825 genSkipz2(&rFalseIfx,0);
3827 emitpcode(POC_ADDLW, popGetLit(0x80));
3828 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3829 genSkipc(&rFalseIfx);
3834 genSkipz2(&rFalseIfx,1);
3836 emitpcode(POC_ADDLW, popGetLit(i));
3837 genSkipc(&rFalseIfx);
3841 if(ifx) ifx->generated = 1;
3845 /* chars are out of the way. now do ints and longs */
3848 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3855 genSkipCond(&rFalseIfx,left,size,7);
3856 if(ifx) ifx->generated = 1;
3861 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3863 //rFalseIfx.condition ^= 1;
3864 //genSkipCond(&rFalseIfx,left,size,7);
3865 //rFalseIfx.condition ^= 1;
3867 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3868 if(rFalseIfx.condition)
3869 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3871 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3873 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3874 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3875 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3878 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3880 if(rFalseIfx.condition) {
3882 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3888 genSkipc(&rFalseIfx);
3889 emitpLabel(truelbl->key);
3890 if(ifx) ifx->generated = 1;
3897 if( (lit & 0xff) == 0) {
3898 /* lower byte is zero */
3899 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3900 i = ((lit >> 8) & 0xff) ^0x80;
3901 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3902 emitpcode(POC_ADDLW, popGetLit( 0x80));
3903 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3904 genSkipc(&rFalseIfx);
3907 if(ifx) ifx->generated = 1;
3912 /* Special cases for signed longs */
3913 if( (lit & 0xffffff) == 0) {
3914 /* lower byte is zero */
3915 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3916 i = ((lit >> 8*3) & 0xff) ^0x80;
3917 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3918 emitpcode(POC_ADDLW, popGetLit( 0x80));
3919 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3920 genSkipc(&rFalseIfx);
3923 if(ifx) ifx->generated = 1;
3931 if(lit & (0x80 << (size*8))) {
3932 /* lit is negative */
3933 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3935 //genSkipCond(&rFalseIfx,left,size,7);
3937 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3939 if(rFalseIfx.condition)
3940 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3942 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3946 /* lit is positive */
3947 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3948 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3949 if(rFalseIfx.condition)
3950 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3952 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3957 This works, but is only good for ints.
3958 It also requires a "known zero" register.
3959 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3960 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3961 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3962 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3963 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3964 genSkipc(&rFalseIfx);
3966 emitpLabel(truelbl->key);
3967 if(ifx) ifx->generated = 1;
3971 /* There are no more special cases, so perform a general compare */
3973 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3974 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3978 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3980 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3982 //rFalseIfx.condition ^= 1;
3983 genSkipc(&rFalseIfx);
3985 emitpLabel(truelbl->key);
3987 if(ifx) ifx->generated = 1;
3994 /* sign is out of the way. So now do an unsigned compare */
3995 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3998 /* General case - compare to an unsigned literal on the right.*/
4000 i = (lit >> (size*8)) & 0xff;
4001 emitpcode(POC_MOVLW, popGetLit(i));
4002 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4004 i = (lit >> (size*8)) & 0xff;
4007 emitpcode(POC_MOVLW, popGetLit(i));
4009 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4011 /* this byte of the lit is zero,
4012 *if it's not the last then OR in the variable */
4014 emitpcode(POC_IORFW, popGet(AOP(left),size));
4019 emitpLabel(lbl->key);
4020 //if(emitFinalCheck)
4021 genSkipc(&rFalseIfx);
4023 emitpLabel(truelbl->key);
4025 if(ifx) ifx->generated = 1;
4032 if(AOP_TYPE(left) == AOP_LIT) {
4033 //symbol *lbl = newiTempLabel(NULL);
4035 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4038 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4041 if((lit == 0) && (sign == 0)){
4044 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4046 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4048 genSkipz2(&rFalseIfx,0);
4049 if(ifx) ifx->generated = 1;
4056 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4057 /* degenerate compare can never be true */
4058 if(rFalseIfx.condition == 0)
4059 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4061 if(ifx) ifx->generated = 1;
4066 /* signed comparisons to a literal byte */
4068 int lp1 = (lit+1) & 0xff;
4070 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4073 rFalseIfx.condition ^= 1;
4074 genSkipCond(&rFalseIfx,right,0,7);
4077 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4078 emitpcode(POC_XORLW, popGetLit(0x7f));
4079 genSkipz2(&rFalseIfx,1);
4082 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4083 emitpcode(POC_ADDLW, popGetLit(0x80));
4084 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4085 rFalseIfx.condition ^= 1;
4086 genSkipc(&rFalseIfx);
4089 if(ifx) ifx->generated = 1;
4091 /* unsigned comparisons to a literal byte */
4093 switch(lit & 0xff ) {
4095 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4096 genSkipz2(&rFalseIfx,0);
4097 if(ifx) ifx->generated = 1;
4100 rFalseIfx.condition ^= 1;
4101 genSkipCond(&rFalseIfx,right,0,7);
4102 if(ifx) ifx->generated = 1;
4106 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4107 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4109 rFalseIfx.condition ^= 1;
4110 if (AOP_TYPE(result) == AOP_CRY) {
4111 genSkipc(&rFalseIfx);
4112 if(ifx) ifx->generated = 1;
4114 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4115 emitpcode(POC_CLRF, popGet(AOP(result),0));
4116 emitpcode(POC_RLF, popGet(AOP(result),0));
4117 emitpcode(POC_MOVLW, popGetLit(0x01));
4118 emitpcode(POC_XORWF, popGet(AOP(result),0));
4129 /* Size is greater than 1 */
4137 /* this means lit = 0xffffffff, or -1 */
4140 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4141 rFalseIfx.condition ^= 1;
4142 genSkipCond(&rFalseIfx,right,size,7);
4143 if(ifx) ifx->generated = 1;
4150 if(rFalseIfx.condition) {
4151 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4155 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4157 emitpcode(POC_IORFW, popGet(AOP(right),size));
4161 if(rFalseIfx.condition) {
4162 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4163 emitpLabel(truelbl->key);
4165 rFalseIfx.condition ^= 1;
4166 genSkipCond(&rFalseIfx,right,s,7);
4169 if(ifx) ifx->generated = 1;
4173 if((size == 1) && (0 == (lp1&0xff))) {
4174 /* lower byte of signed word is zero */
4175 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4176 i = ((lp1 >> 8) & 0xff) ^0x80;
4177 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4178 emitpcode(POC_ADDLW, popGetLit( 0x80));
4179 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4180 rFalseIfx.condition ^= 1;
4181 genSkipc(&rFalseIfx);
4184 if(ifx) ifx->generated = 1;
4188 if(lit & (0x80 << (size*8))) {
4189 /* Lit is less than zero */
4190 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4191 //rFalseIfx.condition ^= 1;
4192 //genSkipCond(&rFalseIfx,left,size,7);
4193 //rFalseIfx.condition ^= 1;
4194 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4195 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4197 if(rFalseIfx.condition)
4198 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4200 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4204 /* Lit is greater than or equal to zero */
4205 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4206 //rFalseIfx.condition ^= 1;
4207 //genSkipCond(&rFalseIfx,right,size,7);
4208 //rFalseIfx.condition ^= 1;
4210 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4211 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4213 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214 if(rFalseIfx.condition)
4215 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4217 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4222 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4223 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4227 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4229 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4231 rFalseIfx.condition ^= 1;
4232 //rFalseIfx.condition = 1;
4233 genSkipc(&rFalseIfx);
4235 emitpLabel(truelbl->key);
4237 if(ifx) ifx->generated = 1;
4242 /* compare word or long to an unsigned literal on the right.*/
4247 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4250 break; /* handled above */
4253 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4255 emitpcode(POC_IORFW, popGet(AOP(right),size));
4256 genSkipz2(&rFalseIfx,0);
4260 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4262 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265 if(rFalseIfx.condition)
4266 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4268 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4271 emitpcode(POC_MOVLW, popGetLit(lit+1));
4272 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4274 rFalseIfx.condition ^= 1;
4275 genSkipc(&rFalseIfx);
4278 emitpLabel(truelbl->key);
4280 if(ifx) ifx->generated = 1;
4286 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4287 i = (lit >> (size*8)) & 0xff;
4289 emitpcode(POC_MOVLW, popGetLit(i));
4290 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4293 i = (lit >> (size*8)) & 0xff;
4296 emitpcode(POC_MOVLW, popGetLit(i));
4298 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4300 /* this byte of the lit is zero,
4301 *if it's not the last then OR in the variable */
4303 emitpcode(POC_IORFW, popGet(AOP(right),size));
4308 emitpLabel(lbl->key);
4310 rFalseIfx.condition ^= 1;
4311 genSkipc(&rFalseIfx);
4315 emitpLabel(truelbl->key);
4316 if(ifx) ifx->generated = 1;
4320 /* Compare two variables */
4322 DEBUGpic14_emitcode(";sign","%d",sign);
4326 /* Sigh. thus sucks... */
4328 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4329 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4330 emitpcode(POC_MOVLW, popGetLit(0x80));
4331 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4332 emitpcode(POC_XORFW, popGet(AOP(right),size));
4333 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4335 /* Signed char comparison */
4336 /* Special thanks to Nikolai Golovchenko for this snippet */
4337 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4338 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4339 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4340 emitpcode(POC_XORFW, popGet(AOP(left),0));
4341 emitpcode(POC_XORFW, popGet(AOP(right),0));
4342 emitpcode(POC_ADDLW, popGetLit(0x80));
4344 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4345 genSkipc(&rFalseIfx);
4347 if(ifx) ifx->generated = 1;
4353 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4354 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4358 /* The rest of the bytes of a multi-byte compare */
4362 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4365 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4366 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4371 emitpLabel(lbl->key);
4373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4374 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4375 (AOP_TYPE(result) == AOP_REG)) {
4376 emitpcode(POC_CLRF, popGet(AOP(result),0));
4377 emitpcode(POC_RLF, popGet(AOP(result),0));
4379 genSkipc(&rFalseIfx);
4381 //genSkipc(&rFalseIfx);
4382 if(ifx) ifx->generated = 1;
4389 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4391 pic14_outBitC(result);
4393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4394 /* if the result is used in the next
4395 ifx conditional branch then generate
4396 code a little differently */
4398 genIfxJump (ifx,"c");
4400 pic14_outBitC(result);
4401 /* leave the result in acc */
4406 /*-----------------------------------------------------------------*/
4407 /* genCmpGt :- greater than comparison */
4408 /*-----------------------------------------------------------------*/
4409 static void genCmpGt (iCode *ic, iCode *ifx)
4411 operand *left, *right, *result;
4412 sym_link *letype , *retype;
4415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4417 right= IC_RIGHT(ic);
4418 result = IC_RESULT(ic);
4420 letype = getSpec(operandType(left));
4421 retype =getSpec(operandType(right));
4422 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4423 /* assign the amsops */
4424 aopOp (left,ic,FALSE);
4425 aopOp (right,ic,FALSE);
4426 aopOp (result,ic,TRUE);
4428 genCmp(right, left, result, ifx, sign);
4430 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4431 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4432 freeAsmop(result,NULL,ic,TRUE);
4435 /*-----------------------------------------------------------------*/
4436 /* genCmpLt - less than comparisons */
4437 /*-----------------------------------------------------------------*/
4438 static void genCmpLt (iCode *ic, iCode *ifx)
4440 operand *left, *right, *result;
4441 sym_link *letype , *retype;
4444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4446 right= IC_RIGHT(ic);
4447 result = IC_RESULT(ic);
4449 letype = getSpec(operandType(left));
4450 retype =getSpec(operandType(right));
4451 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4453 /* assign the amsops */
4454 aopOp (left,ic,FALSE);
4455 aopOp (right,ic,FALSE);
4456 aopOp (result,ic,TRUE);
4458 genCmp(left, right, result, ifx, sign);
4460 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4461 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4462 freeAsmop(result,NULL,ic,TRUE);
4465 /*-----------------------------------------------------------------*/
4466 /* genc16bit2lit - compare a 16 bit value to a literal */
4467 /*-----------------------------------------------------------------*/
4468 static void genc16bit2lit(operand *op, int lit, int offset)
4472 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4473 if( (lit&0xff) == 0)
4478 switch( BYTEofLONG(lit,i)) {
4480 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4483 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4486 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4489 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4490 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4495 switch( BYTEofLONG(lit,i)) {
4497 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4501 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4505 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4508 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4510 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4516 /*-----------------------------------------------------------------*/
4517 /* gencjneshort - compare and jump if not equal */
4518 /*-----------------------------------------------------------------*/
4519 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4521 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4523 int res_offset = 0; /* the result may be a different size then left or right */
4524 int res_size = AOP_SIZE(result);
4528 unsigned long lit = 0L;
4529 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4530 DEBUGpic14_AopType(__LINE__,left,right,result);
4532 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4533 resolveIfx(&rIfx,ifx);
4534 lbl = newiTempLabel(NULL);
4537 /* if the left side is a literal or
4538 if the right is in a pointer register and left
4540 if ((AOP_TYPE(left) == AOP_LIT) ||
4541 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4546 if(AOP_TYPE(right) == AOP_LIT)
4547 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4549 /* if the right side is a literal then anything goes */
4550 if (AOP_TYPE(right) == AOP_LIT &&
4551 AOP_TYPE(left) != AOP_DIR ) {
4554 genc16bit2lit(left, lit, 0);
4556 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4561 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4562 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4564 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4568 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4570 if(res_offset < res_size-1)
4578 /* if the right side is in a register or in direct space or
4579 if the left is a pointer register & right is not */
4580 else if (AOP_TYPE(right) == AOP_REG ||
4581 AOP_TYPE(right) == AOP_DIR ||
4582 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4583 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4584 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4585 int lbl_key = lbl->key;
4588 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4589 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4591 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4592 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4593 __FUNCTION__,__LINE__);
4597 /* switch(size) { */
4599 /* genc16bit2lit(left, lit, 0); */
4601 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4606 if((AOP_TYPE(left) == AOP_DIR) &&
4607 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4609 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4610 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4612 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4614 switch (lit & 0xff) {
4616 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4620 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4621 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4625 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4626 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4627 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4628 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4632 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4633 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4638 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4641 if(AOP_TYPE(result) == AOP_CRY) {
4642 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4647 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4649 /* fix me. probably need to check result size too */
4650 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4655 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4656 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4663 if(res_offset < res_size-1)
4668 } else if(AOP_TYPE(right) == AOP_REG &&
4669 AOP_TYPE(left) != AOP_DIR){
4672 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4673 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4674 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4679 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4681 if(res_offset < res_size-1)
4686 /* right is a pointer reg need both a & b */
4688 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4690 pic14_emitcode("mov","b,%s",l);
4691 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4692 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4697 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4699 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4701 emitpLabel(lbl->key);
4703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4710 /*-----------------------------------------------------------------*/
4711 /* gencjne - compare and jump if not equal */
4712 /*-----------------------------------------------------------------*/
4713 static void gencjne(operand *left, operand *right, iCode *ifx)
4715 symbol *tlbl = newiTempLabel(NULL);
4717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4718 gencjneshort(left, right, lbl);
4720 pic14_emitcode("mov","a,%s",one);
4721 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4722 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4723 pic14_emitcode("clr","a");
4724 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4726 emitpLabel(lbl->key);
4727 emitpLabel(tlbl->key);
4732 /*-----------------------------------------------------------------*/
4733 /* genCmpEq - generates code for equal to */
4734 /*-----------------------------------------------------------------*/
4735 static void genCmpEq (iCode *ic, iCode *ifx)
4737 operand *left, *right, *result;
4738 unsigned long lit = 0L;
4741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4744 DEBUGpic14_emitcode ("; ifx is non-null","");
4746 DEBUGpic14_emitcode ("; ifx is null","");
4748 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4749 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4750 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4752 size = max(AOP_SIZE(left),AOP_SIZE(right));
4754 DEBUGpic14_AopType(__LINE__,left,right,result);
4756 /* if literal, literal on the right or
4757 if the right is in a pointer register and left
4759 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4760 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4761 operand *tmp = right ;
4767 if(ifx && !AOP_SIZE(result)){
4769 /* if they are both bit variables */
4770 if (AOP_TYPE(left) == AOP_CRY &&
4771 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4772 if(AOP_TYPE(right) == AOP_LIT){
4773 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4775 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4776 pic14_emitcode("cpl","c");
4777 } else if(lit == 1L) {
4778 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4780 pic14_emitcode("clr","c");
4782 /* AOP_TYPE(right) == AOP_CRY */
4784 symbol *lbl = newiTempLabel(NULL);
4785 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4786 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4787 pic14_emitcode("cpl","c");
4788 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4790 /* if true label then we jump if condition
4792 tlbl = newiTempLabel(NULL);
4793 if ( IC_TRUE(ifx) ) {
4794 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4795 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4797 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4798 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4800 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4803 /* left and right are both bit variables, result is carry */
4806 resolveIfx(&rIfx,ifx);
4808 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4809 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4810 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4811 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4816 /* They're not both bit variables. Is the right a literal? */
4817 if(AOP_TYPE(right) == AOP_LIT) {
4818 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4823 switch(lit & 0xff) {
4825 if ( IC_TRUE(ifx) ) {
4826 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4828 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4830 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4831 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4835 if ( IC_TRUE(ifx) ) {
4836 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4838 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4840 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4841 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4845 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4847 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4852 /* end of size == 1 */
4856 genc16bit2lit(left,lit,offset);
4859 /* end of size == 2 */
4864 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4865 emitpcode(POC_IORFW,popGet(AOP(left),1));
4866 emitpcode(POC_IORFW,popGet(AOP(left),2));
4867 emitpcode(POC_IORFW,popGet(AOP(left),3));
4871 /* search for patterns that can be optimized */
4873 genc16bit2lit(left,lit,0);
4876 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4878 genc16bit2lit(left,lit,2);
4880 emitpcode(POC_IORFW,popGet(AOP(left),2));
4881 emitpcode(POC_IORFW,popGet(AOP(left),3));
4894 } else if(AOP_TYPE(right) == AOP_CRY ) {
4895 /* we know the left is not a bit, but that the right is */
4896 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4897 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4898 popGet(AOP(right),offset));
4899 emitpcode(POC_XORLW,popGetLit(1));
4901 /* if the two are equal, then W will be 0 and the Z bit is set
4902 * we could test Z now, or go ahead and check the high order bytes if
4903 * the variable we're comparing is larger than a byte. */
4906 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4908 if ( IC_TRUE(ifx) ) {
4910 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4911 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4914 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4915 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4919 /* They're both variables that are larger than bits */
4922 tlbl = newiTempLabel(NULL);
4925 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4926 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4928 if ( IC_TRUE(ifx) ) {
4931 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4932 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4935 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4936 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4940 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4941 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4945 if(s>1 && IC_TRUE(ifx)) {
4946 emitpLabel(tlbl->key);
4947 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4951 /* mark the icode as generated */
4956 /* if they are both bit variables */
4957 if (AOP_TYPE(left) == AOP_CRY &&
4958 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4959 if(AOP_TYPE(right) == AOP_LIT){
4960 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4962 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4963 pic14_emitcode("cpl","c");
4964 } else if(lit == 1L) {
4965 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4967 pic14_emitcode("clr","c");
4969 /* AOP_TYPE(right) == AOP_CRY */
4971 symbol *lbl = newiTempLabel(NULL);
4972 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4973 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4974 pic14_emitcode("cpl","c");
4975 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4978 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4979 pic14_outBitC(result);
4983 genIfxJump (ifx,"c");
4986 /* if the result is used in an arithmetic operation
4987 then put the result in place */
4988 pic14_outBitC(result);
4991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4992 gencjne(left,right,result,ifx);
4995 gencjne(left,right,newiTempLabel(NULL));
4997 if(IC_TRUE(ifx)->key)
4998 gencjne(left,right,IC_TRUE(ifx)->key);
5000 gencjne(left,right,IC_FALSE(ifx)->key);
5004 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5005 aopPut(AOP(result),"a",0);
5010 genIfxJump (ifx,"a");
5014 /* if the result is used in an arithmetic operation
5015 then put the result in place */
5017 if (AOP_TYPE(result) != AOP_CRY)
5018 pic14_outAcc(result);
5020 /* leave the result in acc */
5024 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5025 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5026 freeAsmop(result,NULL,ic,TRUE);
5029 /*-----------------------------------------------------------------*/
5030 /* ifxForOp - returns the icode containing the ifx for operand */
5031 /*-----------------------------------------------------------------*/
5032 static iCode *ifxForOp ( operand *op, iCode *ic )
5034 /* if true symbol then needs to be assigned */
5035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5036 if (IS_TRUE_SYMOP(op))
5039 /* if this has register type condition and
5040 the next instruction is ifx with the same operand
5041 and live to of the operand is upto the ifx only then */
5043 ic->next->op == IFX &&
5044 IC_COND(ic->next)->key == op->key &&
5045 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5049 ic->next->op == IFX &&
5050 IC_COND(ic->next)->key == op->key) {
5051 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5055 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5057 ic->next->op == IFX)
5058 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5061 ic->next->op == IFX &&
5062 IC_COND(ic->next)->key == op->key) {
5063 DEBUGpic14_emitcode ("; "," key is okay");
5064 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5065 OP_SYMBOL(op)->liveTo,
5072 /*-----------------------------------------------------------------*/
5073 /* genAndOp - for && operation */
5074 /*-----------------------------------------------------------------*/
5075 static void genAndOp (iCode *ic)
5077 operand *left,*right, *result;
5080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5081 /* note here that && operations that are in an
5082 if statement are taken away by backPatchLabels
5083 only those used in arthmetic operations remain */
5084 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5085 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5086 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5088 DEBUGpic14_AopType(__LINE__,left,right,result);
5090 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5091 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5092 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5094 /* if both are bit variables */
5095 /* if (AOP_TYPE(left) == AOP_CRY && */
5096 /* AOP_TYPE(right) == AOP_CRY ) { */
5097 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5098 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5099 /* pic14_outBitC(result); */
5101 /* tlbl = newiTempLabel(NULL); */
5102 /* pic14_toBoolean(left); */
5103 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5104 /* pic14_toBoolean(right); */
5105 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5106 /* pic14_outBitAcc(result); */
5109 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5111 freeAsmop(result,NULL,ic,TRUE);
5115 /*-----------------------------------------------------------------*/
5116 /* genOrOp - for || operation */
5117 /*-----------------------------------------------------------------*/
5120 modified this code, but it doesn't appear to ever get called
5123 static void genOrOp (iCode *ic)
5125 operand *left,*right, *result;
5128 /* note here that || operations that are in an
5129 if statement are taken away by backPatchLabels
5130 only those used in arthmetic operations remain */
5131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5132 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5133 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5134 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5136 DEBUGpic14_AopType(__LINE__,left,right,result);
5138 /* if both are bit variables */
5139 if (AOP_TYPE(left) == AOP_CRY &&
5140 AOP_TYPE(right) == AOP_CRY ) {
5141 pic14_emitcode("clrc","");
5142 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5143 AOP(left)->aopu.aop_dir,
5144 AOP(left)->aopu.aop_dir);
5145 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5146 AOP(right)->aopu.aop_dir,
5147 AOP(right)->aopu.aop_dir);
5148 pic14_emitcode("setc","");
5151 tlbl = newiTempLabel(NULL);
5152 pic14_toBoolean(left);
5154 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5155 pic14_toBoolean(right);
5156 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5158 pic14_outBitAcc(result);
5161 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5162 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5163 freeAsmop(result,NULL,ic,TRUE);
5166 /*-----------------------------------------------------------------*/
5167 /* isLiteralBit - test if lit == 2^n */
5168 /*-----------------------------------------------------------------*/
5169 static int isLiteralBit(unsigned long lit)
5171 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5172 0x100L,0x200L,0x400L,0x800L,
5173 0x1000L,0x2000L,0x4000L,0x8000L,
5174 0x10000L,0x20000L,0x40000L,0x80000L,
5175 0x100000L,0x200000L,0x400000L,0x800000L,
5176 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5177 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5181 for(idx = 0; idx < 32; idx++)
5187 /*-----------------------------------------------------------------*/
5188 /* continueIfTrue - */
5189 /*-----------------------------------------------------------------*/
5190 static void continueIfTrue (iCode *ic)
5192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5194 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5198 /*-----------------------------------------------------------------*/
5200 /*-----------------------------------------------------------------*/
5201 static void jumpIfTrue (iCode *ic)
5203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5205 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5209 /*-----------------------------------------------------------------*/
5210 /* jmpTrueOrFalse - */
5211 /*-----------------------------------------------------------------*/
5212 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5214 // ugly but optimized by peephole
5215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5217 symbol *nlbl = newiTempLabel(NULL);
5218 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5219 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5220 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5221 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5224 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5225 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5230 /*-----------------------------------------------------------------*/
5231 /* genAnd - code for and */
5232 /*-----------------------------------------------------------------*/
5233 static void genAnd (iCode *ic, iCode *ifx)
5235 operand *left, *right, *result;
5237 unsigned long lit = 0L;
5242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5243 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5244 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5245 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5247 resolveIfx(&rIfx,ifx);
5249 /* if left is a literal & right is not then exchange them */
5250 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5251 AOP_NEEDSACC(left)) {
5252 operand *tmp = right ;
5257 /* if result = right then exchange them */
5258 if(pic14_sameRegs(AOP(result),AOP(right))){
5259 operand *tmp = right ;
5264 /* if right is bit then exchange them */
5265 if (AOP_TYPE(right) == AOP_CRY &&
5266 AOP_TYPE(left) != AOP_CRY){
5267 operand *tmp = right ;
5271 if(AOP_TYPE(right) == AOP_LIT)
5272 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5274 size = AOP_SIZE(result);
5276 DEBUGpic14_AopType(__LINE__,left,right,result);
5279 // result = bit & yy;
5280 if (AOP_TYPE(left) == AOP_CRY){
5281 // c = bit & literal;
5282 if(AOP_TYPE(right) == AOP_LIT){
5284 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5287 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5290 if(size && (AOP_TYPE(result) == AOP_CRY)){
5291 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5294 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5298 pic14_emitcode("clr","c");
5301 if (AOP_TYPE(right) == AOP_CRY){
5303 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5304 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5307 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5309 pic14_emitcode("rrc","a");
5310 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5316 pic14_outBitC(result);
5318 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5319 genIfxJump(ifx, "c");
5323 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5324 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5325 if((AOP_TYPE(right) == AOP_LIT) &&
5326 (AOP_TYPE(result) == AOP_CRY) &&
5327 (AOP_TYPE(left) != AOP_CRY)){
5328 int posbit = isLiteralBit(lit);
5332 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5335 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5341 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5342 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5344 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5345 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5348 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5349 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5350 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5357 symbol *tlbl = newiTempLabel(NULL);
5358 int sizel = AOP_SIZE(left);
5360 pic14_emitcode("setb","c");
5362 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5363 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5365 if((posbit = isLiteralBit(bytelit)) != 0)
5366 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5368 if(bytelit != 0x0FFL)
5369 pic14_emitcode("anl","a,%s",
5370 aopGet(AOP(right),offset,FALSE,TRUE));
5371 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5376 // bit = left & literal
5378 pic14_emitcode("clr","c");
5379 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5381 // if(left & literal)
5384 jmpTrueOrFalse(ifx, tlbl);
5388 pic14_outBitC(result);
5392 /* if left is same as result */
5393 if(pic14_sameRegs(AOP(result),AOP(left))){
5395 for(;size--; offset++,lit>>=8) {
5396 if(AOP_TYPE(right) == AOP_LIT){
5397 switch(lit & 0xff) {
5399 /* and'ing with 0 has clears the result */
5400 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5401 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5404 /* and'ing with 0xff is a nop when the result and left are the same */
5409 int p = my_powof2( (~lit) & 0xff );
5411 /* only one bit is set in the literal, so use a bcf instruction */
5412 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5413 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5416 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5417 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5418 if(know_W != (lit&0xff))
5419 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5421 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5426 if (AOP_TYPE(left) == AOP_ACC) {
5427 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5429 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5430 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5437 // left & result in different registers
5438 if(AOP_TYPE(result) == AOP_CRY){
5440 // if(size), result in bit
5441 // if(!size && ifx), conditional oper: if(left & right)
5442 symbol *tlbl = newiTempLabel(NULL);
5443 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5445 pic14_emitcode("setb","c");
5447 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5448 pic14_emitcode("anl","a,%s",
5449 aopGet(AOP(left),offset,FALSE,FALSE));
5450 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5455 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5456 pic14_outBitC(result);
5458 jmpTrueOrFalse(ifx, tlbl);
5460 for(;(size--);offset++) {
5462 // result = left & right
5463 if(AOP_TYPE(right) == AOP_LIT){
5464 int t = (lit >> (offset*8)) & 0x0FFL;
5467 pic14_emitcode("clrf","%s",
5468 aopGet(AOP(result),offset,FALSE,FALSE));
5469 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5472 if(AOP_TYPE(left) == AOP_ACC) {
5473 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5475 pic14_emitcode("movf","%s,w",
5476 aopGet(AOP(left),offset,FALSE,FALSE));
5477 pic14_emitcode("movwf","%s",
5478 aopGet(AOP(result),offset,FALSE,FALSE));
5479 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5480 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5484 if(AOP_TYPE(left) == AOP_ACC) {
5485 emitpcode(POC_ANDLW, popGetLit(t));
5486 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5488 pic14_emitcode("movlw","0x%x",t);
5489 pic14_emitcode("andwf","%s,w",
5490 aopGet(AOP(left),offset,FALSE,FALSE));
5491 pic14_emitcode("movwf","%s",
5492 aopGet(AOP(result),offset,FALSE,FALSE));
5494 emitpcode(POC_MOVLW, popGetLit(t));
5495 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5496 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5502 if (AOP_TYPE(left) == AOP_ACC) {
5503 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5504 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5506 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5507 pic14_emitcode("andwf","%s,w",
5508 aopGet(AOP(left),offset,FALSE,FALSE));
5509 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5510 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5512 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5513 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5519 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5520 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521 freeAsmop(result,NULL,ic,TRUE);
5524 /*-----------------------------------------------------------------*/
5525 /* genOr - code for or */
5526 /*-----------------------------------------------------------------*/
5527 static void genOr (iCode *ic, iCode *ifx)
5529 operand *left, *right, *result;
5531 unsigned long lit = 0L;
5533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5535 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5536 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5537 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5539 DEBUGpic14_AopType(__LINE__,left,right,result);
5541 /* if left is a literal & right is not then exchange them */
5542 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5543 AOP_NEEDSACC(left)) {
5544 operand *tmp = right ;
5549 /* if result = right then exchange them */
5550 if(pic14_sameRegs(AOP(result),AOP(right))){
5551 operand *tmp = right ;
5556 /* if right is bit then exchange them */
5557 if (AOP_TYPE(right) == AOP_CRY &&
5558 AOP_TYPE(left) != AOP_CRY){
5559 operand *tmp = right ;
5564 DEBUGpic14_AopType(__LINE__,left,right,result);
5566 if(AOP_TYPE(right) == AOP_LIT)
5567 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5569 size = AOP_SIZE(result);
5573 if (AOP_TYPE(left) == AOP_CRY){
5574 if(AOP_TYPE(right) == AOP_LIT){
5575 // c = bit & literal;
5577 // lit != 0 => result = 1
5578 if(AOP_TYPE(result) == AOP_CRY){
5580 emitpcode(POC_BSF, popGet(AOP(result),0));
5581 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5582 // AOP(result)->aopu.aop_dir,
5583 // AOP(result)->aopu.aop_dir);
5585 continueIfTrue(ifx);
5589 // lit == 0 => result = left
5590 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5592 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5595 if (AOP_TYPE(right) == AOP_CRY){
5596 if(pic14_sameRegs(AOP(result),AOP(left))){
5598 emitpcode(POC_BCF, popGet(AOP(result),0));
5599 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5600 emitpcode(POC_BSF, popGet(AOP(result),0));
5602 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5603 AOP(result)->aopu.aop_dir,
5604 AOP(result)->aopu.aop_dir);
5605 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5606 AOP(right)->aopu.aop_dir,
5607 AOP(right)->aopu.aop_dir);
5608 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5609 AOP(result)->aopu.aop_dir,
5610 AOP(result)->aopu.aop_dir);
5612 if( AOP_TYPE(result) == AOP_ACC) {
5613 emitpcode(POC_MOVLW, popGetLit(0));
5614 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5615 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5616 emitpcode(POC_MOVLW, popGetLit(1));
5620 emitpcode(POC_BCF, popGet(AOP(result),0));
5621 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5622 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5623 emitpcode(POC_BSF, popGet(AOP(result),0));
5625 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5626 AOP(result)->aopu.aop_dir,
5627 AOP(result)->aopu.aop_dir);
5628 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5629 AOP(right)->aopu.aop_dir,
5630 AOP(right)->aopu.aop_dir);
5631 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5632 AOP(left)->aopu.aop_dir,
5633 AOP(left)->aopu.aop_dir);
5634 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5635 AOP(result)->aopu.aop_dir,
5636 AOP(result)->aopu.aop_dir);
5641 symbol *tlbl = newiTempLabel(NULL);
5642 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5645 emitpcode(POC_BCF, popGet(AOP(result),0));
5646 if( AOP_TYPE(right) == AOP_ACC) {
5647 emitpcode(POC_IORLW, popGetLit(0));
5649 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5650 emitpcode(POC_BSF, popGet(AOP(result),0));
5655 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5656 pic14_emitcode(";XXX setb","c");
5657 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5658 AOP(left)->aopu.aop_dir,tlbl->key+100);
5659 pic14_toBoolean(right);
5660 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5661 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5662 jmpTrueOrFalse(ifx, tlbl);
5666 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5673 pic14_outBitC(result);
5675 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5676 genIfxJump(ifx, "c");
5680 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5681 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5682 if((AOP_TYPE(right) == AOP_LIT) &&
5683 (AOP_TYPE(result) == AOP_CRY) &&
5684 (AOP_TYPE(left) != AOP_CRY)){
5686 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5689 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5691 continueIfTrue(ifx);
5694 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5695 // lit = 0, result = boolean(left)
5697 pic14_emitcode(";XXX setb","c");
5698 pic14_toBoolean(right);
5700 symbol *tlbl = newiTempLabel(NULL);
5701 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5703 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5705 genIfxJump (ifx,"a");
5709 pic14_outBitC(result);
5713 /* if left is same as result */
5714 if(pic14_sameRegs(AOP(result),AOP(left))){
5716 for(;size--; offset++,lit>>=8) {
5717 if(AOP_TYPE(right) == AOP_LIT){
5718 if((lit & 0xff) == 0)
5719 /* or'ing with 0 has no effect */
5722 int p = my_powof2(lit & 0xff);
5724 /* only one bit is set in the literal, so use a bsf instruction */
5726 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5728 if(know_W != (lit & 0xff))
5729 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5730 know_W = lit & 0xff;
5731 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5736 if (AOP_TYPE(left) == AOP_ACC) {
5737 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5738 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5740 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5741 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5743 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5744 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5750 // left & result in different registers
5751 if(AOP_TYPE(result) == AOP_CRY){
5753 // if(size), result in bit
5754 // if(!size && ifx), conditional oper: if(left | right)
5755 symbol *tlbl = newiTempLabel(NULL);
5756 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5757 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5761 pic14_emitcode(";XXX setb","c");
5763 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5764 pic14_emitcode(";XXX orl","a,%s",
5765 aopGet(AOP(left),offset,FALSE,FALSE));
5766 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5771 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5772 pic14_outBitC(result);
5774 jmpTrueOrFalse(ifx, tlbl);
5775 } else for(;(size--);offset++){
5777 // result = left & right
5778 if(AOP_TYPE(right) == AOP_LIT){
5779 int t = (lit >> (offset*8)) & 0x0FFL;
5782 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5783 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5785 pic14_emitcode("movf","%s,w",
5786 aopGet(AOP(left),offset,FALSE,FALSE));
5787 pic14_emitcode("movwf","%s",
5788 aopGet(AOP(result),offset,FALSE,FALSE));
5791 emitpcode(POC_MOVLW, popGetLit(t));
5792 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5793 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5795 pic14_emitcode("movlw","0x%x",t);
5796 pic14_emitcode("iorwf","%s,w",
5797 aopGet(AOP(left),offset,FALSE,FALSE));
5798 pic14_emitcode("movwf","%s",
5799 aopGet(AOP(result),offset,FALSE,FALSE));
5805 // faster than result <- left, anl result,right
5806 // and better if result is SFR
5807 if (AOP_TYPE(left) == AOP_ACC) {
5808 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5809 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5811 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5812 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5814 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5815 pic14_emitcode("iorwf","%s,w",
5816 aopGet(AOP(left),offset,FALSE,FALSE));
5818 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5819 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5824 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5825 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826 freeAsmop(result,NULL,ic,TRUE);
5829 /*-----------------------------------------------------------------*/
5830 /* genXor - code for xclusive or */
5831 /*-----------------------------------------------------------------*/
5832 static void genXor (iCode *ic, iCode *ifx)
5834 operand *left, *right, *result;
5836 unsigned long lit = 0L;
5838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5840 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5841 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5842 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5844 /* if left is a literal & right is not ||
5845 if left needs acc & right does not */
5846 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5847 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5848 operand *tmp = right ;
5853 /* if result = right then exchange them */
5854 if(pic14_sameRegs(AOP(result),AOP(right))){
5855 operand *tmp = right ;
5860 /* if right is bit then exchange them */
5861 if (AOP_TYPE(right) == AOP_CRY &&
5862 AOP_TYPE(left) != AOP_CRY){
5863 operand *tmp = right ;
5867 if(AOP_TYPE(right) == AOP_LIT)
5868 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5870 size = AOP_SIZE(result);
5874 if (AOP_TYPE(left) == AOP_CRY){
5875 if(AOP_TYPE(right) == AOP_LIT){
5876 // c = bit & literal;
5878 // lit>>1 != 0 => result = 1
5879 if(AOP_TYPE(result) == AOP_CRY){
5881 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5882 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5884 continueIfTrue(ifx);
5887 pic14_emitcode("setb","c");
5891 // lit == 0, result = left
5892 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5894 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5896 // lit == 1, result = not(left)
5897 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5898 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5899 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5900 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5903 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5904 pic14_emitcode("cpl","c");
5911 symbol *tlbl = newiTempLabel(NULL);
5912 if (AOP_TYPE(right) == AOP_CRY){
5914 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5917 int sizer = AOP_SIZE(right);
5919 // if val>>1 != 0, result = 1
5920 pic14_emitcode("setb","c");
5922 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5924 // test the msb of the lsb
5925 pic14_emitcode("anl","a,#0xfe");
5926 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5930 pic14_emitcode("rrc","a");
5932 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5933 pic14_emitcode("cpl","c");
5934 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5939 pic14_outBitC(result);
5941 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5942 genIfxJump(ifx, "c");
5946 if(pic14_sameRegs(AOP(result),AOP(left))){
5947 /* if left is same as result */
5948 for(;size--; offset++) {
5949 if(AOP_TYPE(right) == AOP_LIT){
5950 int t = (lit >> (offset*8)) & 0x0FFL;
5954 if (IS_AOP_PREG(left)) {
5955 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5956 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5957 aopPut(AOP(result),"a",offset);
5959 emitpcode(POC_MOVLW, popGetLit(t));
5960 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5961 pic14_emitcode("xrl","%s,%s",
5962 aopGet(AOP(left),offset,FALSE,TRUE),
5963 aopGet(AOP(right),offset,FALSE,FALSE));
5966 if (AOP_TYPE(left) == AOP_ACC)
5967 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5969 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5970 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5972 if (IS_AOP_PREG(left)) {
5973 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5974 aopPut(AOP(result),"a",offset);
5976 pic14_emitcode("xrl","%s,a",
5977 aopGet(AOP(left),offset,FALSE,TRUE));
5983 // left & result in different registers
5984 if(AOP_TYPE(result) == AOP_CRY){
5986 // if(size), result in bit
5987 // if(!size && ifx), conditional oper: if(left ^ right)
5988 symbol *tlbl = newiTempLabel(NULL);
5989 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5991 pic14_emitcode("setb","c");
5993 if((AOP_TYPE(right) == AOP_LIT) &&
5994 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5995 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5997 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5998 pic14_emitcode("xrl","a,%s",
5999 aopGet(AOP(left),offset,FALSE,FALSE));
6001 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6006 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6007 pic14_outBitC(result);
6009 jmpTrueOrFalse(ifx, tlbl);
6010 } else for(;(size--);offset++){
6012 // result = left & right
6013 if(AOP_TYPE(right) == AOP_LIT){
6014 int t = (lit >> (offset*8)) & 0x0FFL;
6017 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6018 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6019 pic14_emitcode("movf","%s,w",
6020 aopGet(AOP(left),offset,FALSE,FALSE));
6021 pic14_emitcode("movwf","%s",
6022 aopGet(AOP(result),offset,FALSE,FALSE));
6025 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6026 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027 pic14_emitcode("comf","%s,w",
6028 aopGet(AOP(left),offset,FALSE,FALSE));
6029 pic14_emitcode("movwf","%s",
6030 aopGet(AOP(result),offset,FALSE,FALSE));
6033 emitpcode(POC_MOVLW, popGetLit(t));
6034 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6035 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6036 pic14_emitcode("movlw","0x%x",t);
6037 pic14_emitcode("xorwf","%s,w",
6038 aopGet(AOP(left),offset,FALSE,FALSE));
6039 pic14_emitcode("movwf","%s",
6040 aopGet(AOP(result),offset,FALSE,FALSE));
6046 // faster than result <- left, anl result,right
6047 // and better if result is SFR
6048 if (AOP_TYPE(left) == AOP_ACC) {
6049 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6050 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6052 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6053 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6054 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6055 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6057 if ( AOP_TYPE(result) != AOP_ACC){
6058 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6059 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6065 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6066 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067 freeAsmop(result,NULL,ic,TRUE);
6070 /*-----------------------------------------------------------------*/
6071 /* genInline - write the inline code out */
6072 /*-----------------------------------------------------------------*/
6073 static void genInline (iCode *ic)
6075 char *buffer, *bp, *bp1;
6077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6079 _G.inLine += (!options.asmpeep);
6081 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6082 strcpy(buffer,IC_INLINE(ic));
6084 /* emit each line as a code */
6090 addpCode2pBlock(pb,AssembleLine(bp1));
6097 pic14_emitcode(bp1,"");
6103 if ((bp1 != bp) && *bp1)
6104 addpCode2pBlock(pb,AssembleLine(bp1));
6108 _G.inLine -= (!options.asmpeep);
6111 /*-----------------------------------------------------------------*/
6112 /* genRRC - rotate right with carry */
6113 /*-----------------------------------------------------------------*/
6114 static void genRRC (iCode *ic)
6116 operand *left , *result ;
6117 int size, offset = 0, same;
6119 /* rotate right with carry */
6121 result=IC_RESULT(ic);
6122 aopOp (left,ic,FALSE);
6123 aopOp (result,ic,FALSE);
6125 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6127 same = pic14_sameRegs(AOP(result),AOP(left));
6129 size = AOP_SIZE(result);
6131 /* get the lsb and put it into the carry */
6132 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6139 emitpcode(POC_RRF, popGet(AOP(left),offset));
6141 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6142 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6148 freeAsmop(left,NULL,ic,TRUE);
6149 freeAsmop(result,NULL,ic,TRUE);
6152 /*-----------------------------------------------------------------*/
6153 /* genRLC - generate code for rotate left with carry */
6154 /*-----------------------------------------------------------------*/
6155 static void genRLC (iCode *ic)
6157 operand *left , *result ;
6158 int size, offset = 0;
6161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6162 /* rotate right with carry */
6164 result=IC_RESULT(ic);
6165 aopOp (left,ic,FALSE);
6166 aopOp (result,ic,FALSE);
6168 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6170 same = pic14_sameRegs(AOP(result),AOP(left));
6172 /* move it to the result */
6173 size = AOP_SIZE(result);
6175 /* get the msb and put it into the carry */
6176 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6183 emitpcode(POC_RLF, popGet(AOP(left),offset));
6185 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6186 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6193 freeAsmop(left,NULL,ic,TRUE);
6194 freeAsmop(result,NULL,ic,TRUE);
6197 /*-----------------------------------------------------------------*/
6198 /* genGetHbit - generates code get highest order bit */
6199 /*-----------------------------------------------------------------*/
6200 static void genGetHbit (iCode *ic)
6202 operand *left, *result;
6204 result=IC_RESULT(ic);
6205 aopOp (left,ic,FALSE);
6206 aopOp (result,ic,FALSE);
6208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6209 /* get the highest order byte into a */
6210 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6211 if(AOP_TYPE(result) == AOP_CRY){
6212 pic14_emitcode("rlc","a");
6213 pic14_outBitC(result);
6216 pic14_emitcode("rl","a");
6217 pic14_emitcode("anl","a,#0x01");
6218 pic14_outAcc(result);
6222 freeAsmop(left,NULL,ic,TRUE);
6223 freeAsmop(result,NULL,ic,TRUE);
6226 /*-----------------------------------------------------------------*/
6227 /* AccRol - rotate left accumulator by known count */
6228 /*-----------------------------------------------------------------*/
6229 static void AccRol (int shCount)
6231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6232 shCount &= 0x0007; // shCount : 0..7
6237 pic14_emitcode("rl","a");
6240 pic14_emitcode("rl","a");
6241 pic14_emitcode("rl","a");
6244 pic14_emitcode("swap","a");
6245 pic14_emitcode("rr","a");
6248 pic14_emitcode("swap","a");
6251 pic14_emitcode("swap","a");
6252 pic14_emitcode("rl","a");
6255 pic14_emitcode("rr","a");
6256 pic14_emitcode("rr","a");
6259 pic14_emitcode("rr","a");
6264 /*-----------------------------------------------------------------*/
6265 /* AccLsh - left shift accumulator by known count */
6266 /*-----------------------------------------------------------------*/
6267 static void AccLsh (int shCount)
6269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6272 pic14_emitcode("add","a,acc");
6275 pic14_emitcode("add","a,acc");
6276 pic14_emitcode("add","a,acc");
6278 /* rotate left accumulator */
6280 /* and kill the lower order bits */
6281 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6286 /*-----------------------------------------------------------------*/
6287 /* AccRsh - right shift accumulator by known count */
6288 /*-----------------------------------------------------------------*/
6289 static void AccRsh (int shCount)
6291 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6295 pic14_emitcode("rrc","a");
6297 /* rotate right accumulator */
6298 AccRol(8 - shCount);
6299 /* and kill the higher order bits */
6300 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6306 /*-----------------------------------------------------------------*/
6307 /* AccSRsh - signed right shift accumulator by known count */
6308 /*-----------------------------------------------------------------*/
6309 static void AccSRsh (int shCount)
6312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6315 pic14_emitcode("mov","c,acc.7");
6316 pic14_emitcode("rrc","a");
6317 } else if(shCount == 2){
6318 pic14_emitcode("mov","c,acc.7");
6319 pic14_emitcode("rrc","a");
6320 pic14_emitcode("mov","c,acc.7");
6321 pic14_emitcode("rrc","a");
6323 tlbl = newiTempLabel(NULL);
6324 /* rotate right accumulator */
6325 AccRol(8 - shCount);
6326 /* and kill the higher order bits */
6327 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6328 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6329 pic14_emitcode("orl","a,#0x%02x",
6330 (unsigned char)~SRMask[shCount]);
6331 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6336 /*-----------------------------------------------------------------*/
6337 /* shiftR1Left2Result - shift right one byte from left to result */
6338 /*-----------------------------------------------------------------*/
6339 static void shiftR1Left2ResultSigned (operand *left, int offl,
6340 operand *result, int offr,
6345 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6347 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6351 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6353 emitpcode(POC_RRF, popGet(AOP(result),offr));
6355 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6356 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6362 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6364 emitpcode(POC_RRF, popGet(AOP(result),offr));
6366 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6367 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6369 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6370 emitpcode(POC_RRF, popGet(AOP(result),offr));
6376 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6378 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6379 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6382 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6383 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6384 emitpcode(POC_ANDLW, popGetLit(0x1f));
6386 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6387 emitpcode(POC_IORLW, popGetLit(0xe0));
6389 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6393 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6394 emitpcode(POC_ANDLW, popGetLit(0x0f));
6395 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6396 emitpcode(POC_IORLW, popGetLit(0xf0));
6397 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6401 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6403 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6404 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6407 emitpcode(POC_ANDLW, popGetLit(0x07));
6408 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6409 emitpcode(POC_IORLW, popGetLit(0xf8));
6410 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415 emitpcode(POC_MOVLW, popGetLit(0x00));
6416 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6417 emitpcode(POC_MOVLW, popGetLit(0xfe));
6418 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6419 emitpcode(POC_IORLW, popGetLit(0x01));
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));
6425 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6426 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6432 emitpcode(POC_MOVLW, popGetLit(0x00));
6433 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6434 emitpcode(POC_MOVLW, popGetLit(0xff));
6435 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6437 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6438 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6439 emitpcode(POC_DECF, popGet(AOP(result),offr));
6447 /*-----------------------------------------------------------------*/
6448 /* shiftR1Left2Result - shift right one byte from left to result */
6449 /*-----------------------------------------------------------------*/
6450 static void shiftR1Left2Result (operand *left, int offl,
6451 operand *result, int offr,
6452 int shCount, int sign)
6456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6458 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6460 /* Copy the msb into the carry if signed. */
6462 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6472 emitpcode(POC_RRF, popGet(AOP(result),offr));
6474 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6481 emitpcode(POC_RRF, popGet(AOP(result),offr));
6483 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6484 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6487 emitpcode(POC_RRF, popGet(AOP(result),offr));
6492 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6494 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6495 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6498 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6499 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6500 emitpcode(POC_ANDLW, popGetLit(0x1f));
6501 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6506 emitpcode(POC_ANDLW, popGetLit(0x0f));
6507 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6511 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW, popGetLit(0x0f));
6513 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6515 emitpcode(POC_RRF, popGet(AOP(result),offr));
6520 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6521 emitpcode(POC_ANDLW, popGetLit(0x80));
6522 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6523 emitpcode(POC_RLF, popGet(AOP(result),offr));
6524 emitpcode(POC_RLF, popGet(AOP(result),offr));
6529 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6530 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6531 emitpcode(POC_RLF, popGet(AOP(result),offr));
6540 /*-----------------------------------------------------------------*/
6541 /* shiftL1Left2Result - shift left one byte from left to result */
6542 /*-----------------------------------------------------------------*/
6543 static void shiftL1Left2Result (operand *left, int offl,
6544 operand *result, int offr, int shCount)
6549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6551 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6552 DEBUGpic14_emitcode ("; ***","same = %d",same);
6553 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6555 /* shift left accumulator */
6556 //AccLsh(shCount); // don't comment out just yet...
6557 // aopPut(AOP(result),"a",offr);
6561 /* Shift left 1 bit position */
6562 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6564 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6566 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6567 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6571 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6572 emitpcode(POC_ANDLW,popGetLit(0x7e));
6573 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6574 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6577 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6578 emitpcode(POC_ANDLW,popGetLit(0x3e));
6579 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6580 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6581 emitpcode(POC_RLF, popGet(AOP(result),offr));
6584 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6585 emitpcode(POC_ANDLW, popGetLit(0xf0));
6586 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6590 emitpcode(POC_ANDLW, popGetLit(0xf0));
6591 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6592 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6595 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6596 emitpcode(POC_ANDLW, popGetLit(0x30));
6597 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6598 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6599 emitpcode(POC_RLF, popGet(AOP(result),offr));
6602 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6603 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6604 emitpcode(POC_RRF, popGet(AOP(result),offr));
6608 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6613 /*-----------------------------------------------------------------*/
6614 /* movLeft2Result - move byte from left to result */
6615 /*-----------------------------------------------------------------*/
6616 static void movLeft2Result (operand *left, int offl,
6617 operand *result, int offr)
6620 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6621 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6622 l = aopGet(AOP(left),offl,FALSE,FALSE);
6624 if (*l == '@' && (IS_AOP_PREG(result))) {
6625 pic14_emitcode("mov","a,%s",l);
6626 aopPut(AOP(result),"a",offr);
6628 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6629 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6634 /*-----------------------------------------------------------------*/
6635 /* shiftL2Left2Result - shift left two bytes from left to result */
6636 /*-----------------------------------------------------------------*/
6637 static void shiftL2Left2Result (operand *left, int offl,
6638 operand *result, int offr, int shCount)
6642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6644 if(pic14_sameRegs(AOP(result), AOP(left))) {
6652 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6653 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6654 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_RLF, popGet(AOP(result),offr));
6659 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6665 emitpcode(POC_MOVLW, popGetLit(0x0f));
6666 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6669 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6670 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6671 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6673 emitpcode(POC_RLF, popGet(AOP(result),offr));
6674 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6679 emitpcode(POC_RRF, popGet(AOP(result),offr));
6680 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_RRF, popGet(AOP(result),offr));
6682 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_ANDLW,popGetLit(0xc0));
6684 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6685 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6686 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6690 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6691 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6692 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6693 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6694 emitpcode(POC_RRF, popGet(AOP(result),offr));
6704 /* note, use a mov/add for the shift since the mov has a
6705 chance of getting optimized out */
6706 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6707 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6708 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6709 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6710 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6714 emitpcode(POC_RLF, popGet(AOP(result),offr));
6715 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6721 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6722 emitpcode(POC_ANDLW, popGetLit(0xF0));
6723 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6724 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6725 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6726 emitpcode(POC_ANDLW, popGetLit(0xF0));
6727 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6728 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6732 emitpcode(POC_RLF, popGet(AOP(result),offr));
6733 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6737 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6738 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6740 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6742 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_RRF, popGet(AOP(result),offr));
6744 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6745 emitpcode(POC_ANDLW,popGetLit(0xc0));
6746 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6747 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6748 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6749 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6752 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6753 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6754 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6756 emitpcode(POC_RRF, popGet(AOP(result),offr));
6761 /*-----------------------------------------------------------------*/
6762 /* shiftR2Left2Result - shift right two bytes from left to result */
6763 /*-----------------------------------------------------------------*/
6764 static void shiftR2Left2Result (operand *left, int offl,
6765 operand *result, int offr,
6766 int shCount, int sign)
6770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6771 same = pic14_sameRegs(AOP(result), AOP(left));
6773 if(same && ((offl + MSB16) == offr)){
6775 /* don't crash result[offr] */
6776 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6777 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6780 movLeft2Result(left,offl, result, offr);
6781 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6784 /* a:x >> shCount (x = lsb(result))*/
6787 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6789 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6798 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6804 emitpcode(POC_RRF,popGet(AOP(result),offr));
6806 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6807 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6809 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6814 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6818 emitpcode(POC_RRF,popGet(AOP(result),offr));
6825 emitpcode(POC_MOVLW, popGetLit(0xf0));
6826 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6827 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6829 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6830 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6832 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6834 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6835 emitpcode(POC_ANDLW, popGetLit(0x0f));
6836 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6838 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6839 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6840 emitpcode(POC_ANDLW, popGetLit(0xf0));
6841 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6842 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6846 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6847 emitpcode(POC_RRF, popGet(AOP(result),offr));
6851 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6852 emitpcode(POC_BTFSC,
6853 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6854 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6862 emitpcode(POC_RLF, popGet(AOP(result),offr));
6863 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6865 emitpcode(POC_RLF, popGet(AOP(result),offr));
6866 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6867 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6868 emitpcode(POC_ANDLW,popGetLit(0x03));
6870 emitpcode(POC_BTFSC,
6871 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6872 emitpcode(POC_IORLW,popGetLit(0xfc));
6874 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6875 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6876 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6879 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6880 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6881 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6882 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6883 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6884 emitpcode(POC_RLF, popGet(AOP(result),offr));
6885 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6886 emitpcode(POC_ANDLW,popGetLit(0x03));
6888 emitpcode(POC_BTFSC,
6889 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6890 emitpcode(POC_IORLW,popGetLit(0xfc));
6892 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6893 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6900 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6901 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6902 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6903 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6906 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6908 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6913 /*-----------------------------------------------------------------*/
6914 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6915 /*-----------------------------------------------------------------*/
6916 static void shiftLLeftOrResult (operand *left, int offl,
6917 operand *result, int offr, int shCount)
6919 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6920 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6921 /* shift left accumulator */
6923 /* or with result */
6924 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6925 /* back to result */
6926 aopPut(AOP(result),"a",offr);
6929 /*-----------------------------------------------------------------*/
6930 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6931 /*-----------------------------------------------------------------*/
6932 static void shiftRLeftOrResult (operand *left, int offl,
6933 operand *result, int offr, int shCount)
6935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6936 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6937 /* shift right accumulator */
6939 /* or with result */
6940 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6941 /* back to result */
6942 aopPut(AOP(result),"a",offr);
6945 /*-----------------------------------------------------------------*/
6946 /* genlshOne - left shift a one byte quantity by known count */
6947 /*-----------------------------------------------------------------*/
6948 static void genlshOne (operand *result, operand *left, int shCount)
6950 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6951 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6954 /*-----------------------------------------------------------------*/
6955 /* genlshTwo - left shift two bytes by known amount != 0 */
6956 /*-----------------------------------------------------------------*/
6957 static void genlshTwo (operand *result,operand *left, int shCount)
6961 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6962 size = pic14_getDataSize(result);
6964 /* if shCount >= 8 */
6970 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6972 movLeft2Result(left, LSB, result, MSB16);
6974 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6977 /* 1 <= shCount <= 7 */
6980 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6982 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6986 /*-----------------------------------------------------------------*/
6987 /* shiftLLong - shift left one long from left to result */
6988 /* offl = LSB or MSB16 */
6989 /*-----------------------------------------------------------------*/
6990 static void shiftLLong (operand *left, operand *result, int offr )
6993 int size = AOP_SIZE(result);
6995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6996 if(size >= LSB+offr){
6997 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6999 pic14_emitcode("add","a,acc");
7000 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7001 size >= MSB16+offr && offr != LSB )
7002 pic14_emitcode("xch","a,%s",
7003 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7005 aopPut(AOP(result),"a",LSB+offr);
7008 if(size >= MSB16+offr){
7009 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7010 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7013 pic14_emitcode("rlc","a");
7014 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7015 size >= MSB24+offr && offr != LSB)
7016 pic14_emitcode("xch","a,%s",
7017 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7019 aopPut(AOP(result),"a",MSB16+offr);
7022 if(size >= MSB24+offr){
7023 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7024 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7027 pic14_emitcode("rlc","a");
7028 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7029 size >= MSB32+offr && offr != LSB )
7030 pic14_emitcode("xch","a,%s",
7031 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7033 aopPut(AOP(result),"a",MSB24+offr);
7036 if(size > MSB32+offr){
7037 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7038 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7041 pic14_emitcode("rlc","a");
7042 aopPut(AOP(result),"a",MSB32+offr);
7045 aopPut(AOP(result),zero,LSB);
7048 /*-----------------------------------------------------------------*/
7049 /* genlshFour - shift four byte by a known amount != 0 */
7050 /*-----------------------------------------------------------------*/
7051 static void genlshFour (operand *result, operand *left, int shCount)
7055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7056 size = AOP_SIZE(result);
7058 /* if shifting more that 3 bytes */
7059 if (shCount >= 24 ) {
7062 /* lowest order of left goes to the highest
7063 order of the destination */
7064 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7066 movLeft2Result(left, LSB, result, MSB32);
7067 aopPut(AOP(result),zero,LSB);
7068 aopPut(AOP(result),zero,MSB16);
7069 aopPut(AOP(result),zero,MSB32);
7073 /* more than two bytes */
7074 else if ( shCount >= 16 ) {
7075 /* lower order two bytes goes to higher order two bytes */
7077 /* if some more remaining */
7079 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7081 movLeft2Result(left, MSB16, result, MSB32);
7082 movLeft2Result(left, LSB, result, MSB24);
7084 aopPut(AOP(result),zero,MSB16);
7085 aopPut(AOP(result),zero,LSB);
7089 /* if more than 1 byte */
7090 else if ( shCount >= 8 ) {
7091 /* lower order three bytes goes to higher order three bytes */
7095 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7097 movLeft2Result(left, LSB, result, MSB16);
7099 else{ /* size = 4 */
7101 movLeft2Result(left, MSB24, result, MSB32);
7102 movLeft2Result(left, MSB16, result, MSB24);
7103 movLeft2Result(left, LSB, result, MSB16);
7104 aopPut(AOP(result),zero,LSB);
7106 else if(shCount == 1)
7107 shiftLLong(left, result, MSB16);
7109 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7110 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7111 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7112 aopPut(AOP(result),zero,LSB);
7117 /* 1 <= shCount <= 7 */
7118 else if(shCount <= 2){
7119 shiftLLong(left, result, LSB);
7121 shiftLLong(result, result, LSB);
7123 /* 3 <= shCount <= 7, optimize */
7125 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7126 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7127 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7131 /*-----------------------------------------------------------------*/
7132 /* genLeftShiftLiteral - left shifting by known count */
7133 /*-----------------------------------------------------------------*/
7134 static void genLeftShiftLiteral (operand *left,
7139 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7143 freeAsmop(right,NULL,ic,TRUE);
7145 aopOp(left,ic,FALSE);
7146 aopOp(result,ic,FALSE);
7148 size = getSize(operandType(result));
7151 pic14_emitcode("; shift left ","result %d, left %d",size,
7155 /* I suppose that the left size >= result size */
7158 movLeft2Result(left, size, result, size);
7162 else if(shCount >= (size * 8))
7164 aopPut(AOP(result),zero,size);
7168 genlshOne (result,left,shCount);
7173 genlshTwo (result,left,shCount);
7177 genlshFour (result,left,shCount);
7181 freeAsmop(left,NULL,ic,TRUE);
7182 freeAsmop(result,NULL,ic,TRUE);
7185 /*-----------------------------------------------------------------*
7186 * genMultiAsm - repeat assembly instruction for size of register.
7187 * if endian == 1, then the high byte (i.e base address + size of
7188 * register) is used first else the low byte is used first;
7189 *-----------------------------------------------------------------*/
7190 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7208 emitpcode(poc, popGet(AOP(reg),offset));
7213 /*-----------------------------------------------------------------*/
7214 /* genLeftShift - generates code for left shifting */
7215 /*-----------------------------------------------------------------*/
7216 static void genLeftShift (iCode *ic)
7218 operand *left,*right, *result;
7221 symbol *tlbl , *tlbl1;
7224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7226 right = IC_RIGHT(ic);
7228 result = IC_RESULT(ic);
7230 aopOp(right,ic,FALSE);
7232 /* if the shift count is known then do it
7233 as efficiently as possible */
7234 if (AOP_TYPE(right) == AOP_LIT) {
7235 genLeftShiftLiteral (left,right,result,ic);
7239 /* shift count is unknown then we have to form
7240 a loop get the loop count in B : Note: we take
7241 only the lower order byte since shifting
7242 more that 32 bits make no sense anyway, ( the
7243 largest size of an object can be only 32 bits ) */
7246 aopOp(left,ic,FALSE);
7247 aopOp(result,ic,FALSE);
7249 /* now move the left to the result if they are not the
7251 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7252 AOP_SIZE(result) > 1) {
7254 size = AOP_SIZE(result);
7257 l = aopGet(AOP(left),offset,FALSE,TRUE);
7258 if (*l == '@' && (IS_AOP_PREG(result))) {
7260 pic14_emitcode("mov","a,%s",l);
7261 aopPut(AOP(result),"a",offset);
7263 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7264 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7265 //aopPut(AOP(result),l,offset);
7271 size = AOP_SIZE(result);
7273 /* if it is only one byte then */
7275 if(optimized_for_speed) {
7276 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7277 emitpcode(POC_ANDLW, popGetLit(0xf0));
7278 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7279 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7280 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7281 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7282 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7283 emitpcode(POC_RLFW, popGet(AOP(result),0));
7284 emitpcode(POC_ANDLW, popGetLit(0xfe));
7285 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7286 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7287 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7290 tlbl = newiTempLabel(NULL);
7291 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7292 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7293 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7296 emitpcode(POC_COMFW, popGet(AOP(right),0));
7297 emitpcode(POC_RRF, popGet(AOP(result),0));
7298 emitpLabel(tlbl->key);
7299 emitpcode(POC_RLF, popGet(AOP(result),0));
7300 emitpcode(POC_ADDLW, popGetLit(1));
7302 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7307 if (pic14_sameRegs(AOP(left),AOP(result))) {
7309 tlbl = newiTempLabel(NULL);
7310 emitpcode(POC_COMFW, popGet(AOP(right),0));
7311 genMultiAsm(POC_RRF, result, size,1);
7312 emitpLabel(tlbl->key);
7313 genMultiAsm(POC_RLF, result, size,0);
7314 emitpcode(POC_ADDLW, popGetLit(1));
7316 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7320 //tlbl = newiTempLabel(NULL);
7322 //tlbl1 = newiTempLabel(NULL);
7324 //reAdjustPreg(AOP(result));
7326 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7327 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7328 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7330 //pic14_emitcode("add","a,acc");
7331 //aopPut(AOP(result),"a",offset++);
7333 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7335 // pic14_emitcode("rlc","a");
7336 // aopPut(AOP(result),"a",offset++);
7338 //reAdjustPreg(AOP(result));
7340 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7341 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7344 tlbl = newiTempLabel(NULL);
7345 tlbl1= newiTempLabel(NULL);
7347 size = AOP_SIZE(result);
7350 pctemp = popGetTempReg(); /* grab a temporary working register. */
7352 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7354 /* offset should be 0, 1 or 3 */
7355 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7357 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7359 emitpcode(POC_MOVWF, pctemp);
7362 emitpLabel(tlbl->key);
7365 emitpcode(POC_RLF, popGet(AOP(result),0));
7367 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7369 emitpcode(POC_DECFSZ, pctemp);
7370 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7371 emitpLabel(tlbl1->key);
7373 popReleaseTempReg(pctemp);
7377 freeAsmop (right,NULL,ic,TRUE);
7378 freeAsmop(left,NULL,ic,TRUE);
7379 freeAsmop(result,NULL,ic,TRUE);
7382 /*-----------------------------------------------------------------*/
7383 /* genrshOne - right shift a one byte quantity by known count */
7384 /*-----------------------------------------------------------------*/
7385 static void genrshOne (operand *result, operand *left,
7386 int shCount, int sign)
7388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7389 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7392 /*-----------------------------------------------------------------*/
7393 /* genrshTwo - right shift two bytes by known amount != 0 */
7394 /*-----------------------------------------------------------------*/
7395 static void genrshTwo (operand *result,operand *left,
7396 int shCount, int sign)
7398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7399 /* if shCount >= 8 */
7403 shiftR1Left2Result(left, MSB16, result, LSB,
7406 movLeft2Result(left, MSB16, result, LSB);
7408 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7411 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7412 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7416 /* 1 <= shCount <= 7 */
7418 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7421 /*-----------------------------------------------------------------*/
7422 /* shiftRLong - shift right one long from left to result */
7423 /* offl = LSB or MSB16 */
7424 /*-----------------------------------------------------------------*/
7425 static void shiftRLong (operand *left, int offl,
7426 operand *result, int sign)
7428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7430 pic14_emitcode("clr","c");
7431 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7433 pic14_emitcode("mov","c,acc.7");
7434 pic14_emitcode("rrc","a");
7435 aopPut(AOP(result),"a",MSB32-offl);
7437 /* add sign of "a" */
7438 addSign(result, MSB32, sign);
7440 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7441 pic14_emitcode("rrc","a");
7442 aopPut(AOP(result),"a",MSB24-offl);
7444 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7445 pic14_emitcode("rrc","a");
7446 aopPut(AOP(result),"a",MSB16-offl);
7449 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7450 pic14_emitcode("rrc","a");
7451 aopPut(AOP(result),"a",LSB);
7455 /*-----------------------------------------------------------------*/
7456 /* genrshFour - shift four byte by a known amount != 0 */
7457 /*-----------------------------------------------------------------*/
7458 static void genrshFour (operand *result, operand *left,
7459 int shCount, int sign)
7461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7462 /* if shifting more that 3 bytes */
7463 if(shCount >= 24 ) {
7466 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7468 movLeft2Result(left, MSB32, result, LSB);
7470 addSign(result, MSB16, sign);
7472 else if(shCount >= 16){
7475 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7477 movLeft2Result(left, MSB24, result, LSB);
7478 movLeft2Result(left, MSB32, result, MSB16);
7480 addSign(result, MSB24, sign);
7482 else if(shCount >= 8){
7485 shiftRLong(left, MSB16, result, sign);
7486 else if(shCount == 0){
7487 movLeft2Result(left, MSB16, result, LSB);
7488 movLeft2Result(left, MSB24, result, MSB16);
7489 movLeft2Result(left, MSB32, result, MSB24);
7490 addSign(result, MSB32, sign);
7493 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7494 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7495 /* the last shift is signed */
7496 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7497 addSign(result, MSB32, sign);
7500 else{ /* 1 <= shCount <= 7 */
7502 shiftRLong(left, LSB, result, sign);
7504 shiftRLong(result, LSB, result, sign);
7507 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7508 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7509 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7514 /*-----------------------------------------------------------------*/
7515 /* genRightShiftLiteral - right shifting by known count */
7516 /*-----------------------------------------------------------------*/
7517 static void genRightShiftLiteral (operand *left,
7523 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7526 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7527 freeAsmop(right,NULL,ic,TRUE);
7529 aopOp(left,ic,FALSE);
7530 aopOp(result,ic,FALSE);
7533 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7537 lsize = pic14_getDataSize(left);
7538 res_size = pic14_getDataSize(result);
7539 /* test the LEFT size !!! */
7541 /* I suppose that the left size >= result size */
7544 movLeft2Result(left, lsize, result, res_size);
7547 else if(shCount >= (lsize * 8)){
7550 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7552 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7553 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7558 emitpcode(POC_MOVLW, popGetLit(0));
7559 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7560 emitpcode(POC_MOVLW, popGetLit(0xff));
7562 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7567 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7574 genrshOne (result,left,shCount,sign);
7578 genrshTwo (result,left,shCount,sign);
7582 genrshFour (result,left,shCount,sign);
7590 freeAsmop(left,NULL,ic,TRUE);
7591 freeAsmop(result,NULL,ic,TRUE);
7594 /*-----------------------------------------------------------------*/
7595 /* genSignedRightShift - right shift of signed number */
7596 /*-----------------------------------------------------------------*/
7597 static void genSignedRightShift (iCode *ic)
7599 operand *right, *left, *result;
7602 symbol *tlbl, *tlbl1 ;
7605 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7607 /* we do it the hard way put the shift count in b
7608 and loop thru preserving the sign */
7609 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7611 right = IC_RIGHT(ic);
7613 result = IC_RESULT(ic);
7615 aopOp(right,ic,FALSE);
7616 aopOp(left,ic,FALSE);
7617 aopOp(result,ic,FALSE);
7620 if ( AOP_TYPE(right) == AOP_LIT) {
7621 genRightShiftLiteral (left,right,result,ic,1);
7624 /* shift count is unknown then we have to form
7625 a loop get the loop count in B : Note: we take
7626 only the lower order byte since shifting
7627 more that 32 bits make no sense anyway, ( the
7628 largest size of an object can be only 32 bits ) */
7630 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7631 //pic14_emitcode("inc","b");
7632 //freeAsmop (right,NULL,ic,TRUE);
7633 //aopOp(left,ic,FALSE);
7634 //aopOp(result,ic,FALSE);
7636 /* now move the left to the result if they are not the
7638 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7639 AOP_SIZE(result) > 1) {
7641 size = AOP_SIZE(result);
7645 l = aopGet(AOP(left),offset,FALSE,TRUE);
7646 if (*l == '@' && IS_AOP_PREG(result)) {
7648 pic14_emitcode("mov","a,%s",l);
7649 aopPut(AOP(result),"a",offset);
7651 aopPut(AOP(result),l,offset);
7653 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7654 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7660 /* mov the highest order bit to OVR */
7661 tlbl = newiTempLabel(NULL);
7662 tlbl1= newiTempLabel(NULL);
7664 size = AOP_SIZE(result);
7667 pctemp = popGetTempReg(); /* grab a temporary working register. */
7669 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7671 /* offset should be 0, 1 or 3 */
7672 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7674 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7676 emitpcode(POC_MOVWF, pctemp);
7679 emitpLabel(tlbl->key);
7681 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7682 emitpcode(POC_RRF, popGet(AOP(result),offset));
7685 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7688 emitpcode(POC_DECFSZ, pctemp);
7689 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7690 emitpLabel(tlbl1->key);
7692 popReleaseTempReg(pctemp);
7694 size = AOP_SIZE(result);
7696 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7697 pic14_emitcode("rlc","a");
7698 pic14_emitcode("mov","ov,c");
7699 /* if it is only one byte then */
7701 l = aopGet(AOP(left),0,FALSE,FALSE);
7703 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7704 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7705 pic14_emitcode("mov","c,ov");
7706 pic14_emitcode("rrc","a");
7707 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7708 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7709 aopPut(AOP(result),"a",0);
7713 reAdjustPreg(AOP(result));
7714 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7715 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7716 pic14_emitcode("mov","c,ov");
7718 l = aopGet(AOP(result),offset,FALSE,FALSE);
7720 pic14_emitcode("rrc","a");
7721 aopPut(AOP(result),"a",offset--);
7723 reAdjustPreg(AOP(result));
7724 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7725 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7730 freeAsmop(left,NULL,ic,TRUE);
7731 freeAsmop(result,NULL,ic,TRUE);
7732 freeAsmop(right,NULL,ic,TRUE);
7735 /*-----------------------------------------------------------------*/
7736 /* genRightShift - generate code for right shifting */
7737 /*-----------------------------------------------------------------*/
7738 static void genRightShift (iCode *ic)
7740 operand *right, *left, *result;
7744 symbol *tlbl, *tlbl1 ;
7746 /* if signed then we do it the hard way preserve the
7747 sign bit moving it inwards */
7748 retype = getSpec(operandType(IC_RESULT(ic)));
7749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7751 if (!SPEC_USIGN(retype)) {
7752 genSignedRightShift (ic);
7756 /* signed & unsigned types are treated the same : i.e. the
7757 signed is NOT propagated inwards : quoting from the
7758 ANSI - standard : "for E1 >> E2, is equivalent to division
7759 by 2**E2 if unsigned or if it has a non-negative value,
7760 otherwise the result is implementation defined ", MY definition
7761 is that the sign does not get propagated */
7763 right = IC_RIGHT(ic);
7765 result = IC_RESULT(ic);
7767 aopOp(right,ic,FALSE);
7769 /* if the shift count is known then do it
7770 as efficiently as possible */
7771 if (AOP_TYPE(right) == AOP_LIT) {
7772 genRightShiftLiteral (left,right,result,ic, 0);
7776 /* shift count is unknown then we have to form
7777 a loop get the loop count in B : Note: we take
7778 only the lower order byte since shifting
7779 more that 32 bits make no sense anyway, ( the
7780 largest size of an object can be only 32 bits ) */
7782 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7783 pic14_emitcode("inc","b");
7784 aopOp(left,ic,FALSE);
7785 aopOp(result,ic,FALSE);
7787 /* now move the left to the result if they are not the
7789 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7790 AOP_SIZE(result) > 1) {
7792 size = AOP_SIZE(result);
7795 l = aopGet(AOP(left),offset,FALSE,TRUE);
7796 if (*l == '@' && IS_AOP_PREG(result)) {
7798 pic14_emitcode("mov","a,%s",l);
7799 aopPut(AOP(result),"a",offset);
7801 aopPut(AOP(result),l,offset);
7806 tlbl = newiTempLabel(NULL);
7807 tlbl1= newiTempLabel(NULL);
7808 size = AOP_SIZE(result);
7811 /* if it is only one byte then */
7814 tlbl = newiTempLabel(NULL);
7815 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7816 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7817 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7820 emitpcode(POC_COMFW, popGet(AOP(right),0));
7821 emitpcode(POC_RLF, popGet(AOP(result),0));
7822 emitpLabel(tlbl->key);
7823 emitpcode(POC_RRF, popGet(AOP(result),0));
7824 emitpcode(POC_ADDLW, popGetLit(1));
7826 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7831 reAdjustPreg(AOP(result));
7832 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7833 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7836 l = aopGet(AOP(result),offset,FALSE,FALSE);
7838 pic14_emitcode("rrc","a");
7839 aopPut(AOP(result),"a",offset--);
7841 reAdjustPreg(AOP(result));
7843 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7844 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7847 freeAsmop(left,NULL,ic,TRUE);
7848 freeAsmop (right,NULL,ic,TRUE);
7849 freeAsmop(result,NULL,ic,TRUE);
7852 /*-----------------------------------------------------------------*/
7853 /* genUnpackBits - generates code for unpacking bits */
7854 /*-----------------------------------------------------------------*/
7855 static void genUnpackBits (operand *result, char *rname, int ptype)
7862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7863 etype = getSpec(operandType(result));
7865 /* read the first byte */
7870 pic14_emitcode("mov","a,@%s",rname);
7874 pic14_emitcode("movx","a,@%s",rname);
7878 pic14_emitcode("movx","a,@dptr");
7882 pic14_emitcode("clr","a");
7883 pic14_emitcode("movc","a","@a+dptr");
7887 pic14_emitcode("lcall","__gptrget");
7891 /* if we have bitdisplacement then it fits */
7892 /* into this byte completely or if length is */
7893 /* less than a byte */
7894 if ((shCnt = SPEC_BSTR(etype)) ||
7895 (SPEC_BLEN(etype) <= 8)) {
7897 /* shift right acc */
7900 pic14_emitcode("anl","a,#0x%02x",
7901 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7902 aopPut(AOP(result),"a",offset);
7906 /* bit field did not fit in a byte */
7907 rlen = SPEC_BLEN(etype) - 8;
7908 aopPut(AOP(result),"a",offset++);
7915 pic14_emitcode("inc","%s",rname);
7916 pic14_emitcode("mov","a,@%s",rname);
7920 pic14_emitcode("inc","%s",rname);
7921 pic14_emitcode("movx","a,@%s",rname);
7925 pic14_emitcode("inc","dptr");
7926 pic14_emitcode("movx","a,@dptr");
7930 pic14_emitcode("clr","a");
7931 pic14_emitcode("inc","dptr");
7932 pic14_emitcode("movc","a","@a+dptr");
7936 pic14_emitcode("inc","dptr");
7937 pic14_emitcode("lcall","__gptrget");
7942 /* if we are done */
7946 aopPut(AOP(result),"a",offset++);
7951 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7952 aopPut(AOP(result),"a",offset);
7959 /*-----------------------------------------------------------------*/
7960 /* genDataPointerGet - generates code when ptr offset is known */
7961 /*-----------------------------------------------------------------*/
7962 static void genDataPointerGet (operand *left,
7966 int size , offset = 0;
7969 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7972 /* optimization - most of the time, left and result are the same
7973 * address, but different types. for the pic code, we could omit
7977 aopOp(result,ic,TRUE);
7979 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7981 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7983 size = AOP_SIZE(result);
7986 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7990 freeAsmop(left,NULL,ic,TRUE);
7991 freeAsmop(result,NULL,ic,TRUE);
7994 /*-----------------------------------------------------------------*/
7995 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7996 /*-----------------------------------------------------------------*/
7997 static void genNearPointerGet (operand *left,
8002 //regs *preg = NULL ;
8004 sym_link *rtype, *retype;
8005 sym_link *ltype = operandType(left);
8008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8010 rtype = operandType(result);
8011 retype= getSpec(rtype);
8013 aopOp(left,ic,FALSE);
8015 /* if left is rematerialisable and
8016 result is not bit variable type and
8017 the left is pointer to data space i.e
8018 lower 128 bytes of space */
8019 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8020 !IS_BITVAR(retype) &&
8021 DCL_TYPE(ltype) == POINTER) {
8022 //genDataPointerGet (left,result,ic);
8026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8028 /* if the value is already in a pointer register
8029 then don't need anything more */
8030 if (!AOP_INPREG(AOP(left))) {
8031 /* otherwise get a free pointer register */
8032 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8035 preg = getFreePtr(ic,&aop,FALSE);
8036 pic14_emitcode("mov","%s,%s",
8038 aopGet(AOP(left),0,FALSE,TRUE));
8039 rname = preg->name ;
8043 rname = aopGet(AOP(left),0,FALSE,FALSE);
8045 aopOp (result,ic,FALSE);
8047 /* if bitfield then unpack the bits */
8048 if (IS_BITVAR(retype))
8049 genUnpackBits (result,rname,POINTER);
8051 /* we have can just get the values */
8052 int size = AOP_SIZE(result);
8055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8057 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8058 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8060 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8061 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8063 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8067 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8069 pic14_emitcode("mov","a,@%s",rname);
8070 aopPut(AOP(result),"a",offset);
8072 sprintf(buffer,"@%s",rname);
8073 aopPut(AOP(result),buffer,offset);
8077 pic14_emitcode("inc","%s",rname);
8082 /* now some housekeeping stuff */
8084 /* we had to allocate for this iCode */
8085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8086 freeAsmop(NULL,aop,ic,TRUE);
8088 /* we did not allocate which means left
8089 already in a pointer register, then
8090 if size > 0 && this could be used again
8091 we have to point it back to where it
8093 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8094 if (AOP_SIZE(result) > 1 &&
8095 !OP_SYMBOL(left)->remat &&
8096 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8098 int size = AOP_SIZE(result) - 1;
8100 pic14_emitcode("dec","%s",rname);
8105 freeAsmop(left,NULL,ic,TRUE);
8106 freeAsmop(result,NULL,ic,TRUE);
8110 /*-----------------------------------------------------------------*/
8111 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8112 /*-----------------------------------------------------------------*/
8113 static void genPagedPointerGet (operand *left,
8120 sym_link *rtype, *retype;
8122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8124 rtype = operandType(result);
8125 retype= getSpec(rtype);
8127 aopOp(left,ic,FALSE);
8129 /* if the value is already in a pointer register
8130 then don't need anything more */
8131 if (!AOP_INPREG(AOP(left))) {
8132 /* otherwise get a free pointer register */
8134 preg = getFreePtr(ic,&aop,FALSE);
8135 pic14_emitcode("mov","%s,%s",
8137 aopGet(AOP(left),0,FALSE,TRUE));
8138 rname = preg->name ;
8140 rname = aopGet(AOP(left),0,FALSE,FALSE);
8142 freeAsmop(left,NULL,ic,TRUE);
8143 aopOp (result,ic,FALSE);
8145 /* if bitfield then unpack the bits */
8146 if (IS_BITVAR(retype))
8147 genUnpackBits (result,rname,PPOINTER);
8149 /* we have can just get the values */
8150 int size = AOP_SIZE(result);
8155 pic14_emitcode("movx","a,@%s",rname);
8156 aopPut(AOP(result),"a",offset);
8161 pic14_emitcode("inc","%s",rname);
8165 /* now some housekeeping stuff */
8167 /* we had to allocate for this iCode */
8168 freeAsmop(NULL,aop,ic,TRUE);
8170 /* we did not allocate which means left
8171 already in a pointer register, then
8172 if size > 0 && this could be used again
8173 we have to point it back to where it
8175 if (AOP_SIZE(result) > 1 &&
8176 !OP_SYMBOL(left)->remat &&
8177 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8179 int size = AOP_SIZE(result) - 1;
8181 pic14_emitcode("dec","%s",rname);
8186 freeAsmop(result,NULL,ic,TRUE);
8191 /*-----------------------------------------------------------------*/
8192 /* genFarPointerGet - gget value from far space */
8193 /*-----------------------------------------------------------------*/
8194 static void genFarPointerGet (operand *left,
8195 operand *result, iCode *ic)
8198 sym_link *retype = getSpec(operandType(result));
8200 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8202 aopOp(left,ic,FALSE);
8204 /* if the operand is already in dptr
8205 then we do nothing else we move the value to dptr */
8206 if (AOP_TYPE(left) != AOP_STR) {
8207 /* if this is remateriazable */
8208 if (AOP_TYPE(left) == AOP_IMMD)
8209 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8210 else { /* we need to get it byte by byte */
8211 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8212 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8213 if (options.model == MODEL_FLAT24)
8215 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8219 /* so dptr know contains the address */
8220 freeAsmop(left,NULL,ic,TRUE);
8221 aopOp(result,ic,FALSE);
8223 /* if bit then unpack */
8224 if (IS_BITVAR(retype))
8225 genUnpackBits(result,"dptr",FPOINTER);
8227 size = AOP_SIZE(result);
8231 pic14_emitcode("movx","a,@dptr");
8232 aopPut(AOP(result),"a",offset++);
8234 pic14_emitcode("inc","dptr");
8238 freeAsmop(result,NULL,ic,TRUE);
8241 /*-----------------------------------------------------------------*/
8242 /* genCodePointerGet - get value from code space */
8243 /*-----------------------------------------------------------------*/
8244 static void genCodePointerGet (operand *left,
8245 operand *result, iCode *ic)
8248 sym_link *retype = getSpec(operandType(result));
8250 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8252 aopOp(left,ic,FALSE);
8254 /* if the operand is already in dptr
8255 then we do nothing else we move the value to dptr */
8256 if (AOP_TYPE(left) != AOP_STR) {
8257 /* if this is remateriazable */
8258 if (AOP_TYPE(left) == AOP_IMMD)
8259 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8260 else { /* we need to get it byte by byte */
8261 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8262 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8263 if (options.model == MODEL_FLAT24)
8265 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8269 /* so dptr know contains the address */
8270 freeAsmop(left,NULL,ic,TRUE);
8271 aopOp(result,ic,FALSE);
8273 /* if bit then unpack */
8274 if (IS_BITVAR(retype))
8275 genUnpackBits(result,"dptr",CPOINTER);
8277 size = AOP_SIZE(result);
8281 pic14_emitcode("clr","a");
8282 pic14_emitcode("movc","a,@a+dptr");
8283 aopPut(AOP(result),"a",offset++);
8285 pic14_emitcode("inc","dptr");
8289 freeAsmop(result,NULL,ic,TRUE);
8292 /*-----------------------------------------------------------------*/
8293 /* genGenPointerGet - gget value from generic pointer space */
8294 /*-----------------------------------------------------------------*/
8295 static void genGenPointerGet (operand *left,
8296 operand *result, iCode *ic)
8299 sym_link *retype = getSpec(operandType(result));
8301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8302 aopOp(left,ic,FALSE);
8303 aopOp(result,ic,FALSE);
8306 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8308 /* if the operand is already in dptr
8309 then we do nothing else we move the value to dptr */
8310 // if (AOP_TYPE(left) != AOP_STR) {
8311 /* if this is remateriazable */
8312 if (AOP_TYPE(left) == AOP_IMMD) {
8313 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8314 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8316 else { /* we need to get it byte by byte */
8318 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8319 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8321 size = AOP_SIZE(result);
8325 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8326 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8328 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8333 /* so dptr know contains the address */
8335 /* if bit then unpack */
8336 //if (IS_BITVAR(retype))
8337 // genUnpackBits(result,"dptr",GPOINTER);
8340 freeAsmop(left,NULL,ic,TRUE);
8341 freeAsmop(result,NULL,ic,TRUE);
8345 /*-----------------------------------------------------------------*/
8346 /* genConstPointerGet - get value from const generic pointer space */
8347 /*-----------------------------------------------------------------*/
8348 static void genConstPointerGet (operand *left,
8349 operand *result, iCode *ic)
8351 //sym_link *retype = getSpec(operandType(result));
8352 symbol *albl = newiTempLabel(NULL);
8353 symbol *blbl = newiTempLabel(NULL);
8356 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8357 aopOp(left,ic,FALSE);
8358 aopOp(result,ic,FALSE);
8361 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8363 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8365 emitpcode(POC_CALL,popGetLabel(albl->key));
8366 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8367 emitpLabel(albl->key);
8369 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8371 emitpcode(poc,popGet(AOP(left),1));
8372 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8373 emitpcode(poc,popGet(AOP(left),0));
8374 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8376 emitpLabel(blbl->key);
8378 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8381 freeAsmop(left,NULL,ic,TRUE);
8382 freeAsmop(result,NULL,ic,TRUE);
8385 /*-----------------------------------------------------------------*/
8386 /* genPointerGet - generate code for pointer get */
8387 /*-----------------------------------------------------------------*/
8388 static void genPointerGet (iCode *ic)
8390 operand *left, *result ;
8391 sym_link *type, *etype;
8394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8397 result = IC_RESULT(ic) ;
8399 /* depending on the type of pointer we need to
8400 move it to the correct pointer register */
8401 type = operandType(left);
8402 etype = getSpec(type);
8404 if (IS_PTR_CONST(type))
8405 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8407 /* if left is of type of pointer then it is simple */
8408 if (IS_PTR(type) && !IS_FUNC(type->next))
8409 p_type = DCL_TYPE(type);
8411 /* we have to go by the storage class */
8412 p_type = PTR_TYPE(SPEC_OCLS(etype));
8414 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8416 if (SPEC_OCLS(etype)->codesp ) {
8417 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8418 //p_type = CPOINTER ;
8421 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8422 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8423 /*p_type = FPOINTER ;*/
8425 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8426 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8427 /* p_type = PPOINTER; */
8429 if (SPEC_OCLS(etype) == idata )
8430 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8431 /* p_type = IPOINTER; */
8433 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8434 /* p_type = POINTER ; */
8437 /* now that we have the pointer type we assign
8438 the pointer values */
8443 genNearPointerGet (left,result,ic);
8447 genPagedPointerGet(left,result,ic);
8451 genFarPointerGet (left,result,ic);
8455 genConstPointerGet (left,result,ic);
8456 //pic14_emitcodePointerGet (left,result,ic);
8460 if (IS_PTR_CONST(type))
8461 genConstPointerGet (left,result,ic);
8463 genGenPointerGet (left,result,ic);
8469 /*-----------------------------------------------------------------*/
8470 /* genPackBits - generates code for packed bit storage */
8471 /*-----------------------------------------------------------------*/
8472 static void genPackBits (sym_link *etype ,
8474 char *rname, int p_type)
8482 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8483 blen = SPEC_BLEN(etype);
8484 bstr = SPEC_BSTR(etype);
8486 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8489 /* if the bit lenth is less than or */
8490 /* it exactly fits a byte then */
8491 if (SPEC_BLEN(etype) <= 8 ) {
8492 shCount = SPEC_BSTR(etype) ;
8494 /* shift left acc */
8497 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8502 pic14_emitcode ("mov","b,a");
8503 pic14_emitcode("mov","a,@%s",rname);
8507 pic14_emitcode ("mov","b,a");
8508 pic14_emitcode("movx","a,@dptr");
8512 pic14_emitcode ("push","b");
8513 pic14_emitcode ("push","acc");
8514 pic14_emitcode ("lcall","__gptrget");
8515 pic14_emitcode ("pop","b");
8519 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8520 ((unsigned char)(0xFF << (blen+bstr)) |
8521 (unsigned char)(0xFF >> (8-bstr)) ) );
8522 pic14_emitcode ("orl","a,b");
8523 if (p_type == GPOINTER)
8524 pic14_emitcode("pop","b");
8530 pic14_emitcode("mov","@%s,a",rname);
8534 pic14_emitcode("movx","@dptr,a");
8538 DEBUGpic14_emitcode(";lcall","__gptrput");
8543 if ( SPEC_BLEN(etype) <= 8 )
8546 pic14_emitcode("inc","%s",rname);
8547 rLen = SPEC_BLEN(etype) ;
8549 /* now generate for lengths greater than one byte */
8552 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8562 pic14_emitcode("mov","@%s,a",rname);
8564 pic14_emitcode("mov","@%s,%s",rname,l);
8569 pic14_emitcode("movx","@dptr,a");
8574 DEBUGpic14_emitcode(";lcall","__gptrput");
8577 pic14_emitcode ("inc","%s",rname);
8582 /* last last was not complete */
8584 /* save the byte & read byte */
8587 pic14_emitcode ("mov","b,a");
8588 pic14_emitcode("mov","a,@%s",rname);
8592 pic14_emitcode ("mov","b,a");
8593 pic14_emitcode("movx","a,@dptr");
8597 pic14_emitcode ("push","b");
8598 pic14_emitcode ("push","acc");
8599 pic14_emitcode ("lcall","__gptrget");
8600 pic14_emitcode ("pop","b");
8604 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8605 pic14_emitcode ("orl","a,b");
8608 if (p_type == GPOINTER)
8609 pic14_emitcode("pop","b");
8614 pic14_emitcode("mov","@%s,a",rname);
8618 pic14_emitcode("movx","@dptr,a");
8622 DEBUGpic14_emitcode(";lcall","__gptrput");
8626 /*-----------------------------------------------------------------*/
8627 /* genDataPointerSet - remat pointer to data space */
8628 /*-----------------------------------------------------------------*/
8629 static void genDataPointerSet(operand *right,
8633 int size, offset = 0 ;
8634 char *l, buffer[256];
8636 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8637 aopOp(right,ic,FALSE);
8639 l = aopGet(AOP(result),0,FALSE,TRUE);
8640 size = AOP_SIZE(right);
8642 if ( AOP_TYPE(result) == AOP_PCODE) {
8643 fprintf(stderr,"genDataPointerSet %s, %d\n",
8644 AOP(result)->aopu.pcop->name,
8645 PCOI(AOP(result)->aopu.pcop)->offset);
8649 // tsd, was l+1 - the underline `_' prefix was being stripped
8652 sprintf(buffer,"(%s + %d)",l,offset);
8653 fprintf(stderr,"oops %s\n",buffer);
8655 sprintf(buffer,"%s",l);
8657 if (AOP_TYPE(right) == AOP_LIT) {
8658 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8659 lit = lit >> (8*offset);
8661 pic14_emitcode("movlw","%d",lit);
8662 pic14_emitcode("movwf","%s",buffer);
8664 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8665 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8666 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8669 pic14_emitcode("clrf","%s",buffer);
8670 //emitpcode(POC_CLRF, popRegFromString(buffer));
8671 emitpcode(POC_CLRF, popGet(AOP(result),0));
8674 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8675 pic14_emitcode("movwf","%s",buffer);
8677 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8678 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8679 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8686 freeAsmop(right,NULL,ic,TRUE);
8687 freeAsmop(result,NULL,ic,TRUE);
8690 /*-----------------------------------------------------------------*/
8691 /* genNearPointerSet - pic14_emitcode for near pointer put */
8692 /*-----------------------------------------------------------------*/
8693 static void genNearPointerSet (operand *right,
8700 sym_link *ptype = operandType(result);
8703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8704 retype= getSpec(operandType(right));
8706 aopOp(result,ic,FALSE);
8709 /* if the result is rematerializable &
8710 in data space & not a bit variable */
8711 //if (AOP_TYPE(result) == AOP_IMMD &&
8712 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8713 DCL_TYPE(ptype) == POINTER &&
8714 !IS_BITVAR(retype)) {
8715 genDataPointerSet (right,result,ic);
8716 freeAsmop(result,NULL,ic,TRUE);
8720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8721 aopOp(right,ic,FALSE);
8722 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8724 /* if the value is already in a pointer register
8725 then don't need anything more */
8726 if (!AOP_INPREG(AOP(result))) {
8727 /* otherwise get a free pointer register */
8728 //aop = newAsmop(0);
8729 //preg = getFreePtr(ic,&aop,FALSE);
8730 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8731 //pic14_emitcode("mov","%s,%s",
8733 // aopGet(AOP(result),0,FALSE,TRUE));
8734 //rname = preg->name ;
8735 //pic14_emitcode("movwf","fsr");
8736 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8737 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8738 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8739 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8743 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8746 /* if bitfield then unpack the bits */
8747 if (IS_BITVAR(retype)) {
8748 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8749 "The programmer is obviously confused");
8750 //genPackBits (retype,right,rname,POINTER);
8754 /* we have can just get the values */
8755 int size = AOP_SIZE(right);
8758 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8760 l = aopGet(AOP(right),offset,FALSE,TRUE);
8763 //pic14_emitcode("mov","@%s,a",rname);
8764 pic14_emitcode("movf","indf,w ;1");
8767 if (AOP_TYPE(right) == AOP_LIT) {
8768 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8770 pic14_emitcode("movlw","%s",l);
8771 pic14_emitcode("movwf","indf ;2");
8773 pic14_emitcode("clrf","indf");
8775 pic14_emitcode("movf","%s,w",l);
8776 pic14_emitcode("movwf","indf ;2");
8778 //pic14_emitcode("mov","@%s,%s",rname,l);
8781 pic14_emitcode("incf","fsr,f ;3");
8782 //pic14_emitcode("inc","%s",rname);
8787 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8788 /* now some housekeeping stuff */
8790 /* we had to allocate for this iCode */
8791 freeAsmop(NULL,aop,ic,TRUE);
8793 /* we did not allocate which means left
8794 already in a pointer register, then
8795 if size > 0 && this could be used again
8796 we have to point it back to where it
8798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8799 if (AOP_SIZE(right) > 1 &&
8800 !OP_SYMBOL(result)->remat &&
8801 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8803 int size = AOP_SIZE(right) - 1;
8805 pic14_emitcode("decf","fsr,f");
8806 //pic14_emitcode("dec","%s",rname);
8810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8813 freeAsmop(right,NULL,ic,TRUE);
8814 freeAsmop(result,NULL,ic,TRUE);
8817 /*-----------------------------------------------------------------*/
8818 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8819 /*-----------------------------------------------------------------*/
8820 static void genPagedPointerSet (operand *right,
8829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8831 retype= getSpec(operandType(right));
8833 aopOp(result,ic,FALSE);
8835 /* if the value is already in a pointer register
8836 then don't need anything more */
8837 if (!AOP_INPREG(AOP(result))) {
8838 /* otherwise get a free pointer register */
8840 preg = getFreePtr(ic,&aop,FALSE);
8841 pic14_emitcode("mov","%s,%s",
8843 aopGet(AOP(result),0,FALSE,TRUE));
8844 rname = preg->name ;
8846 rname = aopGet(AOP(result),0,FALSE,FALSE);
8848 freeAsmop(result,NULL,ic,TRUE);
8849 aopOp (right,ic,FALSE);
8851 /* if bitfield then unpack the bits */
8852 if (IS_BITVAR(retype))
8853 genPackBits (retype,right,rname,PPOINTER);
8855 /* we have can just get the values */
8856 int size = AOP_SIZE(right);
8860 l = aopGet(AOP(right),offset,FALSE,TRUE);
8863 pic14_emitcode("movx","@%s,a",rname);
8866 pic14_emitcode("inc","%s",rname);
8872 /* now some housekeeping stuff */
8874 /* we had to allocate for this iCode */
8875 freeAsmop(NULL,aop,ic,TRUE);
8877 /* we did not allocate which means left
8878 already in a pointer register, then
8879 if size > 0 && this could be used again
8880 we have to point it back to where it
8882 if (AOP_SIZE(right) > 1 &&
8883 !OP_SYMBOL(result)->remat &&
8884 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8886 int size = AOP_SIZE(right) - 1;
8888 pic14_emitcode("dec","%s",rname);
8893 freeAsmop(right,NULL,ic,TRUE);
8898 /*-----------------------------------------------------------------*/
8899 /* genFarPointerSet - set value from far space */
8900 /*-----------------------------------------------------------------*/
8901 static void genFarPointerSet (operand *right,
8902 operand *result, iCode *ic)
8905 sym_link *retype = getSpec(operandType(right));
8907 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8908 aopOp(result,ic,FALSE);
8910 /* if the operand is already in dptr
8911 then we do nothing else we move the value to dptr */
8912 if (AOP_TYPE(result) != AOP_STR) {
8913 /* if this is remateriazable */
8914 if (AOP_TYPE(result) == AOP_IMMD)
8915 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8916 else { /* we need to get it byte by byte */
8917 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8918 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8919 if (options.model == MODEL_FLAT24)
8921 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8925 /* so dptr know contains the address */
8926 freeAsmop(result,NULL,ic,TRUE);
8927 aopOp(right,ic,FALSE);
8929 /* if bit then unpack */
8930 if (IS_BITVAR(retype))
8931 genPackBits(retype,right,"dptr",FPOINTER);
8933 size = AOP_SIZE(right);
8937 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8939 pic14_emitcode("movx","@dptr,a");
8941 pic14_emitcode("inc","dptr");
8945 freeAsmop(right,NULL,ic,TRUE);
8948 /*-----------------------------------------------------------------*/
8949 /* genGenPointerSet - set value from generic pointer space */
8950 /*-----------------------------------------------------------------*/
8951 static void genGenPointerSet (operand *right,
8952 operand *result, iCode *ic)
8955 sym_link *retype = getSpec(operandType(right));
8957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8959 aopOp(result,ic,FALSE);
8960 aopOp(right,ic,FALSE);
8961 size = AOP_SIZE(right);
8963 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8965 /* if the operand is already in dptr
8966 then we do nothing else we move the value to dptr */
8967 if (AOP_TYPE(result) != AOP_STR) {
8968 /* if this is remateriazable */
8969 if (AOP_TYPE(result) == AOP_IMMD) {
8970 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8971 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8973 else { /* we need to get it byte by byte */
8974 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8975 size = AOP_SIZE(right);
8978 /* hack hack! see if this the FSR. If so don't load W */
8979 if(AOP_TYPE(right) != AOP_ACC) {
8982 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8983 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8985 if(AOP_SIZE(result) > 1) {
8986 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8987 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8988 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8993 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8995 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8996 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9000 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9001 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9004 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9011 if(aopIdx(AOP(result),0) != 4) {
9013 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9017 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9022 /* so dptr know contains the address */
9025 /* if bit then unpack */
9026 if (IS_BITVAR(retype))
9027 genPackBits(retype,right,"dptr",GPOINTER);
9029 size = AOP_SIZE(right);
9032 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9036 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9037 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9039 if (AOP_TYPE(right) == AOP_LIT)
9040 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9042 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9044 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9051 freeAsmop(right,NULL,ic,TRUE);
9052 freeAsmop(result,NULL,ic,TRUE);
9055 /*-----------------------------------------------------------------*/
9056 /* genPointerSet - stores the value into a pointer location */
9057 /*-----------------------------------------------------------------*/
9058 static void genPointerSet (iCode *ic)
9060 operand *right, *result ;
9061 sym_link *type, *etype;
9064 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9066 right = IC_RIGHT(ic);
9067 result = IC_RESULT(ic) ;
9069 /* depending on the type of pointer we need to
9070 move it to the correct pointer register */
9071 type = operandType(result);
9072 etype = getSpec(type);
9073 /* if left is of type of pointer then it is simple */
9074 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9075 p_type = DCL_TYPE(type);
9078 /* we have to go by the storage class */
9079 p_type = PTR_TYPE(SPEC_OCLS(etype));
9081 /* if (SPEC_OCLS(etype)->codesp ) { */
9082 /* p_type = CPOINTER ; */
9085 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9086 /* p_type = FPOINTER ; */
9088 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9089 /* p_type = PPOINTER ; */
9091 /* if (SPEC_OCLS(etype) == idata ) */
9092 /* p_type = IPOINTER ; */
9094 /* p_type = POINTER ; */
9097 /* now that we have the pointer type we assign
9098 the pointer values */
9103 genNearPointerSet (right,result,ic);
9107 genPagedPointerSet (right,result,ic);
9111 genFarPointerSet (right,result,ic);
9115 genGenPointerSet (right,result,ic);
9119 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9120 "genPointerSet: illegal pointer type");
9124 /*-----------------------------------------------------------------*/
9125 /* genIfx - generate code for Ifx statement */
9126 /*-----------------------------------------------------------------*/
9127 static void genIfx (iCode *ic, iCode *popIc)
9129 operand *cond = IC_COND(ic);
9132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9134 aopOp(cond,ic,FALSE);
9136 /* get the value into acc */
9137 if (AOP_TYPE(cond) != AOP_CRY)
9138 pic14_toBoolean(cond);
9141 /* the result is now in the accumulator */
9142 freeAsmop(cond,NULL,ic,TRUE);
9144 /* if there was something to be popped then do it */
9148 /* if the condition is a bit variable */
9149 if (isbit && IS_ITEMP(cond) &&
9151 genIfxJump(ic,SPIL_LOC(cond)->rname);
9152 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9155 if (isbit && !IS_ITEMP(cond))
9156 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9164 /*-----------------------------------------------------------------*/
9165 /* genAddrOf - generates code for address of */
9166 /*-----------------------------------------------------------------*/
9167 static void genAddrOf (iCode *ic)
9169 operand *right, *result, *left;
9172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9175 //aopOp(IC_RESULT(ic),ic,FALSE);
9177 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9178 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9179 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9181 DEBUGpic14_AopType(__LINE__,left,right,result);
9183 size = AOP_SIZE(IC_RESULT(ic));
9187 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9188 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9192 freeAsmop(left,NULL,ic,FALSE);
9193 freeAsmop(result,NULL,ic,TRUE);
9198 /*-----------------------------------------------------------------*/
9199 /* genFarFarAssign - assignment when both are in far space */
9200 /*-----------------------------------------------------------------*/
9201 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9203 int size = AOP_SIZE(right);
9206 /* first push the right side on to the stack */
9208 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9210 pic14_emitcode ("push","acc");
9213 freeAsmop(right,NULL,ic,FALSE);
9214 /* now assign DPTR to result */
9215 aopOp(result,ic,FALSE);
9216 size = AOP_SIZE(result);
9218 pic14_emitcode ("pop","acc");
9219 aopPut(AOP(result),"a",--offset);
9221 freeAsmop(result,NULL,ic,FALSE);
9226 /*-----------------------------------------------------------------*/
9227 /* genAssign - generate code for assignment */
9228 /*-----------------------------------------------------------------*/
9229 static void genAssign (iCode *ic)
9231 operand *result, *right;
9232 int size, offset,know_W;
9233 unsigned long lit = 0L;
9235 result = IC_RESULT(ic);
9236 right = IC_RIGHT(ic) ;
9238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9240 /* if they are the same */
9241 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9244 aopOp(right,ic,FALSE);
9245 aopOp(result,ic,TRUE);
9247 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9249 /* if they are the same registers */
9250 if (pic14_sameRegs(AOP(right),AOP(result)))
9253 /* if the result is a bit */
9254 if (AOP_TYPE(result) == AOP_CRY) {
9256 /* if the right size is a literal then
9257 we know what the value is */
9258 if (AOP_TYPE(right) == AOP_LIT) {
9260 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9261 popGet(AOP(result),0));
9263 if (((int) operandLitValue(right)))
9264 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9265 AOP(result)->aopu.aop_dir,
9266 AOP(result)->aopu.aop_dir);
9268 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9269 AOP(result)->aopu.aop_dir,
9270 AOP(result)->aopu.aop_dir);
9274 /* the right is also a bit variable */
9275 if (AOP_TYPE(right) == AOP_CRY) {
9276 emitpcode(POC_BCF, popGet(AOP(result),0));
9277 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9278 emitpcode(POC_BSF, popGet(AOP(result),0));
9280 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9281 AOP(result)->aopu.aop_dir,
9282 AOP(result)->aopu.aop_dir);
9283 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9284 AOP(right)->aopu.aop_dir,
9285 AOP(right)->aopu.aop_dir);
9286 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9287 AOP(result)->aopu.aop_dir,
9288 AOP(result)->aopu.aop_dir);
9293 emitpcode(POC_BCF, popGet(AOP(result),0));
9294 pic14_toBoolean(right);
9296 emitpcode(POC_BSF, popGet(AOP(result),0));
9297 //aopPut(AOP(result),"a",0);
9301 /* bit variables done */
9303 size = AOP_SIZE(result);
9305 if(AOP_TYPE(right) == AOP_LIT)
9306 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9308 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9310 if(aopIdx(AOP(result),0) == 4) {
9311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9312 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9313 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9316 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9322 if(AOP_TYPE(right) == AOP_LIT) {
9324 if(know_W != (lit&0xff))
9325 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9327 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9329 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9333 } else if (AOP_TYPE(right) == AOP_CRY) {
9334 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9336 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9337 emitpcode(POC_INCF, popGet(AOP(result),0));
9340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9341 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9342 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9350 freeAsmop (right,NULL,ic,FALSE);
9351 freeAsmop (result,NULL,ic,TRUE);
9354 /*-----------------------------------------------------------------*/
9355 /* genJumpTab - genrates code for jump table */
9356 /*-----------------------------------------------------------------*/
9357 static void genJumpTab (iCode *ic)
9362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9364 aopOp(IC_JTCOND(ic),ic,FALSE);
9365 /* get the condition into accumulator */
9366 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9368 /* multiply by three */
9369 pic14_emitcode("add","a,acc");
9370 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9372 jtab = newiTempLabel(NULL);
9373 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9374 pic14_emitcode("jmp","@a+dptr");
9375 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9377 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9378 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9380 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9381 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9382 emitpLabel(jtab->key);
9384 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9386 /* now generate the jump labels */
9387 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9388 jtab = setNextItem(IC_JTLABELS(ic))) {
9389 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9390 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9396 /*-----------------------------------------------------------------*/
9397 /* genMixedOperation - gen code for operators between mixed types */
9398 /*-----------------------------------------------------------------*/
9400 TSD - Written for the PIC port - but this unfortunately is buggy.
9401 This routine is good in that it is able to efficiently promote
9402 types to different (larger) sizes. Unfortunately, the temporary
9403 variables that are optimized out by this routine are sometimes
9404 used in other places. So until I know how to really parse the
9405 iCode tree, I'm going to not be using this routine :(.
9407 static int genMixedOperation (iCode *ic)
9410 operand *result = IC_RESULT(ic);
9411 sym_link *ctype = operandType(IC_LEFT(ic));
9412 operand *right = IC_RIGHT(ic);
9418 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9420 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9426 nextright = IC_RIGHT(nextic);
9427 nextleft = IC_LEFT(nextic);
9428 nextresult = IC_RESULT(nextic);
9430 aopOp(right,ic,FALSE);
9431 aopOp(result,ic,FALSE);
9432 aopOp(nextright, nextic, FALSE);
9433 aopOp(nextleft, nextic, FALSE);
9434 aopOp(nextresult, nextic, FALSE);
9436 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9442 pic14_emitcode(";remove right +","");
9444 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9450 pic14_emitcode(";remove left +","");
9454 big = AOP_SIZE(nextleft);
9455 small = AOP_SIZE(nextright);
9457 switch(nextic->op) {
9460 pic14_emitcode(";optimize a +","");
9461 /* if unsigned or not an integral type */
9462 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9463 pic14_emitcode(";add a bit to something","");
9466 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9468 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9469 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9470 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9472 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9480 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9481 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9482 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9485 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9487 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9488 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9489 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9490 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9491 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9494 pic14_emitcode("rlf","known_zero,w");
9501 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9502 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9503 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9505 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9515 freeAsmop(right,NULL,ic,TRUE);
9516 freeAsmop(result,NULL,ic,TRUE);
9517 freeAsmop(nextright,NULL,ic,TRUE);
9518 freeAsmop(nextleft,NULL,ic,TRUE);
9520 nextic->generated = 1;
9527 /*-----------------------------------------------------------------*/
9528 /* genCast - gen code for casting */
9529 /*-----------------------------------------------------------------*/
9530 static void genCast (iCode *ic)
9532 operand *result = IC_RESULT(ic);
9533 sym_link *ctype = operandType(IC_LEFT(ic));
9534 sym_link *rtype = operandType(IC_RIGHT(ic));
9535 operand *right = IC_RIGHT(ic);
9538 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9539 /* if they are equivalent then do nothing */
9540 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9543 aopOp(right,ic,FALSE) ;
9544 aopOp(result,ic,FALSE);
9546 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9548 /* if the result is a bit */
9549 if (AOP_TYPE(result) == AOP_CRY) {
9550 /* if the right size is a literal then
9551 we know what the value is */
9552 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9553 if (AOP_TYPE(right) == AOP_LIT) {
9555 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9556 popGet(AOP(result),0));
9558 if (((int) operandLitValue(right)))
9559 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9560 AOP(result)->aopu.aop_dir,
9561 AOP(result)->aopu.aop_dir);
9563 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9564 AOP(result)->aopu.aop_dir,
9565 AOP(result)->aopu.aop_dir);
9570 /* the right is also a bit variable */
9571 if (AOP_TYPE(right) == AOP_CRY) {
9574 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9576 pic14_emitcode("clrc","");
9577 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9578 AOP(right)->aopu.aop_dir,
9579 AOP(right)->aopu.aop_dir);
9580 aopPut(AOP(result),"c",0);
9585 if (AOP_TYPE(right) == AOP_REG) {
9586 emitpcode(POC_BCF, popGet(AOP(result),0));
9587 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9588 emitpcode(POC_BSF, popGet(AOP(result),0));
9590 pic14_toBoolean(right);
9591 aopPut(AOP(result),"a",0);
9595 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9597 size = AOP_SIZE(result);
9599 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9601 emitpcode(POC_CLRF, popGet(AOP(result),0));
9602 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9603 emitpcode(POC_INCF, popGet(AOP(result),0));
9606 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9611 /* if they are the same size : or less */
9612 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9614 /* if they are in the same place */
9615 if (pic14_sameRegs(AOP(right),AOP(result)))
9618 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9619 if (IS_PTR_CONST(rtype))
9620 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9621 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9622 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9624 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9625 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9626 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9627 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9628 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9629 if(AOP_SIZE(result) <2)
9630 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9634 /* if they in different places then copy */
9635 size = AOP_SIZE(result);
9638 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9639 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9641 //aopPut(AOP(result),
9642 // aopGet(AOP(right),offset,FALSE,FALSE),
9652 /* if the result is of type pointer */
9653 if (IS_PTR(ctype)) {
9656 sym_link *type = operandType(right);
9657 sym_link *etype = getSpec(type);
9658 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9660 /* pointer to generic pointer */
9661 if (IS_GENPTR(ctype)) {
9665 p_type = DCL_TYPE(type);
9667 /* we have to go by the storage class */
9668 p_type = PTR_TYPE(SPEC_OCLS(etype));
9670 /* if (SPEC_OCLS(etype)->codesp ) */
9671 /* p_type = CPOINTER ; */
9673 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9674 /* p_type = FPOINTER ; */
9676 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9677 /* p_type = PPOINTER; */
9679 /* if (SPEC_OCLS(etype) == idata ) */
9680 /* p_type = IPOINTER ; */
9682 /* p_type = POINTER ; */
9685 /* the first two bytes are known */
9686 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9687 size = GPTRSIZE - 1;
9690 if(offset < AOP_SIZE(right)) {
9691 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9692 if ((AOP_TYPE(right) == AOP_PCODE) &&
9693 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9694 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9695 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9698 aopGet(AOP(right),offset,FALSE,FALSE),
9702 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9705 /* the last byte depending on type */
9709 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9712 pic14_emitcode(";BUG!? ","%d",__LINE__);
9716 pic14_emitcode(";BUG!? ","%d",__LINE__);
9720 pic14_emitcode(";BUG!? ","%d",__LINE__);
9725 /* this should never happen */
9726 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9727 "got unknown pointer type");
9730 //aopPut(AOP(result),l, GPTRSIZE - 1);
9734 /* just copy the pointers */
9735 size = AOP_SIZE(result);
9739 aopGet(AOP(right),offset,FALSE,FALSE),
9748 /* so we now know that the size of destination is greater
9749 than the size of the source.
9750 Now, if the next iCode is an operator then we might be
9751 able to optimize the operation without performing a cast.
9753 if(genMixedOperation(ic))
9756 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9758 /* we move to result for the size of source */
9759 size = AOP_SIZE(right);
9762 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9763 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9767 /* now depending on the sign of the destination */
9768 size = AOP_SIZE(result) - AOP_SIZE(right);
9769 /* if unsigned or not an integral type */
9770 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9772 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9774 /* we need to extend the sign :{ */
9777 /* Save one instruction of casting char to int */
9778 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9779 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9780 emitpcode(POC_DECF, popGet(AOP(result),offset));
9782 emitpcodeNULLop(POC_CLRW);
9785 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9787 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9789 emitpcode(POC_MOVLW, popGetLit(0xff));
9792 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9797 freeAsmop(right,NULL,ic,TRUE);
9798 freeAsmop(result,NULL,ic,TRUE);
9802 /*-----------------------------------------------------------------*/
9803 /* genDjnz - generate decrement & jump if not zero instrucion */
9804 /*-----------------------------------------------------------------*/
9805 static int genDjnz (iCode *ic, iCode *ifx)
9808 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9813 /* if the if condition has a false label
9814 then we cannot save */
9818 /* if the minus is not of the form
9820 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9821 !IS_OP_LITERAL(IC_RIGHT(ic)))
9824 if (operandLitValue(IC_RIGHT(ic)) != 1)
9827 /* if the size of this greater than one then no
9829 if (getSize(operandType(IC_RESULT(ic))) > 1)
9832 /* otherwise we can save BIG */
9833 lbl = newiTempLabel(NULL);
9834 lbl1= newiTempLabel(NULL);
9836 aopOp(IC_RESULT(ic),ic,FALSE);
9838 if (IS_AOP_PREG(IC_RESULT(ic))) {
9839 pic14_emitcode("dec","%s",
9840 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9841 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9842 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9846 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9847 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9849 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9850 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9853 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9854 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9855 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9856 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9859 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9864 /*-----------------------------------------------------------------*/
9865 /* genReceive - generate code for a receive iCode */
9866 /*-----------------------------------------------------------------*/
9867 static void genReceive (iCode *ic)
9869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9871 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9872 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9873 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9875 int size = getSize(operandType(IC_RESULT(ic)));
9876 int offset = fReturnSizePic - size;
9878 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9879 fReturn[fReturnSizePic - offset - 1] : "acc"));
9882 aopOp(IC_RESULT(ic),ic,FALSE);
9883 size = AOP_SIZE(IC_RESULT(ic));
9886 pic14_emitcode ("pop","acc");
9887 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9892 aopOp(IC_RESULT(ic),ic,FALSE);
9894 assignResultValue(IC_RESULT(ic));
9897 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9900 /*-----------------------------------------------------------------*/
9901 /* genpic14Code - generate code for pic14 based controllers */
9902 /*-----------------------------------------------------------------*/
9904 * At this point, ralloc.c has gone through the iCode and attempted
9905 * to optimize in a way suitable for a PIC. Now we've got to generate
9906 * PIC instructions that correspond to the iCode.
9908 * Once the instructions are generated, we'll pass through both the
9909 * peep hole optimizer and the pCode optimizer.
9910 *-----------------------------------------------------------------*/
9912 void genpic14Code (iCode *lic)
9917 lineHead = lineCurr = NULL;
9919 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9922 /* if debug information required */
9923 if (options.debug && currFunc) {
9925 debugFile->writeFunction(currFunc);
9927 if (IS_STATIC(currFunc->etype)) {
9928 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9929 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9931 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9932 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9939 for (ic = lic ; ic ; ic = ic->next ) {
9941 DEBUGpic14_emitcode(";ic","");
9942 if ( cln != ic->lineno ) {
9943 if ( options.debug ) {
9945 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9946 FileBaseName(ic->filename),ic->lineno,
9947 ic->level,ic->block);
9951 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9952 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9953 printCLine(ic->filename, ic->lineno));
9955 if (!options.noCcodeInAsm) {
9957 newpCodeCSource(ic->lineno,
9959 printCLine(ic->filename, ic->lineno)));
9965 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9967 /* if the result is marked as
9968 spilt and rematerializable or code for
9969 this has already been generated then
9971 if (resultRemat(ic) || ic->generated )
9974 /* depending on the operation */
9993 /* IPOP happens only when trying to restore a
9994 spilt live range, if there is an ifx statement
9995 following this pop then the if statement might
9996 be using some of the registers being popped which
9997 would destory the contents of the register so
9998 we need to check for this condition and handle it */
10000 ic->next->op == IFX &&
10001 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10002 genIfx (ic->next,ic);
10020 genEndFunction (ic);
10040 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10057 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10061 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10068 /* note these two are xlated by algebraic equivalence
10069 during parsing SDCC.y */
10070 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10071 "got '>=' or '<=' shouldn't have come here");
10075 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10087 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10091 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10095 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10119 genRightShift (ic);
10122 case GET_VALUE_AT_ADDRESS:
10127 if (POINTER_SET(ic))
10154 addSet(&_G.sendSet,ic);
10163 /* now we are ready to call the
10164 peep hole optimizer */
10165 if (!options.nopeep) {
10166 peepHole (&lineHead);
10168 /* now do the actual printing */
10169 printLine (lineHead,codeOutFile);
10172 DFPRINTF((stderr,"printing pBlock\n\n"));
10173 printpBlock(stdout,pb);