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"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
67 static int labelOffset=0;
68 static int debug_verbose=1;
69 static int optimized_for_speed = 0;
71 /* max_key keeps track of the largest label number used in
72 a function. This is then used to adjust the label offset
73 for the next function.
76 static int GpsuedoStkPtr=0;
78 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
79 unsigned int pic14aopLiteral (value *val, int offset);
80 const char *AopType(short type);
81 static iCode *ifxForOp ( operand *op, iCode *ic );
83 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
85 /* this is the down and dirty file with all kinds of
86 kludgy & hacky stuff. This is what it is all about
87 CODE GENERATION for a specific MCU . some of the
88 routines may be reusable, will have to see */
90 static char *zero = "#0x00";
91 static char *one = "#0x01";
92 static char *spname = "sp";
94 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
95 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
96 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
97 static char **fReturn = fReturnpic14;
99 static char *accUse[] = {"a","b"};
101 //static short rbank = -1;
113 /* Resolved ifx structure. This structure stores information
114 about an iCode ifx that makes it easier to generate code.
116 typedef struct resolvedIfx {
117 symbol *lbl; /* pointer to a label */
118 int condition; /* true or false ifx */
119 int generated; /* set true when the code associated with the ifx
123 extern int pic14_ptrRegReq ;
124 extern int pic14_nRegs;
125 extern FILE *codeOutFile;
126 static void saverbank (int, iCode *,bool);
128 static lineNode *lineHead = NULL;
129 static lineNode *lineCurr = NULL;
131 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
132 0xE0, 0xC0, 0x80, 0x00};
133 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
134 0x07, 0x03, 0x01, 0x00};
138 /*-----------------------------------------------------------------*/
139 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
140 /* exponent of 2 is returned, otherwise -1 is */
142 /* note that this is similar to the function `powof2' in SDCCsymt */
146 /*-----------------------------------------------------------------*/
147 static int my_powof2 (unsigned long num)
150 if( (num & (num-1)) == 0) {
163 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
174 ((result) ? AOP_SIZE(result) : 0));
178 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
183 ((result) ? AopType(AOP_TYPE(result)) : "-"),
184 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
185 ((left) ? AopType(AOP_TYPE(left)) : "-"),
186 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
187 ((right) ? AopType(AOP_TYPE(right)) : "-"),
188 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
192 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 char lb[INITIAL_INLINEASM];
205 sprintf(lb,"%s\t",inst);
207 sprintf(lb,"%s",inst);
208 vsprintf(lb+(strlen(lb)),fmt,ap);
212 while (isspace(*lbp)) lbp++;
215 lineCurr = (lineCurr ?
216 connectLine(lineCurr,newLineNode(lb)) :
217 (lineHead = newLineNode(lb)));
218 lineCurr->isInline = _G.inLine;
219 lineCurr->isDebug = _G.debugLine;
221 addpCode2pBlock(pb,newpCodeCharP(lb));
227 void emitpLabel(int key)
229 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
236 addpCode2pBlock(pb,newpCode(poc,pcop));
238 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
241 void emitpcodeNULLop(PIC_OPCODE poc)
244 addpCode2pBlock(pb,newpCode(poc,NULL));
248 /*-----------------------------------------------------------------*/
249 /* pic14_emitcode - writes the code into a file : for now it is simple */
250 /*-----------------------------------------------------------------*/
251 void pic14_emitcode (char *inst,char *fmt, ...)
254 char lb[INITIAL_INLINEASM];
261 sprintf(lb,"%s\t",inst);
263 sprintf(lb,"%s",inst);
264 vsprintf(lb+(strlen(lb)),fmt,ap);
268 while (isspace(*lbp)) lbp++;
271 lineCurr = (lineCurr ?
272 connectLine(lineCurr,newLineNode(lb)) :
273 (lineHead = newLineNode(lb)));
274 lineCurr->isInline = _G.inLine;
275 lineCurr->isDebug = _G.debugLine;
278 addpCode2pBlock(pb,newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 /* the logic: if r0 & r1 used in the instruction
293 then we are in trouble otherwise */
295 /* first check if r0 & r1 are used by this
296 instruction, in which case we are in trouble */
297 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
298 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
303 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
304 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
306 /* if no usage of r0 then return it */
307 if (!r0iu && !r0ou) {
308 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
309 (*aopp)->type = AOP_R0;
311 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314 /* if no usage of r1 then return it */
315 if (!r1iu && !r1ou) {
316 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
317 (*aopp)->type = AOP_R1;
319 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322 /* now we know they both have usage */
323 /* if r0 not used in this instruction */
325 /* push it if not already pushed */
327 //pic14_emitcode ("push","%s",
328 // pic14_regWithIdx(R0_IDX)->dname);
332 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
333 (*aopp)->type = AOP_R0;
335 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338 /* if r1 not used then */
341 /* push it if not already pushed */
343 //pic14_emitcode ("push","%s",
344 // pic14_regWithIdx(R1_IDX)->dname);
348 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349 (*aopp)->type = AOP_R1;
350 return pic14_regWithIdx(R1_IDX);
354 /* I said end of world but not quite end of world yet */
355 /* if this is a result then we can push it on the stack*/
357 (*aopp)->type = AOP_STK;
361 /* other wise this is true end of the world */
362 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
363 "getFreePtr should never reach here");
367 /*-----------------------------------------------------------------*/
368 /* newAsmop - creates a new asmOp */
369 /*-----------------------------------------------------------------*/
370 asmop *newAsmop (short type)
374 aop = Safe_calloc(1,sizeof(asmop));
379 static void genSetDPTR(int n)
383 pic14_emitcode(";", "Select standard DPTR");
384 pic14_emitcode("mov", "dps, #0x00");
388 pic14_emitcode(";", "Select alternate DPTR");
389 pic14_emitcode("mov", "dps, #0x01");
393 /*-----------------------------------------------------------------*/
394 /* resolveIfx - converts an iCode ifx into a form more useful for */
395 /* generating code */
396 /*-----------------------------------------------------------------*/
397 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
402 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
404 resIfx->condition = 1; /* assume that the ifx is true */
405 resIfx->generated = 0; /* indicate that the ifx has not been used */
408 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
409 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
410 __FUNCTION__,__LINE__,resIfx->lbl->key);
413 resIfx->lbl = IC_TRUE(ifx);
415 resIfx->lbl = IC_FALSE(ifx);
416 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
424 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
433 return PTR_TYPE(SPEC_OCLS(etype));
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
443 memmap *space= SPEC_OCLS(sym->etype);
445 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446 /* if already has one */
450 /* assign depending on the storage class */
451 /* if it is on the stack or indirectly addressable */
452 /* space we need to assign either r0 or r1 to it */
453 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454 sym->aop = aop = newAsmop(0);
455 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456 aop->size = getSize(sym->type);
458 /* now assign the address of the variable to
459 the pointer register */
460 if (aop->type != AOP_STK) {
464 pic14_emitcode("push","acc");
466 pic14_emitcode("mov","a,_bp");
467 pic14_emitcode("add","a,#0x%02x",
469 ((char)(sym->stack - _G.nRegsSaved )) :
470 ((char)sym->stack)) & 0xff);
471 pic14_emitcode("mov","%s,a",
472 aop->aopu.aop_ptr->name);
475 pic14_emitcode("pop","acc");
477 pic14_emitcode("mov","%s,#%s",
478 aop->aopu.aop_ptr->name,
480 aop->paged = space->paged;
482 aop->aopu.aop_stk = sym->stack;
486 if (sym->onStack && options.stack10bit)
488 /* It's on the 10 bit stack, which is located in
492 //DEBUGpic14_emitcode(";","%d",__LINE__);
495 pic14_emitcode("push","acc");
497 pic14_emitcode("mov","a,_bp");
498 pic14_emitcode("add","a,#0x%02x",
500 ((char)(sym->stack - _G.nRegsSaved )) :
501 ((char)sym->stack)) & 0xff);
504 pic14_emitcode ("mov","dpx1,#0x40");
505 pic14_emitcode ("mov","dph1,#0x00");
506 pic14_emitcode ("mov","dpl1, a");
510 pic14_emitcode("pop","acc");
512 sym->aop = aop = newAsmop(AOP_DPTR2);
513 aop->size = getSize(sym->type);
517 //DEBUGpic14_emitcode(";","%d",__LINE__);
518 /* if in bit space */
519 if (IN_BITSPACE(space)) {
520 sym->aop = aop = newAsmop (AOP_CRY);
521 aop->aopu.aop_dir = sym->rname ;
522 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
526 /* if it is in direct space */
527 if (IN_DIRSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_DIR);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
535 /* special case for a function */
536 if (IS_FUNC(sym->type)) {
537 sym->aop = aop = newAsmop(AOP_IMMD);
538 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
539 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
540 strcpy(aop->aopu.aop_immd,sym->rname);
541 aop->size = FPTRSIZE;
542 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
547 /* only remaining is far space */
548 /* in which case DPTR gets the address */
549 sym->aop = aop = newAsmop(AOP_PCODE);
551 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
552 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
553 PCOI(aop->aopu.pcop)->index = 0;
555 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
556 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
558 allocDirReg (IC_LEFT(ic));
560 aop->size = FPTRSIZE;
562 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
563 sym->aop = aop = newAsmop(AOP_DPTR);
564 pic14_emitcode ("mov","dptr,#%s", sym->rname);
565 aop->size = getSize(sym->type);
567 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
570 /* if it is in code space */
571 if (IN_CODESPACE(space))
577 /*-----------------------------------------------------------------*/
578 /* aopForRemat - rematerialzes an object */
579 /*-----------------------------------------------------------------*/
580 static asmop *aopForRemat (operand *op) // x symbol *sym)
582 symbol *sym = OP_SYMBOL(op);
584 asmop *aop = newAsmop(AOP_PCODE);
588 ic = sym->rematiCode;
590 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
591 if(IS_OP_POINTER(op)) {
592 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
596 val += (int) operandLitValue(IC_RIGHT(ic));
597 } else if (ic->op == '-') {
598 val -= (int) operandLitValue(IC_RIGHT(ic));
602 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
605 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
606 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
607 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
608 PCOI(aop->aopu.pcop)->index = val;
610 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
611 OP_SYMBOL(IC_LEFT(ic))->rname,
612 val, IS_PTR_CONST(operandType(op)));
614 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
616 allocDirReg (IC_LEFT(ic));
621 int aopIdx (asmop *aop, int offset)
626 if(aop->type != AOP_REG)
629 return aop->aopu.aop_reg[offset]->rIdx;
632 /*-----------------------------------------------------------------*/
633 /* regsInCommon - two operands have some registers in common */
634 /*-----------------------------------------------------------------*/
635 static bool regsInCommon (operand *op1, operand *op2)
640 /* if they have registers in common */
641 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
644 sym1 = OP_SYMBOL(op1);
645 sym2 = OP_SYMBOL(op2);
647 if (sym1->nRegs == 0 || sym2->nRegs == 0)
650 for (i = 0 ; i < sym1->nRegs ; i++) {
655 for (j = 0 ; j < sym2->nRegs ;j++ ) {
659 if (sym2->regs[j] == sym1->regs[i])
667 /*-----------------------------------------------------------------*/
668 /* operandsEqu - equivalent */
669 /*-----------------------------------------------------------------*/
670 static bool operandsEqu ( operand *op1, operand *op2)
674 /* if they not symbols */
675 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
678 sym1 = OP_SYMBOL(op1);
679 sym2 = OP_SYMBOL(op2);
681 /* if both are itemps & one is spilt
682 and the other is not then false */
683 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
684 sym1->isspilt != sym2->isspilt )
687 /* if they are the same */
691 if (strcmp(sym1->rname,sym2->rname) == 0)
695 /* if left is a tmp & right is not */
699 (sym1->usl.spillLoc == sym2))
706 (sym2->usl.spillLoc == sym1))
712 /*-----------------------------------------------------------------*/
713 /* pic14_sameRegs - two asmops have the same registers */
714 /*-----------------------------------------------------------------*/
715 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 if (aop1->type != AOP_REG ||
723 aop2->type != AOP_REG )
726 if (aop1->size != aop2->size )
729 for (i = 0 ; i < aop1->size ; i++ )
730 if (aop1->aopu.aop_reg[i] !=
731 aop2->aopu.aop_reg[i] )
737 /*-----------------------------------------------------------------*/
738 /* aopOp - allocates an asmop for an operand : */
739 /*-----------------------------------------------------------------*/
740 void aopOp (operand *op, iCode *ic, bool result)
749 // DEBUGpic14_emitcode(";","%d",__LINE__);
750 /* if this a literal */
751 if (IS_OP_LITERAL(op)) {
752 op->aop = aop = newAsmop(AOP_LIT);
753 aop->aopu.aop_lit = op->operand.valOperand;
754 aop->size = getSize(operandType(op));
759 sym_link *type = operandType(op);
760 if(IS_PTR_CONST(type))
761 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
764 /* if already has a asmop then continue */
768 /* if the underlying symbol has a aop */
769 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
770 DEBUGpic14_emitcode(";","%d",__LINE__);
771 op->aop = OP_SYMBOL(op)->aop;
775 /* if this is a true symbol */
776 if (IS_TRUE_SYMOP(op)) {
777 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
778 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
782 /* this is a temporary : this has
788 e) can be a return use only */
793 /* if the type is a conditional */
794 if (sym->regType == REG_CND) {
795 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
800 /* if it is spilt then two situations
802 b) has a spill location */
803 if (sym->isspilt || sym->nRegs == 0) {
805 DEBUGpic14_emitcode(";","%d",__LINE__);
806 /* rematerialize it NOW */
809 sym->aop = op->aop = aop =
811 aop->size = getSize(sym->type);
812 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
818 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
819 aop->size = getSize(sym->type);
820 for ( i = 0 ; i < 2 ; i++ )
821 aop->aopu.aop_str[i] = accUse[i];
822 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
828 aop = op->aop = sym->aop = newAsmop(AOP_STR);
829 aop->size = getSize(sym->type);
830 for ( i = 0 ; i < fReturnSizePic ; i++ )
831 aop->aopu.aop_str[i] = fReturn[i];
832 DEBUGpic14_emitcode(";","%d",__LINE__);
836 /* else spill location */
837 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
838 /* force a new aop if sizes differ */
839 sym->usl.spillLoc->aop = NULL;
841 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
842 __FUNCTION__,__LINE__,
843 sym->usl.spillLoc->rname,
844 sym->rname, sym->usl.spillLoc->offset);
845 // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
846 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
847 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
848 //allocDirReg (IC_LEFT(ic));
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 sym->aop = op->aop = aop = newAsmop(AOP_REG);
862 aop->size = sym->nRegs;
863 for ( i = 0 ; i < sym->nRegs ;i++)
864 aop->aopu.aop_reg[i] = sym->regs[i];
867 /*-----------------------------------------------------------------*/
868 /* freeAsmop - free up the asmop given to an operand */
869 /*----------------------------------------------------------------*/
870 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
887 /* depending on the asmop type only three cases need work AOP_RO
888 , AOP_R1 && AOP_STK */
894 pic14_emitcode ("pop","ar0");
898 bitVectUnSetBit(ic->rUsed,R0_IDX);
904 pic14_emitcode ("pop","ar1");
908 bitVectUnSetBit(ic->rUsed,R1_IDX);
914 int stk = aop->aopu.aop_stk + aop->size;
915 bitVectUnSetBit(ic->rUsed,R0_IDX);
916 bitVectUnSetBit(ic->rUsed,R1_IDX);
918 getFreePtr(ic,&aop,FALSE);
920 if (options.stack10bit)
922 /* I'm not sure what to do here yet... */
925 "*** Warning: probably generating bad code for "
926 "10 bit stack mode.\n");
930 pic14_emitcode ("mov","a,_bp");
931 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
932 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
934 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
938 pic14_emitcode("pop","acc");
939 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
941 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
944 freeAsmop(op,NULL,ic,TRUE);
946 pic14_emitcode("pop","ar0");
951 pic14_emitcode("pop","ar1");
959 /* all other cases just dealloc */
963 OP_SYMBOL(op)->aop = NULL;
964 /* if the symbol has a spill */
966 SPIL_LOC(op)->aop = NULL;
971 /*-----------------------------------------------------------------*/
972 /* aopGet - for fetching value of the aop */
973 /*-----------------------------------------------------------------*/
974 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
979 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
980 /* offset is greater than
982 if (offset > (aop->size - 1) &&
983 aop->type != AOP_LIT)
986 /* depending on type */
991 DEBUGpic14_emitcode(";","%d",__LINE__);
992 /* if we need to increment it */
993 while (offset > aop->coff) {
994 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
998 while (offset < aop->coff) {
999 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1003 aop->coff = offset ;
1005 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1006 return (dname ? "acc" : "a");
1008 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1009 rs = Safe_calloc(1,strlen(s)+1);
1015 DEBUGpic14_emitcode(";","%d",__LINE__);
1016 if (aop->type == AOP_DPTR2)
1021 while (offset > aop->coff) {
1022 pic14_emitcode ("inc","dptr");
1026 while (offset < aop->coff) {
1027 pic14_emitcode("lcall","__decdptr");
1033 pic14_emitcode("clr","a");
1034 pic14_emitcode("movc","a,@a+dptr");
1037 pic14_emitcode("movx","a,@dptr");
1040 if (aop->type == AOP_DPTR2)
1045 return (dname ? "acc" : "a");
1050 sprintf (s,"%s",aop->aopu.aop_immd);
1053 sprintf(s,"(%s >> %d)",
1058 aop->aopu.aop_immd);
1059 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1060 rs = Safe_calloc(1,strlen(s)+1);
1066 sprintf(s,"(%s + %d)",
1069 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1071 sprintf(s,"%s",aop->aopu.aop_dir);
1072 rs = Safe_calloc(1,strlen(s)+1);
1078 // return aop->aopu.aop_reg[offset]->dname;
1080 return aop->aopu.aop_reg[offset]->name;
1083 //pic14_emitcode(";","%d",__LINE__);
1084 return aop->aopu.aop_dir;
1087 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1088 return "AOP_accumulator_bug";
1091 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1092 rs = Safe_calloc(1,strlen(s)+1);
1097 DEBUGpic14_emitcode(";","%d",__LINE__);
1098 aop->coff = offset ;
1099 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1103 return aop->aopu.aop_str[offset];
1107 pCodeOp *pcop = aop->aopu.pcop;
1108 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
1110 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1111 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1112 sprintf(s,"%s", pcop->name);
1114 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1117 rs = Safe_calloc(1,strlen(s)+1);
1123 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1124 "aopget got unsupported aop->type");
1129 /*-----------------------------------------------------------------*/
1130 /* popGetTempReg - create a new temporary pCodeOp */
1131 /*-----------------------------------------------------------------*/
1132 pCodeOp *popGetTempReg(void)
1137 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1138 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1139 PCOR(pcop)->r->wasUsed=1;
1140 PCOR(pcop)->r->isFree=0;
1146 /*-----------------------------------------------------------------*/
1147 /* popGetTempReg - create a new temporary pCodeOp */
1148 /*-----------------------------------------------------------------*/
1149 void popReleaseTempReg(pCodeOp *pcop)
1152 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1153 PCOR(pcop)->r->isFree = 1;
1156 /*-----------------------------------------------------------------*/
1157 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1158 /*-----------------------------------------------------------------*/
1159 pCodeOp *popGetLabel(unsigned int key)
1162 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1167 return newpCodeOpLabel(NULL,key+100+labelOffset);
1170 /*-----------------------------------------------------------------*/
1171 /* popCopyReg - copy a pcode operator */
1172 /*-----------------------------------------------------------------*/
1173 pCodeOp *popCopyReg(pCodeOpReg *pc)
1177 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1178 pcor->pcop.type = pc->pcop.type;
1180 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1181 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1183 pcor->pcop.name = NULL;
1186 pcor->rIdx = pc->rIdx;
1189 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1193 /*-----------------------------------------------------------------*/
1194 /* popGet - asm operator to pcode operator conversion */
1195 /*-----------------------------------------------------------------*/
1196 pCodeOp *popGetLit(unsigned int lit)
1199 return newpCodeOpLit(lit);
1203 /*-----------------------------------------------------------------*/
1204 /* popGetImmd - asm operator to pcode immediate conversion */
1205 /*-----------------------------------------------------------------*/
1206 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1209 return newpCodeOpImmd(name, offset,index, 0);
1213 /*-----------------------------------------------------------------*/
1214 /* popGet - asm operator to pcode operator conversion */
1215 /*-----------------------------------------------------------------*/
1216 pCodeOp *popGetWithString(char *str)
1222 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1226 pcop = newpCodeOp(str,PO_STR);
1231 pCodeOp *popRegFromString(char *str)
1234 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1235 pcop->type = PO_DIR;
1237 DEBUGpic14_emitcode(";","%d",__LINE__);
1238 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1243 pCodeOp *popRegFromIdx(int rIdx)
1247 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1248 __FUNCTION__,__LINE__,rIdx);
1250 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1252 PCOR(pcop)->rIdx = rIdx;
1253 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1254 PCOR(pcop)->r->isFree = 0;
1255 PCOR(pcop)->r->wasUsed = 1;
1257 pcop->type = PCOR(pcop)->r->pc_type;
1262 /*-----------------------------------------------------------------*/
1263 /* popGet - asm operator to pcode operator conversion */
1264 /*-----------------------------------------------------------------*/
1265 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1267 //char *s = buffer ;
1272 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1273 /* offset is greater than
1276 if (offset > (aop->size - 1) &&
1277 aop->type != AOP_LIT)
1278 return NULL; //zero;
1280 /* depending on type */
1281 switch (aop->type) {
1288 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1292 DEBUGpic14_emitcode(";","%d",__LINE__);
1293 return popGetImmd(aop->aopu.aop_immd,offset,0);
1296 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1297 pcop->type = PO_DIR;
1301 sprintf(s,"(%s + %d)",
1305 sprintf(s,"%s",aop->aopu.aop_dir);
1306 pcop->name = Safe_calloc(1,strlen(s)+1);
1307 strcpy(pcop->name,s);
1309 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1310 strcpy(pcop->name,aop->aopu.aop_dir);
1311 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1312 if(PCOR(pcop)->r == NULL) {
1313 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1314 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1315 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1317 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1319 PCOR(pcop)->instance = offset;
1325 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1327 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1328 PCOR(pcop)->rIdx = rIdx;
1329 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1330 PCOR(pcop)->r->wasUsed=1;
1331 PCOR(pcop)->r->isFree=0;
1333 PCOR(pcop)->instance = offset;
1334 pcop->type = PCOR(pcop)->r->pc_type;
1335 //rs = aop->aopu.aop_reg[offset]->name;
1336 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1341 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1342 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1343 //if(PCOR(pcop)->r == NULL)
1344 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1348 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1351 DEBUGpic14_emitcode(";","%d",__LINE__);
1352 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1354 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1355 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1356 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1357 pcop->type = PCOR(pcop)->r->pc_type;
1358 pcop->name = PCOR(pcop)->r->name;
1364 DEBUGpic14_emitcode(";","popGet AOP_PCODE %d %s",__LINE__,
1365 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1366 pcop = pCodeOpCopy(aop->aopu.pcop);
1367 PCOI(pcop)->offset = offset;
1371 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1372 "popGet got unsupported aop->type");
1375 /*-----------------------------------------------------------------*/
1376 /* aopPut - puts a string for a aop */
1377 /*-----------------------------------------------------------------*/
1378 void aopPut (asmop *aop, char *s, int offset)
1383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1385 if (aop->size && offset > ( aop->size - 1)) {
1386 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1387 "aopPut got offset > aop->size");
1391 /* will assign value to value */
1392 /* depending on where it is ofcourse */
1393 switch (aop->type) {
1396 sprintf(d,"(%s + %d)",
1397 aop->aopu.aop_dir,offset);
1398 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1401 sprintf(d,"%s",aop->aopu.aop_dir);
1404 DEBUGpic14_emitcode(";","%d",__LINE__);
1406 pic14_emitcode("movf","%s,w",s);
1407 pic14_emitcode("movwf","%s",d);
1410 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1411 if(offset >= aop->size) {
1412 emitpcode(POC_CLRF,popGet(aop,offset));
1415 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1418 emitpcode(POC_MOVWF,popGet(aop,offset));
1425 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1426 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1429 strcmp(s,"r0") == 0 ||
1430 strcmp(s,"r1") == 0 ||
1431 strcmp(s,"r2") == 0 ||
1432 strcmp(s,"r3") == 0 ||
1433 strcmp(s,"r4") == 0 ||
1434 strcmp(s,"r5") == 0 ||
1435 strcmp(s,"r6") == 0 ||
1436 strcmp(s,"r7") == 0 )
1437 pic14_emitcode("mov","%s,%s ; %d",
1438 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1442 if(strcmp(s,"W")==0 )
1443 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1445 pic14_emitcode("movwf","%s",
1446 aop->aopu.aop_reg[offset]->name);
1448 if(strcmp(s,zero)==0) {
1449 emitpcode(POC_CLRF,popGet(aop,offset));
1451 } else if(strcmp(s,"W")==0) {
1452 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1453 pcop->type = PO_GPR_REGISTER;
1455 PCOR(pcop)->rIdx = -1;
1456 PCOR(pcop)->r = NULL;
1458 DEBUGpic14_emitcode(";","%d",__LINE__);
1459 pcop->name = Safe_strdup(s);
1460 emitpcode(POC_MOVFW,pcop);
1461 emitpcode(POC_MOVWF,popGet(aop,offset));
1462 } else if(strcmp(s,one)==0) {
1463 emitpcode(POC_CLRF,popGet(aop,offset));
1464 emitpcode(POC_INCF,popGet(aop,offset));
1466 emitpcode(POC_MOVWF,popGet(aop,offset));
1474 if (aop->type == AOP_DPTR2)
1480 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1481 "aopPut writting to code space");
1485 while (offset > aop->coff) {
1487 pic14_emitcode ("inc","dptr");
1490 while (offset < aop->coff) {
1492 pic14_emitcode("lcall","__decdptr");
1497 /* if not in accumulater */
1500 pic14_emitcode ("movx","@dptr,a");
1502 if (aop->type == AOP_DPTR2)
1510 while (offset > aop->coff) {
1512 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1514 while (offset < aop->coff) {
1516 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1522 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1527 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1529 if (strcmp(s,"r0") == 0 ||
1530 strcmp(s,"r1") == 0 ||
1531 strcmp(s,"r2") == 0 ||
1532 strcmp(s,"r3") == 0 ||
1533 strcmp(s,"r4") == 0 ||
1534 strcmp(s,"r5") == 0 ||
1535 strcmp(s,"r6") == 0 ||
1536 strcmp(s,"r7") == 0 ) {
1538 sprintf(buffer,"a%s",s);
1539 pic14_emitcode("mov","@%s,%s",
1540 aop->aopu.aop_ptr->name,buffer);
1542 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1547 if (strcmp(s,"a") == 0)
1548 pic14_emitcode("push","acc");
1550 pic14_emitcode("push","%s",s);
1555 /* if bit variable */
1556 if (!aop->aopu.aop_dir) {
1557 pic14_emitcode("clr","a");
1558 pic14_emitcode("rlc","a");
1561 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1564 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1567 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1569 lbl = newiTempLabel(NULL);
1571 if (strcmp(s,"a")) {
1574 pic14_emitcode("clr","c");
1575 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1576 pic14_emitcode("cpl","c");
1577 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1578 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1585 if (strcmp(aop->aopu.aop_str[offset],s))
1586 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1591 if (!offset && (strcmp(s,"acc") == 0))
1594 if (strcmp(aop->aopu.aop_str[offset],s))
1595 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1599 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1600 "aopPut got unsupported aop->type");
1606 /*-----------------------------------------------------------------*/
1607 /* reAdjustPreg - points a register back to where it should */
1608 /*-----------------------------------------------------------------*/
1609 static void reAdjustPreg (asmop *aop)
1613 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1615 if ((size = aop->size) <= 1)
1618 switch (aop->type) {
1622 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1626 if (aop->type == AOP_DPTR2)
1632 pic14_emitcode("lcall","__decdptr");
1635 if (aop->type == AOP_DPTR2)
1645 /*-----------------------------------------------------------------*/
1646 /* genNotFloat - generates not for float operations */
1647 /*-----------------------------------------------------------------*/
1648 static void genNotFloat (operand *op, operand *res)
1654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1655 /* we will put 127 in the first byte of
1657 aopPut(AOP(res),"#127",0);
1658 size = AOP_SIZE(op) - 1;
1661 l = aopGet(op->aop,offset++,FALSE,FALSE);
1665 pic14_emitcode("orl","a,%s",
1667 offset++,FALSE,FALSE));
1669 tlbl = newiTempLabel(NULL);
1671 tlbl = newiTempLabel(NULL);
1672 aopPut(res->aop,one,1);
1673 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1674 aopPut(res->aop,zero,1);
1675 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1677 size = res->aop->size - 2;
1679 /* put zeros in the rest */
1681 aopPut(res->aop,zero,offset++);
1685 /*-----------------------------------------------------------------*/
1686 /* opIsGptr: returns non-zero if the passed operand is */
1687 /* a generic pointer type. */
1688 /*-----------------------------------------------------------------*/
1689 static int opIsGptr(operand *op)
1691 sym_link *type = operandType(op);
1693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1694 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1702 /*-----------------------------------------------------------------*/
1703 /* pic14_getDataSize - get the operand data size */
1704 /*-----------------------------------------------------------------*/
1705 int pic14_getDataSize(operand *op)
1707 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1710 return AOP_SIZE(op);
1712 // tsd- in the pic port, the genptr size is 1, so this code here
1713 // fails. ( in the 8051 port, the size was 4).
1716 size = AOP_SIZE(op);
1717 if (size == GPTRSIZE)
1719 sym_link *type = operandType(op);
1720 if (IS_GENPTR(type))
1722 /* generic pointer; arithmetic operations
1723 * should ignore the high byte (pointer type).
1726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1733 /*-----------------------------------------------------------------*/
1734 /* pic14_outAcc - output Acc */
1735 /*-----------------------------------------------------------------*/
1736 void pic14_outAcc(operand *result)
1739 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1740 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1743 size = pic14_getDataSize(result);
1745 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1748 /* unsigned or positive */
1750 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1755 /*-----------------------------------------------------------------*/
1756 /* pic14_outBitC - output a bit C */
1757 /*-----------------------------------------------------------------*/
1758 void pic14_outBitC(operand *result)
1761 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1762 /* if the result is bit */
1763 if (AOP_TYPE(result) == AOP_CRY)
1764 aopPut(AOP(result),"c",0);
1766 pic14_emitcode("clr","a ; %d", __LINE__);
1767 pic14_emitcode("rlc","a");
1768 pic14_outAcc(result);
1772 /*-----------------------------------------------------------------*/
1773 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1774 /*-----------------------------------------------------------------*/
1775 void pic14_toBoolean(operand *oper)
1777 int size = AOP_SIZE(oper) - 1;
1780 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1782 if ( AOP_TYPE(oper) != AOP_ACC) {
1783 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1786 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1791 /*-----------------------------------------------------------------*/
1792 /* genNot - generate code for ! operation */
1793 /*-----------------------------------------------------------------*/
1794 static void genNot (iCode *ic)
1797 sym_link *optype = operandType(IC_LEFT(ic));
1800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1801 /* assign asmOps to operand & result */
1802 aopOp (IC_LEFT(ic),ic,FALSE);
1803 aopOp (IC_RESULT(ic),ic,TRUE);
1805 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1806 /* if in bit space then a special case */
1807 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1808 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1809 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1810 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1812 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1813 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1814 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1819 /* if type float then do float */
1820 if (IS_FLOAT(optype)) {
1821 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1825 size = AOP_SIZE(IC_RESULT(ic));
1827 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1828 emitpcode(POC_ANDLW,popGetLit(1));
1829 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1832 pic14_toBoolean(IC_LEFT(ic));
1834 tlbl = newiTempLabel(NULL);
1835 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1836 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1837 pic14_outBitC(IC_RESULT(ic));
1840 /* release the aops */
1841 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1842 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1846 /*-----------------------------------------------------------------*/
1847 /* genCpl - generate code for complement */
1848 /*-----------------------------------------------------------------*/
1849 static void genCpl (iCode *ic)
1855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1856 /* assign asmOps to operand & result */
1857 aopOp (IC_LEFT(ic),ic,FALSE);
1858 aopOp (IC_RESULT(ic),ic,TRUE);
1860 /* if both are in bit space then
1862 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1863 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1865 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1866 pic14_emitcode("cpl","c");
1867 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1871 size = AOP_SIZE(IC_RESULT(ic));
1873 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1875 pic14_emitcode("cpl","a");
1876 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1881 /* release the aops */
1882 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1883 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1886 /*-----------------------------------------------------------------*/
1887 /* genUminusFloat - unary minus for floating points */
1888 /*-----------------------------------------------------------------*/
1889 static void genUminusFloat(operand *op,operand *result)
1891 int size ,offset =0 ;
1894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1895 /* for this we just need to flip the
1896 first it then copy the rest in place */
1897 size = AOP_SIZE(op) - 1;
1898 l = aopGet(AOP(op),3,FALSE,FALSE);
1902 pic14_emitcode("cpl","acc.7");
1903 aopPut(AOP(result),"a",3);
1907 aopGet(AOP(op),offset,FALSE,FALSE),
1913 /*-----------------------------------------------------------------*/
1914 /* genUminus - unary minus code generation */
1915 /*-----------------------------------------------------------------*/
1916 static void genUminus (iCode *ic)
1919 sym_link *optype, *rtype;
1922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1924 aopOp(IC_LEFT(ic),ic,FALSE);
1925 aopOp(IC_RESULT(ic),ic,TRUE);
1927 /* if both in bit space then special
1929 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1930 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1932 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1933 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1934 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1939 optype = operandType(IC_LEFT(ic));
1940 rtype = operandType(IC_RESULT(ic));
1942 /* if float then do float stuff */
1943 if (IS_FLOAT(optype)) {
1944 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1948 /* otherwise subtract from zero by taking the 2's complement */
1949 size = AOP_SIZE(IC_LEFT(ic));
1951 for(i=0; i<size; i++) {
1952 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1953 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1955 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1956 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1960 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1961 for(i=1; i<size; i++) {
1963 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1967 /* release the aops */
1968 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1969 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1972 /*-----------------------------------------------------------------*/
1973 /* saveRegisters - will look for a call and save the registers */
1974 /*-----------------------------------------------------------------*/
1975 static void saveRegisters(iCode *lic)
1982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1984 for (ic = lic ; ic ; ic = ic->next)
1985 if (ic->op == CALL || ic->op == PCALL)
1989 fprintf(stderr,"found parameter push with no function call\n");
1993 /* if the registers have been saved already then
1995 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1998 /* find the registers in use at this time
1999 and push them away to safety */
2000 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2004 if (options.useXstack) {
2005 if (bitVectBitValue(rsave,R0_IDX))
2006 pic14_emitcode("mov","b,r0");
2007 pic14_emitcode("mov","r0,%s",spname);
2008 for (i = 0 ; i < pic14_nRegs ; i++) {
2009 if (bitVectBitValue(rsave,i)) {
2011 pic14_emitcode("mov","a,b");
2013 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2014 pic14_emitcode("movx","@r0,a");
2015 pic14_emitcode("inc","r0");
2018 pic14_emitcode("mov","%s,r0",spname);
2019 if (bitVectBitValue(rsave,R0_IDX))
2020 pic14_emitcode("mov","r0,b");
2022 //for (i = 0 ; i < pic14_nRegs ; i++) {
2023 // if (bitVectBitValue(rsave,i))
2024 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2027 dtype = operandType(IC_LEFT(ic));
2028 if (currFunc && dtype &&
2029 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2030 IFFUNC_ISISR(currFunc->type) &&
2033 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2036 /*-----------------------------------------------------------------*/
2037 /* unsaveRegisters - pop the pushed registers */
2038 /*-----------------------------------------------------------------*/
2039 static void unsaveRegisters (iCode *ic)
2044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2045 /* find the registers in use at this time
2046 and push them away to safety */
2047 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2050 if (options.useXstack) {
2051 pic14_emitcode("mov","r0,%s",spname);
2052 for (i = pic14_nRegs ; i >= 0 ; i--) {
2053 if (bitVectBitValue(rsave,i)) {
2054 pic14_emitcode("dec","r0");
2055 pic14_emitcode("movx","a,@r0");
2057 pic14_emitcode("mov","b,a");
2059 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2063 pic14_emitcode("mov","%s,r0",spname);
2064 if (bitVectBitValue(rsave,R0_IDX))
2065 pic14_emitcode("mov","r0,b");
2067 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2068 // if (bitVectBitValue(rsave,i))
2069 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2075 /*-----------------------------------------------------------------*/
2077 /*-----------------------------------------------------------------*/
2078 static void pushSide(operand * oper, int size)
2082 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2084 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2085 if (AOP_TYPE(oper) != AOP_REG &&
2086 AOP_TYPE(oper) != AOP_DIR &&
2088 pic14_emitcode("mov","a,%s",l);
2089 pic14_emitcode("push","acc");
2091 pic14_emitcode("push","%s",l);
2096 /*-----------------------------------------------------------------*/
2097 /* assignResultValue - */
2098 /*-----------------------------------------------------------------*/
2099 static void assignResultValue(operand * oper)
2101 int size = AOP_SIZE(oper);
2103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2105 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2107 if(!GpsuedoStkPtr) {
2108 /* The last byte in the assignment is in W */
2110 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2115 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2117 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2122 /*-----------------------------------------------------------------*/
2123 /* genIpush - genrate code for pushing this gets a little complex */
2124 /*-----------------------------------------------------------------*/
2125 static void genIpush (iCode *ic)
2128 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2130 int size, offset = 0 ;
2134 /* if this is not a parm push : ie. it is spill push
2135 and spill push is always done on the local stack */
2136 if (!ic->parmPush) {
2138 /* and the item is spilt then do nothing */
2139 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2142 aopOp(IC_LEFT(ic),ic,FALSE);
2143 size = AOP_SIZE(IC_LEFT(ic));
2144 /* push it on the stack */
2146 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2151 pic14_emitcode("push","%s",l);
2156 /* this is a paramter push: in this case we call
2157 the routine to find the call and save those
2158 registers that need to be saved */
2161 /* then do the push */
2162 aopOp(IC_LEFT(ic),ic,FALSE);
2165 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2166 size = AOP_SIZE(IC_LEFT(ic));
2169 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2170 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2171 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2173 pic14_emitcode("mov","a,%s",l);
2174 pic14_emitcode("push","acc");
2176 pic14_emitcode("push","%s",l);
2179 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2183 /*-----------------------------------------------------------------*/
2184 /* genIpop - recover the registers: can happen only for spilling */
2185 /*-----------------------------------------------------------------*/
2186 static void genIpop (iCode *ic)
2188 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2193 /* if the temp was not pushed then */
2194 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2197 aopOp(IC_LEFT(ic),ic,FALSE);
2198 size = AOP_SIZE(IC_LEFT(ic));
2201 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2204 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2208 /*-----------------------------------------------------------------*/
2209 /* unsaverbank - restores the resgister bank from stack */
2210 /*-----------------------------------------------------------------*/
2211 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2213 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2221 if (options.useXstack) {
2223 r = getFreePtr(ic,&aop,FALSE);
2226 pic14_emitcode("mov","%s,_spx",r->name);
2227 pic14_emitcode("movx","a,@%s",r->name);
2228 pic14_emitcode("mov","psw,a");
2229 pic14_emitcode("dec","%s",r->name);
2232 pic14_emitcode ("pop","psw");
2235 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2236 if (options.useXstack) {
2237 pic14_emitcode("movx","a,@%s",r->name);
2238 //pic14_emitcode("mov","(%s+%d),a",
2239 // regspic14[i].base,8*bank+regspic14[i].offset);
2240 pic14_emitcode("dec","%s",r->name);
2243 pic14_emitcode("pop",""); //"(%s+%d)",
2244 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2247 if (options.useXstack) {
2249 pic14_emitcode("mov","_spx,%s",r->name);
2250 freeAsmop(NULL,aop,ic,TRUE);
2256 /*-----------------------------------------------------------------*/
2257 /* saverbank - saves an entire register bank on the stack */
2258 /*-----------------------------------------------------------------*/
2259 static void saverbank (int bank, iCode *ic, bool pushPsw)
2261 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2267 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2268 if (options.useXstack) {
2271 r = getFreePtr(ic,&aop,FALSE);
2272 pic14_emitcode("mov","%s,_spx",r->name);
2276 for (i = 0 ; i < pic14_nRegs ;i++) {
2277 if (options.useXstack) {
2278 pic14_emitcode("inc","%s",r->name);
2279 //pic14_emitcode("mov","a,(%s+%d)",
2280 // regspic14[i].base,8*bank+regspic14[i].offset);
2281 pic14_emitcode("movx","@%s,a",r->name);
2283 pic14_emitcode("push","");// "(%s+%d)",
2284 //regspic14[i].base,8*bank+regspic14[i].offset);
2288 if (options.useXstack) {
2289 pic14_emitcode("mov","a,psw");
2290 pic14_emitcode("movx","@%s,a",r->name);
2291 pic14_emitcode("inc","%s",r->name);
2292 pic14_emitcode("mov","_spx,%s",r->name);
2293 freeAsmop (NULL,aop,ic,TRUE);
2296 pic14_emitcode("push","psw");
2298 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2304 /*-----------------------------------------------------------------*/
2305 /* genCall - generates a call statement */
2306 /*-----------------------------------------------------------------*/
2307 static void genCall (iCode *ic)
2311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2313 /* if caller saves & we have not saved then */
2317 /* if we are calling a function that is not using
2318 the same register bank then we need to save the
2319 destination registers on the stack */
2320 dtype = operandType(IC_LEFT(ic));
2321 if (currFunc && dtype &&
2322 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2323 IFFUNC_ISISR(currFunc->type) &&
2326 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2328 /* if send set is not empty the assign */
2331 /* For the Pic port, there is no data stack.
2332 * So parameters passed to functions are stored
2333 * in registers. (The pCode optimizer will get
2334 * rid of most of these :).
2336 int psuedoStkPtr=-1;
2337 int firstTimeThruLoop = 1;
2339 _G.sendSet = reverseSet(_G.sendSet);
2341 /* First figure how many parameters are getting passed */
2342 for (sic = setFirstItem(_G.sendSet) ; sic ;
2343 sic = setNextItem(_G.sendSet)) {
2345 aopOp(IC_LEFT(sic),sic,FALSE);
2346 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2347 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2350 for (sic = setFirstItem(_G.sendSet) ; sic ;
2351 sic = setNextItem(_G.sendSet)) {
2352 int size, offset = 0;
2354 aopOp(IC_LEFT(sic),sic,FALSE);
2355 size = AOP_SIZE(IC_LEFT(sic));
2358 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2359 AopType(AOP_TYPE(IC_LEFT(sic))));
2361 if(!firstTimeThruLoop) {
2362 /* If this is not the first time we've been through the loop
2363 * then we need to save the parameter in a temporary
2364 * register. The last byte of the last parameter is
2366 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2369 firstTimeThruLoop=0;
2371 //if (strcmp(l,fReturn[offset])) {
2373 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2374 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2375 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2377 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2382 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2387 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2388 OP_SYMBOL(IC_LEFT(ic))->rname :
2389 OP_SYMBOL(IC_LEFT(ic))->name));
2392 /* if we need assign a result value */
2393 if ((IS_ITEMP(IC_RESULT(ic)) &&
2394 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2395 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2396 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2399 aopOp(IC_RESULT(ic),ic,FALSE);
2402 assignResultValue(IC_RESULT(ic));
2404 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2405 AopType(AOP_TYPE(IC_RESULT(ic))));
2407 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2410 /* adjust the stack for parameters if
2412 if (ic->parmBytes) {
2414 if (ic->parmBytes > 3) {
2415 pic14_emitcode("mov","a,%s",spname);
2416 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2417 pic14_emitcode("mov","%s,a",spname);
2419 for ( i = 0 ; i < ic->parmBytes ;i++)
2420 pic14_emitcode("dec","%s",spname);
2424 /* if register bank was saved then pop them */
2426 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2428 /* if we hade saved some registers then unsave them */
2429 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2430 unsaveRegisters (ic);
2435 /*-----------------------------------------------------------------*/
2436 /* genPcall - generates a call by pointer statement */
2437 /*-----------------------------------------------------------------*/
2438 static void genPcall (iCode *ic)
2441 symbol *rlbl = newiTempLabel(NULL);
2444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2445 /* if caller saves & we have not saved then */
2449 /* if we are calling a function that is not using
2450 the same register bank then we need to save the
2451 destination registers on the stack */
2452 dtype = operandType(IC_LEFT(ic));
2453 if (currFunc && dtype &&
2454 IFFUNC_ISISR(currFunc->type) &&
2455 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2456 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2459 /* push the return address on to the stack */
2460 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2461 pic14_emitcode("push","acc");
2462 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2463 pic14_emitcode("push","acc");
2465 if (options.model == MODEL_FLAT24)
2467 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2468 pic14_emitcode("push","acc");
2471 /* now push the calling address */
2472 aopOp(IC_LEFT(ic),ic,FALSE);
2474 pushSide(IC_LEFT(ic), FPTRSIZE);
2476 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2478 /* if send set is not empty the assign */
2482 for (sic = setFirstItem(_G.sendSet) ; sic ;
2483 sic = setNextItem(_G.sendSet)) {
2484 int size, offset = 0;
2485 aopOp(IC_LEFT(sic),sic,FALSE);
2486 size = AOP_SIZE(IC_LEFT(sic));
2488 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2490 if (strcmp(l,fReturn[offset]))
2491 pic14_emitcode("mov","%s,%s",
2496 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2501 pic14_emitcode("ret","");
2502 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2505 /* if we need assign a result value */
2506 if ((IS_ITEMP(IC_RESULT(ic)) &&
2507 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2508 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2509 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2512 aopOp(IC_RESULT(ic),ic,FALSE);
2515 assignResultValue(IC_RESULT(ic));
2517 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2520 /* adjust the stack for parameters if
2522 if (ic->parmBytes) {
2524 if (ic->parmBytes > 3) {
2525 pic14_emitcode("mov","a,%s",spname);
2526 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2527 pic14_emitcode("mov","%s,a",spname);
2529 for ( i = 0 ; i < ic->parmBytes ;i++)
2530 pic14_emitcode("dec","%s",spname);
2534 /* if register bank was saved then unsave them */
2535 if (currFunc && dtype &&
2536 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2537 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2539 /* if we hade saved some registers then
2542 unsaveRegisters (ic);
2546 /*-----------------------------------------------------------------*/
2547 /* resultRemat - result is rematerializable */
2548 /*-----------------------------------------------------------------*/
2549 static int resultRemat (iCode *ic)
2551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2552 if (SKIP_IC(ic) || ic->op == IFX)
2555 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2556 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2557 if (sym->remat && !POINTER_SET(ic))
2564 #if defined(__BORLANDC__) || defined(_MSC_VER)
2565 #define STRCASECMP stricmp
2567 #define STRCASECMP strcasecmp
2571 /*-----------------------------------------------------------------*/
2572 /* inExcludeList - return 1 if the string is in exclude Reg list */
2573 /*-----------------------------------------------------------------*/
2574 static bool inExcludeList(char *s)
2576 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2579 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2580 if (options.excludeRegs[i] &&
2581 STRCASECMP(options.excludeRegs[i],"none") == 0)
2584 for ( i = 0 ; options.excludeRegs[i]; i++) {
2585 if (options.excludeRegs[i] &&
2586 STRCASECMP(s,options.excludeRegs[i]) == 0)
2593 /*-----------------------------------------------------------------*/
2594 /* genFunction - generated code for function entry */
2595 /*-----------------------------------------------------------------*/
2596 static void genFunction (iCode *ic)
2601 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2603 labelOffset += (max_key+4);
2607 /* create the function header */
2608 pic14_emitcode(";","-----------------------------------------");
2609 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2610 pic14_emitcode(";","-----------------------------------------");
2612 pic14_emitcode("","%s:",sym->rname);
2613 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2615 ftype = operandType(IC_LEFT(ic));
2617 /* if critical function then turn interrupts off */
2618 if (IFFUNC_ISCRITICAL(ftype))
2619 pic14_emitcode("clr","ea");
2621 /* here we need to generate the equates for the
2622 register bank if required */
2624 if (FUNC_REGBANK(ftype) != rbank) {
2627 rbank = FUNC_REGBANK(ftype);
2628 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2629 if (strcmp(regspic14[i].base,"0") == 0)
2630 pic14_emitcode("","%s = 0x%02x",
2632 8*rbank+regspic14[i].offset);
2634 pic14_emitcode ("","%s = %s + 0x%02x",
2637 8*rbank+regspic14[i].offset);
2642 /* if this is an interrupt service routine then
2643 save acc, b, dpl, dph */
2644 if (IFFUNC_ISISR(sym->type)) {
2645 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2646 emitpcodeNULLop(POC_NOP);
2647 emitpcodeNULLop(POC_NOP);
2648 emitpcodeNULLop(POC_NOP);
2649 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2650 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2651 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2652 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2654 pBlockConvert2ISR(pb);
2656 if (!inExcludeList("acc"))
2657 pic14_emitcode ("push","acc");
2658 if (!inExcludeList("b"))
2659 pic14_emitcode ("push","b");
2660 if (!inExcludeList("dpl"))
2661 pic14_emitcode ("push","dpl");
2662 if (!inExcludeList("dph"))
2663 pic14_emitcode ("push","dph");
2664 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2666 pic14_emitcode ("push", "dpx");
2667 /* Make sure we're using standard DPTR */
2668 pic14_emitcode ("push", "dps");
2669 pic14_emitcode ("mov", "dps, #0x00");
2670 if (options.stack10bit)
2672 /* This ISR could conceivably use DPTR2. Better save it. */
2673 pic14_emitcode ("push", "dpl1");
2674 pic14_emitcode ("push", "dph1");
2675 pic14_emitcode ("push", "dpx1");
2678 /* if this isr has no bank i.e. is going to
2679 run with bank 0 , then we need to save more
2681 if (!FUNC_REGBANK(sym->type)) {
2683 /* if this function does not call any other
2684 function then we can be economical and
2685 save only those registers that are used */
2686 if (! IFFUNC_HASFCALL(sym->type)) {
2689 /* if any registers used */
2690 if (sym->regsUsed) {
2691 /* save the registers used */
2692 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2693 if (bitVectBitValue(sym->regsUsed,i) ||
2694 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2695 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2700 /* this function has a function call cannot
2701 determines register usage so we will have the
2703 saverbank(0,ic,FALSE);
2708 /* if callee-save to be used for this function
2709 then save the registers being used in this function */
2710 if (IFFUNC_CALLEESAVES(sym->type)) {
2713 /* if any registers used */
2714 if (sym->regsUsed) {
2715 /* save the registers used */
2716 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2717 if (bitVectBitValue(sym->regsUsed,i) ||
2718 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2719 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2727 /* set the register bank to the desired value */
2728 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2729 pic14_emitcode("push","psw");
2730 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2733 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2735 if (options.useXstack) {
2736 pic14_emitcode("mov","r0,%s",spname);
2737 pic14_emitcode("mov","a,_bp");
2738 pic14_emitcode("movx","@r0,a");
2739 pic14_emitcode("inc","%s",spname);
2743 /* set up the stack */
2744 pic14_emitcode ("push","_bp"); /* save the callers stack */
2746 pic14_emitcode ("mov","_bp,%s",spname);
2749 /* adjust the stack for the function */
2754 werror(W_STACK_OVERFLOW,sym->name);
2756 if (i > 3 && sym->recvSize < 4) {
2758 pic14_emitcode ("mov","a,sp");
2759 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2760 pic14_emitcode ("mov","sp,a");
2765 pic14_emitcode("inc","sp");
2770 pic14_emitcode ("mov","a,_spx");
2771 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2772 pic14_emitcode ("mov","_spx,a");
2777 /*-----------------------------------------------------------------*/
2778 /* genEndFunction - generates epilogue for functions */
2779 /*-----------------------------------------------------------------*/
2780 static void genEndFunction (iCode *ic)
2782 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2784 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2786 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2788 pic14_emitcode ("mov","%s,_bp",spname);
2791 /* if use external stack but some variables were
2792 added to the local stack then decrement the
2794 if (options.useXstack && sym->stack) {
2795 pic14_emitcode("mov","a,sp");
2796 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2797 pic14_emitcode("mov","sp,a");
2801 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2802 if (options.useXstack) {
2803 pic14_emitcode("mov","r0,%s",spname);
2804 pic14_emitcode("movx","a,@r0");
2805 pic14_emitcode("mov","_bp,a");
2806 pic14_emitcode("dec","%s",spname);
2810 pic14_emitcode ("pop","_bp");
2814 /* restore the register bank */
2815 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2816 pic14_emitcode ("pop","psw");
2818 if (IFFUNC_ISISR(sym->type)) {
2820 /* now we need to restore the registers */
2821 /* if this isr has no bank i.e. is going to
2822 run with bank 0 , then we need to save more
2824 if (!FUNC_REGBANK(sym->type)) {
2826 /* if this function does not call any other
2827 function then we can be economical and
2828 save only those registers that are used */
2829 if (! IFFUNC_HASFCALL(sym->type)) {
2832 /* if any registers used */
2833 if (sym->regsUsed) {
2834 /* save the registers used */
2835 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2836 if (bitVectBitValue(sym->regsUsed,i) ||
2837 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2838 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2843 /* this function has a function call cannot
2844 determines register usage so we will have the
2846 unsaverbank(0,ic,FALSE);
2850 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2852 if (options.stack10bit)
2854 pic14_emitcode ("pop", "dpx1");
2855 pic14_emitcode ("pop", "dph1");
2856 pic14_emitcode ("pop", "dpl1");
2858 pic14_emitcode ("pop", "dps");
2859 pic14_emitcode ("pop", "dpx");
2861 if (!inExcludeList("dph"))
2862 pic14_emitcode ("pop","dph");
2863 if (!inExcludeList("dpl"))
2864 pic14_emitcode ("pop","dpl");
2865 if (!inExcludeList("b"))
2866 pic14_emitcode ("pop","b");
2867 if (!inExcludeList("acc"))
2868 pic14_emitcode ("pop","acc");
2870 if (IFFUNC_ISCRITICAL(sym->type))
2871 pic14_emitcode("setb","ea");
2874 /* if debug then send end of function */
2875 /* if (options.debug && currFunc) { */
2878 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2879 FileBaseName(ic->filename),currFunc->lastLine,
2880 ic->level,ic->block);
2881 if (IS_STATIC(currFunc->etype))
2882 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2884 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2888 pic14_emitcode ("reti","");
2890 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2891 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2892 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2893 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2894 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2895 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2897 emitpcodeNULLop(POC_RETFIE);
2901 if (IFFUNC_ISCRITICAL(sym->type))
2902 pic14_emitcode("setb","ea");
2904 if (IFFUNC_CALLEESAVES(sym->type)) {
2907 /* if any registers used */
2908 if (sym->regsUsed) {
2909 /* save the registers used */
2910 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2911 if (bitVectBitValue(sym->regsUsed,i) ||
2912 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2913 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2919 /* if debug then send end of function */
2922 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2923 FileBaseName(ic->filename),currFunc->lastLine,
2924 ic->level,ic->block);
2925 if (IS_STATIC(currFunc->etype))
2926 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2928 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2932 pic14_emitcode ("return","");
2933 emitpcodeNULLop(POC_RETURN);
2935 /* Mark the end of a function */
2936 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2941 /*-----------------------------------------------------------------*/
2942 /* genRet - generate code for return statement */
2943 /*-----------------------------------------------------------------*/
2944 static void genRet (iCode *ic)
2946 int size,offset = 0 , pushed = 0;
2948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2949 /* if we have no return value then
2950 just generate the "ret" */
2954 /* we have something to return then
2955 move the return value into place */
2956 aopOp(IC_LEFT(ic),ic,FALSE);
2957 size = AOP_SIZE(IC_LEFT(ic));
2961 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2963 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2965 pic14_emitcode("push","%s",l);
2968 l = aopGet(AOP(IC_LEFT(ic)),offset,
2970 if (strcmp(fReturn[offset],l)) {
2971 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2972 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2973 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2975 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2978 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2979 pic14_emitcode("movwf","%s",fReturn[offset]);
2989 if (strcmp(fReturn[pushed],"a"))
2990 pic14_emitcode("pop",fReturn[pushed]);
2992 pic14_emitcode("pop","acc");
2995 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2998 /* generate a jump to the return label
2999 if the next is not the return statement */
3000 if (!(ic->next && ic->next->op == LABEL &&
3001 IC_LABEL(ic->next) == returnLabel)) {
3003 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3004 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3009 /*-----------------------------------------------------------------*/
3010 /* genLabel - generates a label */
3011 /*-----------------------------------------------------------------*/
3012 static void genLabel (iCode *ic)
3014 /* special case never generate */
3015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3016 if (IC_LABEL(ic) == entryLabel)
3019 emitpLabel(IC_LABEL(ic)->key);
3020 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3023 /*-----------------------------------------------------------------*/
3024 /* genGoto - generates a goto */
3025 /*-----------------------------------------------------------------*/
3027 static void genGoto (iCode *ic)
3029 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3030 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3034 /*-----------------------------------------------------------------*/
3035 /* genMultbits :- multiplication of bits */
3036 /*-----------------------------------------------------------------*/
3037 static void genMultbits (operand *left,
3041 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3043 if(!pic14_sameRegs(AOP(result),AOP(right)))
3044 emitpcode(POC_BSF, popGet(AOP(result),0));
3046 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3047 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3048 emitpcode(POC_BCF, popGet(AOP(result),0));
3053 /*-----------------------------------------------------------------*/
3054 /* genMultOneByte : 8 bit multiplication & division */
3055 /*-----------------------------------------------------------------*/
3056 static void genMultOneByte (operand *left,
3060 sym_link *opetype = operandType(result);
3065 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3066 DEBUGpic14_AopType(__LINE__,left,right,result);
3067 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3069 /* (if two literals, the value is computed before) */
3070 /* if one literal, literal on the right */
3071 if (AOP_TYPE(left) == AOP_LIT){
3077 size = AOP_SIZE(result);
3080 if (AOP_TYPE(right) == AOP_LIT){
3081 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3082 aopGet(AOP(right),0,FALSE,FALSE),
3083 aopGet(AOP(left),0,FALSE,FALSE),
3084 aopGet(AOP(result),0,FALSE,FALSE));
3085 pic14_emitcode("call","genMultLit");
3087 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3088 aopGet(AOP(right),0,FALSE,FALSE),
3089 aopGet(AOP(left),0,FALSE,FALSE),
3090 aopGet(AOP(result),0,FALSE,FALSE));
3091 pic14_emitcode("call","genMult8X8_8");
3094 genMult8X8_8 (left, right,result);
3097 /* signed or unsigned */
3098 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3099 //l = aopGet(AOP(left),0,FALSE,FALSE);
3101 //pic14_emitcode("mul","ab");
3102 /* if result size = 1, mul signed = mul unsigned */
3103 //aopPut(AOP(result),"a",0);
3105 } else { // (size > 1)
3107 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3108 aopGet(AOP(right),0,FALSE,FALSE),
3109 aopGet(AOP(left),0,FALSE,FALSE),
3110 aopGet(AOP(result),0,FALSE,FALSE));
3112 if (SPEC_USIGN(opetype)){
3113 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3114 genUMult8X8_16 (left, right, result, NULL);
3117 /* for filling the MSBs */
3118 emitpcode(POC_CLRF, popGet(AOP(result),2));
3119 emitpcode(POC_CLRF, popGet(AOP(result),3));
3123 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3125 pic14_emitcode("mov","a,b");
3127 /* adjust the MSB if left or right neg */
3129 /* if one literal */
3130 if (AOP_TYPE(right) == AOP_LIT){
3131 pic14_emitcode("multiply ","right is a lit");
3132 /* AND literal negative */
3133 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3134 /* adjust MSB (c==0 after mul) */
3135 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3139 genSMult8X8_16 (left, right, result, NULL);
3143 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3145 pic14_emitcode("rlc","a");
3146 pic14_emitcode("subb","a,acc");
3154 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3155 //aopPut(AOP(result),"a",offset++);
3159 /*-----------------------------------------------------------------*/
3160 /* genMult - generates code for multiplication */
3161 /*-----------------------------------------------------------------*/
3162 static void genMult (iCode *ic)
3164 operand *left = IC_LEFT(ic);
3165 operand *right = IC_RIGHT(ic);
3166 operand *result= IC_RESULT(ic);
3168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3169 /* assign the amsops */
3170 aopOp (left,ic,FALSE);
3171 aopOp (right,ic,FALSE);
3172 aopOp (result,ic,TRUE);
3174 DEBUGpic14_AopType(__LINE__,left,right,result);
3176 /* special cases first */
3178 if (AOP_TYPE(left) == AOP_CRY &&
3179 AOP_TYPE(right)== AOP_CRY) {
3180 genMultbits(left,right,result);
3184 /* if both are of size == 1 */
3185 if (AOP_SIZE(left) == 1 &&
3186 AOP_SIZE(right) == 1 ) {
3187 genMultOneByte(left,right,result);
3191 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3193 /* should have been converted to function call */
3197 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3198 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3199 freeAsmop(result,NULL,ic,TRUE);
3202 /*-----------------------------------------------------------------*/
3203 /* genDivbits :- division of bits */
3204 /*-----------------------------------------------------------------*/
3205 static void genDivbits (operand *left,
3212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3213 /* the result must be bit */
3214 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3215 l = aopGet(AOP(left),0,FALSE,FALSE);
3219 pic14_emitcode("div","ab");
3220 pic14_emitcode("rrc","a");
3221 aopPut(AOP(result),"c",0);
3224 /*-----------------------------------------------------------------*/
3225 /* genDivOneByte : 8 bit division */
3226 /*-----------------------------------------------------------------*/
3227 static void genDivOneByte (operand *left,
3231 sym_link *opetype = operandType(result);
3236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3237 size = AOP_SIZE(result) - 1;
3239 /* signed or unsigned */
3240 if (SPEC_USIGN(opetype)) {
3241 /* unsigned is easy */
3242 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3243 l = aopGet(AOP(left),0,FALSE,FALSE);
3245 pic14_emitcode("div","ab");
3246 aopPut(AOP(result),"a",0);
3248 aopPut(AOP(result),zero,offset++);
3252 /* signed is a little bit more difficult */
3254 /* save the signs of the operands */
3255 l = aopGet(AOP(left),0,FALSE,FALSE);
3257 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3258 pic14_emitcode("push","acc"); /* save it on the stack */
3260 /* now sign adjust for both left & right */
3261 l = aopGet(AOP(right),0,FALSE,FALSE);
3263 lbl = newiTempLabel(NULL);
3264 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3265 pic14_emitcode("cpl","a");
3266 pic14_emitcode("inc","a");
3267 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3268 pic14_emitcode("mov","b,a");
3270 /* sign adjust left side */
3271 l = aopGet(AOP(left),0,FALSE,FALSE);
3274 lbl = newiTempLabel(NULL);
3275 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3276 pic14_emitcode("cpl","a");
3277 pic14_emitcode("inc","a");
3278 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3280 /* now the division */
3281 pic14_emitcode("div","ab");
3282 /* we are interested in the lower order
3284 pic14_emitcode("mov","b,a");
3285 lbl = newiTempLabel(NULL);
3286 pic14_emitcode("pop","acc");
3287 /* if there was an over flow we don't
3288 adjust the sign of the result */
3289 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3290 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3292 pic14_emitcode("clr","a");
3293 pic14_emitcode("subb","a,b");
3294 pic14_emitcode("mov","b,a");
3295 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3297 /* now we are done */
3298 aopPut(AOP(result),"b",0);
3300 pic14_emitcode("mov","c,b.7");
3301 pic14_emitcode("subb","a,acc");
3304 aopPut(AOP(result),"a",offset++);
3308 /*-----------------------------------------------------------------*/
3309 /* genDiv - generates code for division */
3310 /*-----------------------------------------------------------------*/
3311 static void genDiv (iCode *ic)
3313 operand *left = IC_LEFT(ic);
3314 operand *right = IC_RIGHT(ic);
3315 operand *result= IC_RESULT(ic);
3317 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3318 /* assign the amsops */
3319 aopOp (left,ic,FALSE);
3320 aopOp (right,ic,FALSE);
3321 aopOp (result,ic,TRUE);
3323 /* special cases first */
3325 if (AOP_TYPE(left) == AOP_CRY &&
3326 AOP_TYPE(right)== AOP_CRY) {
3327 genDivbits(left,right,result);
3331 /* if both are of size == 1 */
3332 if (AOP_SIZE(left) == 1 &&
3333 AOP_SIZE(right) == 1 ) {
3334 genDivOneByte(left,right,result);
3338 /* should have been converted to function call */
3341 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3342 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3343 freeAsmop(result,NULL,ic,TRUE);
3346 /*-----------------------------------------------------------------*/
3347 /* genModbits :- modulus of bits */
3348 /*-----------------------------------------------------------------*/
3349 static void genModbits (operand *left,
3356 /* the result must be bit */
3357 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3358 l = aopGet(AOP(left),0,FALSE,FALSE);
3362 pic14_emitcode("div","ab");
3363 pic14_emitcode("mov","a,b");
3364 pic14_emitcode("rrc","a");
3365 aopPut(AOP(result),"c",0);
3368 /*-----------------------------------------------------------------*/
3369 /* genModOneByte : 8 bit modulus */
3370 /*-----------------------------------------------------------------*/
3371 static void genModOneByte (operand *left,
3375 sym_link *opetype = operandType(result);
3379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3380 /* signed or unsigned */
3381 if (SPEC_USIGN(opetype)) {
3382 /* unsigned is easy */
3383 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3384 l = aopGet(AOP(left),0,FALSE,FALSE);
3386 pic14_emitcode("div","ab");
3387 aopPut(AOP(result),"b",0);
3391 /* signed is a little bit more difficult */
3393 /* save the signs of the operands */
3394 l = aopGet(AOP(left),0,FALSE,FALSE);
3397 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3398 pic14_emitcode("push","acc"); /* save it on the stack */
3400 /* now sign adjust for both left & right */
3401 l = aopGet(AOP(right),0,FALSE,FALSE);
3404 lbl = newiTempLabel(NULL);
3405 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3406 pic14_emitcode("cpl","a");
3407 pic14_emitcode("inc","a");
3408 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3409 pic14_emitcode("mov","b,a");
3411 /* sign adjust left side */
3412 l = aopGet(AOP(left),0,FALSE,FALSE);
3415 lbl = newiTempLabel(NULL);
3416 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3417 pic14_emitcode("cpl","a");
3418 pic14_emitcode("inc","a");
3419 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3421 /* now the multiplication */
3422 pic14_emitcode("div","ab");
3423 /* we are interested in the lower order
3425 lbl = newiTempLabel(NULL);
3426 pic14_emitcode("pop","acc");
3427 /* if there was an over flow we don't
3428 adjust the sign of the result */
3429 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3430 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3432 pic14_emitcode("clr","a");
3433 pic14_emitcode("subb","a,b");
3434 pic14_emitcode("mov","b,a");
3435 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3437 /* now we are done */
3438 aopPut(AOP(result),"b",0);
3442 /*-----------------------------------------------------------------*/
3443 /* genMod - generates code for division */
3444 /*-----------------------------------------------------------------*/
3445 static void genMod (iCode *ic)
3447 operand *left = IC_LEFT(ic);
3448 operand *right = IC_RIGHT(ic);
3449 operand *result= IC_RESULT(ic);
3451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3452 /* assign the amsops */
3453 aopOp (left,ic,FALSE);
3454 aopOp (right,ic,FALSE);
3455 aopOp (result,ic,TRUE);
3457 /* special cases first */
3459 if (AOP_TYPE(left) == AOP_CRY &&
3460 AOP_TYPE(right)== AOP_CRY) {
3461 genModbits(left,right,result);
3465 /* if both are of size == 1 */
3466 if (AOP_SIZE(left) == 1 &&
3467 AOP_SIZE(right) == 1 ) {
3468 genModOneByte(left,right,result);
3472 /* should have been converted to function call */
3476 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3477 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3478 freeAsmop(result,NULL,ic,TRUE);
3481 /*-----------------------------------------------------------------*/
3482 /* genIfxJump :- will create a jump depending on the ifx */
3483 /*-----------------------------------------------------------------*/
3485 note: May need to add parameter to indicate when a variable is in bit space.
3487 static void genIfxJump (iCode *ic, char *jval)
3490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3491 /* if true label then we jump if condition
3493 if ( IC_TRUE(ic) ) {
3495 if(strcmp(jval,"a") == 0)
3497 else if (strcmp(jval,"c") == 0)
3500 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3501 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3504 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3505 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3509 /* false label is present */
3510 if(strcmp(jval,"a") == 0)
3512 else if (strcmp(jval,"c") == 0)
3515 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3516 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3519 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3520 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3525 /* mark the icode as generated */
3529 /*-----------------------------------------------------------------*/
3531 /*-----------------------------------------------------------------*/
3532 static void genSkip(iCode *ifx,int status_bit)
3537 if ( IC_TRUE(ifx) ) {
3538 switch(status_bit) {
3553 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3554 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3558 switch(status_bit) {
3572 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3573 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3579 /*-----------------------------------------------------------------*/
3581 /*-----------------------------------------------------------------*/
3582 static void genSkipc(resolvedIfx *rifx)
3592 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3593 rifx->generated = 1;
3596 /*-----------------------------------------------------------------*/
3598 /*-----------------------------------------------------------------*/
3599 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3604 if( (rifx->condition ^ invert_condition) & 1)
3609 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3610 rifx->generated = 1;
3613 /*-----------------------------------------------------------------*/
3615 /*-----------------------------------------------------------------*/
3616 static void genSkipz(iCode *ifx, int condition)
3627 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3629 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3632 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3634 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3637 /*-----------------------------------------------------------------*/
3639 /*-----------------------------------------------------------------*/
3640 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3646 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3648 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3651 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3652 rifx->generated = 1;
3656 /*-----------------------------------------------------------------*/
3657 /* genChkZeroes :- greater or less than comparison */
3658 /* For each byte in a literal that is zero, inclusive or the */
3659 /* the corresponding byte in the operand with W */
3660 /* returns true if any of the bytes are zero */
3661 /*-----------------------------------------------------------------*/
3662 static int genChkZeroes(operand *op, int lit, int size)
3669 i = (lit >> (size*8)) & 0xff;
3673 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3675 emitpcode(POC_IORFW, popGet(AOP(op),size));
3684 /*-----------------------------------------------------------------*/
3685 /* genCmp :- greater or less than comparison */
3686 /*-----------------------------------------------------------------*/
3687 static void genCmp (operand *left,operand *right,
3688 operand *result, iCode *ifx, int sign)
3690 int size; //, offset = 0 ;
3691 unsigned long lit = 0L,i = 0;
3692 resolvedIfx rFalseIfx;
3693 // resolvedIfx rTrueIfx;
3695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3697 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3698 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3702 resolveIfx(&rFalseIfx,ifx);
3703 truelbl = newiTempLabel(NULL);
3704 size = max(AOP_SIZE(left),AOP_SIZE(right));
3708 /* if literal is on the right then swap with left */
3709 if ((AOP_TYPE(right) == AOP_LIT)) {
3710 operand *tmp = right ;
3711 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3712 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3714 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
3715 lit = (lit - 1) & mask;
3716 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
3720 rFalseIfx.condition ^= 1;
3723 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3724 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3728 //if(IC_TRUE(ifx) == NULL)
3729 /* if left & right are bit variables */
3730 if (AOP_TYPE(left) == AOP_CRY &&
3731 AOP_TYPE(right) == AOP_CRY ) {
3732 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3733 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3735 /* subtract right from left if at the
3736 end the carry flag is set then we know that
3737 left is greater than right */
3741 symbol *lbl = newiTempLabel(NULL);
3744 if(AOP_TYPE(right) == AOP_LIT) {
3746 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3748 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3755 genSkipCond(&rFalseIfx,left,size-1,7);
3757 /* no need to compare to 0...*/
3758 /* NOTE: this is a de-generate compare that most certainly
3759 * creates some dead code. */
3760 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3762 if(ifx) ifx->generated = 1;
3769 //i = (lit >> (size*8)) & 0xff;
3770 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3772 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3774 i = ((0-lit) & 0xff);
3777 /* lit is 0x7f, all signed chars are less than
3778 * this except for 0x7f itself */
3779 emitpcode(POC_XORLW, popGetLit(0x7f));
3780 genSkipz2(&rFalseIfx,0);
3782 emitpcode(POC_ADDLW, popGetLit(0x80));
3783 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3784 genSkipc(&rFalseIfx);
3789 genSkipz2(&rFalseIfx,1);
3791 emitpcode(POC_ADDLW, popGetLit(i));
3792 genSkipc(&rFalseIfx);
3796 if(ifx) ifx->generated = 1;
3800 /* chars are out of the way. now do ints and longs */
3803 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3810 genSkipCond(&rFalseIfx,left,size,7);
3811 if(ifx) ifx->generated = 1;
3816 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3818 //rFalseIfx.condition ^= 1;
3819 //genSkipCond(&rFalseIfx,left,size,7);
3820 //rFalseIfx.condition ^= 1;
3822 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3823 if(rFalseIfx.condition)
3824 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3826 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3828 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3829 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3830 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3833 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3835 if(rFalseIfx.condition) {
3837 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3843 genSkipc(&rFalseIfx);
3844 emitpLabel(truelbl->key);
3845 if(ifx) ifx->generated = 1;
3852 if( (lit & 0xff) == 0) {
3853 /* lower byte is zero */
3854 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3855 i = ((lit >> 8) & 0xff) ^0x80;
3856 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3857 emitpcode(POC_ADDLW, popGetLit( 0x80));
3858 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3859 genSkipc(&rFalseIfx);
3862 if(ifx) ifx->generated = 1;
3867 /* Special cases for signed longs */
3868 if( (lit & 0xffffff) == 0) {
3869 /* lower byte is zero */
3870 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3871 i = ((lit >> 8*3) & 0xff) ^0x80;
3872 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3873 emitpcode(POC_ADDLW, popGetLit( 0x80));
3874 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3875 genSkipc(&rFalseIfx);
3878 if(ifx) ifx->generated = 1;
3886 if(lit & (0x80 << (size*8))) {
3887 /* lit is negative */
3888 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3890 //genSkipCond(&rFalseIfx,left,size,7);
3892 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3894 if(rFalseIfx.condition)
3895 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3897 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3901 /* lit is positive */
3902 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3903 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3904 if(rFalseIfx.condition)
3905 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3907 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3912 This works, but is only good for ints.
3913 It also requires a "known zero" register.
3914 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3915 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3916 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3917 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3918 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3919 genSkipc(&rFalseIfx);
3921 emitpLabel(truelbl->key);
3922 if(ifx) ifx->generated = 1;
3926 /* There are no more special cases, so perform a general compare */
3928 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3929 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3933 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3935 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3937 //rFalseIfx.condition ^= 1;
3938 genSkipc(&rFalseIfx);
3940 emitpLabel(truelbl->key);
3942 if(ifx) ifx->generated = 1;
3949 /* sign is out of the way. So now do an unsigned compare */
3950 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3953 /* General case - compare to an unsigned literal on the right.*/
3955 i = (lit >> (size*8)) & 0xff;
3956 emitpcode(POC_MOVLW, popGetLit(i));
3957 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3959 i = (lit >> (size*8)) & 0xff;
3962 emitpcode(POC_MOVLW, popGetLit(i));
3964 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3966 /* this byte of the lit is zero,
3967 *if it's not the last then OR in the variable */
3969 emitpcode(POC_IORFW, popGet(AOP(left),size));
3974 emitpLabel(lbl->key);
3975 //if(emitFinalCheck)
3976 genSkipc(&rFalseIfx);
3978 emitpLabel(truelbl->key);
3980 if(ifx) ifx->generated = 1;
3986 if(AOP_TYPE(left) == AOP_LIT) {
3987 //symbol *lbl = newiTempLabel(NULL);
3989 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3992 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3995 if((lit == 0) && (sign == 0)){
3998 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4000 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4002 genSkipz2(&rFalseIfx,0);
4003 if(ifx) ifx->generated = 1;
4010 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4011 /* degenerate compare can never be true */
4012 if(rFalseIfx.condition == 0)
4013 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4015 if(ifx) ifx->generated = 1;
4020 /* signed comparisons to a literal byte */
4022 int lp1 = (lit+1) & 0xff;
4024 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4027 rFalseIfx.condition ^= 1;
4028 genSkipCond(&rFalseIfx,right,0,7);
4031 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4032 emitpcode(POC_XORLW, popGetLit(0x7f));
4033 genSkipz2(&rFalseIfx,1);
4036 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4037 emitpcode(POC_ADDLW, popGetLit(0x80));
4038 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4039 rFalseIfx.condition ^= 1;
4040 genSkipc(&rFalseIfx);
4044 /* unsigned comparisons to a literal byte */
4046 switch(lit & 0xff ) {
4048 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4049 genSkipz2(&rFalseIfx,0);
4052 rFalseIfx.condition ^= 1;
4053 genSkipCond(&rFalseIfx,right,0,7);
4057 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4058 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4060 rFalseIfx.condition ^= 1;
4061 genSkipc(&rFalseIfx);
4066 if(ifx) ifx->generated = 1;
4071 /* Size is greater than 1 */
4079 /* this means lit = 0xffffffff, or -1 */
4082 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4083 rFalseIfx.condition ^= 1;
4084 genSkipCond(&rFalseIfx,right,size,7);
4085 if(ifx) ifx->generated = 1;
4092 if(rFalseIfx.condition) {
4093 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4094 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4097 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4099 emitpcode(POC_IORFW, popGet(AOP(right),size));
4103 if(rFalseIfx.condition) {
4104 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4105 emitpLabel(truelbl->key);
4107 rFalseIfx.condition ^= 1;
4108 genSkipCond(&rFalseIfx,right,s,7);
4111 if(ifx) ifx->generated = 1;
4115 if((size == 1) && (0 == (lp1&0xff))) {
4116 /* lower byte of signed word is zero */
4117 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4118 i = ((lp1 >> 8) & 0xff) ^0x80;
4119 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4120 emitpcode(POC_ADDLW, popGetLit( 0x80));
4121 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4122 rFalseIfx.condition ^= 1;
4123 genSkipc(&rFalseIfx);
4126 if(ifx) ifx->generated = 1;
4130 if(lit & (0x80 << (size*8))) {
4131 /* Lit is less than zero */
4132 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4133 //rFalseIfx.condition ^= 1;
4134 //genSkipCond(&rFalseIfx,left,size,7);
4135 //rFalseIfx.condition ^= 1;
4136 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4137 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4139 if(rFalseIfx.condition)
4140 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4142 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4146 /* Lit is greater than or equal to zero */
4147 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4148 //rFalseIfx.condition ^= 1;
4149 //genSkipCond(&rFalseIfx,right,size,7);
4150 //rFalseIfx.condition ^= 1;
4152 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4153 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4155 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4156 if(rFalseIfx.condition)
4157 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4159 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4164 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4165 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4169 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4171 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4173 rFalseIfx.condition ^= 1;
4174 //rFalseIfx.condition = 1;
4175 genSkipc(&rFalseIfx);
4177 emitpLabel(truelbl->key);
4179 if(ifx) ifx->generated = 1;
4184 /* compare word or long to an unsigned literal on the right.*/
4189 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4192 break; /* handled above */
4195 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4197 emitpcode(POC_IORFW, popGet(AOP(right),size));
4198 genSkipz2(&rFalseIfx,0);
4202 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4204 emitpcode(POC_IORFW, popGet(AOP(right),size));
4207 if(rFalseIfx.condition)
4208 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4210 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4213 emitpcode(POC_MOVLW, popGetLit(lit+1));
4214 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4216 rFalseIfx.condition ^= 1;
4217 genSkipc(&rFalseIfx);
4220 emitpLabel(truelbl->key);
4222 if(ifx) ifx->generated = 1;
4228 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4229 i = (lit >> (size*8)) & 0xff;
4231 emitpcode(POC_MOVLW, popGetLit(i));
4232 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4235 i = (lit >> (size*8)) & 0xff;
4238 emitpcode(POC_MOVLW, popGetLit(i));
4240 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4242 /* this byte of the lit is zero,
4243 *if it's not the last then OR in the variable */
4245 emitpcode(POC_IORFW, popGet(AOP(right),size));
4250 emitpLabel(lbl->key);
4252 rFalseIfx.condition ^= 1;
4253 genSkipc(&rFalseIfx);
4257 emitpLabel(truelbl->key);
4258 if(ifx) ifx->generated = 1;
4262 /* Compare two variables */
4264 DEBUGpic14_emitcode(";sign","%d",sign);
4268 /* Sigh. thus sucks... */
4270 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4271 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4272 emitpcode(POC_MOVLW, popGetLit(0x80));
4273 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4274 emitpcode(POC_XORFW, popGet(AOP(right),size));
4275 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4277 /* Signed char comparison */
4278 /* Special thanks to Nikolai Golovchenko for this snippet */
4279 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4280 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4281 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4282 emitpcode(POC_XORFW, popGet(AOP(left),0));
4283 emitpcode(POC_XORFW, popGet(AOP(right),0));
4284 emitpcode(POC_ADDLW, popGetLit(0x80));
4286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4287 genSkipc(&rFalseIfx);
4289 if(ifx) ifx->generated = 1;
4295 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4296 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4300 /* The rest of the bytes of a multi-byte compare */
4304 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4307 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4308 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4313 emitpLabel(lbl->key);
4315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4316 genSkipc(&rFalseIfx);
4317 if(ifx) ifx->generated = 1;
4322 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4323 pic14_outBitC(result);
4325 /* if the result is used in the next
4326 ifx conditional branch then generate
4327 code a little differently */
4329 genIfxJump (ifx,"c");
4331 pic14_outBitC(result);
4332 /* leave the result in acc */
4337 /*-----------------------------------------------------------------*/
4338 /* genCmpGt :- greater than comparison */
4339 /*-----------------------------------------------------------------*/
4340 static void genCmpGt (iCode *ic, iCode *ifx)
4342 operand *left, *right, *result;
4343 sym_link *letype , *retype;
4346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4348 right= IC_RIGHT(ic);
4349 result = IC_RESULT(ic);
4351 letype = getSpec(operandType(left));
4352 retype =getSpec(operandType(right));
4353 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4354 /* assign the amsops */
4355 aopOp (left,ic,FALSE);
4356 aopOp (right,ic,FALSE);
4357 aopOp (result,ic,TRUE);
4359 genCmp(right, left, result, ifx, sign);
4361 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4362 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4363 freeAsmop(result,NULL,ic,TRUE);
4366 /*-----------------------------------------------------------------*/
4367 /* genCmpLt - less than comparisons */
4368 /*-----------------------------------------------------------------*/
4369 static void genCmpLt (iCode *ic, iCode *ifx)
4371 operand *left, *right, *result;
4372 sym_link *letype , *retype;
4375 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4377 right= IC_RIGHT(ic);
4378 result = IC_RESULT(ic);
4380 letype = getSpec(operandType(left));
4381 retype =getSpec(operandType(right));
4382 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4384 /* assign the amsops */
4385 aopOp (left,ic,FALSE);
4386 aopOp (right,ic,FALSE);
4387 aopOp (result,ic,TRUE);
4389 genCmp(left, right, result, ifx, sign);
4391 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4392 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4393 freeAsmop(result,NULL,ic,TRUE);
4396 /*-----------------------------------------------------------------*/
4397 /* genc16bit2lit - compare a 16 bit value to a literal */
4398 /*-----------------------------------------------------------------*/
4399 static void genc16bit2lit(operand *op, int lit, int offset)
4403 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4404 if( (lit&0xff) == 0)
4409 switch( BYTEofLONG(lit,i)) {
4411 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4414 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4417 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4420 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4421 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4426 switch( BYTEofLONG(lit,i)) {
4428 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4432 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4436 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4439 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4441 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4447 /*-----------------------------------------------------------------*/
4448 /* gencjneshort - compare and jump if not equal */
4449 /*-----------------------------------------------------------------*/
4450 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4452 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4457 unsigned long lit = 0L;
4458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4459 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4461 resolveIfx(&rIfx,ifx);
4462 lbl = newiTempLabel(NULL);
4465 /* if the left side is a literal or
4466 if the right is in a pointer register and left
4468 if ((AOP_TYPE(left) == AOP_LIT) ||
4469 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4474 if(AOP_TYPE(right) == AOP_LIT)
4475 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4477 /* if the right side is a literal then anything goes */
4478 if (AOP_TYPE(right) == AOP_LIT &&
4479 AOP_TYPE(left) != AOP_DIR ) {
4482 genc16bit2lit(left, lit, 0);
4484 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4489 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4490 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4492 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4496 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4504 /* if the right side is in a register or in direct space or
4505 if the left is a pointer register & right is not */
4506 else if (AOP_TYPE(right) == AOP_REG ||
4507 AOP_TYPE(right) == AOP_DIR ||
4508 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4509 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4512 genc16bit2lit(left, lit, 0);
4514 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4519 if((AOP_TYPE(left) == AOP_DIR) &&
4520 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4522 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4523 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4525 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4527 switch (lit & 0xff) {
4529 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4532 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4533 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4537 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4538 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4542 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4543 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4548 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4551 if(AOP_TYPE(result) == AOP_CRY) {
4552 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4557 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4559 /* fix me. probably need to check result size too */
4560 emitpcode(POC_CLRF,popGet(AOP(result),0));
4565 emitpcode(POC_INCF,popGet(AOP(result),0));
4575 } else if(AOP_TYPE(right) == AOP_REG &&
4576 AOP_TYPE(left) != AOP_DIR){
4579 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4580 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4581 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4586 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4591 /* right is a pointer reg need both a & b */
4593 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4595 pic14_emitcode("mov","b,%s",l);
4596 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4597 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4601 emitpLabel(lbl->key);
4608 /*-----------------------------------------------------------------*/
4609 /* gencjne - compare and jump if not equal */
4610 /*-----------------------------------------------------------------*/
4611 static void gencjne(operand *left, operand *right, iCode *ifx)
4613 symbol *tlbl = newiTempLabel(NULL);
4615 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4616 gencjneshort(left, right, lbl);
4618 pic14_emitcode("mov","a,%s",one);
4619 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4620 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4621 pic14_emitcode("clr","a");
4622 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4624 emitpLabel(lbl->key);
4625 emitpLabel(tlbl->key);
4630 /*-----------------------------------------------------------------*/
4631 /* genCmpEq - generates code for equal to */
4632 /*-----------------------------------------------------------------*/
4633 static void genCmpEq (iCode *ic, iCode *ifx)
4635 operand *left, *right, *result;
4636 unsigned long lit = 0L;
4639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4642 DEBUGpic14_emitcode ("; ifx is non-null","");
4644 DEBUGpic14_emitcode ("; ifx is null","");
4646 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4647 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4648 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4650 size = max(AOP_SIZE(left),AOP_SIZE(right));
4652 DEBUGpic14_AopType(__LINE__,left,right,result);
4654 /* if literal, literal on the right or
4655 if the right is in a pointer register and left
4657 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4658 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4659 operand *tmp = right ;
4665 if(ifx && !AOP_SIZE(result)){
4667 /* if they are both bit variables */
4668 if (AOP_TYPE(left) == AOP_CRY &&
4669 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4670 if(AOP_TYPE(right) == AOP_LIT){
4671 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4673 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4674 pic14_emitcode("cpl","c");
4675 } else if(lit == 1L) {
4676 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4678 pic14_emitcode("clr","c");
4680 /* AOP_TYPE(right) == AOP_CRY */
4682 symbol *lbl = newiTempLabel(NULL);
4683 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4684 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4685 pic14_emitcode("cpl","c");
4686 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4688 /* if true label then we jump if condition
4690 tlbl = newiTempLabel(NULL);
4691 if ( IC_TRUE(ifx) ) {
4692 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4693 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4695 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4696 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4698 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4701 /* left and right are both bit variables, result is carry */
4704 resolveIfx(&rIfx,ifx);
4706 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4707 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4708 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4709 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4714 /* They're not both bit variables. Is the right a literal? */
4715 if(AOP_TYPE(right) == AOP_LIT) {
4716 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4721 switch(lit & 0xff) {
4723 if ( IC_TRUE(ifx) ) {
4724 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4726 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4728 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4729 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4733 if ( IC_TRUE(ifx) ) {
4734 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4736 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4738 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4739 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4743 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4745 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4750 /* end of size == 1 */
4754 genc16bit2lit(left,lit,offset);
4757 /* end of size == 2 */
4762 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4763 emitpcode(POC_IORFW,popGet(AOP(left),1));
4764 emitpcode(POC_IORFW,popGet(AOP(left),2));
4765 emitpcode(POC_IORFW,popGet(AOP(left),3));
4769 /* search for patterns that can be optimized */
4771 genc16bit2lit(left,lit,0);
4774 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4776 genc16bit2lit(left,lit,2);
4778 emitpcode(POC_IORFW,popGet(AOP(left),2));
4779 emitpcode(POC_IORFW,popGet(AOP(left),3));
4792 } else if(AOP_TYPE(right) == AOP_CRY ) {
4793 /* we know the left is not a bit, but that the right is */
4794 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4795 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4796 popGet(AOP(right),offset));
4797 emitpcode(POC_XORLW,popGetLit(1));
4799 /* if the two are equal, then W will be 0 and the Z bit is set
4800 * we could test Z now, or go ahead and check the high order bytes if
4801 * the variable we're comparing is larger than a byte. */
4804 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4806 if ( IC_TRUE(ifx) ) {
4808 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4809 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4812 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4813 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4817 /* They're both variables that are larger than bits */
4820 tlbl = newiTempLabel(NULL);
4823 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4824 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4826 if ( IC_TRUE(ifx) ) {
4829 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4830 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4833 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4834 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4838 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4839 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4843 if(s>1 && IC_TRUE(ifx)) {
4844 emitpLabel(tlbl->key);
4845 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4849 /* mark the icode as generated */
4854 /* if they are both bit variables */
4855 if (AOP_TYPE(left) == AOP_CRY &&
4856 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4857 if(AOP_TYPE(right) == AOP_LIT){
4858 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4860 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4861 pic14_emitcode("cpl","c");
4862 } else if(lit == 1L) {
4863 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4865 pic14_emitcode("clr","c");
4867 /* AOP_TYPE(right) == AOP_CRY */
4869 symbol *lbl = newiTempLabel(NULL);
4870 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4871 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4872 pic14_emitcode("cpl","c");
4873 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4876 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4877 pic14_outBitC(result);
4881 genIfxJump (ifx,"c");
4884 /* if the result is used in an arithmetic operation
4885 then put the result in place */
4886 pic14_outBitC(result);
4889 gencjne(left,right,result,ifx);
4892 gencjne(left,right,newiTempLabel(NULL));
4894 if(IC_TRUE(ifx)->key)
4895 gencjne(left,right,IC_TRUE(ifx)->key);
4897 gencjne(left,right,IC_FALSE(ifx)->key);
4901 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4902 aopPut(AOP(result),"a",0);
4907 genIfxJump (ifx,"a");
4911 /* if the result is used in an arithmetic operation
4912 then put the result in place */
4914 if (AOP_TYPE(result) != AOP_CRY)
4915 pic14_outAcc(result);
4917 /* leave the result in acc */
4921 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4922 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4923 freeAsmop(result,NULL,ic,TRUE);
4926 /*-----------------------------------------------------------------*/
4927 /* ifxForOp - returns the icode containing the ifx for operand */
4928 /*-----------------------------------------------------------------*/
4929 static iCode *ifxForOp ( operand *op, iCode *ic )
4931 /* if true symbol then needs to be assigned */
4932 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4933 if (IS_TRUE_SYMOP(op))
4936 /* if this has register type condition and
4937 the next instruction is ifx with the same operand
4938 and live to of the operand is upto the ifx only then */
4940 ic->next->op == IFX &&
4941 IC_COND(ic->next)->key == op->key &&
4942 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4946 ic->next->op == IFX &&
4947 IC_COND(ic->next)->key == op->key) {
4948 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4952 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4954 ic->next->op == IFX)
4955 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4958 ic->next->op == IFX &&
4959 IC_COND(ic->next)->key == op->key) {
4960 DEBUGpic14_emitcode ("; "," key is okay");
4961 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4962 OP_SYMBOL(op)->liveTo,
4969 /*-----------------------------------------------------------------*/
4970 /* genAndOp - for && operation */
4971 /*-----------------------------------------------------------------*/
4972 static void genAndOp (iCode *ic)
4974 operand *left,*right, *result;
4977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4978 /* note here that && operations that are in an
4979 if statement are taken away by backPatchLabels
4980 only those used in arthmetic operations remain */
4981 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4982 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4983 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4985 /* if both are bit variables */
4986 if (AOP_TYPE(left) == AOP_CRY &&
4987 AOP_TYPE(right) == AOP_CRY ) {
4988 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4989 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4990 pic14_outBitC(result);
4992 tlbl = newiTempLabel(NULL);
4993 pic14_toBoolean(left);
4994 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4995 pic14_toBoolean(right);
4996 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4997 pic14_outBitAcc(result);
5000 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5001 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5002 freeAsmop(result,NULL,ic,TRUE);
5006 /*-----------------------------------------------------------------*/
5007 /* genOrOp - for || operation */
5008 /*-----------------------------------------------------------------*/
5011 modified this code, but it doesn't appear to ever get called
5014 static void genOrOp (iCode *ic)
5016 operand *left,*right, *result;
5019 /* note here that || operations that are in an
5020 if statement are taken away by backPatchLabels
5021 only those used in arthmetic operations remain */
5022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5023 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5024 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5025 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5027 DEBUGpic14_AopType(__LINE__,left,right,result);
5029 /* if both are bit variables */
5030 if (AOP_TYPE(left) == AOP_CRY &&
5031 AOP_TYPE(right) == AOP_CRY ) {
5032 pic14_emitcode("clrc","");
5033 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5034 AOP(left)->aopu.aop_dir,
5035 AOP(left)->aopu.aop_dir);
5036 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5037 AOP(right)->aopu.aop_dir,
5038 AOP(right)->aopu.aop_dir);
5039 pic14_emitcode("setc","");
5042 tlbl = newiTempLabel(NULL);
5043 pic14_toBoolean(left);
5045 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5046 pic14_toBoolean(right);
5047 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5049 pic14_outBitAcc(result);
5052 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5053 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5054 freeAsmop(result,NULL,ic,TRUE);
5057 /*-----------------------------------------------------------------*/
5058 /* isLiteralBit - test if lit == 2^n */
5059 /*-----------------------------------------------------------------*/
5060 static int isLiteralBit(unsigned long lit)
5062 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5063 0x100L,0x200L,0x400L,0x800L,
5064 0x1000L,0x2000L,0x4000L,0x8000L,
5065 0x10000L,0x20000L,0x40000L,0x80000L,
5066 0x100000L,0x200000L,0x400000L,0x800000L,
5067 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5068 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5071 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5072 for(idx = 0; idx < 32; idx++)
5078 /*-----------------------------------------------------------------*/
5079 /* continueIfTrue - */
5080 /*-----------------------------------------------------------------*/
5081 static void continueIfTrue (iCode *ic)
5083 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5085 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5089 /*-----------------------------------------------------------------*/
5091 /*-----------------------------------------------------------------*/
5092 static void jumpIfTrue (iCode *ic)
5094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5096 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5100 /*-----------------------------------------------------------------*/
5101 /* jmpTrueOrFalse - */
5102 /*-----------------------------------------------------------------*/
5103 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5105 // ugly but optimized by peephole
5106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5108 symbol *nlbl = newiTempLabel(NULL);
5109 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5110 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5111 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5112 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5115 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5116 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5121 /*-----------------------------------------------------------------*/
5122 /* genAnd - code for and */
5123 /*-----------------------------------------------------------------*/
5124 static void genAnd (iCode *ic, iCode *ifx)
5126 operand *left, *right, *result;
5128 unsigned long lit = 0L;
5133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5134 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5135 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5136 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5138 resolveIfx(&rIfx,ifx);
5140 /* if left is a literal & right is not then exchange them */
5141 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5142 AOP_NEEDSACC(left)) {
5143 operand *tmp = right ;
5148 /* if result = right then exchange them */
5149 if(pic14_sameRegs(AOP(result),AOP(right))){
5150 operand *tmp = right ;
5155 /* if right is bit then exchange them */
5156 if (AOP_TYPE(right) == AOP_CRY &&
5157 AOP_TYPE(left) != AOP_CRY){
5158 operand *tmp = right ;
5162 if(AOP_TYPE(right) == AOP_LIT)
5163 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5165 size = AOP_SIZE(result);
5167 DEBUGpic14_AopType(__LINE__,left,right,result);
5170 // result = bit & yy;
5171 if (AOP_TYPE(left) == AOP_CRY){
5172 // c = bit & literal;
5173 if(AOP_TYPE(right) == AOP_LIT){
5175 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5178 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5181 if(size && (AOP_TYPE(result) == AOP_CRY)){
5182 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5185 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5189 pic14_emitcode("clr","c");
5192 if (AOP_TYPE(right) == AOP_CRY){
5194 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5195 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5198 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5200 pic14_emitcode("rrc","a");
5201 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5207 pic14_outBitC(result);
5209 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5210 genIfxJump(ifx, "c");
5214 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5215 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5216 if((AOP_TYPE(right) == AOP_LIT) &&
5217 (AOP_TYPE(result) == AOP_CRY) &&
5218 (AOP_TYPE(left) != AOP_CRY)){
5219 int posbit = isLiteralBit(lit);
5223 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5226 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5232 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5233 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5235 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5236 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5239 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5240 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5241 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5248 symbol *tlbl = newiTempLabel(NULL);
5249 int sizel = AOP_SIZE(left);
5251 pic14_emitcode("setb","c");
5253 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5254 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5256 if((posbit = isLiteralBit(bytelit)) != 0)
5257 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5259 if(bytelit != 0x0FFL)
5260 pic14_emitcode("anl","a,%s",
5261 aopGet(AOP(right),offset,FALSE,TRUE));
5262 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5267 // bit = left & literal
5269 pic14_emitcode("clr","c");
5270 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5272 // if(left & literal)
5275 jmpTrueOrFalse(ifx, tlbl);
5279 pic14_outBitC(result);
5283 /* if left is same as result */
5284 if(pic14_sameRegs(AOP(result),AOP(left))){
5286 for(;size--; offset++,lit>>=8) {
5287 if(AOP_TYPE(right) == AOP_LIT){
5288 switch(lit & 0xff) {
5290 /* and'ing with 0 has clears the result */
5291 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5292 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5295 /* and'ing with 0xff is a nop when the result and left are the same */
5300 int p = my_powof2( (~lit) & 0xff );
5302 /* only one bit is set in the literal, so use a bcf instruction */
5303 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5304 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5307 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5308 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5309 if(know_W != (lit&0xff))
5310 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5312 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5317 if (AOP_TYPE(left) == AOP_ACC) {
5318 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5320 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5321 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5328 // left & result in different registers
5329 if(AOP_TYPE(result) == AOP_CRY){
5331 // if(size), result in bit
5332 // if(!size && ifx), conditional oper: if(left & right)
5333 symbol *tlbl = newiTempLabel(NULL);
5334 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5336 pic14_emitcode("setb","c");
5338 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5339 pic14_emitcode("anl","a,%s",
5340 aopGet(AOP(left),offset,FALSE,FALSE));
5341 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5346 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5347 pic14_outBitC(result);
5349 jmpTrueOrFalse(ifx, tlbl);
5351 for(;(size--);offset++) {
5353 // result = left & right
5354 if(AOP_TYPE(right) == AOP_LIT){
5355 int t = (lit >> (offset*8)) & 0x0FFL;
5358 pic14_emitcode("clrf","%s",
5359 aopGet(AOP(result),offset,FALSE,FALSE));
5360 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5363 pic14_emitcode("movf","%s,w",
5364 aopGet(AOP(left),offset,FALSE,FALSE));
5365 pic14_emitcode("movwf","%s",
5366 aopGet(AOP(result),offset,FALSE,FALSE));
5367 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5368 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5371 pic14_emitcode("movlw","0x%x",t);
5372 pic14_emitcode("andwf","%s,w",
5373 aopGet(AOP(left),offset,FALSE,FALSE));
5374 pic14_emitcode("movwf","%s",
5375 aopGet(AOP(result),offset,FALSE,FALSE));
5377 emitpcode(POC_MOVLW, popGetLit(t));
5378 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5379 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5384 if (AOP_TYPE(left) == AOP_ACC) {
5385 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5386 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5388 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5389 pic14_emitcode("andwf","%s,w",
5390 aopGet(AOP(left),offset,FALSE,FALSE));
5391 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5392 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5394 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5395 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5401 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5402 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5403 freeAsmop(result,NULL,ic,TRUE);
5406 /*-----------------------------------------------------------------*/
5407 /* genOr - code for or */
5408 /*-----------------------------------------------------------------*/
5409 static void genOr (iCode *ic, iCode *ifx)
5411 operand *left, *right, *result;
5413 unsigned long lit = 0L;
5415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5417 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5418 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5419 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5421 DEBUGpic14_AopType(__LINE__,left,right,result);
5423 /* if left is a literal & right is not then exchange them */
5424 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5425 AOP_NEEDSACC(left)) {
5426 operand *tmp = right ;
5431 /* if result = right then exchange them */
5432 if(pic14_sameRegs(AOP(result),AOP(right))){
5433 operand *tmp = right ;
5438 /* if right is bit then exchange them */
5439 if (AOP_TYPE(right) == AOP_CRY &&
5440 AOP_TYPE(left) != AOP_CRY){
5441 operand *tmp = right ;
5446 DEBUGpic14_AopType(__LINE__,left,right,result);
5448 if(AOP_TYPE(right) == AOP_LIT)
5449 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5451 size = AOP_SIZE(result);
5455 if (AOP_TYPE(left) == AOP_CRY){
5456 if(AOP_TYPE(right) == AOP_LIT){
5457 // c = bit & literal;
5459 // lit != 0 => result = 1
5460 if(AOP_TYPE(result) == AOP_CRY){
5462 emitpcode(POC_BSF, popGet(AOP(result),0));
5463 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5464 // AOP(result)->aopu.aop_dir,
5465 // AOP(result)->aopu.aop_dir);
5467 continueIfTrue(ifx);
5471 // lit == 0 => result = left
5472 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5474 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5477 if (AOP_TYPE(right) == AOP_CRY){
5478 if(pic14_sameRegs(AOP(result),AOP(left))){
5480 emitpcode(POC_BCF, popGet(AOP(result),0));
5481 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5482 emitpcode(POC_BSF, popGet(AOP(result),0));
5484 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5485 AOP(result)->aopu.aop_dir,
5486 AOP(result)->aopu.aop_dir);
5487 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5488 AOP(right)->aopu.aop_dir,
5489 AOP(right)->aopu.aop_dir);
5490 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5491 AOP(result)->aopu.aop_dir,
5492 AOP(result)->aopu.aop_dir);
5494 if( AOP_TYPE(result) == AOP_ACC) {
5495 emitpcode(POC_MOVLW, popGetLit(0));
5496 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5497 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5498 emitpcode(POC_MOVLW, popGetLit(1));
5502 emitpcode(POC_BCF, popGet(AOP(result),0));
5503 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5504 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5505 emitpcode(POC_BSF, popGet(AOP(result),0));
5507 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5508 AOP(result)->aopu.aop_dir,
5509 AOP(result)->aopu.aop_dir);
5510 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5511 AOP(right)->aopu.aop_dir,
5512 AOP(right)->aopu.aop_dir);
5513 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5514 AOP(left)->aopu.aop_dir,
5515 AOP(left)->aopu.aop_dir);
5516 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5517 AOP(result)->aopu.aop_dir,
5518 AOP(result)->aopu.aop_dir);
5523 symbol *tlbl = newiTempLabel(NULL);
5524 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5527 emitpcode(POC_BCF, popGet(AOP(result),0));
5528 if( AOP_TYPE(right) == AOP_ACC) {
5529 emitpcode(POC_IORLW, popGetLit(0));
5531 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5532 emitpcode(POC_BSF, popGet(AOP(result),0));
5537 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5538 pic14_emitcode(";XXX setb","c");
5539 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5540 AOP(left)->aopu.aop_dir,tlbl->key+100);
5541 pic14_toBoolean(right);
5542 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5543 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5544 jmpTrueOrFalse(ifx, tlbl);
5548 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5555 pic14_outBitC(result);
5557 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5558 genIfxJump(ifx, "c");
5562 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5563 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5564 if((AOP_TYPE(right) == AOP_LIT) &&
5565 (AOP_TYPE(result) == AOP_CRY) &&
5566 (AOP_TYPE(left) != AOP_CRY)){
5568 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5571 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5573 continueIfTrue(ifx);
5576 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5577 // lit = 0, result = boolean(left)
5579 pic14_emitcode(";XXX setb","c");
5580 pic14_toBoolean(right);
5582 symbol *tlbl = newiTempLabel(NULL);
5583 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5585 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5587 genIfxJump (ifx,"a");
5591 pic14_outBitC(result);
5595 /* if left is same as result */
5596 if(pic14_sameRegs(AOP(result),AOP(left))){
5598 for(;size--; offset++,lit>>=8) {
5599 if(AOP_TYPE(right) == AOP_LIT){
5600 if((lit & 0xff) == 0)
5601 /* or'ing with 0 has no effect */
5604 int p = my_powof2(lit & 0xff);
5606 /* only one bit is set in the literal, so use a bsf instruction */
5608 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5610 if(know_W != (lit & 0xff))
5611 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5612 know_W = lit & 0xff;
5613 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5618 if (AOP_TYPE(left) == AOP_ACC) {
5619 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5620 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5622 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5623 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5625 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5626 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5632 // left & result in different registers
5633 if(AOP_TYPE(result) == AOP_CRY){
5635 // if(size), result in bit
5636 // if(!size && ifx), conditional oper: if(left | right)
5637 symbol *tlbl = newiTempLabel(NULL);
5638 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5639 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5643 pic14_emitcode(";XXX setb","c");
5645 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5646 pic14_emitcode(";XXX orl","a,%s",
5647 aopGet(AOP(left),offset,FALSE,FALSE));
5648 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5653 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5654 pic14_outBitC(result);
5656 jmpTrueOrFalse(ifx, tlbl);
5657 } else for(;(size--);offset++){
5659 // result = left & right
5660 if(AOP_TYPE(right) == AOP_LIT){
5661 int t = (lit >> (offset*8)) & 0x0FFL;
5664 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5665 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5667 pic14_emitcode("movf","%s,w",
5668 aopGet(AOP(left),offset,FALSE,FALSE));
5669 pic14_emitcode("movwf","%s",
5670 aopGet(AOP(result),offset,FALSE,FALSE));
5673 emitpcode(POC_MOVLW, popGetLit(t));
5674 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5675 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5677 pic14_emitcode("movlw","0x%x",t);
5678 pic14_emitcode("iorwf","%s,w",
5679 aopGet(AOP(left),offset,FALSE,FALSE));
5680 pic14_emitcode("movwf","%s",
5681 aopGet(AOP(result),offset,FALSE,FALSE));
5687 // faster than result <- left, anl result,right
5688 // and better if result is SFR
5689 if (AOP_TYPE(left) == AOP_ACC) {
5690 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5691 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5693 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5694 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5696 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5697 pic14_emitcode("iorwf","%s,w",
5698 aopGet(AOP(left),offset,FALSE,FALSE));
5700 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5701 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5706 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5707 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5708 freeAsmop(result,NULL,ic,TRUE);
5711 /*-----------------------------------------------------------------*/
5712 /* genXor - code for xclusive or */
5713 /*-----------------------------------------------------------------*/
5714 static void genXor (iCode *ic, iCode *ifx)
5716 operand *left, *right, *result;
5718 unsigned long lit = 0L;
5720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5722 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5723 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5724 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5726 /* if left is a literal & right is not ||
5727 if left needs acc & right does not */
5728 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5729 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5730 operand *tmp = right ;
5735 /* if result = right then exchange them */
5736 if(pic14_sameRegs(AOP(result),AOP(right))){
5737 operand *tmp = right ;
5742 /* if right is bit then exchange them */
5743 if (AOP_TYPE(right) == AOP_CRY &&
5744 AOP_TYPE(left) != AOP_CRY){
5745 operand *tmp = right ;
5749 if(AOP_TYPE(right) == AOP_LIT)
5750 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5752 size = AOP_SIZE(result);
5756 if (AOP_TYPE(left) == AOP_CRY){
5757 if(AOP_TYPE(right) == AOP_LIT){
5758 // c = bit & literal;
5760 // lit>>1 != 0 => result = 1
5761 if(AOP_TYPE(result) == AOP_CRY){
5763 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5764 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5766 continueIfTrue(ifx);
5769 pic14_emitcode("setb","c");
5773 // lit == 0, result = left
5774 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5776 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5778 // lit == 1, result = not(left)
5779 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5780 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5781 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5782 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5785 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5786 pic14_emitcode("cpl","c");
5793 symbol *tlbl = newiTempLabel(NULL);
5794 if (AOP_TYPE(right) == AOP_CRY){
5796 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5799 int sizer = AOP_SIZE(right);
5801 // if val>>1 != 0, result = 1
5802 pic14_emitcode("setb","c");
5804 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5806 // test the msb of the lsb
5807 pic14_emitcode("anl","a,#0xfe");
5808 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5812 pic14_emitcode("rrc","a");
5814 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5815 pic14_emitcode("cpl","c");
5816 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5821 pic14_outBitC(result);
5823 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5824 genIfxJump(ifx, "c");
5828 if(pic14_sameRegs(AOP(result),AOP(left))){
5829 /* if left is same as result */
5830 for(;size--; offset++) {
5831 if(AOP_TYPE(right) == AOP_LIT){
5832 int t = (lit >> (offset*8)) & 0x0FFL;
5836 if (IS_AOP_PREG(left)) {
5837 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5838 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5839 aopPut(AOP(result),"a",offset);
5841 emitpcode(POC_MOVLW, popGetLit(t));
5842 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5843 pic14_emitcode("xrl","%s,%s",
5844 aopGet(AOP(left),offset,FALSE,TRUE),
5845 aopGet(AOP(right),offset,FALSE,FALSE));
5848 if (AOP_TYPE(left) == AOP_ACC)
5849 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5851 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5852 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5854 if (IS_AOP_PREG(left)) {
5855 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5856 aopPut(AOP(result),"a",offset);
5858 pic14_emitcode("xrl","%s,a",
5859 aopGet(AOP(left),offset,FALSE,TRUE));
5865 // left & result in different registers
5866 if(AOP_TYPE(result) == AOP_CRY){
5868 // if(size), result in bit
5869 // if(!size && ifx), conditional oper: if(left ^ right)
5870 symbol *tlbl = newiTempLabel(NULL);
5871 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5873 pic14_emitcode("setb","c");
5875 if((AOP_TYPE(right) == AOP_LIT) &&
5876 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5877 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5879 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5880 pic14_emitcode("xrl","a,%s",
5881 aopGet(AOP(left),offset,FALSE,FALSE));
5883 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5888 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5889 pic14_outBitC(result);
5891 jmpTrueOrFalse(ifx, tlbl);
5892 } else for(;(size--);offset++){
5894 // result = left & right
5895 if(AOP_TYPE(right) == AOP_LIT){
5896 int t = (lit >> (offset*8)) & 0x0FFL;
5899 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5900 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5901 pic14_emitcode("movf","%s,w",
5902 aopGet(AOP(left),offset,FALSE,FALSE));
5903 pic14_emitcode("movwf","%s",
5904 aopGet(AOP(result),offset,FALSE,FALSE));
5907 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5908 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5909 pic14_emitcode("comf","%s,w",
5910 aopGet(AOP(left),offset,FALSE,FALSE));
5911 pic14_emitcode("movwf","%s",
5912 aopGet(AOP(result),offset,FALSE,FALSE));
5915 emitpcode(POC_MOVLW, popGetLit(t));
5916 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5917 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5918 pic14_emitcode("movlw","0x%x",t);
5919 pic14_emitcode("xorwf","%s,w",
5920 aopGet(AOP(left),offset,FALSE,FALSE));
5921 pic14_emitcode("movwf","%s",
5922 aopGet(AOP(result),offset,FALSE,FALSE));
5928 // faster than result <- left, anl result,right
5929 // and better if result is SFR
5930 if (AOP_TYPE(left) == AOP_ACC) {
5931 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5932 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5934 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5935 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5936 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5937 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5939 if ( AOP_TYPE(result) != AOP_ACC){
5940 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5941 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5947 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5948 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5949 freeAsmop(result,NULL,ic,TRUE);
5952 /*-----------------------------------------------------------------*/
5953 /* genInline - write the inline code out */
5954 /*-----------------------------------------------------------------*/
5955 static void genInline (iCode *ic)
5957 char *buffer, *bp, *bp1;
5959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5961 _G.inLine += (!options.asmpeep);
5963 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5964 strcpy(buffer,IC_INLINE(ic));
5966 /* emit each line as a code */
5970 pic14_emitcode(bp1,"");
5971 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5978 pic14_emitcode(bp1,"");
5985 pic14_emitcode(bp1,"");
5986 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5988 /* pic14_emitcode("",buffer); */
5989 _G.inLine -= (!options.asmpeep);
5992 /*-----------------------------------------------------------------*/
5993 /* genRRC - rotate right with carry */
5994 /*-----------------------------------------------------------------*/
5995 static void genRRC (iCode *ic)
5997 operand *left , *result ;
5998 int size, offset = 0, same;
6000 /* rotate right with carry */
6002 result=IC_RESULT(ic);
6003 aopOp (left,ic,FALSE);
6004 aopOp (result,ic,FALSE);
6006 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6008 same = pic14_sameRegs(AOP(result),AOP(left));
6010 size = AOP_SIZE(result);
6012 /* get the lsb and put it into the carry */
6013 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6020 emitpcode(POC_RRF, popGet(AOP(left),offset));
6022 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6023 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6029 freeAsmop(left,NULL,ic,TRUE);
6030 freeAsmop(result,NULL,ic,TRUE);
6033 /*-----------------------------------------------------------------*/
6034 /* genRLC - generate code for rotate left with carry */
6035 /*-----------------------------------------------------------------*/
6036 static void genRLC (iCode *ic)
6038 operand *left , *result ;
6039 int size, offset = 0;
6042 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6043 /* rotate right with carry */
6045 result=IC_RESULT(ic);
6046 aopOp (left,ic,FALSE);
6047 aopOp (result,ic,FALSE);
6049 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6051 same = pic14_sameRegs(AOP(result),AOP(left));
6053 /* move it to the result */
6054 size = AOP_SIZE(result);
6056 /* get the msb and put it into the carry */
6057 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6064 emitpcode(POC_RLF, popGet(AOP(left),offset));
6066 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6067 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6074 freeAsmop(left,NULL,ic,TRUE);
6075 freeAsmop(result,NULL,ic,TRUE);
6078 /*-----------------------------------------------------------------*/
6079 /* genGetHbit - generates code get highest order bit */
6080 /*-----------------------------------------------------------------*/
6081 static void genGetHbit (iCode *ic)
6083 operand *left, *result;
6085 result=IC_RESULT(ic);
6086 aopOp (left,ic,FALSE);
6087 aopOp (result,ic,FALSE);
6089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6090 /* get the highest order byte into a */
6091 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6092 if(AOP_TYPE(result) == AOP_CRY){
6093 pic14_emitcode("rlc","a");
6094 pic14_outBitC(result);
6097 pic14_emitcode("rl","a");
6098 pic14_emitcode("anl","a,#0x01");
6099 pic14_outAcc(result);
6103 freeAsmop(left,NULL,ic,TRUE);
6104 freeAsmop(result,NULL,ic,TRUE);
6107 /*-----------------------------------------------------------------*/
6108 /* AccRol - rotate left accumulator by known count */
6109 /*-----------------------------------------------------------------*/
6110 static void AccRol (int shCount)
6112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6113 shCount &= 0x0007; // shCount : 0..7
6118 pic14_emitcode("rl","a");
6121 pic14_emitcode("rl","a");
6122 pic14_emitcode("rl","a");
6125 pic14_emitcode("swap","a");
6126 pic14_emitcode("rr","a");
6129 pic14_emitcode("swap","a");
6132 pic14_emitcode("swap","a");
6133 pic14_emitcode("rl","a");
6136 pic14_emitcode("rr","a");
6137 pic14_emitcode("rr","a");
6140 pic14_emitcode("rr","a");
6145 /*-----------------------------------------------------------------*/
6146 /* AccLsh - left shift accumulator by known count */
6147 /*-----------------------------------------------------------------*/
6148 static void AccLsh (int shCount)
6150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6153 pic14_emitcode("add","a,acc");
6156 pic14_emitcode("add","a,acc");
6157 pic14_emitcode("add","a,acc");
6159 /* rotate left accumulator */
6161 /* and kill the lower order bits */
6162 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6167 /*-----------------------------------------------------------------*/
6168 /* AccRsh - right shift accumulator by known count */
6169 /*-----------------------------------------------------------------*/
6170 static void AccRsh (int shCount)
6172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6176 pic14_emitcode("rrc","a");
6178 /* rotate right accumulator */
6179 AccRol(8 - shCount);
6180 /* and kill the higher order bits */
6181 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6187 /*-----------------------------------------------------------------*/
6188 /* AccSRsh - signed right shift accumulator by known count */
6189 /*-----------------------------------------------------------------*/
6190 static void AccSRsh (int shCount)
6193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6196 pic14_emitcode("mov","c,acc.7");
6197 pic14_emitcode("rrc","a");
6198 } else if(shCount == 2){
6199 pic14_emitcode("mov","c,acc.7");
6200 pic14_emitcode("rrc","a");
6201 pic14_emitcode("mov","c,acc.7");
6202 pic14_emitcode("rrc","a");
6204 tlbl = newiTempLabel(NULL);
6205 /* rotate right accumulator */
6206 AccRol(8 - shCount);
6207 /* and kill the higher order bits */
6208 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6209 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6210 pic14_emitcode("orl","a,#0x%02x",
6211 (unsigned char)~SRMask[shCount]);
6212 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6217 /*-----------------------------------------------------------------*/
6218 /* shiftR1Left2Result - shift right one byte from left to result */
6219 /*-----------------------------------------------------------------*/
6220 static void shiftR1Left2ResultSigned (operand *left, int offl,
6221 operand *result, int offr,
6226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6228 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6232 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6234 emitpcode(POC_RRF, popGet(AOP(result),offr));
6236 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6237 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6243 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6245 emitpcode(POC_RRF, popGet(AOP(result),offr));
6247 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6248 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6250 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6251 emitpcode(POC_RRF, popGet(AOP(result),offr));
6257 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6259 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6260 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6263 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6264 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6265 emitpcode(POC_ANDLW, popGetLit(0x1f));
6267 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6268 emitpcode(POC_IORLW, popGetLit(0xe0));
6270 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6274 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6275 emitpcode(POC_ANDLW, popGetLit(0x0f));
6276 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6277 emitpcode(POC_IORLW, popGetLit(0xf0));
6278 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6282 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6284 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6285 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6287 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6288 emitpcode(POC_ANDLW, popGetLit(0x07));
6289 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6290 emitpcode(POC_IORLW, popGetLit(0xf8));
6291 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6296 emitpcode(POC_MOVLW, popGetLit(0x00));
6297 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6298 emitpcode(POC_MOVLW, popGetLit(0xfe));
6299 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6300 emitpcode(POC_IORLW, popGetLit(0x01));
6301 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6303 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6304 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6305 emitpcode(POC_DECF, popGet(AOP(result),offr));
6306 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6307 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6313 emitpcode(POC_MOVLW, popGetLit(0x00));
6314 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6315 emitpcode(POC_MOVLW, popGetLit(0xff));
6316 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6318 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6319 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6320 emitpcode(POC_DECF, popGet(AOP(result),offr));
6328 /*-----------------------------------------------------------------*/
6329 /* shiftR1Left2Result - shift right one byte from left to result */
6330 /*-----------------------------------------------------------------*/
6331 static void shiftR1Left2Result (operand *left, int offl,
6332 operand *result, int offr,
6333 int shCount, int sign)
6337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6339 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6341 /* Copy the msb into the carry if signed. */
6343 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
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_RRF, popGet(AOP(result),offr));
6364 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6365 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6368 emitpcode(POC_RRF, popGet(AOP(result),offr));
6373 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6375 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6376 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6379 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6380 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6381 emitpcode(POC_ANDLW, popGetLit(0x1f));
6382 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6386 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6387 emitpcode(POC_ANDLW, popGetLit(0x0f));
6388 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6393 emitpcode(POC_ANDLW, popGetLit(0x0f));
6394 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6396 emitpcode(POC_RRF, popGet(AOP(result),offr));
6401 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6402 emitpcode(POC_ANDLW, popGetLit(0x80));
6403 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6404 emitpcode(POC_RLF, popGet(AOP(result),offr));
6405 emitpcode(POC_RLF, popGet(AOP(result),offr));
6410 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6411 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6412 emitpcode(POC_RLF, popGet(AOP(result),offr));
6421 /*-----------------------------------------------------------------*/
6422 /* shiftL1Left2Result - shift left one byte from left to result */
6423 /*-----------------------------------------------------------------*/
6424 static void shiftL1Left2Result (operand *left, int offl,
6425 operand *result, int offr, int shCount)
6430 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6432 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6433 DEBUGpic14_emitcode ("; ***","same = %d",same);
6434 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6436 /* shift left accumulator */
6437 //AccLsh(shCount); // don't comment out just yet...
6438 // aopPut(AOP(result),"a",offr);
6442 /* Shift left 1 bit position */
6443 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6445 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6447 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6448 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6452 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6453 emitpcode(POC_ANDLW,popGetLit(0x7e));
6454 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6455 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6458 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6459 emitpcode(POC_ANDLW,popGetLit(0x3e));
6460 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6461 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6462 emitpcode(POC_RLF, popGet(AOP(result),offr));
6465 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6466 emitpcode(POC_ANDLW, popGetLit(0xf0));
6467 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6470 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6471 emitpcode(POC_ANDLW, popGetLit(0xf0));
6472 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6473 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6476 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6477 emitpcode(POC_ANDLW, popGetLit(0x30));
6478 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6479 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6480 emitpcode(POC_RLF, popGet(AOP(result),offr));
6483 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6484 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6485 emitpcode(POC_RRF, popGet(AOP(result),offr));
6489 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6494 /*-----------------------------------------------------------------*/
6495 /* movLeft2Result - move byte from left to result */
6496 /*-----------------------------------------------------------------*/
6497 static void movLeft2Result (operand *left, int offl,
6498 operand *result, int offr)
6501 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6502 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6503 l = aopGet(AOP(left),offl,FALSE,FALSE);
6505 if (*l == '@' && (IS_AOP_PREG(result))) {
6506 pic14_emitcode("mov","a,%s",l);
6507 aopPut(AOP(result),"a",offr);
6509 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6510 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6515 /*-----------------------------------------------------------------*/
6516 /* shiftL2Left2Result - shift left two bytes from left to result */
6517 /*-----------------------------------------------------------------*/
6518 static void shiftL2Left2Result (operand *left, int offl,
6519 operand *result, int offr, int shCount)
6523 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6525 if(pic14_sameRegs(AOP(result), AOP(left))) {
6533 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6534 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6535 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6539 emitpcode(POC_RLF, popGet(AOP(result),offr));
6540 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6546 emitpcode(POC_MOVLW, popGetLit(0x0f));
6547 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6548 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6549 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6550 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6551 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6552 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6554 emitpcode(POC_RLF, popGet(AOP(result),offr));
6555 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6559 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6560 emitpcode(POC_RRF, popGet(AOP(result),offr));
6561 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6562 emitpcode(POC_RRF, popGet(AOP(result),offr));
6563 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6564 emitpcode(POC_ANDLW,popGetLit(0xc0));
6565 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6566 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6567 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6568 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6571 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6572 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6573 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6574 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6575 emitpcode(POC_RRF, popGet(AOP(result),offr));
6585 /* note, use a mov/add for the shift since the mov has a
6586 chance of getting optimized out */
6587 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6588 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6589 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6590 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6591 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6595 emitpcode(POC_RLF, popGet(AOP(result),offr));
6596 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6602 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6603 emitpcode(POC_ANDLW, popGetLit(0xF0));
6604 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6606 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6607 emitpcode(POC_ANDLW, popGetLit(0xF0));
6608 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6609 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_RLF, popGet(AOP(result),offr));
6614 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6619 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6620 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6621 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6623 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6624 emitpcode(POC_RRF, popGet(AOP(result),offr));
6625 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6626 emitpcode(POC_ANDLW,popGetLit(0xc0));
6627 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6628 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6629 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6630 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6633 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6634 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6635 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6636 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6637 emitpcode(POC_RRF, popGet(AOP(result),offr));
6642 /*-----------------------------------------------------------------*/
6643 /* shiftR2Left2Result - shift right two bytes from left to result */
6644 /*-----------------------------------------------------------------*/
6645 static void shiftR2Left2Result (operand *left, int offl,
6646 operand *result, int offr,
6647 int shCount, int sign)
6651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6652 same = pic14_sameRegs(AOP(result), AOP(left));
6654 if(same && ((offl + MSB16) == offr)){
6656 /* don't crash result[offr] */
6657 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6658 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6660 movLeft2Result(left,offl, result, offr);
6661 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6663 /* a:x >> shCount (x = lsb(result))*/
6666 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6668 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6677 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_RRF,popGet(AOP(result),offr));
6685 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6686 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6687 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6688 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6693 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6696 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6697 emitpcode(POC_RRF,popGet(AOP(result),offr));
6704 emitpcode(POC_MOVLW, popGetLit(0xf0));
6705 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6706 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6708 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6709 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6710 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6711 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6713 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6714 emitpcode(POC_ANDLW, popGetLit(0x0f));
6715 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6717 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6718 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6719 emitpcode(POC_ANDLW, popGetLit(0xf0));
6720 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6721 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6725 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6726 emitpcode(POC_RRF, popGet(AOP(result),offr));
6730 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6731 emitpcode(POC_BTFSC,
6732 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6733 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RLF, popGet(AOP(result),offr));
6742 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_RLF, popGet(AOP(result),offr));
6745 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6747 emitpcode(POC_ANDLW,popGetLit(0x03));
6749 emitpcode(POC_BTFSC,
6750 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6751 emitpcode(POC_IORLW,popGetLit(0xfc));
6753 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6754 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6756 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6758 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6759 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6760 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6761 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6762 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6763 emitpcode(POC_ANDLW,popGetLit(0x03));
6765 emitpcode(POC_BTFSC,
6766 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6767 emitpcode(POC_IORLW,popGetLit(0xfc));
6769 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6770 emitpcode(POC_RLF, popGet(AOP(result),offr));
6777 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6778 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6779 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6780 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6783 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6785 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6790 /*-----------------------------------------------------------------*/
6791 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6792 /*-----------------------------------------------------------------*/
6793 static void shiftLLeftOrResult (operand *left, int offl,
6794 operand *result, int offr, int shCount)
6796 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6797 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6798 /* shift left accumulator */
6800 /* or with result */
6801 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6802 /* back to result */
6803 aopPut(AOP(result),"a",offr);
6806 /*-----------------------------------------------------------------*/
6807 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6808 /*-----------------------------------------------------------------*/
6809 static void shiftRLeftOrResult (operand *left, int offl,
6810 operand *result, int offr, int shCount)
6812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6813 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6814 /* shift right accumulator */
6816 /* or with result */
6817 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6818 /* back to result */
6819 aopPut(AOP(result),"a",offr);
6822 /*-----------------------------------------------------------------*/
6823 /* genlshOne - left shift a one byte quantity by known count */
6824 /*-----------------------------------------------------------------*/
6825 static void genlshOne (operand *result, operand *left, int shCount)
6827 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6828 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6831 /*-----------------------------------------------------------------*/
6832 /* genlshTwo - left shift two bytes by known amount != 0 */
6833 /*-----------------------------------------------------------------*/
6834 static void genlshTwo (operand *result,operand *left, int shCount)
6838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6839 size = pic14_getDataSize(result);
6841 /* if shCount >= 8 */
6847 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6849 movLeft2Result(left, LSB, result, MSB16);
6851 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6854 /* 1 <= shCount <= 7 */
6857 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6859 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6863 /*-----------------------------------------------------------------*/
6864 /* shiftLLong - shift left one long from left to result */
6865 /* offl = LSB or MSB16 */
6866 /*-----------------------------------------------------------------*/
6867 static void shiftLLong (operand *left, operand *result, int offr )
6870 int size = AOP_SIZE(result);
6872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6873 if(size >= LSB+offr){
6874 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6876 pic14_emitcode("add","a,acc");
6877 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6878 size >= MSB16+offr && offr != LSB )
6879 pic14_emitcode("xch","a,%s",
6880 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6882 aopPut(AOP(result),"a",LSB+offr);
6885 if(size >= MSB16+offr){
6886 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6887 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6890 pic14_emitcode("rlc","a");
6891 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6892 size >= MSB24+offr && offr != LSB)
6893 pic14_emitcode("xch","a,%s",
6894 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6896 aopPut(AOP(result),"a",MSB16+offr);
6899 if(size >= MSB24+offr){
6900 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6901 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6904 pic14_emitcode("rlc","a");
6905 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6906 size >= MSB32+offr && offr != LSB )
6907 pic14_emitcode("xch","a,%s",
6908 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6910 aopPut(AOP(result),"a",MSB24+offr);
6913 if(size > MSB32+offr){
6914 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6915 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6918 pic14_emitcode("rlc","a");
6919 aopPut(AOP(result),"a",MSB32+offr);
6922 aopPut(AOP(result),zero,LSB);
6925 /*-----------------------------------------------------------------*/
6926 /* genlshFour - shift four byte by a known amount != 0 */
6927 /*-----------------------------------------------------------------*/
6928 static void genlshFour (operand *result, operand *left, int shCount)
6932 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6933 size = AOP_SIZE(result);
6935 /* if shifting more that 3 bytes */
6936 if (shCount >= 24 ) {
6939 /* lowest order of left goes to the highest
6940 order of the destination */
6941 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6943 movLeft2Result(left, LSB, result, MSB32);
6944 aopPut(AOP(result),zero,LSB);
6945 aopPut(AOP(result),zero,MSB16);
6946 aopPut(AOP(result),zero,MSB32);
6950 /* more than two bytes */
6951 else if ( shCount >= 16 ) {
6952 /* lower order two bytes goes to higher order two bytes */
6954 /* if some more remaining */
6956 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6958 movLeft2Result(left, MSB16, result, MSB32);
6959 movLeft2Result(left, LSB, result, MSB24);
6961 aopPut(AOP(result),zero,MSB16);
6962 aopPut(AOP(result),zero,LSB);
6966 /* if more than 1 byte */
6967 else if ( shCount >= 8 ) {
6968 /* lower order three bytes goes to higher order three bytes */
6972 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6974 movLeft2Result(left, LSB, result, MSB16);
6976 else{ /* size = 4 */
6978 movLeft2Result(left, MSB24, result, MSB32);
6979 movLeft2Result(left, MSB16, result, MSB24);
6980 movLeft2Result(left, LSB, result, MSB16);
6981 aopPut(AOP(result),zero,LSB);
6983 else if(shCount == 1)
6984 shiftLLong(left, result, MSB16);
6986 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6987 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6988 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6989 aopPut(AOP(result),zero,LSB);
6994 /* 1 <= shCount <= 7 */
6995 else if(shCount <= 2){
6996 shiftLLong(left, result, LSB);
6998 shiftLLong(result, result, LSB);
7000 /* 3 <= shCount <= 7, optimize */
7002 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7003 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7004 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7008 /*-----------------------------------------------------------------*/
7009 /* genLeftShiftLiteral - left shifting by known count */
7010 /*-----------------------------------------------------------------*/
7011 static void genLeftShiftLiteral (operand *left,
7016 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7019 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7020 freeAsmop(right,NULL,ic,TRUE);
7022 aopOp(left,ic,FALSE);
7023 aopOp(result,ic,FALSE);
7025 size = getSize(operandType(result));
7028 pic14_emitcode("; shift left ","result %d, left %d",size,
7032 /* I suppose that the left size >= result size */
7035 movLeft2Result(left, size, result, size);
7039 else if(shCount >= (size * 8))
7041 aopPut(AOP(result),zero,size);
7045 genlshOne (result,left,shCount);
7050 genlshTwo (result,left,shCount);
7054 genlshFour (result,left,shCount);
7058 freeAsmop(left,NULL,ic,TRUE);
7059 freeAsmop(result,NULL,ic,TRUE);
7062 /*-----------------------------------------------------------------*
7063 * genMultiAsm - repeat assembly instruction for size of register.
7064 * if endian == 1, then the high byte (i.e base address + size of
7065 * register) is used first else the low byte is used first;
7066 *-----------------------------------------------------------------*/
7067 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7085 emitpcode(poc, popGet(AOP(reg),offset));
7090 /*-----------------------------------------------------------------*/
7091 /* genLeftShift - generates code for left shifting */
7092 /*-----------------------------------------------------------------*/
7093 static void genLeftShift (iCode *ic)
7095 operand *left,*right, *result;
7098 symbol *tlbl , *tlbl1;
7101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7103 right = IC_RIGHT(ic);
7105 result = IC_RESULT(ic);
7107 aopOp(right,ic,FALSE);
7109 /* if the shift count is known then do it
7110 as efficiently as possible */
7111 if (AOP_TYPE(right) == AOP_LIT) {
7112 genLeftShiftLiteral (left,right,result,ic);
7116 /* shift count is unknown then we have to form
7117 a loop get the loop count in B : Note: we take
7118 only the lower order byte since shifting
7119 more that 32 bits make no sense anyway, ( the
7120 largest size of an object can be only 32 bits ) */
7123 aopOp(left,ic,FALSE);
7124 aopOp(result,ic,FALSE);
7126 /* now move the left to the result if they are not the
7128 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7129 AOP_SIZE(result) > 1) {
7131 size = AOP_SIZE(result);
7134 l = aopGet(AOP(left),offset,FALSE,TRUE);
7135 if (*l == '@' && (IS_AOP_PREG(result))) {
7137 pic14_emitcode("mov","a,%s",l);
7138 aopPut(AOP(result),"a",offset);
7140 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7141 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7142 //aopPut(AOP(result),l,offset);
7148 size = AOP_SIZE(result);
7150 /* if it is only one byte then */
7152 if(optimized_for_speed) {
7153 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7154 emitpcode(POC_ANDLW, popGetLit(0xf0));
7155 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7156 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7157 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7158 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7159 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7160 emitpcode(POC_RLFW, popGet(AOP(result),0));
7161 emitpcode(POC_ANDLW, popGetLit(0xfe));
7162 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7163 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7164 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7167 tlbl = newiTempLabel(NULL);
7168 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7169 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7170 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7173 emitpcode(POC_COMFW, popGet(AOP(right),0));
7174 emitpcode(POC_RRF, popGet(AOP(result),0));
7175 emitpLabel(tlbl->key);
7176 emitpcode(POC_RLF, popGet(AOP(result),0));
7177 emitpcode(POC_ADDLW, popGetLit(1));
7179 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7184 if (pic14_sameRegs(AOP(left),AOP(result))) {
7186 tlbl = newiTempLabel(NULL);
7187 emitpcode(POC_COMFW, popGet(AOP(right),0));
7188 genMultiAsm(POC_RRF, result, size,1);
7189 emitpLabel(tlbl->key);
7190 genMultiAsm(POC_RLF, result, size,0);
7191 emitpcode(POC_ADDLW, popGetLit(1));
7193 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7197 //tlbl = newiTempLabel(NULL);
7199 //tlbl1 = newiTempLabel(NULL);
7201 //reAdjustPreg(AOP(result));
7203 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7204 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7205 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7207 //pic14_emitcode("add","a,acc");
7208 //aopPut(AOP(result),"a",offset++);
7210 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7212 // pic14_emitcode("rlc","a");
7213 // aopPut(AOP(result),"a",offset++);
7215 //reAdjustPreg(AOP(result));
7217 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7218 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7221 tlbl = newiTempLabel(NULL);
7222 tlbl1= newiTempLabel(NULL);
7224 size = AOP_SIZE(result);
7227 pctemp = popGetTempReg(); /* grab a temporary working register. */
7229 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7231 /* offset should be 0, 1 or 3 */
7232 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7234 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7236 emitpcode(POC_MOVWF, pctemp);
7239 emitpLabel(tlbl->key);
7242 emitpcode(POC_RLF, popGet(AOP(result),0));
7244 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7246 emitpcode(POC_DECFSZ, pctemp);
7247 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7248 emitpLabel(tlbl1->key);
7250 popReleaseTempReg(pctemp);
7254 freeAsmop (right,NULL,ic,TRUE);
7255 freeAsmop(left,NULL,ic,TRUE);
7256 freeAsmop(result,NULL,ic,TRUE);
7259 /*-----------------------------------------------------------------*/
7260 /* genrshOne - right shift a one byte quantity by known count */
7261 /*-----------------------------------------------------------------*/
7262 static void genrshOne (operand *result, operand *left,
7263 int shCount, int sign)
7265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7266 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7269 /*-----------------------------------------------------------------*/
7270 /* genrshTwo - right shift two bytes by known amount != 0 */
7271 /*-----------------------------------------------------------------*/
7272 static void genrshTwo (operand *result,operand *left,
7273 int shCount, int sign)
7275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7276 /* if shCount >= 8 */
7280 shiftR1Left2Result(left, MSB16, result, LSB,
7283 movLeft2Result(left, MSB16, result, LSB);
7285 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7288 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7289 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7293 /* 1 <= shCount <= 7 */
7295 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7298 /*-----------------------------------------------------------------*/
7299 /* shiftRLong - shift right one long from left to result */
7300 /* offl = LSB or MSB16 */
7301 /*-----------------------------------------------------------------*/
7302 static void shiftRLong (operand *left, int offl,
7303 operand *result, int sign)
7305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7307 pic14_emitcode("clr","c");
7308 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7310 pic14_emitcode("mov","c,acc.7");
7311 pic14_emitcode("rrc","a");
7312 aopPut(AOP(result),"a",MSB32-offl);
7314 /* add sign of "a" */
7315 addSign(result, MSB32, sign);
7317 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7318 pic14_emitcode("rrc","a");
7319 aopPut(AOP(result),"a",MSB24-offl);
7321 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7322 pic14_emitcode("rrc","a");
7323 aopPut(AOP(result),"a",MSB16-offl);
7326 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7327 pic14_emitcode("rrc","a");
7328 aopPut(AOP(result),"a",LSB);
7332 /*-----------------------------------------------------------------*/
7333 /* genrshFour - shift four byte by a known amount != 0 */
7334 /*-----------------------------------------------------------------*/
7335 static void genrshFour (operand *result, operand *left,
7336 int shCount, int sign)
7338 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7339 /* if shifting more that 3 bytes */
7340 if(shCount >= 24 ) {
7343 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7345 movLeft2Result(left, MSB32, result, LSB);
7347 addSign(result, MSB16, sign);
7349 else if(shCount >= 16){
7352 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7354 movLeft2Result(left, MSB24, result, LSB);
7355 movLeft2Result(left, MSB32, result, MSB16);
7357 addSign(result, MSB24, sign);
7359 else if(shCount >= 8){
7362 shiftRLong(left, MSB16, result, sign);
7363 else if(shCount == 0){
7364 movLeft2Result(left, MSB16, result, LSB);
7365 movLeft2Result(left, MSB24, result, MSB16);
7366 movLeft2Result(left, MSB32, result, MSB24);
7367 addSign(result, MSB32, sign);
7370 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7371 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7372 /* the last shift is signed */
7373 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7374 addSign(result, MSB32, sign);
7377 else{ /* 1 <= shCount <= 7 */
7379 shiftRLong(left, LSB, result, sign);
7381 shiftRLong(result, LSB, result, sign);
7384 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7385 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7386 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7391 /*-----------------------------------------------------------------*/
7392 /* genRightShiftLiteral - right shifting by known count */
7393 /*-----------------------------------------------------------------*/
7394 static void genRightShiftLiteral (operand *left,
7400 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7403 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7404 freeAsmop(right,NULL,ic,TRUE);
7406 aopOp(left,ic,FALSE);
7407 aopOp(result,ic,FALSE);
7410 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7414 lsize = pic14_getDataSize(left);
7415 res_size = pic14_getDataSize(result);
7416 /* test the LEFT size !!! */
7418 /* I suppose that the left size >= result size */
7421 movLeft2Result(left, lsize, result, res_size);
7424 else if(shCount >= (lsize * 8)){
7427 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7429 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7430 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7435 emitpcode(POC_MOVLW, popGetLit(0));
7436 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7437 emitpcode(POC_MOVLW, popGetLit(0xff));
7439 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7444 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7451 genrshOne (result,left,shCount,sign);
7455 genrshTwo (result,left,shCount,sign);
7459 genrshFour (result,left,shCount,sign);
7467 freeAsmop(left,NULL,ic,TRUE);
7468 freeAsmop(result,NULL,ic,TRUE);
7471 /*-----------------------------------------------------------------*/
7472 /* genSignedRightShift - right shift of signed number */
7473 /*-----------------------------------------------------------------*/
7474 static void genSignedRightShift (iCode *ic)
7476 operand *right, *left, *result;
7479 symbol *tlbl, *tlbl1 ;
7482 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7484 /* we do it the hard way put the shift count in b
7485 and loop thru preserving the sign */
7486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7488 right = IC_RIGHT(ic);
7490 result = IC_RESULT(ic);
7492 aopOp(right,ic,FALSE);
7493 aopOp(left,ic,FALSE);
7494 aopOp(result,ic,FALSE);
7497 if ( AOP_TYPE(right) == AOP_LIT) {
7498 genRightShiftLiteral (left,right,result,ic,1);
7501 /* shift count is unknown then we have to form
7502 a loop get the loop count in B : Note: we take
7503 only the lower order byte since shifting
7504 more that 32 bits make no sense anyway, ( the
7505 largest size of an object can be only 32 bits ) */
7507 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7508 //pic14_emitcode("inc","b");
7509 //freeAsmop (right,NULL,ic,TRUE);
7510 //aopOp(left,ic,FALSE);
7511 //aopOp(result,ic,FALSE);
7513 /* now move the left to the result if they are not the
7515 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7516 AOP_SIZE(result) > 1) {
7518 size = AOP_SIZE(result);
7522 l = aopGet(AOP(left),offset,FALSE,TRUE);
7523 if (*l == '@' && IS_AOP_PREG(result)) {
7525 pic14_emitcode("mov","a,%s",l);
7526 aopPut(AOP(result),"a",offset);
7528 aopPut(AOP(result),l,offset);
7530 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7531 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7537 /* mov the highest order bit to OVR */
7538 tlbl = newiTempLabel(NULL);
7539 tlbl1= newiTempLabel(NULL);
7541 size = AOP_SIZE(result);
7544 pctemp = popGetTempReg(); /* grab a temporary working register. */
7546 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7548 /* offset should be 0, 1 or 3 */
7549 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7551 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7553 emitpcode(POC_MOVWF, pctemp);
7556 emitpLabel(tlbl->key);
7558 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7559 emitpcode(POC_RRF, popGet(AOP(result),offset));
7562 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7565 emitpcode(POC_DECFSZ, pctemp);
7566 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7567 emitpLabel(tlbl1->key);
7569 popReleaseTempReg(pctemp);
7571 size = AOP_SIZE(result);
7573 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7574 pic14_emitcode("rlc","a");
7575 pic14_emitcode("mov","ov,c");
7576 /* if it is only one byte then */
7578 l = aopGet(AOP(left),0,FALSE,FALSE);
7580 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7581 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7582 pic14_emitcode("mov","c,ov");
7583 pic14_emitcode("rrc","a");
7584 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7585 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7586 aopPut(AOP(result),"a",0);
7590 reAdjustPreg(AOP(result));
7591 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7592 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7593 pic14_emitcode("mov","c,ov");
7595 l = aopGet(AOP(result),offset,FALSE,FALSE);
7597 pic14_emitcode("rrc","a");
7598 aopPut(AOP(result),"a",offset--);
7600 reAdjustPreg(AOP(result));
7601 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7602 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7607 freeAsmop(left,NULL,ic,TRUE);
7608 freeAsmop(result,NULL,ic,TRUE);
7609 freeAsmop(right,NULL,ic,TRUE);
7612 /*-----------------------------------------------------------------*/
7613 /* genRightShift - generate code for right shifting */
7614 /*-----------------------------------------------------------------*/
7615 static void genRightShift (iCode *ic)
7617 operand *right, *left, *result;
7621 symbol *tlbl, *tlbl1 ;
7623 /* if signed then we do it the hard way preserve the
7624 sign bit moving it inwards */
7625 retype = getSpec(operandType(IC_RESULT(ic)));
7626 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7628 if (!SPEC_USIGN(retype)) {
7629 genSignedRightShift (ic);
7633 /* signed & unsigned types are treated the same : i.e. the
7634 signed is NOT propagated inwards : quoting from the
7635 ANSI - standard : "for E1 >> E2, is equivalent to division
7636 by 2**E2 if unsigned or if it has a non-negative value,
7637 otherwise the result is implementation defined ", MY definition
7638 is that the sign does not get propagated */
7640 right = IC_RIGHT(ic);
7642 result = IC_RESULT(ic);
7644 aopOp(right,ic,FALSE);
7646 /* if the shift count is known then do it
7647 as efficiently as possible */
7648 if (AOP_TYPE(right) == AOP_LIT) {
7649 genRightShiftLiteral (left,right,result,ic, 0);
7653 /* shift count is unknown then we have to form
7654 a loop get the loop count in B : Note: we take
7655 only the lower order byte since shifting
7656 more that 32 bits make no sense anyway, ( the
7657 largest size of an object can be only 32 bits ) */
7659 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7660 pic14_emitcode("inc","b");
7661 aopOp(left,ic,FALSE);
7662 aopOp(result,ic,FALSE);
7664 /* now move the left to the result if they are not the
7666 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7667 AOP_SIZE(result) > 1) {
7669 size = AOP_SIZE(result);
7672 l = aopGet(AOP(left),offset,FALSE,TRUE);
7673 if (*l == '@' && IS_AOP_PREG(result)) {
7675 pic14_emitcode("mov","a,%s",l);
7676 aopPut(AOP(result),"a",offset);
7678 aopPut(AOP(result),l,offset);
7683 tlbl = newiTempLabel(NULL);
7684 tlbl1= newiTempLabel(NULL);
7685 size = AOP_SIZE(result);
7688 /* if it is only one byte then */
7691 tlbl = newiTempLabel(NULL);
7692 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7693 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7694 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7697 emitpcode(POC_COMFW, popGet(AOP(right),0));
7698 emitpcode(POC_RLF, popGet(AOP(result),0));
7699 emitpLabel(tlbl->key);
7700 emitpcode(POC_RRF, popGet(AOP(result),0));
7701 emitpcode(POC_ADDLW, popGetLit(1));
7703 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7708 reAdjustPreg(AOP(result));
7709 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7710 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7713 l = aopGet(AOP(result),offset,FALSE,FALSE);
7715 pic14_emitcode("rrc","a");
7716 aopPut(AOP(result),"a",offset--);
7718 reAdjustPreg(AOP(result));
7720 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7721 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7724 freeAsmop(left,NULL,ic,TRUE);
7725 freeAsmop (right,NULL,ic,TRUE);
7726 freeAsmop(result,NULL,ic,TRUE);
7729 /*-----------------------------------------------------------------*/
7730 /* genUnpackBits - generates code for unpacking bits */
7731 /*-----------------------------------------------------------------*/
7732 static void genUnpackBits (operand *result, char *rname, int ptype)
7739 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7740 etype = getSpec(operandType(result));
7742 /* read the first byte */
7747 pic14_emitcode("mov","a,@%s",rname);
7751 pic14_emitcode("movx","a,@%s",rname);
7755 pic14_emitcode("movx","a,@dptr");
7759 pic14_emitcode("clr","a");
7760 pic14_emitcode("movc","a","@a+dptr");
7764 pic14_emitcode("lcall","__gptrget");
7768 /* if we have bitdisplacement then it fits */
7769 /* into this byte completely or if length is */
7770 /* less than a byte */
7771 if ((shCnt = SPEC_BSTR(etype)) ||
7772 (SPEC_BLEN(etype) <= 8)) {
7774 /* shift right acc */
7777 pic14_emitcode("anl","a,#0x%02x",
7778 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7779 aopPut(AOP(result),"a",offset);
7783 /* bit field did not fit in a byte */
7784 rlen = SPEC_BLEN(etype) - 8;
7785 aopPut(AOP(result),"a",offset++);
7792 pic14_emitcode("inc","%s",rname);
7793 pic14_emitcode("mov","a,@%s",rname);
7797 pic14_emitcode("inc","%s",rname);
7798 pic14_emitcode("movx","a,@%s",rname);
7802 pic14_emitcode("inc","dptr");
7803 pic14_emitcode("movx","a,@dptr");
7807 pic14_emitcode("clr","a");
7808 pic14_emitcode("inc","dptr");
7809 pic14_emitcode("movc","a","@a+dptr");
7813 pic14_emitcode("inc","dptr");
7814 pic14_emitcode("lcall","__gptrget");
7819 /* if we are done */
7823 aopPut(AOP(result),"a",offset++);
7828 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7829 aopPut(AOP(result),"a",offset);
7836 /*-----------------------------------------------------------------*/
7837 /* genDataPointerGet - generates code when ptr offset is known */
7838 /*-----------------------------------------------------------------*/
7839 static void genDataPointerGet (operand *left,
7843 int size , offset = 0;
7846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7849 /* optimization - most of the time, left and result are the same
7850 * address, but different types. for the pic code, we could omit
7854 aopOp(result,ic,TRUE);
7856 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7858 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7860 size = AOP_SIZE(result);
7863 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7867 freeAsmop(left,NULL,ic,TRUE);
7868 freeAsmop(result,NULL,ic,TRUE);
7871 /*-----------------------------------------------------------------*/
7872 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7873 /*-----------------------------------------------------------------*/
7874 static void genNearPointerGet (operand *left,
7881 sym_link *rtype, *retype;
7882 sym_link *ltype = operandType(left);
7885 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7887 rtype = operandType(result);
7888 retype= getSpec(rtype);
7890 aopOp(left,ic,FALSE);
7892 /* if left is rematerialisable and
7893 result is not bit variable type and
7894 the left is pointer to data space i.e
7895 lower 128 bytes of space */
7896 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7897 !IS_BITVAR(retype) &&
7898 DCL_TYPE(ltype) == POINTER) {
7899 //genDataPointerGet (left,result,ic);
7903 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7905 /* if the value is already in a pointer register
7906 then don't need anything more */
7907 if (!AOP_INPREG(AOP(left))) {
7908 /* otherwise get a free pointer register */
7909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7912 preg = getFreePtr(ic,&aop,FALSE);
7913 pic14_emitcode("mov","%s,%s",
7915 aopGet(AOP(left),0,FALSE,TRUE));
7916 rname = preg->name ;
7920 rname = aopGet(AOP(left),0,FALSE,FALSE);
7922 aopOp (result,ic,FALSE);
7924 /* if bitfield then unpack the bits */
7925 if (IS_BITVAR(retype))
7926 genUnpackBits (result,rname,POINTER);
7928 /* we have can just get the values */
7929 int size = AOP_SIZE(result);
7932 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7934 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7935 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7937 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7938 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7940 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7944 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7946 pic14_emitcode("mov","a,@%s",rname);
7947 aopPut(AOP(result),"a",offset);
7949 sprintf(buffer,"@%s",rname);
7950 aopPut(AOP(result),buffer,offset);
7954 pic14_emitcode("inc","%s",rname);
7959 /* now some housekeeping stuff */
7961 /* we had to allocate for this iCode */
7962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 freeAsmop(NULL,aop,ic,TRUE);
7965 /* we did not allocate which means left
7966 already in a pointer register, then
7967 if size > 0 && this could be used again
7968 we have to point it back to where it
7970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7971 if (AOP_SIZE(result) > 1 &&
7972 !OP_SYMBOL(left)->remat &&
7973 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7975 int size = AOP_SIZE(result) - 1;
7977 pic14_emitcode("dec","%s",rname);
7982 freeAsmop(left,NULL,ic,TRUE);
7983 freeAsmop(result,NULL,ic,TRUE);
7987 /*-----------------------------------------------------------------*/
7988 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7989 /*-----------------------------------------------------------------*/
7990 static void genPagedPointerGet (operand *left,
7997 sym_link *rtype, *retype;
7999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8001 rtype = operandType(result);
8002 retype= getSpec(rtype);
8004 aopOp(left,ic,FALSE);
8006 /* if the value is already in a pointer register
8007 then don't need anything more */
8008 if (!AOP_INPREG(AOP(left))) {
8009 /* otherwise get a free pointer register */
8011 preg = getFreePtr(ic,&aop,FALSE);
8012 pic14_emitcode("mov","%s,%s",
8014 aopGet(AOP(left),0,FALSE,TRUE));
8015 rname = preg->name ;
8017 rname = aopGet(AOP(left),0,FALSE,FALSE);
8019 freeAsmop(left,NULL,ic,TRUE);
8020 aopOp (result,ic,FALSE);
8022 /* if bitfield then unpack the bits */
8023 if (IS_BITVAR(retype))
8024 genUnpackBits (result,rname,PPOINTER);
8026 /* we have can just get the values */
8027 int size = AOP_SIZE(result);
8032 pic14_emitcode("movx","a,@%s",rname);
8033 aopPut(AOP(result),"a",offset);
8038 pic14_emitcode("inc","%s",rname);
8042 /* now some housekeeping stuff */
8044 /* we had to allocate for this iCode */
8045 freeAsmop(NULL,aop,ic,TRUE);
8047 /* we did not allocate which means left
8048 already in a pointer register, then
8049 if size > 0 && this could be used again
8050 we have to point it back to where it
8052 if (AOP_SIZE(result) > 1 &&
8053 !OP_SYMBOL(left)->remat &&
8054 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8056 int size = AOP_SIZE(result) - 1;
8058 pic14_emitcode("dec","%s",rname);
8063 freeAsmop(result,NULL,ic,TRUE);
8068 /*-----------------------------------------------------------------*/
8069 /* genFarPointerGet - gget value from far space */
8070 /*-----------------------------------------------------------------*/
8071 static void genFarPointerGet (operand *left,
8072 operand *result, iCode *ic)
8075 sym_link *retype = getSpec(operandType(result));
8077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8079 aopOp(left,ic,FALSE);
8081 /* if the operand is already in dptr
8082 then we do nothing else we move the value to dptr */
8083 if (AOP_TYPE(left) != AOP_STR) {
8084 /* if this is remateriazable */
8085 if (AOP_TYPE(left) == AOP_IMMD)
8086 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8087 else { /* we need to get it byte by byte */
8088 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8089 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8090 if (options.model == MODEL_FLAT24)
8092 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8096 /* so dptr know contains the address */
8097 freeAsmop(left,NULL,ic,TRUE);
8098 aopOp(result,ic,FALSE);
8100 /* if bit then unpack */
8101 if (IS_BITVAR(retype))
8102 genUnpackBits(result,"dptr",FPOINTER);
8104 size = AOP_SIZE(result);
8108 pic14_emitcode("movx","a,@dptr");
8109 aopPut(AOP(result),"a",offset++);
8111 pic14_emitcode("inc","dptr");
8115 freeAsmop(result,NULL,ic,TRUE);
8118 /*-----------------------------------------------------------------*/
8119 /* genCodePointerGet - get value from code space */
8120 /*-----------------------------------------------------------------*/
8121 static void genCodePointerGet (operand *left,
8122 operand *result, iCode *ic)
8125 sym_link *retype = getSpec(operandType(result));
8127 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8129 aopOp(left,ic,FALSE);
8131 /* if the operand is already in dptr
8132 then we do nothing else we move the value to dptr */
8133 if (AOP_TYPE(left) != AOP_STR) {
8134 /* if this is remateriazable */
8135 if (AOP_TYPE(left) == AOP_IMMD)
8136 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8137 else { /* we need to get it byte by byte */
8138 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8139 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8140 if (options.model == MODEL_FLAT24)
8142 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8146 /* so dptr know contains the address */
8147 freeAsmop(left,NULL,ic,TRUE);
8148 aopOp(result,ic,FALSE);
8150 /* if bit then unpack */
8151 if (IS_BITVAR(retype))
8152 genUnpackBits(result,"dptr",CPOINTER);
8154 size = AOP_SIZE(result);
8158 pic14_emitcode("clr","a");
8159 pic14_emitcode("movc","a,@a+dptr");
8160 aopPut(AOP(result),"a",offset++);
8162 pic14_emitcode("inc","dptr");
8166 freeAsmop(result,NULL,ic,TRUE);
8169 /*-----------------------------------------------------------------*/
8170 /* genGenPointerGet - gget value from generic pointer space */
8171 /*-----------------------------------------------------------------*/
8172 static void genGenPointerGet (operand *left,
8173 operand *result, iCode *ic)
8176 sym_link *retype = getSpec(operandType(result));
8178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8179 aopOp(left,ic,FALSE);
8180 aopOp(result,ic,FALSE);
8183 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8185 /* if the operand is already in dptr
8186 then we do nothing else we move the value to dptr */
8187 // if (AOP_TYPE(left) != AOP_STR) {
8188 /* if this is remateriazable */
8189 if (AOP_TYPE(left) == AOP_IMMD) {
8190 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8191 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8193 else { /* we need to get it byte by byte */
8195 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8196 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8198 size = AOP_SIZE(result);
8202 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8203 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8205 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8210 /* so dptr know contains the address */
8212 /* if bit then unpack */
8213 //if (IS_BITVAR(retype))
8214 // genUnpackBits(result,"dptr",GPOINTER);
8217 freeAsmop(left,NULL,ic,TRUE);
8218 freeAsmop(result,NULL,ic,TRUE);
8222 /*-----------------------------------------------------------------*/
8223 /* genConstPointerGet - get value from const generic pointer space */
8224 /*-----------------------------------------------------------------*/
8225 static void genConstPointerGet (operand *left,
8226 operand *result, iCode *ic)
8228 //sym_link *retype = getSpec(operandType(result));
8229 symbol *albl = newiTempLabel(NULL);
8230 symbol *blbl = newiTempLabel(NULL);
8233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8234 aopOp(left,ic,FALSE);
8235 aopOp(result,ic,FALSE);
8238 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8240 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8242 emitpcode(POC_CALL,popGetLabel(albl->key));
8243 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8244 emitpLabel(albl->key);
8246 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8248 emitpcode(poc,popGet(AOP(left),1));
8249 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8250 emitpcode(poc,popGet(AOP(left),0));
8251 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8253 emitpLabel(blbl->key);
8255 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8258 freeAsmop(left,NULL,ic,TRUE);
8259 freeAsmop(result,NULL,ic,TRUE);
8262 /*-----------------------------------------------------------------*/
8263 /* genPointerGet - generate code for pointer get */
8264 /*-----------------------------------------------------------------*/
8265 static void genPointerGet (iCode *ic)
8267 operand *left, *result ;
8268 sym_link *type, *etype;
8271 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8274 result = IC_RESULT(ic) ;
8276 /* depending on the type of pointer we need to
8277 move it to the correct pointer register */
8278 type = operandType(left);
8279 etype = getSpec(type);
8281 if (IS_PTR_CONST(type))
8282 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8284 /* if left is of type of pointer then it is simple */
8285 if (IS_PTR(type) && !IS_FUNC(type->next))
8286 p_type = DCL_TYPE(type);
8288 /* we have to go by the storage class */
8289 p_type = PTR_TYPE(SPEC_OCLS(etype));
8291 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8293 if (SPEC_OCLS(etype)->codesp ) {
8294 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8295 //p_type = CPOINTER ;
8298 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8299 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8300 /*p_type = FPOINTER ;*/
8302 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8303 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8304 /* p_type = PPOINTER; */
8306 if (SPEC_OCLS(etype) == idata )
8307 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8308 /* p_type = IPOINTER; */
8310 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8311 /* p_type = POINTER ; */
8314 /* now that we have the pointer type we assign
8315 the pointer values */
8320 genNearPointerGet (left,result,ic);
8324 genPagedPointerGet(left,result,ic);
8328 genFarPointerGet (left,result,ic);
8332 genConstPointerGet (left,result,ic);
8333 //pic14_emitcodePointerGet (left,result,ic);
8337 if (IS_PTR_CONST(type))
8338 genConstPointerGet (left,result,ic);
8340 genGenPointerGet (left,result,ic);
8346 /*-----------------------------------------------------------------*/
8347 /* genPackBits - generates code for packed bit storage */
8348 /*-----------------------------------------------------------------*/
8349 static void genPackBits (sym_link *etype ,
8351 char *rname, int p_type)
8359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8360 blen = SPEC_BLEN(etype);
8361 bstr = SPEC_BSTR(etype);
8363 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8366 /* if the bit lenth is less than or */
8367 /* it exactly fits a byte then */
8368 if (SPEC_BLEN(etype) <= 8 ) {
8369 shCount = SPEC_BSTR(etype) ;
8371 /* shift left acc */
8374 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8379 pic14_emitcode ("mov","b,a");
8380 pic14_emitcode("mov","a,@%s",rname);
8384 pic14_emitcode ("mov","b,a");
8385 pic14_emitcode("movx","a,@dptr");
8389 pic14_emitcode ("push","b");
8390 pic14_emitcode ("push","acc");
8391 pic14_emitcode ("lcall","__gptrget");
8392 pic14_emitcode ("pop","b");
8396 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8397 ((unsigned char)(0xFF << (blen+bstr)) |
8398 (unsigned char)(0xFF >> (8-bstr)) ) );
8399 pic14_emitcode ("orl","a,b");
8400 if (p_type == GPOINTER)
8401 pic14_emitcode("pop","b");
8407 pic14_emitcode("mov","@%s,a",rname);
8411 pic14_emitcode("movx","@dptr,a");
8415 DEBUGpic14_emitcode(";lcall","__gptrput");
8420 if ( SPEC_BLEN(etype) <= 8 )
8423 pic14_emitcode("inc","%s",rname);
8424 rLen = SPEC_BLEN(etype) ;
8426 /* now generate for lengths greater than one byte */
8429 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8439 pic14_emitcode("mov","@%s,a",rname);
8441 pic14_emitcode("mov","@%s,%s",rname,l);
8446 pic14_emitcode("movx","@dptr,a");
8451 DEBUGpic14_emitcode(";lcall","__gptrput");
8454 pic14_emitcode ("inc","%s",rname);
8459 /* last last was not complete */
8461 /* save the byte & read byte */
8464 pic14_emitcode ("mov","b,a");
8465 pic14_emitcode("mov","a,@%s",rname);
8469 pic14_emitcode ("mov","b,a");
8470 pic14_emitcode("movx","a,@dptr");
8474 pic14_emitcode ("push","b");
8475 pic14_emitcode ("push","acc");
8476 pic14_emitcode ("lcall","__gptrget");
8477 pic14_emitcode ("pop","b");
8481 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8482 pic14_emitcode ("orl","a,b");
8485 if (p_type == GPOINTER)
8486 pic14_emitcode("pop","b");
8491 pic14_emitcode("mov","@%s,a",rname);
8495 pic14_emitcode("movx","@dptr,a");
8499 DEBUGpic14_emitcode(";lcall","__gptrput");
8503 /*-----------------------------------------------------------------*/
8504 /* genDataPointerSet - remat pointer to data space */
8505 /*-----------------------------------------------------------------*/
8506 static void genDataPointerSet(operand *right,
8510 int size, offset = 0 ;
8511 char *l, buffer[256];
8513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8514 aopOp(right,ic,FALSE);
8516 l = aopGet(AOP(result),0,FALSE,TRUE);
8517 size = AOP_SIZE(right);
8519 if ( AOP_TYPE(result) == AOP_PCODE) {
8520 fprintf(stderr,"genDataPointerSet %s, %d\n",
8521 AOP(result)->aopu.pcop->name,
8522 PCOI(AOP(result)->aopu.pcop)->offset);
8526 // tsd, was l+1 - the underline `_' prefix was being stripped
8529 sprintf(buffer,"(%s + %d)",l,offset);
8530 fprintf(stderr,"oops %s\n",buffer);
8532 sprintf(buffer,"%s",l);
8534 if (AOP_TYPE(right) == AOP_LIT) {
8535 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8536 lit = lit >> (8*offset);
8538 pic14_emitcode("movlw","%d",lit);
8539 pic14_emitcode("movwf","%s",buffer);
8541 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8542 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8543 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8546 pic14_emitcode("clrf","%s",buffer);
8547 //emitpcode(POC_CLRF, popRegFromString(buffer));
8548 emitpcode(POC_CLRF, popGet(AOP(result),0));
8551 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8552 pic14_emitcode("movwf","%s",buffer);
8554 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8555 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8556 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8563 freeAsmop(right,NULL,ic,TRUE);
8564 freeAsmop(result,NULL,ic,TRUE);
8567 /*-----------------------------------------------------------------*/
8568 /* genNearPointerSet - pic14_emitcode for near pointer put */
8569 /*-----------------------------------------------------------------*/
8570 static void genNearPointerSet (operand *right,
8577 sym_link *ptype = operandType(result);
8580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8581 retype= getSpec(operandType(right));
8583 aopOp(result,ic,FALSE);
8586 /* if the result is rematerializable &
8587 in data space & not a bit variable */
8588 //if (AOP_TYPE(result) == AOP_IMMD &&
8589 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8590 DCL_TYPE(ptype) == POINTER &&
8591 !IS_BITVAR(retype)) {
8592 genDataPointerSet (right,result,ic);
8593 freeAsmop(result,NULL,ic,TRUE);
8597 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8598 aopOp(right,ic,FALSE);
8599 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8601 /* if the value is already in a pointer register
8602 then don't need anything more */
8603 if (!AOP_INPREG(AOP(result))) {
8604 /* otherwise get a free pointer register */
8605 //aop = newAsmop(0);
8606 //preg = getFreePtr(ic,&aop,FALSE);
8607 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8608 //pic14_emitcode("mov","%s,%s",
8610 // aopGet(AOP(result),0,FALSE,TRUE));
8611 //rname = preg->name ;
8612 //pic14_emitcode("movwf","fsr");
8613 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8614 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8615 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8616 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8620 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8623 /* if bitfield then unpack the bits */
8624 if (IS_BITVAR(retype)) {
8625 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8626 "The programmer is obviously confused");
8627 //genPackBits (retype,right,rname,POINTER);
8631 /* we have can just get the values */
8632 int size = AOP_SIZE(right);
8635 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8637 l = aopGet(AOP(right),offset,FALSE,TRUE);
8640 //pic14_emitcode("mov","@%s,a",rname);
8641 pic14_emitcode("movf","indf,w ;1");
8644 if (AOP_TYPE(right) == AOP_LIT) {
8645 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8647 pic14_emitcode("movlw","%s",l);
8648 pic14_emitcode("movwf","indf ;2");
8650 pic14_emitcode("clrf","indf");
8652 pic14_emitcode("movf","%s,w",l);
8653 pic14_emitcode("movwf","indf ;2");
8655 //pic14_emitcode("mov","@%s,%s",rname,l);
8658 pic14_emitcode("incf","fsr,f ;3");
8659 //pic14_emitcode("inc","%s",rname);
8664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8665 /* now some housekeeping stuff */
8667 /* we had to allocate for this iCode */
8668 freeAsmop(NULL,aop,ic,TRUE);
8670 /* we did not allocate which means left
8671 already in a pointer register, then
8672 if size > 0 && this could be used again
8673 we have to point it back to where it
8675 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8676 if (AOP_SIZE(right) > 1 &&
8677 !OP_SYMBOL(result)->remat &&
8678 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8680 int size = AOP_SIZE(right) - 1;
8682 pic14_emitcode("decf","fsr,f");
8683 //pic14_emitcode("dec","%s",rname);
8687 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8690 freeAsmop(right,NULL,ic,TRUE);
8691 freeAsmop(result,NULL,ic,TRUE);
8694 /*-----------------------------------------------------------------*/
8695 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8696 /*-----------------------------------------------------------------*/
8697 static void genPagedPointerSet (operand *right,
8706 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8708 retype= getSpec(operandType(right));
8710 aopOp(result,ic,FALSE);
8712 /* if the value is already in a pointer register
8713 then don't need anything more */
8714 if (!AOP_INPREG(AOP(result))) {
8715 /* otherwise get a free pointer register */
8717 preg = getFreePtr(ic,&aop,FALSE);
8718 pic14_emitcode("mov","%s,%s",
8720 aopGet(AOP(result),0,FALSE,TRUE));
8721 rname = preg->name ;
8723 rname = aopGet(AOP(result),0,FALSE,FALSE);
8725 freeAsmop(result,NULL,ic,TRUE);
8726 aopOp (right,ic,FALSE);
8728 /* if bitfield then unpack the bits */
8729 if (IS_BITVAR(retype))
8730 genPackBits (retype,right,rname,PPOINTER);
8732 /* we have can just get the values */
8733 int size = AOP_SIZE(right);
8737 l = aopGet(AOP(right),offset,FALSE,TRUE);
8740 pic14_emitcode("movx","@%s,a",rname);
8743 pic14_emitcode("inc","%s",rname);
8749 /* now some housekeeping stuff */
8751 /* we had to allocate for this iCode */
8752 freeAsmop(NULL,aop,ic,TRUE);
8754 /* we did not allocate which means left
8755 already in a pointer register, then
8756 if size > 0 && this could be used again
8757 we have to point it back to where it
8759 if (AOP_SIZE(right) > 1 &&
8760 !OP_SYMBOL(result)->remat &&
8761 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8763 int size = AOP_SIZE(right) - 1;
8765 pic14_emitcode("dec","%s",rname);
8770 freeAsmop(right,NULL,ic,TRUE);
8775 /*-----------------------------------------------------------------*/
8776 /* genFarPointerSet - set value from far space */
8777 /*-----------------------------------------------------------------*/
8778 static void genFarPointerSet (operand *right,
8779 operand *result, iCode *ic)
8782 sym_link *retype = getSpec(operandType(right));
8784 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8785 aopOp(result,ic,FALSE);
8787 /* if the operand is already in dptr
8788 then we do nothing else we move the value to dptr */
8789 if (AOP_TYPE(result) != AOP_STR) {
8790 /* if this is remateriazable */
8791 if (AOP_TYPE(result) == AOP_IMMD)
8792 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8793 else { /* we need to get it byte by byte */
8794 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8795 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8796 if (options.model == MODEL_FLAT24)
8798 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8802 /* so dptr know contains the address */
8803 freeAsmop(result,NULL,ic,TRUE);
8804 aopOp(right,ic,FALSE);
8806 /* if bit then unpack */
8807 if (IS_BITVAR(retype))
8808 genPackBits(retype,right,"dptr",FPOINTER);
8810 size = AOP_SIZE(right);
8814 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8816 pic14_emitcode("movx","@dptr,a");
8818 pic14_emitcode("inc","dptr");
8822 freeAsmop(right,NULL,ic,TRUE);
8825 /*-----------------------------------------------------------------*/
8826 /* genGenPointerSet - set value from generic pointer space */
8827 /*-----------------------------------------------------------------*/
8828 static void genGenPointerSet (operand *right,
8829 operand *result, iCode *ic)
8832 sym_link *retype = getSpec(operandType(right));
8834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8836 aopOp(result,ic,FALSE);
8837 aopOp(right,ic,FALSE);
8838 size = AOP_SIZE(right);
8840 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8842 /* if the operand is already in dptr
8843 then we do nothing else we move the value to dptr */
8844 if (AOP_TYPE(result) != AOP_STR) {
8845 /* if this is remateriazable */
8846 if (AOP_TYPE(result) == AOP_IMMD) {
8847 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8848 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8850 else { /* we need to get it byte by byte */
8851 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8852 size = AOP_SIZE(right);
8855 /* hack hack! see if this the FSR. If so don't load W */
8856 if(AOP_TYPE(right) != AOP_ACC) {
8858 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8859 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8862 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8864 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8865 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8869 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8870 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8873 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8880 if(aopIdx(AOP(result),0) != 4) {
8882 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8886 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8891 /* so dptr know contains the address */
8894 /* if bit then unpack */
8895 if (IS_BITVAR(retype))
8896 genPackBits(retype,right,"dptr",GPOINTER);
8898 size = AOP_SIZE(right);
8902 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8904 pic14_emitcode("incf","fsr,f");
8905 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8906 pic14_emitcode("movwf","indf");
8908 //DEBUGpic14_emitcode(";lcall","__gptrput");
8910 // pic14_emitcode("inc","dptr");
8915 freeAsmop(right,NULL,ic,TRUE);
8916 freeAsmop(result,NULL,ic,TRUE);
8919 /*-----------------------------------------------------------------*/
8920 /* genPointerSet - stores the value into a pointer location */
8921 /*-----------------------------------------------------------------*/
8922 static void genPointerSet (iCode *ic)
8924 operand *right, *result ;
8925 sym_link *type, *etype;
8928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8930 right = IC_RIGHT(ic);
8931 result = IC_RESULT(ic) ;
8933 /* depending on the type of pointer we need to
8934 move it to the correct pointer register */
8935 type = operandType(result);
8936 etype = getSpec(type);
8937 /* if left is of type of pointer then it is simple */
8938 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8939 p_type = DCL_TYPE(type);
8942 /* we have to go by the storage class */
8943 p_type = PTR_TYPE(SPEC_OCLS(etype));
8945 /* if (SPEC_OCLS(etype)->codesp ) { */
8946 /* p_type = CPOINTER ; */
8949 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8950 /* p_type = FPOINTER ; */
8952 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8953 /* p_type = PPOINTER ; */
8955 /* if (SPEC_OCLS(etype) == idata ) */
8956 /* p_type = IPOINTER ; */
8958 /* p_type = POINTER ; */
8961 /* now that we have the pointer type we assign
8962 the pointer values */
8967 genNearPointerSet (right,result,ic);
8971 genPagedPointerSet (right,result,ic);
8975 genFarPointerSet (right,result,ic);
8979 genGenPointerSet (right,result,ic);
8983 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8984 "genPointerSet: illegal pointer type");
8988 /*-----------------------------------------------------------------*/
8989 /* genIfx - generate code for Ifx statement */
8990 /*-----------------------------------------------------------------*/
8991 static void genIfx (iCode *ic, iCode *popIc)
8993 operand *cond = IC_COND(ic);
8996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8998 aopOp(cond,ic,FALSE);
9000 /* get the value into acc */
9001 if (AOP_TYPE(cond) != AOP_CRY)
9002 pic14_toBoolean(cond);
9005 /* the result is now in the accumulator */
9006 freeAsmop(cond,NULL,ic,TRUE);
9008 /* if there was something to be popped then do it */
9012 /* if the condition is a bit variable */
9013 if (isbit && IS_ITEMP(cond) &&
9015 genIfxJump(ic,SPIL_LOC(cond)->rname);
9016 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9019 if (isbit && !IS_ITEMP(cond))
9020 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9028 /*-----------------------------------------------------------------*/
9029 /* genAddrOf - generates code for address of */
9030 /*-----------------------------------------------------------------*/
9031 static void genAddrOf (iCode *ic)
9033 operand *right, *result, *left;
9036 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9039 //aopOp(IC_RESULT(ic),ic,FALSE);
9041 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9042 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9043 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9045 DEBUGpic14_AopType(__LINE__,left,right,result);
9047 size = AOP_SIZE(IC_RESULT(ic));
9051 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9052 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9056 freeAsmop(left,NULL,ic,FALSE);
9057 freeAsmop(result,NULL,ic,TRUE);
9062 /*-----------------------------------------------------------------*/
9063 /* genFarFarAssign - assignment when both are in far space */
9064 /*-----------------------------------------------------------------*/
9065 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9067 int size = AOP_SIZE(right);
9070 /* first push the right side on to the stack */
9072 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9074 pic14_emitcode ("push","acc");
9077 freeAsmop(right,NULL,ic,FALSE);
9078 /* now assign DPTR to result */
9079 aopOp(result,ic,FALSE);
9080 size = AOP_SIZE(result);
9082 pic14_emitcode ("pop","acc");
9083 aopPut(AOP(result),"a",--offset);
9085 freeAsmop(result,NULL,ic,FALSE);
9090 /*-----------------------------------------------------------------*/
9091 /* genAssign - generate code for assignment */
9092 /*-----------------------------------------------------------------*/
9093 static void genAssign (iCode *ic)
9095 operand *result, *right;
9096 int size, offset,know_W;
9097 unsigned long lit = 0L;
9099 result = IC_RESULT(ic);
9100 right = IC_RIGHT(ic) ;
9102 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9104 /* if they are the same */
9105 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9108 aopOp(right,ic,FALSE);
9109 aopOp(result,ic,TRUE);
9111 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9113 /* if they are the same registers */
9114 if (pic14_sameRegs(AOP(right),AOP(result)))
9117 /* if the result is a bit */
9118 if (AOP_TYPE(result) == AOP_CRY) {
9120 /* if the right size is a literal then
9121 we know what the value is */
9122 if (AOP_TYPE(right) == AOP_LIT) {
9124 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9125 popGet(AOP(result),0));
9127 if (((int) operandLitValue(right)))
9128 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9129 AOP(result)->aopu.aop_dir,
9130 AOP(result)->aopu.aop_dir);
9132 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9133 AOP(result)->aopu.aop_dir,
9134 AOP(result)->aopu.aop_dir);
9138 /* the right is also a bit variable */
9139 if (AOP_TYPE(right) == AOP_CRY) {
9140 emitpcode(POC_BCF, popGet(AOP(result),0));
9141 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9142 emitpcode(POC_BSF, popGet(AOP(result),0));
9144 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9145 AOP(result)->aopu.aop_dir,
9146 AOP(result)->aopu.aop_dir);
9147 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9148 AOP(right)->aopu.aop_dir,
9149 AOP(right)->aopu.aop_dir);
9150 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9151 AOP(result)->aopu.aop_dir,
9152 AOP(result)->aopu.aop_dir);
9157 emitpcode(POC_BCF, popGet(AOP(result),0));
9158 pic14_toBoolean(right);
9160 emitpcode(POC_BSF, popGet(AOP(result),0));
9161 //aopPut(AOP(result),"a",0);
9165 /* bit variables done */
9167 size = AOP_SIZE(result);
9169 if(AOP_TYPE(right) == AOP_LIT)
9170 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9172 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9174 if(aopIdx(AOP(result),0) == 4) {
9175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9176 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9177 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9180 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9186 if(AOP_TYPE(right) == AOP_LIT) {
9188 if(know_W != (lit&0xff))
9189 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9191 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9193 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9197 } else if (AOP_TYPE(right) == AOP_CRY) {
9198 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9200 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9201 emitpcode(POC_INCF, popGet(AOP(result),0));
9204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9205 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9206 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9214 freeAsmop (right,NULL,ic,FALSE);
9215 freeAsmop (result,NULL,ic,TRUE);
9218 /*-----------------------------------------------------------------*/
9219 /* genJumpTab - genrates code for jump table */
9220 /*-----------------------------------------------------------------*/
9221 static void genJumpTab (iCode *ic)
9226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9228 aopOp(IC_JTCOND(ic),ic,FALSE);
9229 /* get the condition into accumulator */
9230 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9232 /* multiply by three */
9233 pic14_emitcode("add","a,acc");
9234 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9236 jtab = newiTempLabel(NULL);
9237 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9238 pic14_emitcode("jmp","@a+dptr");
9239 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9241 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9242 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9244 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9245 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9246 emitpLabel(jtab->key);
9248 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9250 /* now generate the jump labels */
9251 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9252 jtab = setNextItem(IC_JTLABELS(ic))) {
9253 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9254 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9260 /*-----------------------------------------------------------------*/
9261 /* genMixedOperation - gen code for operators between mixed types */
9262 /*-----------------------------------------------------------------*/
9264 TSD - Written for the PIC port - but this unfortunately is buggy.
9265 This routine is good in that it is able to efficiently promote
9266 types to different (larger) sizes. Unfortunately, the temporary
9267 variables that are optimized out by this routine are sometimes
9268 used in other places. So until I know how to really parse the
9269 iCode tree, I'm going to not be using this routine :(.
9271 static int genMixedOperation (iCode *ic)
9274 operand *result = IC_RESULT(ic);
9275 sym_link *ctype = operandType(IC_LEFT(ic));
9276 operand *right = IC_RIGHT(ic);
9282 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9284 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9290 nextright = IC_RIGHT(nextic);
9291 nextleft = IC_LEFT(nextic);
9292 nextresult = IC_RESULT(nextic);
9294 aopOp(right,ic,FALSE);
9295 aopOp(result,ic,FALSE);
9296 aopOp(nextright, nextic, FALSE);
9297 aopOp(nextleft, nextic, FALSE);
9298 aopOp(nextresult, nextic, FALSE);
9300 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9306 pic14_emitcode(";remove right +","");
9308 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9314 pic14_emitcode(";remove left +","");
9318 big = AOP_SIZE(nextleft);
9319 small = AOP_SIZE(nextright);
9321 switch(nextic->op) {
9324 pic14_emitcode(";optimize a +","");
9325 /* if unsigned or not an integral type */
9326 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9327 pic14_emitcode(";add a bit to something","");
9330 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9332 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9333 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9334 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9336 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9344 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9345 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9346 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9349 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9351 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9352 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9353 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9354 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9355 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9358 pic14_emitcode("rlf","known_zero,w");
9365 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9366 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9367 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9369 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9379 freeAsmop(right,NULL,ic,TRUE);
9380 freeAsmop(result,NULL,ic,TRUE);
9381 freeAsmop(nextright,NULL,ic,TRUE);
9382 freeAsmop(nextleft,NULL,ic,TRUE);
9384 nextic->generated = 1;
9391 /*-----------------------------------------------------------------*/
9392 /* genCast - gen code for casting */
9393 /*-----------------------------------------------------------------*/
9394 static void genCast (iCode *ic)
9396 operand *result = IC_RESULT(ic);
9397 sym_link *ctype = operandType(IC_LEFT(ic));
9398 sym_link *rtype = operandType(IC_RIGHT(ic));
9399 operand *right = IC_RIGHT(ic);
9402 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9403 /* if they are equivalent then do nothing */
9404 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9407 aopOp(right,ic,FALSE) ;
9408 aopOp(result,ic,FALSE);
9410 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9412 /* if the result is a bit */
9413 if (AOP_TYPE(result) == AOP_CRY) {
9414 /* if the right size is a literal then
9415 we know what the value is */
9416 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9417 if (AOP_TYPE(right) == AOP_LIT) {
9419 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9420 popGet(AOP(result),0));
9422 if (((int) operandLitValue(right)))
9423 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9424 AOP(result)->aopu.aop_dir,
9425 AOP(result)->aopu.aop_dir);
9427 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9428 AOP(result)->aopu.aop_dir,
9429 AOP(result)->aopu.aop_dir);
9434 /* the right is also a bit variable */
9435 if (AOP_TYPE(right) == AOP_CRY) {
9438 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9440 pic14_emitcode("clrc","");
9441 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9442 AOP(right)->aopu.aop_dir,
9443 AOP(right)->aopu.aop_dir);
9444 aopPut(AOP(result),"c",0);
9449 if (AOP_TYPE(right) == AOP_REG) {
9450 emitpcode(POC_BCF, popGet(AOP(result),0));
9451 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9452 emitpcode(POC_BSF, popGet(AOP(result),0));
9454 pic14_toBoolean(right);
9455 aopPut(AOP(result),"a",0);
9459 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9461 size = AOP_SIZE(result);
9463 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9465 emitpcode(POC_CLRF, popGet(AOP(result),0));
9466 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9467 emitpcode(POC_INCF, popGet(AOP(result),0));
9470 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9475 /* if they are the same size : or less */
9476 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9478 /* if they are in the same place */
9479 if (pic14_sameRegs(AOP(right),AOP(result)))
9482 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9483 if (IS_PTR_CONST(rtype))
9484 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9485 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9486 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9488 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9489 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9490 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9491 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9492 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9493 if(AOP_SIZE(result) <2)
9494 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9498 /* if they in different places then copy */
9499 size = AOP_SIZE(result);
9502 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9503 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9505 //aopPut(AOP(result),
9506 // aopGet(AOP(right),offset,FALSE,FALSE),
9516 /* if the result is of type pointer */
9517 if (IS_PTR(ctype)) {
9520 sym_link *type = operandType(right);
9521 sym_link *etype = getSpec(type);
9522 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9524 /* pointer to generic pointer */
9525 if (IS_GENPTR(ctype)) {
9529 p_type = DCL_TYPE(type);
9531 /* we have to go by the storage class */
9532 p_type = PTR_TYPE(SPEC_OCLS(etype));
9534 /* if (SPEC_OCLS(etype)->codesp ) */
9535 /* p_type = CPOINTER ; */
9537 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9538 /* p_type = FPOINTER ; */
9540 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9541 /* p_type = PPOINTER; */
9543 /* if (SPEC_OCLS(etype) == idata ) */
9544 /* p_type = IPOINTER ; */
9546 /* p_type = POINTER ; */
9549 /* the first two bytes are known */
9550 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9551 size = GPTRSIZE - 1;
9554 if(offset < AOP_SIZE(right)) {
9555 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9556 if ((AOP_TYPE(right) == AOP_PCODE) &&
9557 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9558 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9559 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9562 aopGet(AOP(right),offset,FALSE,FALSE),
9566 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9569 /* the last byte depending on type */
9573 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9576 pic14_emitcode(";BUG!? ","%d",__LINE__);
9580 pic14_emitcode(";BUG!? ","%d",__LINE__);
9584 pic14_emitcode(";BUG!? ","%d",__LINE__);
9589 /* this should never happen */
9590 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9591 "got unknown pointer type");
9594 //aopPut(AOP(result),l, GPTRSIZE - 1);
9598 /* just copy the pointers */
9599 size = AOP_SIZE(result);
9603 aopGet(AOP(right),offset,FALSE,FALSE),
9612 /* so we now know that the size of destination is greater
9613 than the size of the source.
9614 Now, if the next iCode is an operator then we might be
9615 able to optimize the operation without performing a cast.
9617 if(genMixedOperation(ic))
9620 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9622 /* we move to result for the size of source */
9623 size = AOP_SIZE(right);
9626 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9627 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9631 /* now depending on the sign of the destination */
9632 size = AOP_SIZE(result) - AOP_SIZE(right);
9633 /* if unsigned or not an integral type */
9634 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9636 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9638 /* we need to extend the sign :{ */
9641 /* Save one instruction of casting char to int */
9642 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9643 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9644 emitpcode(POC_DECF, popGet(AOP(result),offset));
9646 emitpcodeNULLop(POC_CLRW);
9649 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9651 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9653 emitpcode(POC_MOVLW, popGetLit(0xff));
9656 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9661 freeAsmop(right,NULL,ic,TRUE);
9662 freeAsmop(result,NULL,ic,TRUE);
9666 /*-----------------------------------------------------------------*/
9667 /* genDjnz - generate decrement & jump if not zero instrucion */
9668 /*-----------------------------------------------------------------*/
9669 static int genDjnz (iCode *ic, iCode *ifx)
9672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9677 /* if the if condition has a false label
9678 then we cannot save */
9682 /* if the minus is not of the form
9684 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9685 !IS_OP_LITERAL(IC_RIGHT(ic)))
9688 if (operandLitValue(IC_RIGHT(ic)) != 1)
9691 /* if the size of this greater than one then no
9693 if (getSize(operandType(IC_RESULT(ic))) > 1)
9696 /* otherwise we can save BIG */
9697 lbl = newiTempLabel(NULL);
9698 lbl1= newiTempLabel(NULL);
9700 aopOp(IC_RESULT(ic),ic,FALSE);
9702 if (IS_AOP_PREG(IC_RESULT(ic))) {
9703 pic14_emitcode("dec","%s",
9704 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9705 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9706 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9710 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9711 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9713 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9714 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9717 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9718 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9719 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9720 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9723 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9728 /*-----------------------------------------------------------------*/
9729 /* genReceive - generate code for a receive iCode */
9730 /*-----------------------------------------------------------------*/
9731 static void genReceive (iCode *ic)
9733 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9735 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9736 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9737 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9739 int size = getSize(operandType(IC_RESULT(ic)));
9740 int offset = fReturnSizePic - size;
9742 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9743 fReturn[fReturnSizePic - offset - 1] : "acc"));
9746 aopOp(IC_RESULT(ic),ic,FALSE);
9747 size = AOP_SIZE(IC_RESULT(ic));
9750 pic14_emitcode ("pop","acc");
9751 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9756 aopOp(IC_RESULT(ic),ic,FALSE);
9758 assignResultValue(IC_RESULT(ic));
9761 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9764 /*-----------------------------------------------------------------*/
9765 /* genpic14Code - generate code for pic14 based controllers */
9766 /*-----------------------------------------------------------------*/
9768 * At this point, ralloc.c has gone through the iCode and attempted
9769 * to optimize in a way suitable for a PIC. Now we've got to generate
9770 * PIC instructions that correspond to the iCode.
9772 * Once the instructions are generated, we'll pass through both the
9773 * peep hole optimizer and the pCode optimizer.
9774 *-----------------------------------------------------------------*/
9776 void genpic14Code (iCode *lic)
9781 lineHead = lineCurr = NULL;
9783 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9786 /* if debug information required */
9787 if (options.debug && currFunc) {
9789 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9791 if (IS_STATIC(currFunc->etype)) {
9792 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9793 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9795 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9796 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9803 for (ic = lic ; ic ; ic = ic->next ) {
9805 DEBUGpic14_emitcode(";ic","");
9806 if ( cln != ic->lineno ) {
9807 if ( options.debug ) {
9809 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9810 FileBaseName(ic->filename),ic->lineno,
9811 ic->level,ic->block);
9815 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9816 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9817 printCLine(ic->filename, ic->lineno));
9820 newpCodeCSource(ic->lineno,
9822 printCLine(ic->filename, ic->lineno)));
9826 /* if the result is marked as
9827 spilt and rematerializable or code for
9828 this has already been generated then
9830 if (resultRemat(ic) || ic->generated )
9833 /* depending on the operation */
9852 /* IPOP happens only when trying to restore a
9853 spilt live range, if there is an ifx statement
9854 following this pop then the if statement might
9855 be using some of the registers being popped which
9856 would destory the contents of the register so
9857 we need to check for this condition and handle it */
9859 ic->next->op == IFX &&
9860 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9861 genIfx (ic->next,ic);
9879 genEndFunction (ic);
9899 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9916 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9920 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9927 /* note these two are xlated by algebraic equivalence
9928 during parsing SDCC.y */
9929 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9930 "got '>=' or '<=' shouldn't have come here");
9934 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9946 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9950 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9954 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9981 case GET_VALUE_AT_ADDRESS:
9986 if (POINTER_SET(ic))
10013 addSet(&_G.sendSet,ic);
10022 /* now we are ready to call the
10023 peep hole optimizer */
10024 if (!options.nopeep) {
10025 peepHole (&lineHead);
10027 /* now do the actual printing */
10028 printLine (lineHead,codeOutFile);
10031 DFPRINTF((stderr,"printing pBlock\n\n"));
10032 printpBlock(stdout,pb);