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",__LINE__);
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);
1317 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1318 PCOR(pcop)->instance = offset;
1324 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1326 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1327 PCOR(pcop)->rIdx = rIdx;
1328 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1329 PCOR(pcop)->instance = offset;
1330 pcop->type = PCOR(pcop)->r->pc_type;
1331 //rs = aop->aopu.aop_reg[offset]->name;
1332 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1337 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1338 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1339 //if(PCOR(pcop)->r == NULL)
1340 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1344 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1347 DEBUGpic14_emitcode(";","%d",__LINE__);
1348 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1350 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1351 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1352 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1353 pcop->type = PCOR(pcop)->r->pc_type;
1354 pcop->name = PCOR(pcop)->r->name;
1360 DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
1361 pcop = pCodeOpCopy(aop->aopu.pcop);
1362 PCOI(pcop)->offset = offset;
1366 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1367 "popGet got unsupported aop->type");
1370 /*-----------------------------------------------------------------*/
1371 /* aopPut - puts a string for a aop */
1372 /*-----------------------------------------------------------------*/
1373 void aopPut (asmop *aop, char *s, int offset)
1378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1380 if (aop->size && offset > ( aop->size - 1)) {
1381 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1382 "aopPut got offset > aop->size");
1386 /* will assign value to value */
1387 /* depending on where it is ofcourse */
1388 switch (aop->type) {
1391 sprintf(d,"(%s + %d)",
1392 aop->aopu.aop_dir,offset);
1393 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1396 sprintf(d,"%s",aop->aopu.aop_dir);
1399 DEBUGpic14_emitcode(";","%d",__LINE__);
1401 pic14_emitcode("movf","%s,w",s);
1402 pic14_emitcode("movwf","%s",d);
1405 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1406 if(offset >= aop->size) {
1407 emitpcode(POC_CLRF,popGet(aop,offset));
1410 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1413 emitpcode(POC_MOVWF,popGet(aop,offset));
1420 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1421 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1424 strcmp(s,"r0") == 0 ||
1425 strcmp(s,"r1") == 0 ||
1426 strcmp(s,"r2") == 0 ||
1427 strcmp(s,"r3") == 0 ||
1428 strcmp(s,"r4") == 0 ||
1429 strcmp(s,"r5") == 0 ||
1430 strcmp(s,"r6") == 0 ||
1431 strcmp(s,"r7") == 0 )
1432 pic14_emitcode("mov","%s,%s ; %d",
1433 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1438 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1440 pic14_emitcode("movwf","%s",
1441 aop->aopu.aop_reg[offset]->name);
1444 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1445 pcop->type = PO_GPR_REGISTER;
1447 PCOR(pcop)->rIdx = -1;
1448 PCOR(pcop)->r = NULL;
1450 DEBUGpic14_emitcode(";","%d",__LINE__);
1451 pcop->name = Safe_strdup(s);
1452 emitpcode(POC_MOVFW,pcop);
1454 emitpcode(POC_MOVWF,popGet(aop,offset));
1462 if (aop->type == AOP_DPTR2)
1468 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1469 "aopPut writting to code space");
1473 while (offset > aop->coff) {
1475 pic14_emitcode ("inc","dptr");
1478 while (offset < aop->coff) {
1480 pic14_emitcode("lcall","__decdptr");
1485 /* if not in accumulater */
1488 pic14_emitcode ("movx","@dptr,a");
1490 if (aop->type == AOP_DPTR2)
1498 while (offset > aop->coff) {
1500 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1502 while (offset < aop->coff) {
1504 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1510 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1515 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1517 if (strcmp(s,"r0") == 0 ||
1518 strcmp(s,"r1") == 0 ||
1519 strcmp(s,"r2") == 0 ||
1520 strcmp(s,"r3") == 0 ||
1521 strcmp(s,"r4") == 0 ||
1522 strcmp(s,"r5") == 0 ||
1523 strcmp(s,"r6") == 0 ||
1524 strcmp(s,"r7") == 0 ) {
1526 sprintf(buffer,"a%s",s);
1527 pic14_emitcode("mov","@%s,%s",
1528 aop->aopu.aop_ptr->name,buffer);
1530 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1535 if (strcmp(s,"a") == 0)
1536 pic14_emitcode("push","acc");
1538 pic14_emitcode("push","%s",s);
1543 /* if bit variable */
1544 if (!aop->aopu.aop_dir) {
1545 pic14_emitcode("clr","a");
1546 pic14_emitcode("rlc","a");
1549 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1552 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1555 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1557 lbl = newiTempLabel(NULL);
1559 if (strcmp(s,"a")) {
1562 pic14_emitcode("clr","c");
1563 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1564 pic14_emitcode("cpl","c");
1565 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1566 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1573 if (strcmp(aop->aopu.aop_str[offset],s))
1574 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1579 if (!offset && (strcmp(s,"acc") == 0))
1582 if (strcmp(aop->aopu.aop_str[offset],s))
1583 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1587 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1588 "aopPut got unsupported aop->type");
1594 /*-----------------------------------------------------------------*/
1595 /* reAdjustPreg - points a register back to where it should */
1596 /*-----------------------------------------------------------------*/
1597 static void reAdjustPreg (asmop *aop)
1601 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1603 if ((size = aop->size) <= 1)
1606 switch (aop->type) {
1610 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1614 if (aop->type == AOP_DPTR2)
1620 pic14_emitcode("lcall","__decdptr");
1623 if (aop->type == AOP_DPTR2)
1633 /*-----------------------------------------------------------------*/
1634 /* genNotFloat - generates not for float operations */
1635 /*-----------------------------------------------------------------*/
1636 static void genNotFloat (operand *op, operand *res)
1642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1643 /* we will put 127 in the first byte of
1645 aopPut(AOP(res),"#127",0);
1646 size = AOP_SIZE(op) - 1;
1649 l = aopGet(op->aop,offset++,FALSE,FALSE);
1653 pic14_emitcode("orl","a,%s",
1655 offset++,FALSE,FALSE));
1657 tlbl = newiTempLabel(NULL);
1659 tlbl = newiTempLabel(NULL);
1660 aopPut(res->aop,one,1);
1661 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1662 aopPut(res->aop,zero,1);
1663 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1665 size = res->aop->size - 2;
1667 /* put zeros in the rest */
1669 aopPut(res->aop,zero,offset++);
1673 /*-----------------------------------------------------------------*/
1674 /* opIsGptr: returns non-zero if the passed operand is */
1675 /* a generic pointer type. */
1676 /*-----------------------------------------------------------------*/
1677 static int opIsGptr(operand *op)
1679 sym_link *type = operandType(op);
1681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1682 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1690 /*-----------------------------------------------------------------*/
1691 /* pic14_getDataSize - get the operand data size */
1692 /*-----------------------------------------------------------------*/
1693 int pic14_getDataSize(operand *op)
1695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1698 return AOP_SIZE(op);
1700 // tsd- in the pic port, the genptr size is 1, so this code here
1701 // fails. ( in the 8051 port, the size was 4).
1704 size = AOP_SIZE(op);
1705 if (size == GPTRSIZE)
1707 sym_link *type = operandType(op);
1708 if (IS_GENPTR(type))
1710 /* generic pointer; arithmetic operations
1711 * should ignore the high byte (pointer type).
1714 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1721 /*-----------------------------------------------------------------*/
1722 /* pic14_outAcc - output Acc */
1723 /*-----------------------------------------------------------------*/
1724 void pic14_outAcc(operand *result)
1727 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1728 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1731 size = pic14_getDataSize(result);
1733 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1736 /* unsigned or positive */
1738 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1743 /*-----------------------------------------------------------------*/
1744 /* pic14_outBitC - output a bit C */
1745 /*-----------------------------------------------------------------*/
1746 void pic14_outBitC(operand *result)
1749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1750 /* if the result is bit */
1751 if (AOP_TYPE(result) == AOP_CRY)
1752 aopPut(AOP(result),"c",0);
1754 pic14_emitcode("clr","a ; %d", __LINE__);
1755 pic14_emitcode("rlc","a");
1756 pic14_outAcc(result);
1760 /*-----------------------------------------------------------------*/
1761 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1762 /*-----------------------------------------------------------------*/
1763 void pic14_toBoolean(operand *oper)
1765 int size = AOP_SIZE(oper) - 1;
1768 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1770 if ( AOP_TYPE(oper) != AOP_ACC) {
1771 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1774 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1779 /*-----------------------------------------------------------------*/
1780 /* genNot - generate code for ! operation */
1781 /*-----------------------------------------------------------------*/
1782 static void genNot (iCode *ic)
1785 sym_link *optype = operandType(IC_LEFT(ic));
1788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1789 /* assign asmOps to operand & result */
1790 aopOp (IC_LEFT(ic),ic,FALSE);
1791 aopOp (IC_RESULT(ic),ic,TRUE);
1793 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1794 /* if in bit space then a special case */
1795 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1796 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1797 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1798 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1800 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1801 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1802 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1807 /* if type float then do float */
1808 if (IS_FLOAT(optype)) {
1809 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1813 size = AOP_SIZE(IC_RESULT(ic));
1815 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1816 emitpcode(POC_ANDLW,popGetLit(1));
1817 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1820 pic14_toBoolean(IC_LEFT(ic));
1822 tlbl = newiTempLabel(NULL);
1823 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1824 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1825 pic14_outBitC(IC_RESULT(ic));
1828 /* release the aops */
1829 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1830 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1834 /*-----------------------------------------------------------------*/
1835 /* genCpl - generate code for complement */
1836 /*-----------------------------------------------------------------*/
1837 static void genCpl (iCode *ic)
1843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1844 /* assign asmOps to operand & result */
1845 aopOp (IC_LEFT(ic),ic,FALSE);
1846 aopOp (IC_RESULT(ic),ic,TRUE);
1848 /* if both are in bit space then
1850 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1851 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1853 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1854 pic14_emitcode("cpl","c");
1855 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1859 size = AOP_SIZE(IC_RESULT(ic));
1861 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1863 pic14_emitcode("cpl","a");
1864 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1869 /* release the aops */
1870 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1871 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1874 /*-----------------------------------------------------------------*/
1875 /* genUminusFloat - unary minus for floating points */
1876 /*-----------------------------------------------------------------*/
1877 static void genUminusFloat(operand *op,operand *result)
1879 int size ,offset =0 ;
1882 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1883 /* for this we just need to flip the
1884 first it then copy the rest in place */
1885 size = AOP_SIZE(op) - 1;
1886 l = aopGet(AOP(op),3,FALSE,FALSE);
1890 pic14_emitcode("cpl","acc.7");
1891 aopPut(AOP(result),"a",3);
1895 aopGet(AOP(op),offset,FALSE,FALSE),
1901 /*-----------------------------------------------------------------*/
1902 /* genUminus - unary minus code generation */
1903 /*-----------------------------------------------------------------*/
1904 static void genUminus (iCode *ic)
1907 sym_link *optype, *rtype;
1910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 aopOp(IC_LEFT(ic),ic,FALSE);
1913 aopOp(IC_RESULT(ic),ic,TRUE);
1915 /* if both in bit space then special
1917 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1918 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1920 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1921 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1922 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1927 optype = operandType(IC_LEFT(ic));
1928 rtype = operandType(IC_RESULT(ic));
1930 /* if float then do float stuff */
1931 if (IS_FLOAT(optype)) {
1932 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1936 /* otherwise subtract from zero by taking the 2's complement */
1937 size = AOP_SIZE(IC_LEFT(ic));
1939 for(i=0; i<size; i++) {
1940 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1941 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1943 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1944 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1948 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1949 for(i=1; i<size; i++) {
1951 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1955 /* release the aops */
1956 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1957 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1960 /*-----------------------------------------------------------------*/
1961 /* saveRegisters - will look for a call and save the registers */
1962 /*-----------------------------------------------------------------*/
1963 static void saveRegisters(iCode *lic)
1970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1972 for (ic = lic ; ic ; ic = ic->next)
1973 if (ic->op == CALL || ic->op == PCALL)
1977 fprintf(stderr,"found parameter push with no function call\n");
1981 /* if the registers have been saved already then
1983 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1986 /* find the registers in use at this time
1987 and push them away to safety */
1988 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1992 if (options.useXstack) {
1993 if (bitVectBitValue(rsave,R0_IDX))
1994 pic14_emitcode("mov","b,r0");
1995 pic14_emitcode("mov","r0,%s",spname);
1996 for (i = 0 ; i < pic14_nRegs ; i++) {
1997 if (bitVectBitValue(rsave,i)) {
1999 pic14_emitcode("mov","a,b");
2001 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2002 pic14_emitcode("movx","@r0,a");
2003 pic14_emitcode("inc","r0");
2006 pic14_emitcode("mov","%s,r0",spname);
2007 if (bitVectBitValue(rsave,R0_IDX))
2008 pic14_emitcode("mov","r0,b");
2010 //for (i = 0 ; i < pic14_nRegs ; i++) {
2011 // if (bitVectBitValue(rsave,i))
2012 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2015 dtype = operandType(IC_LEFT(ic));
2016 if (currFunc && dtype &&
2017 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2018 IFFUNC_ISISR(currFunc->type) &&
2021 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2024 /*-----------------------------------------------------------------*/
2025 /* unsaveRegisters - pop the pushed registers */
2026 /*-----------------------------------------------------------------*/
2027 static void unsaveRegisters (iCode *ic)
2032 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2033 /* find the registers in use at this time
2034 and push them away to safety */
2035 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2038 if (options.useXstack) {
2039 pic14_emitcode("mov","r0,%s",spname);
2040 for (i = pic14_nRegs ; i >= 0 ; i--) {
2041 if (bitVectBitValue(rsave,i)) {
2042 pic14_emitcode("dec","r0");
2043 pic14_emitcode("movx","a,@r0");
2045 pic14_emitcode("mov","b,a");
2047 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2051 pic14_emitcode("mov","%s,r0",spname);
2052 if (bitVectBitValue(rsave,R0_IDX))
2053 pic14_emitcode("mov","r0,b");
2055 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2056 // if (bitVectBitValue(rsave,i))
2057 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2063 /*-----------------------------------------------------------------*/
2065 /*-----------------------------------------------------------------*/
2066 static void pushSide(operand * oper, int size)
2070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2072 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2073 if (AOP_TYPE(oper) != AOP_REG &&
2074 AOP_TYPE(oper) != AOP_DIR &&
2076 pic14_emitcode("mov","a,%s",l);
2077 pic14_emitcode("push","acc");
2079 pic14_emitcode("push","%s",l);
2084 /*-----------------------------------------------------------------*/
2085 /* assignResultValue - */
2086 /*-----------------------------------------------------------------*/
2087 static void assignResultValue(operand * oper)
2089 int size = AOP_SIZE(oper);
2091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2093 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2095 if(!GpsuedoStkPtr) {
2096 /* The last byte in the assignment is in W */
2098 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2103 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2105 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2110 /*-----------------------------------------------------------------*/
2111 /* genIpush - genrate code for pushing this gets a little complex */
2112 /*-----------------------------------------------------------------*/
2113 static void genIpush (iCode *ic)
2116 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2118 int size, offset = 0 ;
2122 /* if this is not a parm push : ie. it is spill push
2123 and spill push is always done on the local stack */
2124 if (!ic->parmPush) {
2126 /* and the item is spilt then do nothing */
2127 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2130 aopOp(IC_LEFT(ic),ic,FALSE);
2131 size = AOP_SIZE(IC_LEFT(ic));
2132 /* push it on the stack */
2134 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2139 pic14_emitcode("push","%s",l);
2144 /* this is a paramter push: in this case we call
2145 the routine to find the call and save those
2146 registers that need to be saved */
2149 /* then do the push */
2150 aopOp(IC_LEFT(ic),ic,FALSE);
2153 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2154 size = AOP_SIZE(IC_LEFT(ic));
2157 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2158 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2159 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2161 pic14_emitcode("mov","a,%s",l);
2162 pic14_emitcode("push","acc");
2164 pic14_emitcode("push","%s",l);
2167 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2171 /*-----------------------------------------------------------------*/
2172 /* genIpop - recover the registers: can happen only for spilling */
2173 /*-----------------------------------------------------------------*/
2174 static void genIpop (iCode *ic)
2176 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2181 /* if the temp was not pushed then */
2182 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2185 aopOp(IC_LEFT(ic),ic,FALSE);
2186 size = AOP_SIZE(IC_LEFT(ic));
2189 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2192 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2196 /*-----------------------------------------------------------------*/
2197 /* unsaverbank - restores the resgister bank from stack */
2198 /*-----------------------------------------------------------------*/
2199 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2201 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2209 if (options.useXstack) {
2211 r = getFreePtr(ic,&aop,FALSE);
2214 pic14_emitcode("mov","%s,_spx",r->name);
2215 pic14_emitcode("movx","a,@%s",r->name);
2216 pic14_emitcode("mov","psw,a");
2217 pic14_emitcode("dec","%s",r->name);
2220 pic14_emitcode ("pop","psw");
2223 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2224 if (options.useXstack) {
2225 pic14_emitcode("movx","a,@%s",r->name);
2226 //pic14_emitcode("mov","(%s+%d),a",
2227 // regspic14[i].base,8*bank+regspic14[i].offset);
2228 pic14_emitcode("dec","%s",r->name);
2231 pic14_emitcode("pop",""); //"(%s+%d)",
2232 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2235 if (options.useXstack) {
2237 pic14_emitcode("mov","_spx,%s",r->name);
2238 freeAsmop(NULL,aop,ic,TRUE);
2244 /*-----------------------------------------------------------------*/
2245 /* saverbank - saves an entire register bank on the stack */
2246 /*-----------------------------------------------------------------*/
2247 static void saverbank (int bank, iCode *ic, bool pushPsw)
2249 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2255 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2256 if (options.useXstack) {
2259 r = getFreePtr(ic,&aop,FALSE);
2260 pic14_emitcode("mov","%s,_spx",r->name);
2264 for (i = 0 ; i < pic14_nRegs ;i++) {
2265 if (options.useXstack) {
2266 pic14_emitcode("inc","%s",r->name);
2267 //pic14_emitcode("mov","a,(%s+%d)",
2268 // regspic14[i].base,8*bank+regspic14[i].offset);
2269 pic14_emitcode("movx","@%s,a",r->name);
2271 pic14_emitcode("push","");// "(%s+%d)",
2272 //regspic14[i].base,8*bank+regspic14[i].offset);
2276 if (options.useXstack) {
2277 pic14_emitcode("mov","a,psw");
2278 pic14_emitcode("movx","@%s,a",r->name);
2279 pic14_emitcode("inc","%s",r->name);
2280 pic14_emitcode("mov","_spx,%s",r->name);
2281 freeAsmop (NULL,aop,ic,TRUE);
2284 pic14_emitcode("push","psw");
2286 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2292 /*-----------------------------------------------------------------*/
2293 /* genCall - generates a call statement */
2294 /*-----------------------------------------------------------------*/
2295 static void genCall (iCode *ic)
2299 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2301 /* if caller saves & we have not saved then */
2305 /* if we are calling a function that is not using
2306 the same register bank then we need to save the
2307 destination registers on the stack */
2308 dtype = operandType(IC_LEFT(ic));
2309 if (currFunc && dtype &&
2310 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2311 IFFUNC_ISISR(currFunc->type) &&
2314 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2316 /* if send set is not empty the assign */
2319 /* For the Pic port, there is no data stack.
2320 * So parameters passed to functions are stored
2321 * in registers. (The pCode optimizer will get
2322 * rid of most of these :).
2324 int psuedoStkPtr=-1;
2325 int firstTimeThruLoop = 1;
2327 _G.sendSet = reverseSet(_G.sendSet);
2329 /* First figure how many parameters are getting passed */
2330 for (sic = setFirstItem(_G.sendSet) ; sic ;
2331 sic = setNextItem(_G.sendSet)) {
2333 aopOp(IC_LEFT(sic),sic,FALSE);
2334 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2335 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2338 for (sic = setFirstItem(_G.sendSet) ; sic ;
2339 sic = setNextItem(_G.sendSet)) {
2340 int size, offset = 0;
2342 aopOp(IC_LEFT(sic),sic,FALSE);
2343 size = AOP_SIZE(IC_LEFT(sic));
2346 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2347 AopType(AOP_TYPE(IC_LEFT(sic))));
2349 if(!firstTimeThruLoop) {
2350 /* If this is not the first time we've been through the loop
2351 * then we need to save the parameter in a temporary
2352 * register. The last byte of the last parameter is
2354 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2357 firstTimeThruLoop=0;
2359 //if (strcmp(l,fReturn[offset])) {
2361 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2362 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2363 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2365 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2370 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2375 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2376 OP_SYMBOL(IC_LEFT(ic))->rname :
2377 OP_SYMBOL(IC_LEFT(ic))->name));
2380 /* if we need assign a result value */
2381 if ((IS_ITEMP(IC_RESULT(ic)) &&
2382 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2383 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2384 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2387 aopOp(IC_RESULT(ic),ic,FALSE);
2390 assignResultValue(IC_RESULT(ic));
2392 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2393 AopType(AOP_TYPE(IC_RESULT(ic))));
2395 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2398 /* adjust the stack for parameters if
2400 if (ic->parmBytes) {
2402 if (ic->parmBytes > 3) {
2403 pic14_emitcode("mov","a,%s",spname);
2404 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2405 pic14_emitcode("mov","%s,a",spname);
2407 for ( i = 0 ; i < ic->parmBytes ;i++)
2408 pic14_emitcode("dec","%s",spname);
2412 /* if register bank was saved then pop them */
2414 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2416 /* if we hade saved some registers then unsave them */
2417 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2418 unsaveRegisters (ic);
2423 /*-----------------------------------------------------------------*/
2424 /* genPcall - generates a call by pointer statement */
2425 /*-----------------------------------------------------------------*/
2426 static void genPcall (iCode *ic)
2429 symbol *rlbl = newiTempLabel(NULL);
2432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2433 /* if caller saves & we have not saved then */
2437 /* if we are calling a function that is not using
2438 the same register bank then we need to save the
2439 destination registers on the stack */
2440 dtype = operandType(IC_LEFT(ic));
2441 if (currFunc && dtype &&
2442 IFFUNC_ISISR(currFunc->type) &&
2443 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2444 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2447 /* push the return address on to the stack */
2448 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2449 pic14_emitcode("push","acc");
2450 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2451 pic14_emitcode("push","acc");
2453 if (options.model == MODEL_FLAT24)
2455 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2456 pic14_emitcode("push","acc");
2459 /* now push the calling address */
2460 aopOp(IC_LEFT(ic),ic,FALSE);
2462 pushSide(IC_LEFT(ic), FPTRSIZE);
2464 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2466 /* if send set is not empty the assign */
2470 for (sic = setFirstItem(_G.sendSet) ; sic ;
2471 sic = setNextItem(_G.sendSet)) {
2472 int size, offset = 0;
2473 aopOp(IC_LEFT(sic),sic,FALSE);
2474 size = AOP_SIZE(IC_LEFT(sic));
2476 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2478 if (strcmp(l,fReturn[offset]))
2479 pic14_emitcode("mov","%s,%s",
2484 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2489 pic14_emitcode("ret","");
2490 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2493 /* if we need assign a result value */
2494 if ((IS_ITEMP(IC_RESULT(ic)) &&
2495 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2496 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2497 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2500 aopOp(IC_RESULT(ic),ic,FALSE);
2503 assignResultValue(IC_RESULT(ic));
2505 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2508 /* adjust the stack for parameters if
2510 if (ic->parmBytes) {
2512 if (ic->parmBytes > 3) {
2513 pic14_emitcode("mov","a,%s",spname);
2514 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2515 pic14_emitcode("mov","%s,a",spname);
2517 for ( i = 0 ; i < ic->parmBytes ;i++)
2518 pic14_emitcode("dec","%s",spname);
2522 /* if register bank was saved then unsave them */
2523 if (currFunc && dtype &&
2524 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2525 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2527 /* if we hade saved some registers then
2530 unsaveRegisters (ic);
2534 /*-----------------------------------------------------------------*/
2535 /* resultRemat - result is rematerializable */
2536 /*-----------------------------------------------------------------*/
2537 static int resultRemat (iCode *ic)
2539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2540 if (SKIP_IC(ic) || ic->op == IFX)
2543 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2544 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2545 if (sym->remat && !POINTER_SET(ic))
2552 #if defined(__BORLANDC__) || defined(_MSC_VER)
2553 #define STRCASECMP stricmp
2555 #define STRCASECMP strcasecmp
2559 /*-----------------------------------------------------------------*/
2560 /* inExcludeList - return 1 if the string is in exclude Reg list */
2561 /*-----------------------------------------------------------------*/
2562 static bool inExcludeList(char *s)
2564 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2568 if (options.excludeRegs[i] &&
2569 STRCASECMP(options.excludeRegs[i],"none") == 0)
2572 for ( i = 0 ; options.excludeRegs[i]; i++) {
2573 if (options.excludeRegs[i] &&
2574 STRCASECMP(s,options.excludeRegs[i]) == 0)
2581 /*-----------------------------------------------------------------*/
2582 /* genFunction - generated code for function entry */
2583 /*-----------------------------------------------------------------*/
2584 static void genFunction (iCode *ic)
2589 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2591 labelOffset += (max_key+4);
2595 /* create the function header */
2596 pic14_emitcode(";","-----------------------------------------");
2597 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2598 pic14_emitcode(";","-----------------------------------------");
2600 pic14_emitcode("","%s:",sym->rname);
2601 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2603 ftype = operandType(IC_LEFT(ic));
2605 /* if critical function then turn interrupts off */
2606 if (IFFUNC_ISCRITICAL(ftype))
2607 pic14_emitcode("clr","ea");
2609 /* here we need to generate the equates for the
2610 register bank if required */
2612 if (FUNC_REGBANK(ftype) != rbank) {
2615 rbank = FUNC_REGBANK(ftype);
2616 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2617 if (strcmp(regspic14[i].base,"0") == 0)
2618 pic14_emitcode("","%s = 0x%02x",
2620 8*rbank+regspic14[i].offset);
2622 pic14_emitcode ("","%s = %s + 0x%02x",
2625 8*rbank+regspic14[i].offset);
2630 /* if this is an interrupt service routine then
2631 save acc, b, dpl, dph */
2632 if (IFFUNC_ISISR(sym->type)) {
2633 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2634 emitpcodeNULLop(POC_NOP);
2635 emitpcodeNULLop(POC_NOP);
2636 emitpcodeNULLop(POC_NOP);
2637 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2638 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2639 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2640 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2642 pBlockConvert2ISR(pb);
2644 if (!inExcludeList("acc"))
2645 pic14_emitcode ("push","acc");
2646 if (!inExcludeList("b"))
2647 pic14_emitcode ("push","b");
2648 if (!inExcludeList("dpl"))
2649 pic14_emitcode ("push","dpl");
2650 if (!inExcludeList("dph"))
2651 pic14_emitcode ("push","dph");
2652 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2654 pic14_emitcode ("push", "dpx");
2655 /* Make sure we're using standard DPTR */
2656 pic14_emitcode ("push", "dps");
2657 pic14_emitcode ("mov", "dps, #0x00");
2658 if (options.stack10bit)
2660 /* This ISR could conceivably use DPTR2. Better save it. */
2661 pic14_emitcode ("push", "dpl1");
2662 pic14_emitcode ("push", "dph1");
2663 pic14_emitcode ("push", "dpx1");
2666 /* if this isr has no bank i.e. is going to
2667 run with bank 0 , then we need to save more
2669 if (!FUNC_REGBANK(sym->type)) {
2671 /* if this function does not call any other
2672 function then we can be economical and
2673 save only those registers that are used */
2674 if (! IFFUNC_HASFCALL(sym->type)) {
2677 /* if any registers used */
2678 if (sym->regsUsed) {
2679 /* save the registers used */
2680 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2681 if (bitVectBitValue(sym->regsUsed,i) ||
2682 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2683 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2688 /* this function has a function call cannot
2689 determines register usage so we will have the
2691 saverbank(0,ic,FALSE);
2696 /* if callee-save to be used for this function
2697 then save the registers being used in this function */
2698 if (IFFUNC_CALLEESAVES(sym->type)) {
2701 /* if any registers used */
2702 if (sym->regsUsed) {
2703 /* save the registers used */
2704 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2705 if (bitVectBitValue(sym->regsUsed,i) ||
2706 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2707 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2715 /* set the register bank to the desired value */
2716 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2717 pic14_emitcode("push","psw");
2718 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2721 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2723 if (options.useXstack) {
2724 pic14_emitcode("mov","r0,%s",spname);
2725 pic14_emitcode("mov","a,_bp");
2726 pic14_emitcode("movx","@r0,a");
2727 pic14_emitcode("inc","%s",spname);
2731 /* set up the stack */
2732 pic14_emitcode ("push","_bp"); /* save the callers stack */
2734 pic14_emitcode ("mov","_bp,%s",spname);
2737 /* adjust the stack for the function */
2742 werror(W_STACK_OVERFLOW,sym->name);
2744 if (i > 3 && sym->recvSize < 4) {
2746 pic14_emitcode ("mov","a,sp");
2747 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2748 pic14_emitcode ("mov","sp,a");
2753 pic14_emitcode("inc","sp");
2758 pic14_emitcode ("mov","a,_spx");
2759 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2760 pic14_emitcode ("mov","_spx,a");
2765 /*-----------------------------------------------------------------*/
2766 /* genEndFunction - generates epilogue for functions */
2767 /*-----------------------------------------------------------------*/
2768 static void genEndFunction (iCode *ic)
2770 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2774 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2776 pic14_emitcode ("mov","%s,_bp",spname);
2779 /* if use external stack but some variables were
2780 added to the local stack then decrement the
2782 if (options.useXstack && sym->stack) {
2783 pic14_emitcode("mov","a,sp");
2784 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2785 pic14_emitcode("mov","sp,a");
2789 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2790 if (options.useXstack) {
2791 pic14_emitcode("mov","r0,%s",spname);
2792 pic14_emitcode("movx","a,@r0");
2793 pic14_emitcode("mov","_bp,a");
2794 pic14_emitcode("dec","%s",spname);
2798 pic14_emitcode ("pop","_bp");
2802 /* restore the register bank */
2803 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2804 pic14_emitcode ("pop","psw");
2806 if (IFFUNC_ISISR(sym->type)) {
2808 /* now we need to restore the registers */
2809 /* if this isr has no bank i.e. is going to
2810 run with bank 0 , then we need to save more
2812 if (!FUNC_REGBANK(sym->type)) {
2814 /* if this function does not call any other
2815 function then we can be economical and
2816 save only those registers that are used */
2817 if (! IFFUNC_HASFCALL(sym->type)) {
2820 /* if any registers used */
2821 if (sym->regsUsed) {
2822 /* save the registers used */
2823 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2824 if (bitVectBitValue(sym->regsUsed,i) ||
2825 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2826 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2831 /* this function has a function call cannot
2832 determines register usage so we will have the
2834 unsaverbank(0,ic,FALSE);
2838 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2840 if (options.stack10bit)
2842 pic14_emitcode ("pop", "dpx1");
2843 pic14_emitcode ("pop", "dph1");
2844 pic14_emitcode ("pop", "dpl1");
2846 pic14_emitcode ("pop", "dps");
2847 pic14_emitcode ("pop", "dpx");
2849 if (!inExcludeList("dph"))
2850 pic14_emitcode ("pop","dph");
2851 if (!inExcludeList("dpl"))
2852 pic14_emitcode ("pop","dpl");
2853 if (!inExcludeList("b"))
2854 pic14_emitcode ("pop","b");
2855 if (!inExcludeList("acc"))
2856 pic14_emitcode ("pop","acc");
2858 if (IFFUNC_ISCRITICAL(sym->type))
2859 pic14_emitcode("setb","ea");
2862 /* if debug then send end of function */
2863 /* if (options.debug && currFunc) { */
2866 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2867 FileBaseName(ic->filename),currFunc->lastLine,
2868 ic->level,ic->block);
2869 if (IS_STATIC(currFunc->etype))
2870 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2872 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2876 pic14_emitcode ("reti","");
2878 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2879 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2880 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2881 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2882 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2883 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2885 emitpcodeNULLop(POC_RETFIE);
2889 if (IFFUNC_ISCRITICAL(sym->type))
2890 pic14_emitcode("setb","ea");
2892 if (IFFUNC_CALLEESAVES(sym->type)) {
2895 /* if any registers used */
2896 if (sym->regsUsed) {
2897 /* save the registers used */
2898 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2899 if (bitVectBitValue(sym->regsUsed,i) ||
2900 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2901 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2907 /* if debug then send end of function */
2910 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2911 FileBaseName(ic->filename),currFunc->lastLine,
2912 ic->level,ic->block);
2913 if (IS_STATIC(currFunc->etype))
2914 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2916 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2920 pic14_emitcode ("return","");
2921 emitpcodeNULLop(POC_RETURN);
2923 /* Mark the end of a function */
2924 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2929 /*-----------------------------------------------------------------*/
2930 /* genRet - generate code for return statement */
2931 /*-----------------------------------------------------------------*/
2932 static void genRet (iCode *ic)
2934 int size,offset = 0 , pushed = 0;
2936 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2937 /* if we have no return value then
2938 just generate the "ret" */
2942 /* we have something to return then
2943 move the return value into place */
2944 aopOp(IC_LEFT(ic),ic,FALSE);
2945 size = AOP_SIZE(IC_LEFT(ic));
2949 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2951 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2953 pic14_emitcode("push","%s",l);
2956 l = aopGet(AOP(IC_LEFT(ic)),offset,
2958 if (strcmp(fReturn[offset],l)) {
2959 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2960 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2961 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2963 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2966 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2967 pic14_emitcode("movwf","%s",fReturn[offset]);
2977 if (strcmp(fReturn[pushed],"a"))
2978 pic14_emitcode("pop",fReturn[pushed]);
2980 pic14_emitcode("pop","acc");
2983 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2986 /* generate a jump to the return label
2987 if the next is not the return statement */
2988 if (!(ic->next && ic->next->op == LABEL &&
2989 IC_LABEL(ic->next) == returnLabel)) {
2991 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2992 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2997 /*-----------------------------------------------------------------*/
2998 /* genLabel - generates a label */
2999 /*-----------------------------------------------------------------*/
3000 static void genLabel (iCode *ic)
3002 /* special case never generate */
3003 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3004 if (IC_LABEL(ic) == entryLabel)
3007 emitpLabel(IC_LABEL(ic)->key);
3008 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3011 /*-----------------------------------------------------------------*/
3012 /* genGoto - generates a goto */
3013 /*-----------------------------------------------------------------*/
3015 static void genGoto (iCode *ic)
3017 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3018 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3022 /*-----------------------------------------------------------------*/
3023 /* genMultbits :- multiplication of bits */
3024 /*-----------------------------------------------------------------*/
3025 static void genMultbits (operand *left,
3029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3031 if(!pic14_sameRegs(AOP(result),AOP(right)))
3032 emitpcode(POC_BSF, popGet(AOP(result),0));
3034 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3035 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3036 emitpcode(POC_BCF, popGet(AOP(result),0));
3041 /*-----------------------------------------------------------------*/
3042 /* genMultOneByte : 8 bit multiplication & division */
3043 /*-----------------------------------------------------------------*/
3044 static void genMultOneByte (operand *left,
3048 sym_link *opetype = operandType(result);
3053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3054 DEBUGpic14_AopType(__LINE__,left,right,result);
3055 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3057 /* (if two literals, the value is computed before) */
3058 /* if one literal, literal on the right */
3059 if (AOP_TYPE(left) == AOP_LIT){
3065 size = AOP_SIZE(result);
3068 if (AOP_TYPE(right) == AOP_LIT){
3069 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3070 aopGet(AOP(right),0,FALSE,FALSE),
3071 aopGet(AOP(left),0,FALSE,FALSE),
3072 aopGet(AOP(result),0,FALSE,FALSE));
3073 pic14_emitcode("call","genMultLit");
3075 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3076 aopGet(AOP(right),0,FALSE,FALSE),
3077 aopGet(AOP(left),0,FALSE,FALSE),
3078 aopGet(AOP(result),0,FALSE,FALSE));
3079 pic14_emitcode("call","genMult8X8_8");
3082 genMult8X8_8 (left, right,result);
3085 /* signed or unsigned */
3086 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3087 //l = aopGet(AOP(left),0,FALSE,FALSE);
3089 //pic14_emitcode("mul","ab");
3090 /* if result size = 1, mul signed = mul unsigned */
3091 //aopPut(AOP(result),"a",0);
3093 } else { // (size > 1)
3095 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3096 aopGet(AOP(right),0,FALSE,FALSE),
3097 aopGet(AOP(left),0,FALSE,FALSE),
3098 aopGet(AOP(result),0,FALSE,FALSE));
3100 if (SPEC_USIGN(opetype)){
3101 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3102 genUMult8X8_16 (left, right, result, NULL);
3105 /* for filling the MSBs */
3106 emitpcode(POC_CLRF, popGet(AOP(result),2));
3107 emitpcode(POC_CLRF, popGet(AOP(result),3));
3111 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3113 pic14_emitcode("mov","a,b");
3115 /* adjust the MSB if left or right neg */
3117 /* if one literal */
3118 if (AOP_TYPE(right) == AOP_LIT){
3119 pic14_emitcode("multiply ","right is a lit");
3120 /* AND literal negative */
3121 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3122 /* adjust MSB (c==0 after mul) */
3123 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3127 genSMult8X8_16 (left, right, result, NULL);
3131 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3133 pic14_emitcode("rlc","a");
3134 pic14_emitcode("subb","a,acc");
3142 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3143 //aopPut(AOP(result),"a",offset++);
3147 /*-----------------------------------------------------------------*/
3148 /* genMult - generates code for multiplication */
3149 /*-----------------------------------------------------------------*/
3150 static void genMult (iCode *ic)
3152 operand *left = IC_LEFT(ic);
3153 operand *right = IC_RIGHT(ic);
3154 operand *result= IC_RESULT(ic);
3156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3157 /* assign the amsops */
3158 aopOp (left,ic,FALSE);
3159 aopOp (right,ic,FALSE);
3160 aopOp (result,ic,TRUE);
3162 DEBUGpic14_AopType(__LINE__,left,right,result);
3164 /* special cases first */
3166 if (AOP_TYPE(left) == AOP_CRY &&
3167 AOP_TYPE(right)== AOP_CRY) {
3168 genMultbits(left,right,result);
3172 /* if both are of size == 1 */
3173 if (AOP_SIZE(left) == 1 &&
3174 AOP_SIZE(right) == 1 ) {
3175 genMultOneByte(left,right,result);
3179 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3181 /* should have been converted to function call */
3185 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3186 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3187 freeAsmop(result,NULL,ic,TRUE);
3190 /*-----------------------------------------------------------------*/
3191 /* genDivbits :- division of bits */
3192 /*-----------------------------------------------------------------*/
3193 static void genDivbits (operand *left,
3200 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3201 /* the result must be bit */
3202 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3203 l = aopGet(AOP(left),0,FALSE,FALSE);
3207 pic14_emitcode("div","ab");
3208 pic14_emitcode("rrc","a");
3209 aopPut(AOP(result),"c",0);
3212 /*-----------------------------------------------------------------*/
3213 /* genDivOneByte : 8 bit division */
3214 /*-----------------------------------------------------------------*/
3215 static void genDivOneByte (operand *left,
3219 sym_link *opetype = operandType(result);
3224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3225 size = AOP_SIZE(result) - 1;
3227 /* signed or unsigned */
3228 if (SPEC_USIGN(opetype)) {
3229 /* unsigned is easy */
3230 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3231 l = aopGet(AOP(left),0,FALSE,FALSE);
3233 pic14_emitcode("div","ab");
3234 aopPut(AOP(result),"a",0);
3236 aopPut(AOP(result),zero,offset++);
3240 /* signed is a little bit more difficult */
3242 /* save the signs of the operands */
3243 l = aopGet(AOP(left),0,FALSE,FALSE);
3245 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3246 pic14_emitcode("push","acc"); /* save it on the stack */
3248 /* now sign adjust for both left & right */
3249 l = aopGet(AOP(right),0,FALSE,FALSE);
3251 lbl = newiTempLabel(NULL);
3252 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3253 pic14_emitcode("cpl","a");
3254 pic14_emitcode("inc","a");
3255 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3256 pic14_emitcode("mov","b,a");
3258 /* sign adjust left side */
3259 l = aopGet(AOP(left),0,FALSE,FALSE);
3262 lbl = newiTempLabel(NULL);
3263 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3264 pic14_emitcode("cpl","a");
3265 pic14_emitcode("inc","a");
3266 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3268 /* now the division */
3269 pic14_emitcode("div","ab");
3270 /* we are interested in the lower order
3272 pic14_emitcode("mov","b,a");
3273 lbl = newiTempLabel(NULL);
3274 pic14_emitcode("pop","acc");
3275 /* if there was an over flow we don't
3276 adjust the sign of the result */
3277 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3278 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3280 pic14_emitcode("clr","a");
3281 pic14_emitcode("subb","a,b");
3282 pic14_emitcode("mov","b,a");
3283 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3285 /* now we are done */
3286 aopPut(AOP(result),"b",0);
3288 pic14_emitcode("mov","c,b.7");
3289 pic14_emitcode("subb","a,acc");
3292 aopPut(AOP(result),"a",offset++);
3296 /*-----------------------------------------------------------------*/
3297 /* genDiv - generates code for division */
3298 /*-----------------------------------------------------------------*/
3299 static void genDiv (iCode *ic)
3301 operand *left = IC_LEFT(ic);
3302 operand *right = IC_RIGHT(ic);
3303 operand *result= IC_RESULT(ic);
3305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3306 /* assign the amsops */
3307 aopOp (left,ic,FALSE);
3308 aopOp (right,ic,FALSE);
3309 aopOp (result,ic,TRUE);
3311 /* special cases first */
3313 if (AOP_TYPE(left) == AOP_CRY &&
3314 AOP_TYPE(right)== AOP_CRY) {
3315 genDivbits(left,right,result);
3319 /* if both are of size == 1 */
3320 if (AOP_SIZE(left) == 1 &&
3321 AOP_SIZE(right) == 1 ) {
3322 genDivOneByte(left,right,result);
3326 /* should have been converted to function call */
3329 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3330 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3331 freeAsmop(result,NULL,ic,TRUE);
3334 /*-----------------------------------------------------------------*/
3335 /* genModbits :- modulus of bits */
3336 /*-----------------------------------------------------------------*/
3337 static void genModbits (operand *left,
3344 /* the result must be bit */
3345 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3346 l = aopGet(AOP(left),0,FALSE,FALSE);
3350 pic14_emitcode("div","ab");
3351 pic14_emitcode("mov","a,b");
3352 pic14_emitcode("rrc","a");
3353 aopPut(AOP(result),"c",0);
3356 /*-----------------------------------------------------------------*/
3357 /* genModOneByte : 8 bit modulus */
3358 /*-----------------------------------------------------------------*/
3359 static void genModOneByte (operand *left,
3363 sym_link *opetype = operandType(result);
3367 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3368 /* signed or unsigned */
3369 if (SPEC_USIGN(opetype)) {
3370 /* unsigned is easy */
3371 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3372 l = aopGet(AOP(left),0,FALSE,FALSE);
3374 pic14_emitcode("div","ab");
3375 aopPut(AOP(result),"b",0);
3379 /* signed is a little bit more difficult */
3381 /* save the signs of the operands */
3382 l = aopGet(AOP(left),0,FALSE,FALSE);
3385 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3386 pic14_emitcode("push","acc"); /* save it on the stack */
3388 /* now sign adjust for both left & right */
3389 l = aopGet(AOP(right),0,FALSE,FALSE);
3392 lbl = newiTempLabel(NULL);
3393 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3394 pic14_emitcode("cpl","a");
3395 pic14_emitcode("inc","a");
3396 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3397 pic14_emitcode("mov","b,a");
3399 /* sign adjust left side */
3400 l = aopGet(AOP(left),0,FALSE,FALSE);
3403 lbl = newiTempLabel(NULL);
3404 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3405 pic14_emitcode("cpl","a");
3406 pic14_emitcode("inc","a");
3407 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3409 /* now the multiplication */
3410 pic14_emitcode("div","ab");
3411 /* we are interested in the lower order
3413 lbl = newiTempLabel(NULL);
3414 pic14_emitcode("pop","acc");
3415 /* if there was an over flow we don't
3416 adjust the sign of the result */
3417 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3418 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3420 pic14_emitcode("clr","a");
3421 pic14_emitcode("subb","a,b");
3422 pic14_emitcode("mov","b,a");
3423 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3425 /* now we are done */
3426 aopPut(AOP(result),"b",0);
3430 /*-----------------------------------------------------------------*/
3431 /* genMod - generates code for division */
3432 /*-----------------------------------------------------------------*/
3433 static void genMod (iCode *ic)
3435 operand *left = IC_LEFT(ic);
3436 operand *right = IC_RIGHT(ic);
3437 operand *result= IC_RESULT(ic);
3439 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3440 /* assign the amsops */
3441 aopOp (left,ic,FALSE);
3442 aopOp (right,ic,FALSE);
3443 aopOp (result,ic,TRUE);
3445 /* special cases first */
3447 if (AOP_TYPE(left) == AOP_CRY &&
3448 AOP_TYPE(right)== AOP_CRY) {
3449 genModbits(left,right,result);
3453 /* if both are of size == 1 */
3454 if (AOP_SIZE(left) == 1 &&
3455 AOP_SIZE(right) == 1 ) {
3456 genModOneByte(left,right,result);
3460 /* should have been converted to function call */
3464 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3465 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3466 freeAsmop(result,NULL,ic,TRUE);
3469 /*-----------------------------------------------------------------*/
3470 /* genIfxJump :- will create a jump depending on the ifx */
3471 /*-----------------------------------------------------------------*/
3473 note: May need to add parameter to indicate when a variable is in bit space.
3475 static void genIfxJump (iCode *ic, char *jval)
3478 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3479 /* if true label then we jump if condition
3481 if ( IC_TRUE(ic) ) {
3483 if(strcmp(jval,"a") == 0)
3485 else if (strcmp(jval,"c") == 0)
3488 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3489 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3492 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3493 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3497 /* false label is present */
3498 if(strcmp(jval,"a") == 0)
3500 else if (strcmp(jval,"c") == 0)
3503 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3504 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3507 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3508 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3513 /* mark the icode as generated */
3517 /*-----------------------------------------------------------------*/
3519 /*-----------------------------------------------------------------*/
3520 static void genSkip(iCode *ifx,int status_bit)
3525 if ( IC_TRUE(ifx) ) {
3526 switch(status_bit) {
3541 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3542 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3546 switch(status_bit) {
3560 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3561 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3567 /*-----------------------------------------------------------------*/
3569 /*-----------------------------------------------------------------*/
3570 static void genSkipc(resolvedIfx *rifx)
3580 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3581 rifx->generated = 1;
3584 /*-----------------------------------------------------------------*/
3586 /*-----------------------------------------------------------------*/
3587 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3592 if( (rifx->condition ^ invert_condition) & 1)
3597 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3598 rifx->generated = 1;
3601 /*-----------------------------------------------------------------*/
3603 /*-----------------------------------------------------------------*/
3604 static void genSkipz(iCode *ifx, int condition)
3615 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3617 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3620 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3622 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3625 /*-----------------------------------------------------------------*/
3627 /*-----------------------------------------------------------------*/
3628 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3634 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3636 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3639 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3640 rifx->generated = 1;
3644 /*-----------------------------------------------------------------*/
3645 /* genChkZeroes :- greater or less than comparison */
3646 /* For each byte in a literal that is zero, inclusive or the */
3647 /* the corresponding byte in the operand with W */
3648 /* returns true if any of the bytes are zero */
3649 /*-----------------------------------------------------------------*/
3650 static int genChkZeroes(operand *op, int lit, int size)
3657 i = (lit >> (size*8)) & 0xff;
3661 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3663 emitpcode(POC_IORFW, popGet(AOP(op),size));
3672 /*-----------------------------------------------------------------*/
3673 /* genCmp :- greater or less than comparison */
3674 /*-----------------------------------------------------------------*/
3675 static void genCmp (operand *left,operand *right,
3676 operand *result, iCode *ifx, int sign)
3678 int size; //, offset = 0 ;
3679 unsigned long lit = 0L,i = 0;
3680 resolvedIfx rFalseIfx;
3681 // resolvedIfx rTrueIfx;
3683 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3685 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3686 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3690 resolveIfx(&rFalseIfx,ifx);
3691 truelbl = newiTempLabel(NULL);
3692 size = max(AOP_SIZE(left),AOP_SIZE(right));
3696 /* if literal is on the right then swap with left */
3697 if ((AOP_TYPE(right) == AOP_LIT)) {
3698 operand *tmp = right ;
3699 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3700 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3702 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
3703 lit = (lit - 1) & mask;
3704 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
3708 rFalseIfx.condition ^= 1;
3711 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3712 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3716 //if(IC_TRUE(ifx) == NULL)
3717 /* if left & right are bit variables */
3718 if (AOP_TYPE(left) == AOP_CRY &&
3719 AOP_TYPE(right) == AOP_CRY ) {
3720 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3721 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3723 /* subtract right from left if at the
3724 end the carry flag is set then we know that
3725 left is greater than right */
3729 symbol *lbl = newiTempLabel(NULL);
3732 if(AOP_TYPE(right) == AOP_LIT) {
3734 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3736 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3743 genSkipCond(&rFalseIfx,left,size-1,7);
3745 /* no need to compare to 0...*/
3746 /* NOTE: this is a de-generate compare that most certainly
3747 * creates some dead code. */
3748 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3750 if(ifx) ifx->generated = 1;
3757 //i = (lit >> (size*8)) & 0xff;
3758 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3760 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3762 i = ((0-lit) & 0xff);
3765 /* lit is 0x7f, all signed chars are less than
3766 * this except for 0x7f itself */
3767 emitpcode(POC_XORLW, popGetLit(0x7f));
3768 genSkipz2(&rFalseIfx,0);
3770 emitpcode(POC_ADDLW, popGetLit(0x80));
3771 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3772 genSkipc(&rFalseIfx);
3777 genSkipz2(&rFalseIfx,1);
3779 emitpcode(POC_ADDLW, popGetLit(i));
3780 genSkipc(&rFalseIfx);
3784 if(ifx) ifx->generated = 1;
3788 /* chars are out of the way. now do ints and longs */
3791 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3798 genSkipCond(&rFalseIfx,left,size,7);
3799 if(ifx) ifx->generated = 1;
3804 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3806 //rFalseIfx.condition ^= 1;
3807 //genSkipCond(&rFalseIfx,left,size,7);
3808 //rFalseIfx.condition ^= 1;
3810 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3811 if(rFalseIfx.condition)
3812 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3814 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3816 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3817 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3818 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3821 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3823 if(rFalseIfx.condition) {
3825 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3831 genSkipc(&rFalseIfx);
3832 emitpLabel(truelbl->key);
3833 if(ifx) ifx->generated = 1;
3840 if( (lit & 0xff) == 0) {
3841 /* lower byte is zero */
3842 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3843 i = ((lit >> 8) & 0xff) ^0x80;
3844 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3845 emitpcode(POC_ADDLW, popGetLit( 0x80));
3846 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3847 genSkipc(&rFalseIfx);
3850 if(ifx) ifx->generated = 1;
3855 /* Special cases for signed longs */
3856 if( (lit & 0xffffff) == 0) {
3857 /* lower byte is zero */
3858 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3859 i = ((lit >> 8*3) & 0xff) ^0x80;
3860 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3861 emitpcode(POC_ADDLW, popGetLit( 0x80));
3862 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3863 genSkipc(&rFalseIfx);
3866 if(ifx) ifx->generated = 1;
3874 if(lit & (0x80 << (size*8))) {
3875 /* lit is negative */
3876 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3878 //genSkipCond(&rFalseIfx,left,size,7);
3880 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3882 if(rFalseIfx.condition)
3883 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3885 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3889 /* lit is positive */
3890 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3891 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3892 if(rFalseIfx.condition)
3893 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3895 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3900 This works, but is only good for ints.
3901 It also requires a "known zero" register.
3902 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3903 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3904 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3905 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3906 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3907 genSkipc(&rFalseIfx);
3909 emitpLabel(truelbl->key);
3910 if(ifx) ifx->generated = 1;
3914 /* There are no more special cases, so perform a general compare */
3916 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3917 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3921 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3923 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3925 //rFalseIfx.condition ^= 1;
3926 genSkipc(&rFalseIfx);
3928 emitpLabel(truelbl->key);
3930 if(ifx) ifx->generated = 1;
3937 /* sign is out of the way. So now do an unsigned compare */
3938 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3941 /* General case - compare to an unsigned literal on the right.*/
3943 i = (lit >> (size*8)) & 0xff;
3944 emitpcode(POC_MOVLW, popGetLit(i));
3945 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3947 i = (lit >> (size*8)) & 0xff;
3950 emitpcode(POC_MOVLW, popGetLit(i));
3952 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3954 /* this byte of the lit is zero,
3955 *if it's not the last then OR in the variable */
3957 emitpcode(POC_IORFW, popGet(AOP(left),size));
3962 emitpLabel(lbl->key);
3963 //if(emitFinalCheck)
3964 genSkipc(&rFalseIfx);
3966 emitpLabel(truelbl->key);
3968 if(ifx) ifx->generated = 1;
3974 if(AOP_TYPE(left) == AOP_LIT) {
3975 //symbol *lbl = newiTempLabel(NULL);
3977 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3980 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3983 if((lit == 0) && (sign == 0)){
3986 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3988 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3990 genSkipz2(&rFalseIfx,0);
3991 if(ifx) ifx->generated = 1;
3998 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3999 /* degenerate compare can never be true */
4000 if(rFalseIfx.condition == 0)
4001 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4003 if(ifx) ifx->generated = 1;
4008 /* signed comparisons to a literal byte */
4010 int lp1 = (lit+1) & 0xff;
4012 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4015 rFalseIfx.condition ^= 1;
4016 genSkipCond(&rFalseIfx,right,0,7);
4019 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4020 emitpcode(POC_XORLW, popGetLit(0x7f));
4021 genSkipz2(&rFalseIfx,1);
4024 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4025 emitpcode(POC_ADDLW, popGetLit(0x80));
4026 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4027 rFalseIfx.condition ^= 1;
4028 genSkipc(&rFalseIfx);
4032 /* unsigned comparisons to a literal byte */
4034 switch(lit & 0xff ) {
4036 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4037 genSkipz2(&rFalseIfx,0);
4040 rFalseIfx.condition ^= 1;
4041 genSkipCond(&rFalseIfx,right,0,7);
4045 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4046 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4048 rFalseIfx.condition ^= 1;
4049 genSkipc(&rFalseIfx);
4054 if(ifx) ifx->generated = 1;
4059 /* Size is greater than 1 */
4067 /* this means lit = 0xffffffff, or -1 */
4070 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4071 rFalseIfx.condition ^= 1;
4072 genSkipCond(&rFalseIfx,right,size,7);
4073 if(ifx) ifx->generated = 1;
4080 if(rFalseIfx.condition) {
4081 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4082 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4085 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4087 emitpcode(POC_IORFW, popGet(AOP(right),size));
4091 if(rFalseIfx.condition) {
4092 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4093 emitpLabel(truelbl->key);
4095 rFalseIfx.condition ^= 1;
4096 genSkipCond(&rFalseIfx,right,s,7);
4099 if(ifx) ifx->generated = 1;
4103 if((size == 1) && (0 == (lp1&0xff))) {
4104 /* lower byte of signed word is zero */
4105 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4106 i = ((lp1 >> 8) & 0xff) ^0x80;
4107 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4108 emitpcode(POC_ADDLW, popGetLit( 0x80));
4109 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4110 rFalseIfx.condition ^= 1;
4111 genSkipc(&rFalseIfx);
4114 if(ifx) ifx->generated = 1;
4118 if(lit & (0x80 << (size*8))) {
4119 /* Lit is less than zero */
4120 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4121 //rFalseIfx.condition ^= 1;
4122 //genSkipCond(&rFalseIfx,left,size,7);
4123 //rFalseIfx.condition ^= 1;
4124 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4125 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4127 if(rFalseIfx.condition)
4128 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4130 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4134 /* Lit is greater than or equal to zero */
4135 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4136 //rFalseIfx.condition ^= 1;
4137 //genSkipCond(&rFalseIfx,right,size,7);
4138 //rFalseIfx.condition ^= 1;
4140 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4141 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4143 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4144 if(rFalseIfx.condition)
4145 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4147 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4152 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4153 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4157 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4159 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4161 rFalseIfx.condition ^= 1;
4162 //rFalseIfx.condition = 1;
4163 genSkipc(&rFalseIfx);
4165 emitpLabel(truelbl->key);
4167 if(ifx) ifx->generated = 1;
4172 /* compare word or long to an unsigned literal on the right.*/
4177 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4180 break; /* handled above */
4183 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4185 emitpcode(POC_IORFW, popGet(AOP(right),size));
4186 genSkipz2(&rFalseIfx,0);
4190 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4192 emitpcode(POC_IORFW, popGet(AOP(right),size));
4195 if(rFalseIfx.condition)
4196 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4198 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4201 emitpcode(POC_MOVLW, popGetLit(lit+1));
4202 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4204 rFalseIfx.condition ^= 1;
4205 genSkipc(&rFalseIfx);
4208 emitpLabel(truelbl->key);
4210 if(ifx) ifx->generated = 1;
4216 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4217 i = (lit >> (size*8)) & 0xff;
4219 emitpcode(POC_MOVLW, popGetLit(i));
4220 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4223 i = (lit >> (size*8)) & 0xff;
4226 emitpcode(POC_MOVLW, popGetLit(i));
4228 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230 /* this byte of the lit is zero,
4231 *if it's not the last then OR in the variable */
4233 emitpcode(POC_IORFW, popGet(AOP(right),size));
4238 emitpLabel(lbl->key);
4240 rFalseIfx.condition ^= 1;
4241 genSkipc(&rFalseIfx);
4245 emitpLabel(truelbl->key);
4246 if(ifx) ifx->generated = 1;
4250 /* Compare two variables */
4252 DEBUGpic14_emitcode(";sign","%d",sign);
4256 /* Sigh. thus sucks... */
4258 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4259 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4260 emitpcode(POC_MOVLW, popGetLit(0x80));
4261 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4262 emitpcode(POC_XORFW, popGet(AOP(right),size));
4263 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4265 /* Signed char comparison */
4266 /* Special thanks to Nikolai Golovchenko for this snippet */
4267 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4268 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4269 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4270 emitpcode(POC_XORFW, popGet(AOP(left),0));
4271 emitpcode(POC_XORFW, popGet(AOP(right),0));
4272 emitpcode(POC_ADDLW, popGetLit(0x80));
4274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4275 genSkipc(&rFalseIfx);
4277 if(ifx) ifx->generated = 1;
4283 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4284 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4288 /* The rest of the bytes of a multi-byte compare */
4292 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4295 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4296 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4301 emitpLabel(lbl->key);
4303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4304 genSkipc(&rFalseIfx);
4305 if(ifx) ifx->generated = 1;
4310 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4311 pic14_outBitC(result);
4313 /* if the result is used in the next
4314 ifx conditional branch then generate
4315 code a little differently */
4317 genIfxJump (ifx,"c");
4319 pic14_outBitC(result);
4320 /* leave the result in acc */
4325 /*-----------------------------------------------------------------*/
4326 /* genCmpGt :- greater than comparison */
4327 /*-----------------------------------------------------------------*/
4328 static void genCmpGt (iCode *ic, iCode *ifx)
4330 operand *left, *right, *result;
4331 sym_link *letype , *retype;
4334 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4336 right= IC_RIGHT(ic);
4337 result = IC_RESULT(ic);
4339 letype = getSpec(operandType(left));
4340 retype =getSpec(operandType(right));
4341 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4342 /* assign the amsops */
4343 aopOp (left,ic,FALSE);
4344 aopOp (right,ic,FALSE);
4345 aopOp (result,ic,TRUE);
4347 genCmp(right, left, result, ifx, sign);
4349 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4350 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4351 freeAsmop(result,NULL,ic,TRUE);
4354 /*-----------------------------------------------------------------*/
4355 /* genCmpLt - less than comparisons */
4356 /*-----------------------------------------------------------------*/
4357 static void genCmpLt (iCode *ic, iCode *ifx)
4359 operand *left, *right, *result;
4360 sym_link *letype , *retype;
4363 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4365 right= IC_RIGHT(ic);
4366 result = IC_RESULT(ic);
4368 letype = getSpec(operandType(left));
4369 retype =getSpec(operandType(right));
4370 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4372 /* assign the amsops */
4373 aopOp (left,ic,FALSE);
4374 aopOp (right,ic,FALSE);
4375 aopOp (result,ic,TRUE);
4377 genCmp(left, right, result, ifx, sign);
4379 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4381 freeAsmop(result,NULL,ic,TRUE);
4384 /*-----------------------------------------------------------------*/
4385 /* genc16bit2lit - compare a 16 bit value to a literal */
4386 /*-----------------------------------------------------------------*/
4387 static void genc16bit2lit(operand *op, int lit, int offset)
4391 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4392 if( (lit&0xff) == 0)
4397 switch( BYTEofLONG(lit,i)) {
4399 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4402 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4405 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4408 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4409 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4414 switch( BYTEofLONG(lit,i)) {
4416 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4420 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4424 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4427 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4429 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4435 /*-----------------------------------------------------------------*/
4436 /* gencjneshort - compare and jump if not equal */
4437 /*-----------------------------------------------------------------*/
4438 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4440 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4445 unsigned long lit = 0L;
4446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4447 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4449 resolveIfx(&rIfx,ifx);
4450 lbl = newiTempLabel(NULL);
4453 /* if the left side is a literal or
4454 if the right is in a pointer register and left
4456 if ((AOP_TYPE(left) == AOP_LIT) ||
4457 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4462 if(AOP_TYPE(right) == AOP_LIT)
4463 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4465 /* if the right side is a literal then anything goes */
4466 if (AOP_TYPE(right) == AOP_LIT &&
4467 AOP_TYPE(left) != AOP_DIR ) {
4470 genc16bit2lit(left, lit, 0);
4472 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4477 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4478 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4480 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4484 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4492 /* if the right side is in a register or in direct space or
4493 if the left is a pointer register & right is not */
4494 else if (AOP_TYPE(right) == AOP_REG ||
4495 AOP_TYPE(right) == AOP_DIR ||
4496 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4497 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4500 genc16bit2lit(left, lit, 0);
4502 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4507 if((AOP_TYPE(left) == AOP_DIR) &&
4508 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4510 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4511 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4513 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4515 switch (lit & 0xff) {
4517 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4520 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4521 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4525 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4526 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4530 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4531 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4536 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4539 if(AOP_TYPE(result) == AOP_CRY) {
4540 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4545 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4547 /* fix me. probably need to check result size too */
4548 emitpcode(POC_CLRF,popGet(AOP(result),0));
4553 emitpcode(POC_INCF,popGet(AOP(result),0));
4563 } else if(AOP_TYPE(right) == AOP_REG &&
4564 AOP_TYPE(left) != AOP_DIR){
4567 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4568 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4569 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4574 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4579 /* right is a pointer reg need both a & b */
4581 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4583 pic14_emitcode("mov","b,%s",l);
4584 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4585 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4589 emitpLabel(lbl->key);
4596 /*-----------------------------------------------------------------*/
4597 /* gencjne - compare and jump if not equal */
4598 /*-----------------------------------------------------------------*/
4599 static void gencjne(operand *left, operand *right, iCode *ifx)
4601 symbol *tlbl = newiTempLabel(NULL);
4603 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4604 gencjneshort(left, right, lbl);
4606 pic14_emitcode("mov","a,%s",one);
4607 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4608 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4609 pic14_emitcode("clr","a");
4610 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4612 emitpLabel(lbl->key);
4613 emitpLabel(tlbl->key);
4618 /*-----------------------------------------------------------------*/
4619 /* genCmpEq - generates code for equal to */
4620 /*-----------------------------------------------------------------*/
4621 static void genCmpEq (iCode *ic, iCode *ifx)
4623 operand *left, *right, *result;
4624 unsigned long lit = 0L;
4627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4630 DEBUGpic14_emitcode ("; ifx is non-null","");
4632 DEBUGpic14_emitcode ("; ifx is null","");
4634 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4635 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4636 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4638 size = max(AOP_SIZE(left),AOP_SIZE(right));
4640 DEBUGpic14_AopType(__LINE__,left,right,result);
4642 /* if literal, literal on the right or
4643 if the right is in a pointer register and left
4645 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4646 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4647 operand *tmp = right ;
4653 if(ifx && !AOP_SIZE(result)){
4655 /* if they are both bit variables */
4656 if (AOP_TYPE(left) == AOP_CRY &&
4657 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4658 if(AOP_TYPE(right) == AOP_LIT){
4659 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4661 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4662 pic14_emitcode("cpl","c");
4663 } else if(lit == 1L) {
4664 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4666 pic14_emitcode("clr","c");
4668 /* AOP_TYPE(right) == AOP_CRY */
4670 symbol *lbl = newiTempLabel(NULL);
4671 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4672 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4673 pic14_emitcode("cpl","c");
4674 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4676 /* if true label then we jump if condition
4678 tlbl = newiTempLabel(NULL);
4679 if ( IC_TRUE(ifx) ) {
4680 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4681 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4683 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4684 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4686 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4689 /* left and right are both bit variables, result is carry */
4692 resolveIfx(&rIfx,ifx);
4694 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4695 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4696 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4697 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4702 /* They're not both bit variables. Is the right a literal? */
4703 if(AOP_TYPE(right) == AOP_LIT) {
4704 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4709 switch(lit & 0xff) {
4711 if ( IC_TRUE(ifx) ) {
4712 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4714 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4716 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4717 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4721 if ( IC_TRUE(ifx) ) {
4722 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4724 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4726 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4727 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4731 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4733 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4738 /* end of size == 1 */
4742 genc16bit2lit(left,lit,offset);
4745 /* end of size == 2 */
4750 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4751 emitpcode(POC_IORFW,popGet(AOP(left),1));
4752 emitpcode(POC_IORFW,popGet(AOP(left),2));
4753 emitpcode(POC_IORFW,popGet(AOP(left),3));
4757 /* search for patterns that can be optimized */
4759 genc16bit2lit(left,lit,0);
4762 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4764 genc16bit2lit(left,lit,2);
4766 emitpcode(POC_IORFW,popGet(AOP(left),2));
4767 emitpcode(POC_IORFW,popGet(AOP(left),3));
4780 } else if(AOP_TYPE(right) == AOP_CRY ) {
4781 /* we know the left is not a bit, but that the right is */
4782 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4783 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4784 popGet(AOP(right),offset));
4785 emitpcode(POC_XORLW,popGetLit(1));
4787 /* if the two are equal, then W will be 0 and the Z bit is set
4788 * we could test Z now, or go ahead and check the high order bytes if
4789 * the variable we're comparing is larger than a byte. */
4792 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4794 if ( IC_TRUE(ifx) ) {
4796 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4797 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4800 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4801 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4805 /* They're both variables that are larger than bits */
4808 tlbl = newiTempLabel(NULL);
4811 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4812 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4814 if ( IC_TRUE(ifx) ) {
4817 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4818 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4821 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4822 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4826 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4827 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4831 if(s>1 && IC_TRUE(ifx)) {
4832 emitpLabel(tlbl->key);
4833 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4837 /* mark the icode as generated */
4842 /* if they are both bit variables */
4843 if (AOP_TYPE(left) == AOP_CRY &&
4844 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4845 if(AOP_TYPE(right) == AOP_LIT){
4846 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4848 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4849 pic14_emitcode("cpl","c");
4850 } else if(lit == 1L) {
4851 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4853 pic14_emitcode("clr","c");
4855 /* AOP_TYPE(right) == AOP_CRY */
4857 symbol *lbl = newiTempLabel(NULL);
4858 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4859 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4860 pic14_emitcode("cpl","c");
4861 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4864 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4865 pic14_outBitC(result);
4869 genIfxJump (ifx,"c");
4872 /* if the result is used in an arithmetic operation
4873 then put the result in place */
4874 pic14_outBitC(result);
4877 gencjne(left,right,result,ifx);
4880 gencjne(left,right,newiTempLabel(NULL));
4882 if(IC_TRUE(ifx)->key)
4883 gencjne(left,right,IC_TRUE(ifx)->key);
4885 gencjne(left,right,IC_FALSE(ifx)->key);
4889 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4890 aopPut(AOP(result),"a",0);
4895 genIfxJump (ifx,"a");
4899 /* if the result is used in an arithmetic operation
4900 then put the result in place */
4902 if (AOP_TYPE(result) != AOP_CRY)
4903 pic14_outAcc(result);
4905 /* leave the result in acc */
4909 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4910 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4911 freeAsmop(result,NULL,ic,TRUE);
4914 /*-----------------------------------------------------------------*/
4915 /* ifxForOp - returns the icode containing the ifx for operand */
4916 /*-----------------------------------------------------------------*/
4917 static iCode *ifxForOp ( operand *op, iCode *ic )
4919 /* if true symbol then needs to be assigned */
4920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4921 if (IS_TRUE_SYMOP(op))
4924 /* if this has register type condition and
4925 the next instruction is ifx with the same operand
4926 and live to of the operand is upto the ifx only then */
4928 ic->next->op == IFX &&
4929 IC_COND(ic->next)->key == op->key &&
4930 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4934 ic->next->op == IFX &&
4935 IC_COND(ic->next)->key == op->key) {
4936 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4940 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4942 ic->next->op == IFX)
4943 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4946 ic->next->op == IFX &&
4947 IC_COND(ic->next)->key == op->key) {
4948 DEBUGpic14_emitcode ("; "," key is okay");
4949 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4950 OP_SYMBOL(op)->liveTo,
4957 /*-----------------------------------------------------------------*/
4958 /* genAndOp - for && operation */
4959 /*-----------------------------------------------------------------*/
4960 static void genAndOp (iCode *ic)
4962 operand *left,*right, *result;
4965 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4966 /* note here that && operations that are in an
4967 if statement are taken away by backPatchLabels
4968 only those used in arthmetic operations remain */
4969 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4970 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4971 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4973 /* if both are bit variables */
4974 if (AOP_TYPE(left) == AOP_CRY &&
4975 AOP_TYPE(right) == AOP_CRY ) {
4976 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4977 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4978 pic14_outBitC(result);
4980 tlbl = newiTempLabel(NULL);
4981 pic14_toBoolean(left);
4982 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4983 pic14_toBoolean(right);
4984 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4985 pic14_outBitAcc(result);
4988 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4989 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4990 freeAsmop(result,NULL,ic,TRUE);
4994 /*-----------------------------------------------------------------*/
4995 /* genOrOp - for || operation */
4996 /*-----------------------------------------------------------------*/
4999 modified this code, but it doesn't appear to ever get called
5002 static void genOrOp (iCode *ic)
5004 operand *left,*right, *result;
5007 /* note here that || operations that are in an
5008 if statement are taken away by backPatchLabels
5009 only those used in arthmetic operations remain */
5010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5011 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5012 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5013 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5015 DEBUGpic14_AopType(__LINE__,left,right,result);
5017 /* if both are bit variables */
5018 if (AOP_TYPE(left) == AOP_CRY &&
5019 AOP_TYPE(right) == AOP_CRY ) {
5020 pic14_emitcode("clrc","");
5021 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5022 AOP(left)->aopu.aop_dir,
5023 AOP(left)->aopu.aop_dir);
5024 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5025 AOP(right)->aopu.aop_dir,
5026 AOP(right)->aopu.aop_dir);
5027 pic14_emitcode("setc","");
5030 tlbl = newiTempLabel(NULL);
5031 pic14_toBoolean(left);
5033 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5034 pic14_toBoolean(right);
5035 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5037 pic14_outBitAcc(result);
5040 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5041 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5042 freeAsmop(result,NULL,ic,TRUE);
5045 /*-----------------------------------------------------------------*/
5046 /* isLiteralBit - test if lit == 2^n */
5047 /*-----------------------------------------------------------------*/
5048 static int isLiteralBit(unsigned long lit)
5050 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5051 0x100L,0x200L,0x400L,0x800L,
5052 0x1000L,0x2000L,0x4000L,0x8000L,
5053 0x10000L,0x20000L,0x40000L,0x80000L,
5054 0x100000L,0x200000L,0x400000L,0x800000L,
5055 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5056 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5060 for(idx = 0; idx < 32; idx++)
5066 /*-----------------------------------------------------------------*/
5067 /* continueIfTrue - */
5068 /*-----------------------------------------------------------------*/
5069 static void continueIfTrue (iCode *ic)
5071 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5073 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5077 /*-----------------------------------------------------------------*/
5079 /*-----------------------------------------------------------------*/
5080 static void jumpIfTrue (iCode *ic)
5082 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5084 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5088 /*-----------------------------------------------------------------*/
5089 /* jmpTrueOrFalse - */
5090 /*-----------------------------------------------------------------*/
5091 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5093 // ugly but optimized by peephole
5094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5096 symbol *nlbl = newiTempLabel(NULL);
5097 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5098 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5099 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5100 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5103 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5104 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5109 /*-----------------------------------------------------------------*/
5110 /* genAnd - code for and */
5111 /*-----------------------------------------------------------------*/
5112 static void genAnd (iCode *ic, iCode *ifx)
5114 operand *left, *right, *result;
5116 unsigned long lit = 0L;
5121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5122 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5123 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5124 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5126 resolveIfx(&rIfx,ifx);
5128 /* if left is a literal & right is not then exchange them */
5129 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5130 AOP_NEEDSACC(left)) {
5131 operand *tmp = right ;
5136 /* if result = right then exchange them */
5137 if(pic14_sameRegs(AOP(result),AOP(right))){
5138 operand *tmp = right ;
5143 /* if right is bit then exchange them */
5144 if (AOP_TYPE(right) == AOP_CRY &&
5145 AOP_TYPE(left) != AOP_CRY){
5146 operand *tmp = right ;
5150 if(AOP_TYPE(right) == AOP_LIT)
5151 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5153 size = AOP_SIZE(result);
5155 DEBUGpic14_AopType(__LINE__,left,right,result);
5158 // result = bit & yy;
5159 if (AOP_TYPE(left) == AOP_CRY){
5160 // c = bit & literal;
5161 if(AOP_TYPE(right) == AOP_LIT){
5163 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5166 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5169 if(size && (AOP_TYPE(result) == AOP_CRY)){
5170 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5173 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5177 pic14_emitcode("clr","c");
5180 if (AOP_TYPE(right) == AOP_CRY){
5182 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5183 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5186 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5188 pic14_emitcode("rrc","a");
5189 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5195 pic14_outBitC(result);
5197 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5198 genIfxJump(ifx, "c");
5202 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5203 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5204 if((AOP_TYPE(right) == AOP_LIT) &&
5205 (AOP_TYPE(result) == AOP_CRY) &&
5206 (AOP_TYPE(left) != AOP_CRY)){
5207 int posbit = isLiteralBit(lit);
5211 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5214 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5220 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5221 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5223 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5224 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5227 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5228 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5229 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5236 symbol *tlbl = newiTempLabel(NULL);
5237 int sizel = AOP_SIZE(left);
5239 pic14_emitcode("setb","c");
5241 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5242 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5244 if((posbit = isLiteralBit(bytelit)) != 0)
5245 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5247 if(bytelit != 0x0FFL)
5248 pic14_emitcode("anl","a,%s",
5249 aopGet(AOP(right),offset,FALSE,TRUE));
5250 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5255 // bit = left & literal
5257 pic14_emitcode("clr","c");
5258 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5260 // if(left & literal)
5263 jmpTrueOrFalse(ifx, tlbl);
5267 pic14_outBitC(result);
5271 /* if left is same as result */
5272 if(pic14_sameRegs(AOP(result),AOP(left))){
5274 for(;size--; offset++,lit>>=8) {
5275 if(AOP_TYPE(right) == AOP_LIT){
5276 switch(lit & 0xff) {
5278 /* and'ing with 0 has clears the result */
5279 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5280 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5283 /* and'ing with 0xff is a nop when the result and left are the same */
5288 int p = my_powof2( (~lit) & 0xff );
5290 /* only one bit is set in the literal, so use a bcf instruction */
5291 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5292 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5295 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5296 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5297 if(know_W != (lit&0xff))
5298 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5300 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5305 if (AOP_TYPE(left) == AOP_ACC) {
5306 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5308 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5309 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5316 // left & result in different registers
5317 if(AOP_TYPE(result) == AOP_CRY){
5319 // if(size), result in bit
5320 // if(!size && ifx), conditional oper: if(left & right)
5321 symbol *tlbl = newiTempLabel(NULL);
5322 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5324 pic14_emitcode("setb","c");
5326 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5327 pic14_emitcode("anl","a,%s",
5328 aopGet(AOP(left),offset,FALSE,FALSE));
5329 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5334 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5335 pic14_outBitC(result);
5337 jmpTrueOrFalse(ifx, tlbl);
5339 for(;(size--);offset++) {
5341 // result = left & right
5342 if(AOP_TYPE(right) == AOP_LIT){
5343 int t = (lit >> (offset*8)) & 0x0FFL;
5346 pic14_emitcode("clrf","%s",
5347 aopGet(AOP(result),offset,FALSE,FALSE));
5348 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5351 pic14_emitcode("movf","%s,w",
5352 aopGet(AOP(left),offset,FALSE,FALSE));
5353 pic14_emitcode("movwf","%s",
5354 aopGet(AOP(result),offset,FALSE,FALSE));
5355 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5356 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5359 pic14_emitcode("movlw","0x%x",t);
5360 pic14_emitcode("andwf","%s,w",
5361 aopGet(AOP(left),offset,FALSE,FALSE));
5362 pic14_emitcode("movwf","%s",
5363 aopGet(AOP(result),offset,FALSE,FALSE));
5365 emitpcode(POC_MOVLW, popGetLit(t));
5366 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5367 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5372 if (AOP_TYPE(left) == AOP_ACC) {
5373 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5374 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5376 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5377 pic14_emitcode("andwf","%s,w",
5378 aopGet(AOP(left),offset,FALSE,FALSE));
5379 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5380 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5382 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5383 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5389 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5390 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5391 freeAsmop(result,NULL,ic,TRUE);
5394 /*-----------------------------------------------------------------*/
5395 /* genOr - code for or */
5396 /*-----------------------------------------------------------------*/
5397 static void genOr (iCode *ic, iCode *ifx)
5399 operand *left, *right, *result;
5401 unsigned long lit = 0L;
5403 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5405 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5406 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5407 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5409 DEBUGpic14_AopType(__LINE__,left,right,result);
5411 /* if left is a literal & right is not then exchange them */
5412 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5413 AOP_NEEDSACC(left)) {
5414 operand *tmp = right ;
5419 /* if result = right then exchange them */
5420 if(pic14_sameRegs(AOP(result),AOP(right))){
5421 operand *tmp = right ;
5426 /* if right is bit then exchange them */
5427 if (AOP_TYPE(right) == AOP_CRY &&
5428 AOP_TYPE(left) != AOP_CRY){
5429 operand *tmp = right ;
5434 DEBUGpic14_AopType(__LINE__,left,right,result);
5436 if(AOP_TYPE(right) == AOP_LIT)
5437 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5439 size = AOP_SIZE(result);
5443 if (AOP_TYPE(left) == AOP_CRY){
5444 if(AOP_TYPE(right) == AOP_LIT){
5445 // c = bit & literal;
5447 // lit != 0 => result = 1
5448 if(AOP_TYPE(result) == AOP_CRY){
5450 emitpcode(POC_BSF, popGet(AOP(result),0));
5451 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5452 // AOP(result)->aopu.aop_dir,
5453 // AOP(result)->aopu.aop_dir);
5455 continueIfTrue(ifx);
5459 // lit == 0 => result = left
5460 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5462 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5465 if (AOP_TYPE(right) == AOP_CRY){
5466 if(pic14_sameRegs(AOP(result),AOP(left))){
5468 emitpcode(POC_BCF, popGet(AOP(result),0));
5469 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5470 emitpcode(POC_BSF, popGet(AOP(result),0));
5472 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5473 AOP(result)->aopu.aop_dir,
5474 AOP(result)->aopu.aop_dir);
5475 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5476 AOP(right)->aopu.aop_dir,
5477 AOP(right)->aopu.aop_dir);
5478 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5479 AOP(result)->aopu.aop_dir,
5480 AOP(result)->aopu.aop_dir);
5482 if( AOP_TYPE(result) == AOP_ACC) {
5483 emitpcode(POC_MOVLW, popGetLit(0));
5484 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5485 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5486 emitpcode(POC_MOVLW, popGetLit(1));
5490 emitpcode(POC_BCF, popGet(AOP(result),0));
5491 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5492 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5493 emitpcode(POC_BSF, popGet(AOP(result),0));
5495 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5496 AOP(result)->aopu.aop_dir,
5497 AOP(result)->aopu.aop_dir);
5498 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5499 AOP(right)->aopu.aop_dir,
5500 AOP(right)->aopu.aop_dir);
5501 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5502 AOP(left)->aopu.aop_dir,
5503 AOP(left)->aopu.aop_dir);
5504 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5505 AOP(result)->aopu.aop_dir,
5506 AOP(result)->aopu.aop_dir);
5511 symbol *tlbl = newiTempLabel(NULL);
5512 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5515 emitpcode(POC_BCF, popGet(AOP(result),0));
5516 if( AOP_TYPE(right) == AOP_ACC) {
5517 emitpcode(POC_IORLW, popGetLit(0));
5519 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5520 emitpcode(POC_BSF, popGet(AOP(result),0));
5525 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5526 pic14_emitcode(";XXX setb","c");
5527 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5528 AOP(left)->aopu.aop_dir,tlbl->key+100);
5529 pic14_toBoolean(right);
5530 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5531 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5532 jmpTrueOrFalse(ifx, tlbl);
5536 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5543 pic14_outBitC(result);
5545 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5546 genIfxJump(ifx, "c");
5550 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5551 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5552 if((AOP_TYPE(right) == AOP_LIT) &&
5553 (AOP_TYPE(result) == AOP_CRY) &&
5554 (AOP_TYPE(left) != AOP_CRY)){
5556 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5559 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5561 continueIfTrue(ifx);
5564 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5565 // lit = 0, result = boolean(left)
5567 pic14_emitcode(";XXX setb","c");
5568 pic14_toBoolean(right);
5570 symbol *tlbl = newiTempLabel(NULL);
5571 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5573 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5575 genIfxJump (ifx,"a");
5579 pic14_outBitC(result);
5583 /* if left is same as result */
5584 if(pic14_sameRegs(AOP(result),AOP(left))){
5586 for(;size--; offset++,lit>>=8) {
5587 if(AOP_TYPE(right) == AOP_LIT){
5588 if((lit & 0xff) == 0)
5589 /* or'ing with 0 has no effect */
5592 int p = my_powof2(lit & 0xff);
5594 /* only one bit is set in the literal, so use a bsf instruction */
5596 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5598 if(know_W != (lit & 0xff))
5599 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5600 know_W = lit & 0xff;
5601 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5606 if (AOP_TYPE(left) == AOP_ACC) {
5607 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5608 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5610 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5611 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5613 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5614 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5620 // left & result in different registers
5621 if(AOP_TYPE(result) == AOP_CRY){
5623 // if(size), result in bit
5624 // if(!size && ifx), conditional oper: if(left | right)
5625 symbol *tlbl = newiTempLabel(NULL);
5626 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5627 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5631 pic14_emitcode(";XXX setb","c");
5633 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5634 pic14_emitcode(";XXX orl","a,%s",
5635 aopGet(AOP(left),offset,FALSE,FALSE));
5636 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5641 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5642 pic14_outBitC(result);
5644 jmpTrueOrFalse(ifx, tlbl);
5645 } else for(;(size--);offset++){
5647 // result = left & right
5648 if(AOP_TYPE(right) == AOP_LIT){
5649 int t = (lit >> (offset*8)) & 0x0FFL;
5652 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5653 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5655 pic14_emitcode("movf","%s,w",
5656 aopGet(AOP(left),offset,FALSE,FALSE));
5657 pic14_emitcode("movwf","%s",
5658 aopGet(AOP(result),offset,FALSE,FALSE));
5661 emitpcode(POC_MOVLW, popGetLit(t));
5662 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5663 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5665 pic14_emitcode("movlw","0x%x",t);
5666 pic14_emitcode("iorwf","%s,w",
5667 aopGet(AOP(left),offset,FALSE,FALSE));
5668 pic14_emitcode("movwf","%s",
5669 aopGet(AOP(result),offset,FALSE,FALSE));
5675 // faster than result <- left, anl result,right
5676 // and better if result is SFR
5677 if (AOP_TYPE(left) == AOP_ACC) {
5678 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5679 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5681 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5682 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5684 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5685 pic14_emitcode("iorwf","%s,w",
5686 aopGet(AOP(left),offset,FALSE,FALSE));
5688 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5689 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5694 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5695 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5696 freeAsmop(result,NULL,ic,TRUE);
5699 /*-----------------------------------------------------------------*/
5700 /* genXor - code for xclusive or */
5701 /*-----------------------------------------------------------------*/
5702 static void genXor (iCode *ic, iCode *ifx)
5704 operand *left, *right, *result;
5706 unsigned long lit = 0L;
5708 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5710 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5711 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5712 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5714 /* if left is a literal & right is not ||
5715 if left needs acc & right does not */
5716 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5717 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5718 operand *tmp = right ;
5723 /* if result = right then exchange them */
5724 if(pic14_sameRegs(AOP(result),AOP(right))){
5725 operand *tmp = right ;
5730 /* if right is bit then exchange them */
5731 if (AOP_TYPE(right) == AOP_CRY &&
5732 AOP_TYPE(left) != AOP_CRY){
5733 operand *tmp = right ;
5737 if(AOP_TYPE(right) == AOP_LIT)
5738 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5740 size = AOP_SIZE(result);
5744 if (AOP_TYPE(left) == AOP_CRY){
5745 if(AOP_TYPE(right) == AOP_LIT){
5746 // c = bit & literal;
5748 // lit>>1 != 0 => result = 1
5749 if(AOP_TYPE(result) == AOP_CRY){
5751 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5752 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5754 continueIfTrue(ifx);
5757 pic14_emitcode("setb","c");
5761 // lit == 0, result = left
5762 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5764 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5766 // lit == 1, result = not(left)
5767 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5768 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5769 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5770 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5773 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5774 pic14_emitcode("cpl","c");
5781 symbol *tlbl = newiTempLabel(NULL);
5782 if (AOP_TYPE(right) == AOP_CRY){
5784 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5787 int sizer = AOP_SIZE(right);
5789 // if val>>1 != 0, result = 1
5790 pic14_emitcode("setb","c");
5792 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5794 // test the msb of the lsb
5795 pic14_emitcode("anl","a,#0xfe");
5796 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5800 pic14_emitcode("rrc","a");
5802 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5803 pic14_emitcode("cpl","c");
5804 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5809 pic14_outBitC(result);
5811 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5812 genIfxJump(ifx, "c");
5816 if(pic14_sameRegs(AOP(result),AOP(left))){
5817 /* if left is same as result */
5818 for(;size--; offset++) {
5819 if(AOP_TYPE(right) == AOP_LIT){
5820 int t = (lit >> (offset*8)) & 0x0FFL;
5824 if (IS_AOP_PREG(left)) {
5825 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5826 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5827 aopPut(AOP(result),"a",offset);
5829 emitpcode(POC_MOVLW, popGetLit(t));
5830 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5831 pic14_emitcode("xrl","%s,%s",
5832 aopGet(AOP(left),offset,FALSE,TRUE),
5833 aopGet(AOP(right),offset,FALSE,FALSE));
5836 if (AOP_TYPE(left) == AOP_ACC)
5837 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5839 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5840 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5842 if (IS_AOP_PREG(left)) {
5843 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5844 aopPut(AOP(result),"a",offset);
5846 pic14_emitcode("xrl","%s,a",
5847 aopGet(AOP(left),offset,FALSE,TRUE));
5853 // left & result in different registers
5854 if(AOP_TYPE(result) == AOP_CRY){
5856 // if(size), result in bit
5857 // if(!size && ifx), conditional oper: if(left ^ right)
5858 symbol *tlbl = newiTempLabel(NULL);
5859 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5861 pic14_emitcode("setb","c");
5863 if((AOP_TYPE(right) == AOP_LIT) &&
5864 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5865 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5867 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5868 pic14_emitcode("xrl","a,%s",
5869 aopGet(AOP(left),offset,FALSE,FALSE));
5871 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5876 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5877 pic14_outBitC(result);
5879 jmpTrueOrFalse(ifx, tlbl);
5880 } else for(;(size--);offset++){
5882 // result = left & right
5883 if(AOP_TYPE(right) == AOP_LIT){
5884 int t = (lit >> (offset*8)) & 0x0FFL;
5887 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5888 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5889 pic14_emitcode("movf","%s,w",
5890 aopGet(AOP(left),offset,FALSE,FALSE));
5891 pic14_emitcode("movwf","%s",
5892 aopGet(AOP(result),offset,FALSE,FALSE));
5895 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5896 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5897 pic14_emitcode("comf","%s,w",
5898 aopGet(AOP(left),offset,FALSE,FALSE));
5899 pic14_emitcode("movwf","%s",
5900 aopGet(AOP(result),offset,FALSE,FALSE));
5903 emitpcode(POC_MOVLW, popGetLit(t));
5904 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5905 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5906 pic14_emitcode("movlw","0x%x",t);
5907 pic14_emitcode("xorwf","%s,w",
5908 aopGet(AOP(left),offset,FALSE,FALSE));
5909 pic14_emitcode("movwf","%s",
5910 aopGet(AOP(result),offset,FALSE,FALSE));
5916 // faster than result <- left, anl result,right
5917 // and better if result is SFR
5918 if (AOP_TYPE(left) == AOP_ACC) {
5919 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5920 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5922 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5923 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5924 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5925 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5927 if ( AOP_TYPE(result) != AOP_ACC){
5928 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5929 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5935 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5936 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5937 freeAsmop(result,NULL,ic,TRUE);
5940 /*-----------------------------------------------------------------*/
5941 /* genInline - write the inline code out */
5942 /*-----------------------------------------------------------------*/
5943 static void genInline (iCode *ic)
5945 char *buffer, *bp, *bp1;
5947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5949 _G.inLine += (!options.asmpeep);
5951 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5952 strcpy(buffer,IC_INLINE(ic));
5954 /* emit each line as a code */
5958 pic14_emitcode(bp1,"");
5959 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5966 pic14_emitcode(bp1,"");
5973 pic14_emitcode(bp1,"");
5974 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5976 /* pic14_emitcode("",buffer); */
5977 _G.inLine -= (!options.asmpeep);
5980 /*-----------------------------------------------------------------*/
5981 /* genRRC - rotate right with carry */
5982 /*-----------------------------------------------------------------*/
5983 static void genRRC (iCode *ic)
5985 operand *left , *result ;
5986 int size, offset = 0, same;
5988 /* rotate right with carry */
5990 result=IC_RESULT(ic);
5991 aopOp (left,ic,FALSE);
5992 aopOp (result,ic,FALSE);
5994 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5996 same = pic14_sameRegs(AOP(result),AOP(left));
5998 size = AOP_SIZE(result);
6000 /* get the lsb and put it into the carry */
6001 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6008 emitpcode(POC_RRF, popGet(AOP(left),offset));
6010 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6011 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6017 freeAsmop(left,NULL,ic,TRUE);
6018 freeAsmop(result,NULL,ic,TRUE);
6021 /*-----------------------------------------------------------------*/
6022 /* genRLC - generate code for rotate left with carry */
6023 /*-----------------------------------------------------------------*/
6024 static void genRLC (iCode *ic)
6026 operand *left , *result ;
6027 int size, offset = 0;
6030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6031 /* rotate right with carry */
6033 result=IC_RESULT(ic);
6034 aopOp (left,ic,FALSE);
6035 aopOp (result,ic,FALSE);
6037 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6039 same = pic14_sameRegs(AOP(result),AOP(left));
6041 /* move it to the result */
6042 size = AOP_SIZE(result);
6044 /* get the msb and put it into the carry */
6045 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6052 emitpcode(POC_RLF, popGet(AOP(left),offset));
6054 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6055 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6062 freeAsmop(left,NULL,ic,TRUE);
6063 freeAsmop(result,NULL,ic,TRUE);
6066 /*-----------------------------------------------------------------*/
6067 /* genGetHbit - generates code get highest order bit */
6068 /*-----------------------------------------------------------------*/
6069 static void genGetHbit (iCode *ic)
6071 operand *left, *result;
6073 result=IC_RESULT(ic);
6074 aopOp (left,ic,FALSE);
6075 aopOp (result,ic,FALSE);
6077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6078 /* get the highest order byte into a */
6079 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6080 if(AOP_TYPE(result) == AOP_CRY){
6081 pic14_emitcode("rlc","a");
6082 pic14_outBitC(result);
6085 pic14_emitcode("rl","a");
6086 pic14_emitcode("anl","a,#0x01");
6087 pic14_outAcc(result);
6091 freeAsmop(left,NULL,ic,TRUE);
6092 freeAsmop(result,NULL,ic,TRUE);
6095 /*-----------------------------------------------------------------*/
6096 /* AccRol - rotate left accumulator by known count */
6097 /*-----------------------------------------------------------------*/
6098 static void AccRol (int shCount)
6100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6101 shCount &= 0x0007; // shCount : 0..7
6106 pic14_emitcode("rl","a");
6109 pic14_emitcode("rl","a");
6110 pic14_emitcode("rl","a");
6113 pic14_emitcode("swap","a");
6114 pic14_emitcode("rr","a");
6117 pic14_emitcode("swap","a");
6120 pic14_emitcode("swap","a");
6121 pic14_emitcode("rl","a");
6124 pic14_emitcode("rr","a");
6125 pic14_emitcode("rr","a");
6128 pic14_emitcode("rr","a");
6133 /*-----------------------------------------------------------------*/
6134 /* AccLsh - left shift accumulator by known count */
6135 /*-----------------------------------------------------------------*/
6136 static void AccLsh (int shCount)
6138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6141 pic14_emitcode("add","a,acc");
6144 pic14_emitcode("add","a,acc");
6145 pic14_emitcode("add","a,acc");
6147 /* rotate left accumulator */
6149 /* and kill the lower order bits */
6150 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6155 /*-----------------------------------------------------------------*/
6156 /* AccRsh - right shift accumulator by known count */
6157 /*-----------------------------------------------------------------*/
6158 static void AccRsh (int shCount)
6160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6164 pic14_emitcode("rrc","a");
6166 /* rotate right accumulator */
6167 AccRol(8 - shCount);
6168 /* and kill the higher order bits */
6169 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6175 /*-----------------------------------------------------------------*/
6176 /* AccSRsh - signed right shift accumulator by known count */
6177 /*-----------------------------------------------------------------*/
6178 static void AccSRsh (int shCount)
6181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6184 pic14_emitcode("mov","c,acc.7");
6185 pic14_emitcode("rrc","a");
6186 } else if(shCount == 2){
6187 pic14_emitcode("mov","c,acc.7");
6188 pic14_emitcode("rrc","a");
6189 pic14_emitcode("mov","c,acc.7");
6190 pic14_emitcode("rrc","a");
6192 tlbl = newiTempLabel(NULL);
6193 /* rotate right accumulator */
6194 AccRol(8 - shCount);
6195 /* and kill the higher order bits */
6196 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6197 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6198 pic14_emitcode("orl","a,#0x%02x",
6199 (unsigned char)~SRMask[shCount]);
6200 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6205 /*-----------------------------------------------------------------*/
6206 /* shiftR1Left2Result - shift right one byte from left to result */
6207 /*-----------------------------------------------------------------*/
6208 static void shiftR1Left2ResultSigned (operand *left, int offl,
6209 operand *result, int offr,
6214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6216 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6220 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6222 emitpcode(POC_RRF, popGet(AOP(result),offr));
6224 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6225 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6231 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6233 emitpcode(POC_RRF, popGet(AOP(result),offr));
6235 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6236 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6238 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6239 emitpcode(POC_RRF, popGet(AOP(result),offr));
6245 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6247 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6248 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6251 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6252 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6253 emitpcode(POC_ANDLW, popGetLit(0x1f));
6255 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6256 emitpcode(POC_IORLW, popGetLit(0xe0));
6258 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6262 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6263 emitpcode(POC_ANDLW, popGetLit(0x0f));
6264 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6265 emitpcode(POC_IORLW, popGetLit(0xf0));
6266 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6270 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6272 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6273 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6275 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6276 emitpcode(POC_ANDLW, popGetLit(0x07));
6277 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6278 emitpcode(POC_IORLW, popGetLit(0xf8));
6279 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6284 emitpcode(POC_MOVLW, popGetLit(0x00));
6285 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6286 emitpcode(POC_MOVLW, popGetLit(0xfe));
6287 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6288 emitpcode(POC_IORLW, popGetLit(0x01));
6289 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6291 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6292 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6293 emitpcode(POC_DECF, popGet(AOP(result),offr));
6294 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6295 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6301 emitpcode(POC_MOVLW, popGetLit(0x00));
6302 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6303 emitpcode(POC_MOVLW, popGetLit(0xff));
6304 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6306 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6307 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6308 emitpcode(POC_DECF, popGet(AOP(result),offr));
6316 /*-----------------------------------------------------------------*/
6317 /* shiftR1Left2Result - shift right one byte from left to result */
6318 /*-----------------------------------------------------------------*/
6319 static void shiftR1Left2Result (operand *left, int offl,
6320 operand *result, int offr,
6321 int shCount, int sign)
6325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6327 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6329 /* Copy the msb into the carry if signed. */
6331 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6341 emitpcode(POC_RRF, popGet(AOP(result),offr));
6343 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6344 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6350 emitpcode(POC_RRF, popGet(AOP(result),offr));
6352 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6353 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6356 emitpcode(POC_RRF, popGet(AOP(result),offr));
6361 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6363 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6364 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6367 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6368 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6369 emitpcode(POC_ANDLW, popGetLit(0x1f));
6370 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6374 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6375 emitpcode(POC_ANDLW, popGetLit(0x0f));
6376 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6380 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6381 emitpcode(POC_ANDLW, popGetLit(0x0f));
6382 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6384 emitpcode(POC_RRF, popGet(AOP(result),offr));
6389 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6390 emitpcode(POC_ANDLW, popGetLit(0x80));
6391 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392 emitpcode(POC_RLF, popGet(AOP(result),offr));
6393 emitpcode(POC_RLF, popGet(AOP(result),offr));
6398 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6399 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6400 emitpcode(POC_RLF, popGet(AOP(result),offr));
6409 /*-----------------------------------------------------------------*/
6410 /* shiftL1Left2Result - shift left one byte from left to result */
6411 /*-----------------------------------------------------------------*/
6412 static void shiftL1Left2Result (operand *left, int offl,
6413 operand *result, int offr, int shCount)
6418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6420 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6421 DEBUGpic14_emitcode ("; ***","same = %d",same);
6422 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6424 /* shift left accumulator */
6425 //AccLsh(shCount); // don't comment out just yet...
6426 // aopPut(AOP(result),"a",offr);
6430 /* Shift left 1 bit position */
6431 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6433 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6435 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6436 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6440 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6441 emitpcode(POC_ANDLW,popGetLit(0x7e));
6442 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6443 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6446 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6447 emitpcode(POC_ANDLW,popGetLit(0x3e));
6448 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6449 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6450 emitpcode(POC_RLF, popGet(AOP(result),offr));
6453 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6454 emitpcode(POC_ANDLW, popGetLit(0xf0));
6455 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6458 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6459 emitpcode(POC_ANDLW, popGetLit(0xf0));
6460 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6461 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6464 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6465 emitpcode(POC_ANDLW, popGetLit(0x30));
6466 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6467 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6468 emitpcode(POC_RLF, popGet(AOP(result),offr));
6471 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6472 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6473 emitpcode(POC_RRF, popGet(AOP(result),offr));
6477 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6482 /*-----------------------------------------------------------------*/
6483 /* movLeft2Result - move byte from left to result */
6484 /*-----------------------------------------------------------------*/
6485 static void movLeft2Result (operand *left, int offl,
6486 operand *result, int offr)
6489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6490 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6491 l = aopGet(AOP(left),offl,FALSE,FALSE);
6493 if (*l == '@' && (IS_AOP_PREG(result))) {
6494 pic14_emitcode("mov","a,%s",l);
6495 aopPut(AOP(result),"a",offr);
6497 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6498 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6503 /*-----------------------------------------------------------------*/
6504 /* shiftL2Left2Result - shift left two bytes from left to result */
6505 /*-----------------------------------------------------------------*/
6506 static void shiftL2Left2Result (operand *left, int offl,
6507 operand *result, int offr, int shCount)
6511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6513 if(pic14_sameRegs(AOP(result), AOP(left))) {
6521 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6522 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6523 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6527 emitpcode(POC_RLF, popGet(AOP(result),offr));
6528 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6534 emitpcode(POC_MOVLW, popGetLit(0x0f));
6535 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6536 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6537 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6538 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6539 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6540 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6542 emitpcode(POC_RLF, popGet(AOP(result),offr));
6543 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6547 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6548 emitpcode(POC_RRF, popGet(AOP(result),offr));
6549 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6550 emitpcode(POC_RRF, popGet(AOP(result),offr));
6551 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6552 emitpcode(POC_ANDLW,popGetLit(0xc0));
6553 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6554 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6555 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6556 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6559 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6560 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6561 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6562 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6563 emitpcode(POC_RRF, popGet(AOP(result),offr));
6573 /* note, use a mov/add for the shift since the mov has a
6574 chance of getting optimized out */
6575 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6576 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6577 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6578 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6579 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_RLF, popGet(AOP(result),offr));
6584 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6590 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6591 emitpcode(POC_ANDLW, popGetLit(0xF0));
6592 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6593 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6594 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6595 emitpcode(POC_ANDLW, popGetLit(0xF0));
6596 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6597 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_RLF, popGet(AOP(result),offr));
6602 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6607 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6609 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6611 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6612 emitpcode(POC_RRF, popGet(AOP(result),offr));
6613 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6614 emitpcode(POC_ANDLW,popGetLit(0xc0));
6615 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6616 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6617 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6618 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6621 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6622 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6623 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6624 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6625 emitpcode(POC_RRF, popGet(AOP(result),offr));
6630 /*-----------------------------------------------------------------*/
6631 /* shiftR2Left2Result - shift right two bytes from left to result */
6632 /*-----------------------------------------------------------------*/
6633 static void shiftR2Left2Result (operand *left, int offl,
6634 operand *result, int offr,
6635 int shCount, int sign)
6639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6640 same = pic14_sameRegs(AOP(result), AOP(left));
6642 if(same && ((offl + MSB16) == offr)){
6644 /* don't crash result[offr] */
6645 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6646 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6648 movLeft2Result(left,offl, result, offr);
6649 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6651 /* a:x >> shCount (x = lsb(result))*/
6654 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6656 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6665 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6671 emitpcode(POC_RRF,popGet(AOP(result),offr));
6673 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6674 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6675 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6676 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6681 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6685 emitpcode(POC_RRF,popGet(AOP(result),offr));
6692 emitpcode(POC_MOVLW, popGetLit(0xf0));
6693 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6694 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6696 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6697 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6698 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6699 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6701 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6702 emitpcode(POC_ANDLW, popGetLit(0x0f));
6703 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6705 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6706 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6707 emitpcode(POC_ANDLW, popGetLit(0xf0));
6708 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6709 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6713 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6714 emitpcode(POC_RRF, popGet(AOP(result),offr));
6718 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6719 emitpcode(POC_BTFSC,
6720 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6721 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6729 emitpcode(POC_RLF, popGet(AOP(result),offr));
6730 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6732 emitpcode(POC_RLF, popGet(AOP(result),offr));
6733 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6734 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6735 emitpcode(POC_ANDLW,popGetLit(0x03));
6737 emitpcode(POC_BTFSC,
6738 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6739 emitpcode(POC_IORLW,popGetLit(0xfc));
6741 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6746 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6747 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6748 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6749 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6750 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_ANDLW,popGetLit(0x03));
6753 emitpcode(POC_BTFSC,
6754 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6755 emitpcode(POC_IORLW,popGetLit(0xfc));
6757 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6758 emitpcode(POC_RLF, popGet(AOP(result),offr));
6765 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6766 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6767 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6768 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6771 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6778 /*-----------------------------------------------------------------*/
6779 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6780 /*-----------------------------------------------------------------*/
6781 static void shiftLLeftOrResult (operand *left, int offl,
6782 operand *result, int offr, int shCount)
6784 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6785 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6786 /* shift left accumulator */
6788 /* or with result */
6789 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6790 /* back to result */
6791 aopPut(AOP(result),"a",offr);
6794 /*-----------------------------------------------------------------*/
6795 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6796 /*-----------------------------------------------------------------*/
6797 static void shiftRLeftOrResult (operand *left, int offl,
6798 operand *result, int offr, int shCount)
6800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6801 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6802 /* shift right accumulator */
6804 /* or with result */
6805 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6806 /* back to result */
6807 aopPut(AOP(result),"a",offr);
6810 /*-----------------------------------------------------------------*/
6811 /* genlshOne - left shift a one byte quantity by known count */
6812 /*-----------------------------------------------------------------*/
6813 static void genlshOne (operand *result, operand *left, int shCount)
6815 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6816 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6819 /*-----------------------------------------------------------------*/
6820 /* genlshTwo - left shift two bytes by known amount != 0 */
6821 /*-----------------------------------------------------------------*/
6822 static void genlshTwo (operand *result,operand *left, int shCount)
6826 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6827 size = pic14_getDataSize(result);
6829 /* if shCount >= 8 */
6835 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6837 movLeft2Result(left, LSB, result, MSB16);
6839 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6842 /* 1 <= shCount <= 7 */
6845 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6847 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6851 /*-----------------------------------------------------------------*/
6852 /* shiftLLong - shift left one long from left to result */
6853 /* offl = LSB or MSB16 */
6854 /*-----------------------------------------------------------------*/
6855 static void shiftLLong (operand *left, operand *result, int offr )
6858 int size = AOP_SIZE(result);
6860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6861 if(size >= LSB+offr){
6862 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6864 pic14_emitcode("add","a,acc");
6865 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6866 size >= MSB16+offr && offr != LSB )
6867 pic14_emitcode("xch","a,%s",
6868 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6870 aopPut(AOP(result),"a",LSB+offr);
6873 if(size >= MSB16+offr){
6874 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6875 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6878 pic14_emitcode("rlc","a");
6879 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6880 size >= MSB24+offr && offr != LSB)
6881 pic14_emitcode("xch","a,%s",
6882 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6884 aopPut(AOP(result),"a",MSB16+offr);
6887 if(size >= MSB24+offr){
6888 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6889 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6892 pic14_emitcode("rlc","a");
6893 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6894 size >= MSB32+offr && offr != LSB )
6895 pic14_emitcode("xch","a,%s",
6896 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6898 aopPut(AOP(result),"a",MSB24+offr);
6901 if(size > MSB32+offr){
6902 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6903 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6906 pic14_emitcode("rlc","a");
6907 aopPut(AOP(result),"a",MSB32+offr);
6910 aopPut(AOP(result),zero,LSB);
6913 /*-----------------------------------------------------------------*/
6914 /* genlshFour - shift four byte by a known amount != 0 */
6915 /*-----------------------------------------------------------------*/
6916 static void genlshFour (operand *result, operand *left, int shCount)
6920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6921 size = AOP_SIZE(result);
6923 /* if shifting more that 3 bytes */
6924 if (shCount >= 24 ) {
6927 /* lowest order of left goes to the highest
6928 order of the destination */
6929 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6931 movLeft2Result(left, LSB, result, MSB32);
6932 aopPut(AOP(result),zero,LSB);
6933 aopPut(AOP(result),zero,MSB16);
6934 aopPut(AOP(result),zero,MSB32);
6938 /* more than two bytes */
6939 else if ( shCount >= 16 ) {
6940 /* lower order two bytes goes to higher order two bytes */
6942 /* if some more remaining */
6944 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6946 movLeft2Result(left, MSB16, result, MSB32);
6947 movLeft2Result(left, LSB, result, MSB24);
6949 aopPut(AOP(result),zero,MSB16);
6950 aopPut(AOP(result),zero,LSB);
6954 /* if more than 1 byte */
6955 else if ( shCount >= 8 ) {
6956 /* lower order three bytes goes to higher order three bytes */
6960 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6962 movLeft2Result(left, LSB, result, MSB16);
6964 else{ /* size = 4 */
6966 movLeft2Result(left, MSB24, result, MSB32);
6967 movLeft2Result(left, MSB16, result, MSB24);
6968 movLeft2Result(left, LSB, result, MSB16);
6969 aopPut(AOP(result),zero,LSB);
6971 else if(shCount == 1)
6972 shiftLLong(left, result, MSB16);
6974 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6975 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6976 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6977 aopPut(AOP(result),zero,LSB);
6982 /* 1 <= shCount <= 7 */
6983 else if(shCount <= 2){
6984 shiftLLong(left, result, LSB);
6986 shiftLLong(result, result, LSB);
6988 /* 3 <= shCount <= 7, optimize */
6990 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6991 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6992 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6996 /*-----------------------------------------------------------------*/
6997 /* genLeftShiftLiteral - left shifting by known count */
6998 /*-----------------------------------------------------------------*/
6999 static void genLeftShiftLiteral (operand *left,
7004 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7007 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7008 freeAsmop(right,NULL,ic,TRUE);
7010 aopOp(left,ic,FALSE);
7011 aopOp(result,ic,FALSE);
7013 size = getSize(operandType(result));
7016 pic14_emitcode("; shift left ","result %d, left %d",size,
7020 /* I suppose that the left size >= result size */
7023 movLeft2Result(left, size, result, size);
7027 else if(shCount >= (size * 8))
7029 aopPut(AOP(result),zero,size);
7033 genlshOne (result,left,shCount);
7038 genlshTwo (result,left,shCount);
7042 genlshFour (result,left,shCount);
7046 freeAsmop(left,NULL,ic,TRUE);
7047 freeAsmop(result,NULL,ic,TRUE);
7050 /*-----------------------------------------------------------------*
7051 * genMultiAsm - repeat assembly instruction for size of register.
7052 * if endian == 1, then the high byte (i.e base address + size of
7053 * register) is used first else the low byte is used first;
7054 *-----------------------------------------------------------------*/
7055 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7073 emitpcode(poc, popGet(AOP(reg),offset));
7078 /*-----------------------------------------------------------------*/
7079 /* genLeftShift - generates code for left shifting */
7080 /*-----------------------------------------------------------------*/
7081 static void genLeftShift (iCode *ic)
7083 operand *left,*right, *result;
7086 symbol *tlbl , *tlbl1;
7089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7091 right = IC_RIGHT(ic);
7093 result = IC_RESULT(ic);
7095 aopOp(right,ic,FALSE);
7097 /* if the shift count is known then do it
7098 as efficiently as possible */
7099 if (AOP_TYPE(right) == AOP_LIT) {
7100 genLeftShiftLiteral (left,right,result,ic);
7104 /* shift count is unknown then we have to form
7105 a loop get the loop count in B : Note: we take
7106 only the lower order byte since shifting
7107 more that 32 bits make no sense anyway, ( the
7108 largest size of an object can be only 32 bits ) */
7111 aopOp(left,ic,FALSE);
7112 aopOp(result,ic,FALSE);
7114 /* now move the left to the result if they are not the
7116 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7117 AOP_SIZE(result) > 1) {
7119 size = AOP_SIZE(result);
7122 l = aopGet(AOP(left),offset,FALSE,TRUE);
7123 if (*l == '@' && (IS_AOP_PREG(result))) {
7125 pic14_emitcode("mov","a,%s",l);
7126 aopPut(AOP(result),"a",offset);
7128 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7129 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7130 //aopPut(AOP(result),l,offset);
7136 size = AOP_SIZE(result);
7138 /* if it is only one byte then */
7140 if(optimized_for_speed) {
7141 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7142 emitpcode(POC_ANDLW, popGetLit(0xf0));
7143 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7144 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7145 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7146 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7147 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7148 emitpcode(POC_RLFW, popGet(AOP(result),0));
7149 emitpcode(POC_ANDLW, popGetLit(0xfe));
7150 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7151 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7152 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7155 tlbl = newiTempLabel(NULL);
7156 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7157 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7158 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7161 emitpcode(POC_COMFW, popGet(AOP(right),0));
7162 emitpcode(POC_RRF, popGet(AOP(result),0));
7163 emitpLabel(tlbl->key);
7164 emitpcode(POC_RLF, popGet(AOP(result),0));
7165 emitpcode(POC_ADDLW, popGetLit(1));
7167 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7172 if (pic14_sameRegs(AOP(left),AOP(result))) {
7174 tlbl = newiTempLabel(NULL);
7175 emitpcode(POC_COMFW, popGet(AOP(right),0));
7176 genMultiAsm(POC_RRF, result, size,1);
7177 emitpLabel(tlbl->key);
7178 genMultiAsm(POC_RLF, result, size,0);
7179 emitpcode(POC_ADDLW, popGetLit(1));
7181 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7185 //tlbl = newiTempLabel(NULL);
7187 //tlbl1 = newiTempLabel(NULL);
7189 //reAdjustPreg(AOP(result));
7191 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7192 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7193 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7195 //pic14_emitcode("add","a,acc");
7196 //aopPut(AOP(result),"a",offset++);
7198 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7200 // pic14_emitcode("rlc","a");
7201 // aopPut(AOP(result),"a",offset++);
7203 //reAdjustPreg(AOP(result));
7205 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7206 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7209 tlbl = newiTempLabel(NULL);
7210 tlbl1= newiTempLabel(NULL);
7212 size = AOP_SIZE(result);
7215 pctemp = popGetTempReg(); /* grab a temporary working register. */
7217 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7219 /* offset should be 0, 1 or 3 */
7220 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7222 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7224 emitpcode(POC_MOVWF, pctemp);
7227 emitpLabel(tlbl->key);
7230 emitpcode(POC_RLF, popGet(AOP(result),0));
7232 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7234 emitpcode(POC_DECFSZ, pctemp);
7235 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7236 emitpLabel(tlbl1->key);
7238 popReleaseTempReg(pctemp);
7242 freeAsmop (right,NULL,ic,TRUE);
7243 freeAsmop(left,NULL,ic,TRUE);
7244 freeAsmop(result,NULL,ic,TRUE);
7247 /*-----------------------------------------------------------------*/
7248 /* genrshOne - right shift a one byte quantity by known count */
7249 /*-----------------------------------------------------------------*/
7250 static void genrshOne (operand *result, operand *left,
7251 int shCount, int sign)
7253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7254 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7257 /*-----------------------------------------------------------------*/
7258 /* genrshTwo - right shift two bytes by known amount != 0 */
7259 /*-----------------------------------------------------------------*/
7260 static void genrshTwo (operand *result,operand *left,
7261 int shCount, int sign)
7263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7264 /* if shCount >= 8 */
7268 shiftR1Left2Result(left, MSB16, result, LSB,
7271 movLeft2Result(left, MSB16, result, LSB);
7273 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7276 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7277 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7281 /* 1 <= shCount <= 7 */
7283 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7286 /*-----------------------------------------------------------------*/
7287 /* shiftRLong - shift right one long from left to result */
7288 /* offl = LSB or MSB16 */
7289 /*-----------------------------------------------------------------*/
7290 static void shiftRLong (operand *left, int offl,
7291 operand *result, int sign)
7293 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7295 pic14_emitcode("clr","c");
7296 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7298 pic14_emitcode("mov","c,acc.7");
7299 pic14_emitcode("rrc","a");
7300 aopPut(AOP(result),"a",MSB32-offl);
7302 /* add sign of "a" */
7303 addSign(result, MSB32, sign);
7305 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7306 pic14_emitcode("rrc","a");
7307 aopPut(AOP(result),"a",MSB24-offl);
7309 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7310 pic14_emitcode("rrc","a");
7311 aopPut(AOP(result),"a",MSB16-offl);
7314 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7315 pic14_emitcode("rrc","a");
7316 aopPut(AOP(result),"a",LSB);
7320 /*-----------------------------------------------------------------*/
7321 /* genrshFour - shift four byte by a known amount != 0 */
7322 /*-----------------------------------------------------------------*/
7323 static void genrshFour (operand *result, operand *left,
7324 int shCount, int sign)
7326 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7327 /* if shifting more that 3 bytes */
7328 if(shCount >= 24 ) {
7331 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7333 movLeft2Result(left, MSB32, result, LSB);
7335 addSign(result, MSB16, sign);
7337 else if(shCount >= 16){
7340 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7342 movLeft2Result(left, MSB24, result, LSB);
7343 movLeft2Result(left, MSB32, result, MSB16);
7345 addSign(result, MSB24, sign);
7347 else if(shCount >= 8){
7350 shiftRLong(left, MSB16, result, sign);
7351 else if(shCount == 0){
7352 movLeft2Result(left, MSB16, result, LSB);
7353 movLeft2Result(left, MSB24, result, MSB16);
7354 movLeft2Result(left, MSB32, result, MSB24);
7355 addSign(result, MSB32, sign);
7358 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7359 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7360 /* the last shift is signed */
7361 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7362 addSign(result, MSB32, sign);
7365 else{ /* 1 <= shCount <= 7 */
7367 shiftRLong(left, LSB, result, sign);
7369 shiftRLong(result, LSB, result, sign);
7372 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7373 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7374 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7379 /*-----------------------------------------------------------------*/
7380 /* genRightShiftLiteral - right shifting by known count */
7381 /*-----------------------------------------------------------------*/
7382 static void genRightShiftLiteral (operand *left,
7388 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7392 freeAsmop(right,NULL,ic,TRUE);
7394 aopOp(left,ic,FALSE);
7395 aopOp(result,ic,FALSE);
7398 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7402 lsize = pic14_getDataSize(left);
7403 res_size = pic14_getDataSize(result);
7404 /* test the LEFT size !!! */
7406 /* I suppose that the left size >= result size */
7409 movLeft2Result(left, lsize, result, res_size);
7412 else if(shCount >= (lsize * 8)){
7415 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7417 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7418 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7423 emitpcode(POC_MOVLW, popGetLit(0));
7424 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7425 emitpcode(POC_MOVLW, popGetLit(0xff));
7427 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7432 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7439 genrshOne (result,left,shCount,sign);
7443 genrshTwo (result,left,shCount,sign);
7447 genrshFour (result,left,shCount,sign);
7455 freeAsmop(left,NULL,ic,TRUE);
7456 freeAsmop(result,NULL,ic,TRUE);
7459 /*-----------------------------------------------------------------*/
7460 /* genSignedRightShift - right shift of signed number */
7461 /*-----------------------------------------------------------------*/
7462 static void genSignedRightShift (iCode *ic)
7464 operand *right, *left, *result;
7467 symbol *tlbl, *tlbl1 ;
7470 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7472 /* we do it the hard way put the shift count in b
7473 and loop thru preserving the sign */
7474 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7476 right = IC_RIGHT(ic);
7478 result = IC_RESULT(ic);
7480 aopOp(right,ic,FALSE);
7481 aopOp(left,ic,FALSE);
7482 aopOp(result,ic,FALSE);
7485 if ( AOP_TYPE(right) == AOP_LIT) {
7486 genRightShiftLiteral (left,right,result,ic,1);
7489 /* shift count is unknown then we have to form
7490 a loop get the loop count in B : Note: we take
7491 only the lower order byte since shifting
7492 more that 32 bits make no sense anyway, ( the
7493 largest size of an object can be only 32 bits ) */
7495 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7496 //pic14_emitcode("inc","b");
7497 //freeAsmop (right,NULL,ic,TRUE);
7498 //aopOp(left,ic,FALSE);
7499 //aopOp(result,ic,FALSE);
7501 /* now move the left to the result if they are not the
7503 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7504 AOP_SIZE(result) > 1) {
7506 size = AOP_SIZE(result);
7510 l = aopGet(AOP(left),offset,FALSE,TRUE);
7511 if (*l == '@' && IS_AOP_PREG(result)) {
7513 pic14_emitcode("mov","a,%s",l);
7514 aopPut(AOP(result),"a",offset);
7516 aopPut(AOP(result),l,offset);
7518 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7519 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7525 /* mov the highest order bit to OVR */
7526 tlbl = newiTempLabel(NULL);
7527 tlbl1= newiTempLabel(NULL);
7529 size = AOP_SIZE(result);
7532 pctemp = popGetTempReg(); /* grab a temporary working register. */
7534 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7536 /* offset should be 0, 1 or 3 */
7537 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7539 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7541 emitpcode(POC_MOVWF, pctemp);
7544 emitpLabel(tlbl->key);
7546 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7547 emitpcode(POC_RRF, popGet(AOP(result),offset));
7550 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7553 emitpcode(POC_DECFSZ, pctemp);
7554 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7555 emitpLabel(tlbl1->key);
7557 popReleaseTempReg(pctemp);
7559 size = AOP_SIZE(result);
7561 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7562 pic14_emitcode("rlc","a");
7563 pic14_emitcode("mov","ov,c");
7564 /* if it is only one byte then */
7566 l = aopGet(AOP(left),0,FALSE,FALSE);
7568 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7569 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7570 pic14_emitcode("mov","c,ov");
7571 pic14_emitcode("rrc","a");
7572 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7573 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7574 aopPut(AOP(result),"a",0);
7578 reAdjustPreg(AOP(result));
7579 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7580 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7581 pic14_emitcode("mov","c,ov");
7583 l = aopGet(AOP(result),offset,FALSE,FALSE);
7585 pic14_emitcode("rrc","a");
7586 aopPut(AOP(result),"a",offset--);
7588 reAdjustPreg(AOP(result));
7589 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7590 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7595 freeAsmop(left,NULL,ic,TRUE);
7596 freeAsmop(result,NULL,ic,TRUE);
7597 freeAsmop(right,NULL,ic,TRUE);
7600 /*-----------------------------------------------------------------*/
7601 /* genRightShift - generate code for right shifting */
7602 /*-----------------------------------------------------------------*/
7603 static void genRightShift (iCode *ic)
7605 operand *right, *left, *result;
7609 symbol *tlbl, *tlbl1 ;
7611 /* if signed then we do it the hard way preserve the
7612 sign bit moving it inwards */
7613 retype = getSpec(operandType(IC_RESULT(ic)));
7614 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7616 if (!SPEC_USIGN(retype)) {
7617 genSignedRightShift (ic);
7621 /* signed & unsigned types are treated the same : i.e. the
7622 signed is NOT propagated inwards : quoting from the
7623 ANSI - standard : "for E1 >> E2, is equivalent to division
7624 by 2**E2 if unsigned or if it has a non-negative value,
7625 otherwise the result is implementation defined ", MY definition
7626 is that the sign does not get propagated */
7628 right = IC_RIGHT(ic);
7630 result = IC_RESULT(ic);
7632 aopOp(right,ic,FALSE);
7634 /* if the shift count is known then do it
7635 as efficiently as possible */
7636 if (AOP_TYPE(right) == AOP_LIT) {
7637 genRightShiftLiteral (left,right,result,ic, 0);
7641 /* shift count is unknown then we have to form
7642 a loop get the loop count in B : Note: we take
7643 only the lower order byte since shifting
7644 more that 32 bits make no sense anyway, ( the
7645 largest size of an object can be only 32 bits ) */
7647 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7648 pic14_emitcode("inc","b");
7649 aopOp(left,ic,FALSE);
7650 aopOp(result,ic,FALSE);
7652 /* now move the left to the result if they are not the
7654 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7655 AOP_SIZE(result) > 1) {
7657 size = AOP_SIZE(result);
7660 l = aopGet(AOP(left),offset,FALSE,TRUE);
7661 if (*l == '@' && IS_AOP_PREG(result)) {
7663 pic14_emitcode("mov","a,%s",l);
7664 aopPut(AOP(result),"a",offset);
7666 aopPut(AOP(result),l,offset);
7671 tlbl = newiTempLabel(NULL);
7672 tlbl1= newiTempLabel(NULL);
7673 size = AOP_SIZE(result);
7676 /* if it is only one byte then */
7679 tlbl = newiTempLabel(NULL);
7680 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7681 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7682 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7685 emitpcode(POC_COMFW, popGet(AOP(right),0));
7686 emitpcode(POC_RLF, popGet(AOP(result),0));
7687 emitpLabel(tlbl->key);
7688 emitpcode(POC_RRF, popGet(AOP(result),0));
7689 emitpcode(POC_ADDLW, popGetLit(1));
7691 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7696 reAdjustPreg(AOP(result));
7697 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7698 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7701 l = aopGet(AOP(result),offset,FALSE,FALSE);
7703 pic14_emitcode("rrc","a");
7704 aopPut(AOP(result),"a",offset--);
7706 reAdjustPreg(AOP(result));
7708 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7709 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7712 freeAsmop(left,NULL,ic,TRUE);
7713 freeAsmop (right,NULL,ic,TRUE);
7714 freeAsmop(result,NULL,ic,TRUE);
7717 /*-----------------------------------------------------------------*/
7718 /* genUnpackBits - generates code for unpacking bits */
7719 /*-----------------------------------------------------------------*/
7720 static void genUnpackBits (operand *result, char *rname, int ptype)
7727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7728 etype = getSpec(operandType(result));
7730 /* read the first byte */
7735 pic14_emitcode("mov","a,@%s",rname);
7739 pic14_emitcode("movx","a,@%s",rname);
7743 pic14_emitcode("movx","a,@dptr");
7747 pic14_emitcode("clr","a");
7748 pic14_emitcode("movc","a","@a+dptr");
7752 pic14_emitcode("lcall","__gptrget");
7756 /* if we have bitdisplacement then it fits */
7757 /* into this byte completely or if length is */
7758 /* less than a byte */
7759 if ((shCnt = SPEC_BSTR(etype)) ||
7760 (SPEC_BLEN(etype) <= 8)) {
7762 /* shift right acc */
7765 pic14_emitcode("anl","a,#0x%02x",
7766 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7767 aopPut(AOP(result),"a",offset);
7771 /* bit field did not fit in a byte */
7772 rlen = SPEC_BLEN(etype) - 8;
7773 aopPut(AOP(result),"a",offset++);
7780 pic14_emitcode("inc","%s",rname);
7781 pic14_emitcode("mov","a,@%s",rname);
7785 pic14_emitcode("inc","%s",rname);
7786 pic14_emitcode("movx","a,@%s",rname);
7790 pic14_emitcode("inc","dptr");
7791 pic14_emitcode("movx","a,@dptr");
7795 pic14_emitcode("clr","a");
7796 pic14_emitcode("inc","dptr");
7797 pic14_emitcode("movc","a","@a+dptr");
7801 pic14_emitcode("inc","dptr");
7802 pic14_emitcode("lcall","__gptrget");
7807 /* if we are done */
7811 aopPut(AOP(result),"a",offset++);
7816 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7817 aopPut(AOP(result),"a",offset);
7824 /*-----------------------------------------------------------------*/
7825 /* genDataPointerGet - generates code when ptr offset is known */
7826 /*-----------------------------------------------------------------*/
7827 static void genDataPointerGet (operand *left,
7831 int size , offset = 0;
7834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7837 /* optimization - most of the time, left and result are the same
7838 * address, but different types. for the pic code, we could omit
7842 aopOp(result,ic,TRUE);
7844 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7846 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7848 size = AOP_SIZE(result);
7851 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7855 freeAsmop(left,NULL,ic,TRUE);
7856 freeAsmop(result,NULL,ic,TRUE);
7859 /*-----------------------------------------------------------------*/
7860 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7861 /*-----------------------------------------------------------------*/
7862 static void genNearPointerGet (operand *left,
7869 sym_link *rtype, *retype;
7870 sym_link *ltype = operandType(left);
7873 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7875 rtype = operandType(result);
7876 retype= getSpec(rtype);
7878 aopOp(left,ic,FALSE);
7880 /* if left is rematerialisable and
7881 result is not bit variable type and
7882 the left is pointer to data space i.e
7883 lower 128 bytes of space */
7884 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7885 !IS_BITVAR(retype) &&
7886 DCL_TYPE(ltype) == POINTER) {
7887 //genDataPointerGet (left,result,ic);
7891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7893 /* if the value is already in a pointer register
7894 then don't need anything more */
7895 if (!AOP_INPREG(AOP(left))) {
7896 /* otherwise get a free pointer register */
7897 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7900 preg = getFreePtr(ic,&aop,FALSE);
7901 pic14_emitcode("mov","%s,%s",
7903 aopGet(AOP(left),0,FALSE,TRUE));
7904 rname = preg->name ;
7908 rname = aopGet(AOP(left),0,FALSE,FALSE);
7910 aopOp (result,ic,FALSE);
7912 /* if bitfield then unpack the bits */
7913 if (IS_BITVAR(retype))
7914 genUnpackBits (result,rname,POINTER);
7916 /* we have can just get the values */
7917 int size = AOP_SIZE(result);
7920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7922 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7923 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7925 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7926 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7928 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7932 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7934 pic14_emitcode("mov","a,@%s",rname);
7935 aopPut(AOP(result),"a",offset);
7937 sprintf(buffer,"@%s",rname);
7938 aopPut(AOP(result),buffer,offset);
7942 pic14_emitcode("inc","%s",rname);
7947 /* now some housekeeping stuff */
7949 /* we had to allocate for this iCode */
7950 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7951 freeAsmop(NULL,aop,ic,TRUE);
7953 /* we did not allocate which means left
7954 already in a pointer register, then
7955 if size > 0 && this could be used again
7956 we have to point it back to where it
7958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7959 if (AOP_SIZE(result) > 1 &&
7960 !OP_SYMBOL(left)->remat &&
7961 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7963 int size = AOP_SIZE(result) - 1;
7965 pic14_emitcode("dec","%s",rname);
7970 freeAsmop(left,NULL,ic,TRUE);
7971 freeAsmop(result,NULL,ic,TRUE);
7975 /*-----------------------------------------------------------------*/
7976 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7977 /*-----------------------------------------------------------------*/
7978 static void genPagedPointerGet (operand *left,
7985 sym_link *rtype, *retype;
7987 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7989 rtype = operandType(result);
7990 retype= getSpec(rtype);
7992 aopOp(left,ic,FALSE);
7994 /* if the value is already in a pointer register
7995 then don't need anything more */
7996 if (!AOP_INPREG(AOP(left))) {
7997 /* otherwise get a free pointer register */
7999 preg = getFreePtr(ic,&aop,FALSE);
8000 pic14_emitcode("mov","%s,%s",
8002 aopGet(AOP(left),0,FALSE,TRUE));
8003 rname = preg->name ;
8005 rname = aopGet(AOP(left),0,FALSE,FALSE);
8007 freeAsmop(left,NULL,ic,TRUE);
8008 aopOp (result,ic,FALSE);
8010 /* if bitfield then unpack the bits */
8011 if (IS_BITVAR(retype))
8012 genUnpackBits (result,rname,PPOINTER);
8014 /* we have can just get the values */
8015 int size = AOP_SIZE(result);
8020 pic14_emitcode("movx","a,@%s",rname);
8021 aopPut(AOP(result),"a",offset);
8026 pic14_emitcode("inc","%s",rname);
8030 /* now some housekeeping stuff */
8032 /* we had to allocate for this iCode */
8033 freeAsmop(NULL,aop,ic,TRUE);
8035 /* we did not allocate which means left
8036 already in a pointer register, then
8037 if size > 0 && this could be used again
8038 we have to point it back to where it
8040 if (AOP_SIZE(result) > 1 &&
8041 !OP_SYMBOL(left)->remat &&
8042 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8044 int size = AOP_SIZE(result) - 1;
8046 pic14_emitcode("dec","%s",rname);
8051 freeAsmop(result,NULL,ic,TRUE);
8056 /*-----------------------------------------------------------------*/
8057 /* genFarPointerGet - gget value from far space */
8058 /*-----------------------------------------------------------------*/
8059 static void genFarPointerGet (operand *left,
8060 operand *result, iCode *ic)
8063 sym_link *retype = getSpec(operandType(result));
8065 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8067 aopOp(left,ic,FALSE);
8069 /* if the operand is already in dptr
8070 then we do nothing else we move the value to dptr */
8071 if (AOP_TYPE(left) != AOP_STR) {
8072 /* if this is remateriazable */
8073 if (AOP_TYPE(left) == AOP_IMMD)
8074 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8075 else { /* we need to get it byte by byte */
8076 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8077 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8078 if (options.model == MODEL_FLAT24)
8080 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8084 /* so dptr know contains the address */
8085 freeAsmop(left,NULL,ic,TRUE);
8086 aopOp(result,ic,FALSE);
8088 /* if bit then unpack */
8089 if (IS_BITVAR(retype))
8090 genUnpackBits(result,"dptr",FPOINTER);
8092 size = AOP_SIZE(result);
8096 pic14_emitcode("movx","a,@dptr");
8097 aopPut(AOP(result),"a",offset++);
8099 pic14_emitcode("inc","dptr");
8103 freeAsmop(result,NULL,ic,TRUE);
8106 /*-----------------------------------------------------------------*/
8107 /* genCodePointerGet - get value from code space */
8108 /*-----------------------------------------------------------------*/
8109 static void genCodePointerGet (operand *left,
8110 operand *result, iCode *ic)
8113 sym_link *retype = getSpec(operandType(result));
8115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8117 aopOp(left,ic,FALSE);
8119 /* if the operand is already in dptr
8120 then we do nothing else we move the value to dptr */
8121 if (AOP_TYPE(left) != AOP_STR) {
8122 /* if this is remateriazable */
8123 if (AOP_TYPE(left) == AOP_IMMD)
8124 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8125 else { /* we need to get it byte by byte */
8126 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8127 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8128 if (options.model == MODEL_FLAT24)
8130 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8134 /* so dptr know contains the address */
8135 freeAsmop(left,NULL,ic,TRUE);
8136 aopOp(result,ic,FALSE);
8138 /* if bit then unpack */
8139 if (IS_BITVAR(retype))
8140 genUnpackBits(result,"dptr",CPOINTER);
8142 size = AOP_SIZE(result);
8146 pic14_emitcode("clr","a");
8147 pic14_emitcode("movc","a,@a+dptr");
8148 aopPut(AOP(result),"a",offset++);
8150 pic14_emitcode("inc","dptr");
8154 freeAsmop(result,NULL,ic,TRUE);
8157 /*-----------------------------------------------------------------*/
8158 /* genGenPointerGet - gget value from generic pointer space */
8159 /*-----------------------------------------------------------------*/
8160 static void genGenPointerGet (operand *left,
8161 operand *result, iCode *ic)
8164 sym_link *retype = getSpec(operandType(result));
8166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8167 aopOp(left,ic,FALSE);
8168 aopOp(result,ic,FALSE);
8171 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8173 /* if the operand is already in dptr
8174 then we do nothing else we move the value to dptr */
8175 // if (AOP_TYPE(left) != AOP_STR) {
8176 /* if this is remateriazable */
8177 if (AOP_TYPE(left) == AOP_IMMD) {
8178 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8179 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8181 else { /* we need to get it byte by byte */
8183 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8184 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8186 size = AOP_SIZE(result);
8190 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8191 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8193 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8198 /* so dptr know contains the address */
8200 /* if bit then unpack */
8201 //if (IS_BITVAR(retype))
8202 // genUnpackBits(result,"dptr",GPOINTER);
8205 freeAsmop(left,NULL,ic,TRUE);
8206 freeAsmop(result,NULL,ic,TRUE);
8210 /*-----------------------------------------------------------------*/
8211 /* genConstPointerGet - get value from const generic pointer space */
8212 /*-----------------------------------------------------------------*/
8213 static void genConstPointerGet (operand *left,
8214 operand *result, iCode *ic)
8216 //sym_link *retype = getSpec(operandType(result));
8217 symbol *albl = newiTempLabel(NULL);
8218 symbol *blbl = newiTempLabel(NULL);
8221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8222 aopOp(left,ic,FALSE);
8223 aopOp(result,ic,FALSE);
8226 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8228 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8230 emitpcode(POC_CALL,popGetLabel(albl->key));
8231 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8232 emitpLabel(albl->key);
8234 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8236 emitpcode(poc,popGet(AOP(left),1));
8237 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8238 emitpcode(poc,popGet(AOP(left),0));
8239 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8241 emitpLabel(blbl->key);
8243 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8246 freeAsmop(left,NULL,ic,TRUE);
8247 freeAsmop(result,NULL,ic,TRUE);
8250 /*-----------------------------------------------------------------*/
8251 /* genPointerGet - generate code for pointer get */
8252 /*-----------------------------------------------------------------*/
8253 static void genPointerGet (iCode *ic)
8255 operand *left, *result ;
8256 sym_link *type, *etype;
8259 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8262 result = IC_RESULT(ic) ;
8264 /* depending on the type of pointer we need to
8265 move it to the correct pointer register */
8266 type = operandType(left);
8267 etype = getSpec(type);
8269 if (IS_PTR_CONST(type))
8270 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8272 /* if left is of type of pointer then it is simple */
8273 if (IS_PTR(type) && !IS_FUNC(type->next))
8274 p_type = DCL_TYPE(type);
8276 /* we have to go by the storage class */
8277 p_type = PTR_TYPE(SPEC_OCLS(etype));
8279 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8281 if (SPEC_OCLS(etype)->codesp ) {
8282 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8283 //p_type = CPOINTER ;
8286 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8287 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8288 /*p_type = FPOINTER ;*/
8290 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8291 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8292 /* p_type = PPOINTER; */
8294 if (SPEC_OCLS(etype) == idata )
8295 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8296 /* p_type = IPOINTER; */
8298 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8299 /* p_type = POINTER ; */
8302 /* now that we have the pointer type we assign
8303 the pointer values */
8308 genNearPointerGet (left,result,ic);
8312 genPagedPointerGet(left,result,ic);
8316 genFarPointerGet (left,result,ic);
8320 genConstPointerGet (left,result,ic);
8321 //pic14_emitcodePointerGet (left,result,ic);
8325 if (IS_PTR_CONST(type))
8326 genConstPointerGet (left,result,ic);
8328 genGenPointerGet (left,result,ic);
8334 /*-----------------------------------------------------------------*/
8335 /* genPackBits - generates code for packed bit storage */
8336 /*-----------------------------------------------------------------*/
8337 static void genPackBits (sym_link *etype ,
8339 char *rname, int p_type)
8347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8348 blen = SPEC_BLEN(etype);
8349 bstr = SPEC_BSTR(etype);
8351 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8354 /* if the bit lenth is less than or */
8355 /* it exactly fits a byte then */
8356 if (SPEC_BLEN(etype) <= 8 ) {
8357 shCount = SPEC_BSTR(etype) ;
8359 /* shift left acc */
8362 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8367 pic14_emitcode ("mov","b,a");
8368 pic14_emitcode("mov","a,@%s",rname);
8372 pic14_emitcode ("mov","b,a");
8373 pic14_emitcode("movx","a,@dptr");
8377 pic14_emitcode ("push","b");
8378 pic14_emitcode ("push","acc");
8379 pic14_emitcode ("lcall","__gptrget");
8380 pic14_emitcode ("pop","b");
8384 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8385 ((unsigned char)(0xFF << (blen+bstr)) |
8386 (unsigned char)(0xFF >> (8-bstr)) ) );
8387 pic14_emitcode ("orl","a,b");
8388 if (p_type == GPOINTER)
8389 pic14_emitcode("pop","b");
8395 pic14_emitcode("mov","@%s,a",rname);
8399 pic14_emitcode("movx","@dptr,a");
8403 DEBUGpic14_emitcode(";lcall","__gptrput");
8408 if ( SPEC_BLEN(etype) <= 8 )
8411 pic14_emitcode("inc","%s",rname);
8412 rLen = SPEC_BLEN(etype) ;
8414 /* now generate for lengths greater than one byte */
8417 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8427 pic14_emitcode("mov","@%s,a",rname);
8429 pic14_emitcode("mov","@%s,%s",rname,l);
8434 pic14_emitcode("movx","@dptr,a");
8439 DEBUGpic14_emitcode(";lcall","__gptrput");
8442 pic14_emitcode ("inc","%s",rname);
8447 /* last last was not complete */
8449 /* save the byte & read byte */
8452 pic14_emitcode ("mov","b,a");
8453 pic14_emitcode("mov","a,@%s",rname);
8457 pic14_emitcode ("mov","b,a");
8458 pic14_emitcode("movx","a,@dptr");
8462 pic14_emitcode ("push","b");
8463 pic14_emitcode ("push","acc");
8464 pic14_emitcode ("lcall","__gptrget");
8465 pic14_emitcode ("pop","b");
8469 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8470 pic14_emitcode ("orl","a,b");
8473 if (p_type == GPOINTER)
8474 pic14_emitcode("pop","b");
8479 pic14_emitcode("mov","@%s,a",rname);
8483 pic14_emitcode("movx","@dptr,a");
8487 DEBUGpic14_emitcode(";lcall","__gptrput");
8491 /*-----------------------------------------------------------------*/
8492 /* genDataPointerSet - remat pointer to data space */
8493 /*-----------------------------------------------------------------*/
8494 static void genDataPointerSet(operand *right,
8498 int size, offset = 0 ;
8499 char *l, buffer[256];
8501 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8502 aopOp(right,ic,FALSE);
8504 l = aopGet(AOP(result),0,FALSE,TRUE);
8505 size = AOP_SIZE(right);
8507 if ( AOP_TYPE(result) == AOP_PCODE) {
8508 fprintf(stderr,"genDataPointerSet %s, %d\n",
8509 AOP(result)->aopu.pcop->name,
8510 PCOI(AOP(result)->aopu.pcop)->offset);
8514 // tsd, was l+1 - the underline `_' prefix was being stripped
8517 sprintf(buffer,"(%s + %d)",l,offset);
8518 fprintf(stderr,"oops %s\n",buffer);
8520 sprintf(buffer,"%s",l);
8522 if (AOP_TYPE(right) == AOP_LIT) {
8523 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8524 lit = lit >> (8*offset);
8526 pic14_emitcode("movlw","%d",lit);
8527 pic14_emitcode("movwf","%s",buffer);
8529 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8530 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8531 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8534 pic14_emitcode("clrf","%s",buffer);
8535 //emitpcode(POC_CLRF, popRegFromString(buffer));
8536 emitpcode(POC_CLRF, popGet(AOP(result),0));
8539 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8540 pic14_emitcode("movwf","%s",buffer);
8542 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8543 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8544 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8551 freeAsmop(right,NULL,ic,TRUE);
8552 freeAsmop(result,NULL,ic,TRUE);
8555 /*-----------------------------------------------------------------*/
8556 /* genNearPointerSet - pic14_emitcode for near pointer put */
8557 /*-----------------------------------------------------------------*/
8558 static void genNearPointerSet (operand *right,
8565 sym_link *ptype = operandType(result);
8568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8569 retype= getSpec(operandType(right));
8571 aopOp(result,ic,FALSE);
8574 /* if the result is rematerializable &
8575 in data space & not a bit variable */
8576 //if (AOP_TYPE(result) == AOP_IMMD &&
8577 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8578 DCL_TYPE(ptype) == POINTER &&
8579 !IS_BITVAR(retype)) {
8580 genDataPointerSet (right,result,ic);
8581 freeAsmop(result,NULL,ic,TRUE);
8585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8586 aopOp(right,ic,FALSE);
8587 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8589 /* if the value is already in a pointer register
8590 then don't need anything more */
8591 if (!AOP_INPREG(AOP(result))) {
8592 /* otherwise get a free pointer register */
8593 //aop = newAsmop(0);
8594 //preg = getFreePtr(ic,&aop,FALSE);
8595 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8596 //pic14_emitcode("mov","%s,%s",
8598 // aopGet(AOP(result),0,FALSE,TRUE));
8599 //rname = preg->name ;
8600 //pic14_emitcode("movwf","fsr");
8601 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8602 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8603 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8604 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8608 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8611 /* if bitfield then unpack the bits */
8612 if (IS_BITVAR(retype)) {
8613 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8614 "The programmer is obviously confused");
8615 //genPackBits (retype,right,rname,POINTER);
8619 /* we have can just get the values */
8620 int size = AOP_SIZE(right);
8623 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8625 l = aopGet(AOP(right),offset,FALSE,TRUE);
8628 //pic14_emitcode("mov","@%s,a",rname);
8629 pic14_emitcode("movf","indf,w ;1");
8632 if (AOP_TYPE(right) == AOP_LIT) {
8633 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8635 pic14_emitcode("movlw","%s",l);
8636 pic14_emitcode("movwf","indf ;2");
8638 pic14_emitcode("clrf","indf");
8640 pic14_emitcode("movf","%s,w",l);
8641 pic14_emitcode("movwf","indf ;2");
8643 //pic14_emitcode("mov","@%s,%s",rname,l);
8646 pic14_emitcode("incf","fsr,f ;3");
8647 //pic14_emitcode("inc","%s",rname);
8652 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8653 /* now some housekeeping stuff */
8655 /* we had to allocate for this iCode */
8656 freeAsmop(NULL,aop,ic,TRUE);
8658 /* we did not allocate which means left
8659 already in a pointer register, then
8660 if size > 0 && this could be used again
8661 we have to point it back to where it
8663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8664 if (AOP_SIZE(right) > 1 &&
8665 !OP_SYMBOL(result)->remat &&
8666 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8668 int size = AOP_SIZE(right) - 1;
8670 pic14_emitcode("decf","fsr,f");
8671 //pic14_emitcode("dec","%s",rname);
8675 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8678 freeAsmop(right,NULL,ic,TRUE);
8679 freeAsmop(result,NULL,ic,TRUE);
8682 /*-----------------------------------------------------------------*/
8683 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8684 /*-----------------------------------------------------------------*/
8685 static void genPagedPointerSet (operand *right,
8694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8696 retype= getSpec(operandType(right));
8698 aopOp(result,ic,FALSE);
8700 /* if the value is already in a pointer register
8701 then don't need anything more */
8702 if (!AOP_INPREG(AOP(result))) {
8703 /* otherwise get a free pointer register */
8705 preg = getFreePtr(ic,&aop,FALSE);
8706 pic14_emitcode("mov","%s,%s",
8708 aopGet(AOP(result),0,FALSE,TRUE));
8709 rname = preg->name ;
8711 rname = aopGet(AOP(result),0,FALSE,FALSE);
8713 freeAsmop(result,NULL,ic,TRUE);
8714 aopOp (right,ic,FALSE);
8716 /* if bitfield then unpack the bits */
8717 if (IS_BITVAR(retype))
8718 genPackBits (retype,right,rname,PPOINTER);
8720 /* we have can just get the values */
8721 int size = AOP_SIZE(right);
8725 l = aopGet(AOP(right),offset,FALSE,TRUE);
8728 pic14_emitcode("movx","@%s,a",rname);
8731 pic14_emitcode("inc","%s",rname);
8737 /* now some housekeeping stuff */
8739 /* we had to allocate for this iCode */
8740 freeAsmop(NULL,aop,ic,TRUE);
8742 /* we did not allocate which means left
8743 already in a pointer register, then
8744 if size > 0 && this could be used again
8745 we have to point it back to where it
8747 if (AOP_SIZE(right) > 1 &&
8748 !OP_SYMBOL(result)->remat &&
8749 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8751 int size = AOP_SIZE(right) - 1;
8753 pic14_emitcode("dec","%s",rname);
8758 freeAsmop(right,NULL,ic,TRUE);
8763 /*-----------------------------------------------------------------*/
8764 /* genFarPointerSet - set value from far space */
8765 /*-----------------------------------------------------------------*/
8766 static void genFarPointerSet (operand *right,
8767 operand *result, iCode *ic)
8770 sym_link *retype = getSpec(operandType(right));
8772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8773 aopOp(result,ic,FALSE);
8775 /* if the operand is already in dptr
8776 then we do nothing else we move the value to dptr */
8777 if (AOP_TYPE(result) != AOP_STR) {
8778 /* if this is remateriazable */
8779 if (AOP_TYPE(result) == AOP_IMMD)
8780 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8781 else { /* we need to get it byte by byte */
8782 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8783 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8784 if (options.model == MODEL_FLAT24)
8786 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8790 /* so dptr know contains the address */
8791 freeAsmop(result,NULL,ic,TRUE);
8792 aopOp(right,ic,FALSE);
8794 /* if bit then unpack */
8795 if (IS_BITVAR(retype))
8796 genPackBits(retype,right,"dptr",FPOINTER);
8798 size = AOP_SIZE(right);
8802 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8804 pic14_emitcode("movx","@dptr,a");
8806 pic14_emitcode("inc","dptr");
8810 freeAsmop(right,NULL,ic,TRUE);
8813 /*-----------------------------------------------------------------*/
8814 /* genGenPointerSet - set value from generic pointer space */
8815 /*-----------------------------------------------------------------*/
8816 static void genGenPointerSet (operand *right,
8817 operand *result, iCode *ic)
8820 sym_link *retype = getSpec(operandType(right));
8822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8824 aopOp(result,ic,FALSE);
8825 aopOp(right,ic,FALSE);
8826 size = AOP_SIZE(right);
8828 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8830 /* if the operand is already in dptr
8831 then we do nothing else we move the value to dptr */
8832 if (AOP_TYPE(result) != AOP_STR) {
8833 /* if this is remateriazable */
8834 if (AOP_TYPE(result) == AOP_IMMD) {
8835 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8836 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8838 else { /* we need to get it byte by byte */
8839 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8840 size = AOP_SIZE(right);
8843 /* hack hack! see if this the FSR. If so don't load W */
8844 if(AOP_TYPE(right) != AOP_ACC) {
8846 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8847 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8850 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8852 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8853 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8857 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8858 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8861 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8868 if(aopIdx(AOP(result),0) != 4) {
8870 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8874 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8879 /* so dptr know contains the address */
8882 /* if bit then unpack */
8883 if (IS_BITVAR(retype))
8884 genPackBits(retype,right,"dptr",GPOINTER);
8886 size = AOP_SIZE(right);
8890 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8892 pic14_emitcode("incf","fsr,f");
8893 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8894 pic14_emitcode("movwf","indf");
8896 //DEBUGpic14_emitcode(";lcall","__gptrput");
8898 // pic14_emitcode("inc","dptr");
8903 freeAsmop(right,NULL,ic,TRUE);
8904 freeAsmop(result,NULL,ic,TRUE);
8907 /*-----------------------------------------------------------------*/
8908 /* genPointerSet - stores the value into a pointer location */
8909 /*-----------------------------------------------------------------*/
8910 static void genPointerSet (iCode *ic)
8912 operand *right, *result ;
8913 sym_link *type, *etype;
8916 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8918 right = IC_RIGHT(ic);
8919 result = IC_RESULT(ic) ;
8921 /* depending on the type of pointer we need to
8922 move it to the correct pointer register */
8923 type = operandType(result);
8924 etype = getSpec(type);
8925 /* if left is of type of pointer then it is simple */
8926 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8927 p_type = DCL_TYPE(type);
8930 /* we have to go by the storage class */
8931 p_type = PTR_TYPE(SPEC_OCLS(etype));
8933 /* if (SPEC_OCLS(etype)->codesp ) { */
8934 /* p_type = CPOINTER ; */
8937 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8938 /* p_type = FPOINTER ; */
8940 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8941 /* p_type = PPOINTER ; */
8943 /* if (SPEC_OCLS(etype) == idata ) */
8944 /* p_type = IPOINTER ; */
8946 /* p_type = POINTER ; */
8949 /* now that we have the pointer type we assign
8950 the pointer values */
8955 genNearPointerSet (right,result,ic);
8959 genPagedPointerSet (right,result,ic);
8963 genFarPointerSet (right,result,ic);
8967 genGenPointerSet (right,result,ic);
8971 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8972 "genPointerSet: illegal pointer type");
8976 /*-----------------------------------------------------------------*/
8977 /* genIfx - generate code for Ifx statement */
8978 /*-----------------------------------------------------------------*/
8979 static void genIfx (iCode *ic, iCode *popIc)
8981 operand *cond = IC_COND(ic);
8984 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8986 aopOp(cond,ic,FALSE);
8988 /* get the value into acc */
8989 if (AOP_TYPE(cond) != AOP_CRY)
8990 pic14_toBoolean(cond);
8993 /* the result is now in the accumulator */
8994 freeAsmop(cond,NULL,ic,TRUE);
8996 /* if there was something to be popped then do it */
9000 /* if the condition is a bit variable */
9001 if (isbit && IS_ITEMP(cond) &&
9003 genIfxJump(ic,SPIL_LOC(cond)->rname);
9004 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9007 if (isbit && !IS_ITEMP(cond))
9008 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9016 /*-----------------------------------------------------------------*/
9017 /* genAddrOf - generates code for address of */
9018 /*-----------------------------------------------------------------*/
9019 static void genAddrOf (iCode *ic)
9021 operand *right, *result, *left;
9024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9027 //aopOp(IC_RESULT(ic),ic,FALSE);
9029 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9030 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9031 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9033 DEBUGpic14_AopType(__LINE__,left,right,result);
9035 size = AOP_SIZE(IC_RESULT(ic));
9039 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9040 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9044 freeAsmop(left,NULL,ic,FALSE);
9045 freeAsmop(result,NULL,ic,TRUE);
9050 /*-----------------------------------------------------------------*/
9051 /* genFarFarAssign - assignment when both are in far space */
9052 /*-----------------------------------------------------------------*/
9053 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9055 int size = AOP_SIZE(right);
9058 /* first push the right side on to the stack */
9060 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9062 pic14_emitcode ("push","acc");
9065 freeAsmop(right,NULL,ic,FALSE);
9066 /* now assign DPTR to result */
9067 aopOp(result,ic,FALSE);
9068 size = AOP_SIZE(result);
9070 pic14_emitcode ("pop","acc");
9071 aopPut(AOP(result),"a",--offset);
9073 freeAsmop(result,NULL,ic,FALSE);
9078 /*-----------------------------------------------------------------*/
9079 /* genAssign - generate code for assignment */
9080 /*-----------------------------------------------------------------*/
9081 static void genAssign (iCode *ic)
9083 operand *result, *right;
9084 int size, offset,know_W;
9085 unsigned long lit = 0L;
9087 result = IC_RESULT(ic);
9088 right = IC_RIGHT(ic) ;
9090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9092 /* if they are the same */
9093 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9096 aopOp(right,ic,FALSE);
9097 aopOp(result,ic,TRUE);
9099 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9101 /* if they are the same registers */
9102 if (pic14_sameRegs(AOP(right),AOP(result)))
9105 /* if the result is a bit */
9106 if (AOP_TYPE(result) == AOP_CRY) {
9108 /* if the right size is a literal then
9109 we know what the value is */
9110 if (AOP_TYPE(right) == AOP_LIT) {
9112 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9113 popGet(AOP(result),0));
9115 if (((int) operandLitValue(right)))
9116 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9117 AOP(result)->aopu.aop_dir,
9118 AOP(result)->aopu.aop_dir);
9120 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9121 AOP(result)->aopu.aop_dir,
9122 AOP(result)->aopu.aop_dir);
9126 /* the right is also a bit variable */
9127 if (AOP_TYPE(right) == AOP_CRY) {
9128 emitpcode(POC_BCF, popGet(AOP(result),0));
9129 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9130 emitpcode(POC_BSF, popGet(AOP(result),0));
9132 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9133 AOP(result)->aopu.aop_dir,
9134 AOP(result)->aopu.aop_dir);
9135 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9136 AOP(right)->aopu.aop_dir,
9137 AOP(right)->aopu.aop_dir);
9138 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9139 AOP(result)->aopu.aop_dir,
9140 AOP(result)->aopu.aop_dir);
9145 emitpcode(POC_BCF, popGet(AOP(result),0));
9146 pic14_toBoolean(right);
9148 emitpcode(POC_BSF, popGet(AOP(result),0));
9149 //aopPut(AOP(result),"a",0);
9153 /* bit variables done */
9155 size = AOP_SIZE(result);
9157 if(AOP_TYPE(right) == AOP_LIT)
9158 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9160 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9162 if(aopIdx(AOP(result),0) == 4) {
9163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9164 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9165 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9168 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9174 if(AOP_TYPE(right) == AOP_LIT) {
9176 if(know_W != (lit&0xff))
9177 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9179 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9181 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9185 } else if (AOP_TYPE(right) == AOP_CRY) {
9186 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9188 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9189 emitpcode(POC_INCF, popGet(AOP(result),0));
9192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9193 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9194 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9202 freeAsmop (right,NULL,ic,FALSE);
9203 freeAsmop (result,NULL,ic,TRUE);
9206 /*-----------------------------------------------------------------*/
9207 /* genJumpTab - genrates code for jump table */
9208 /*-----------------------------------------------------------------*/
9209 static void genJumpTab (iCode *ic)
9214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9216 aopOp(IC_JTCOND(ic),ic,FALSE);
9217 /* get the condition into accumulator */
9218 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9220 /* multiply by three */
9221 pic14_emitcode("add","a,acc");
9222 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9224 jtab = newiTempLabel(NULL);
9225 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9226 pic14_emitcode("jmp","@a+dptr");
9227 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9229 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9230 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9232 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9233 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9234 emitpLabel(jtab->key);
9236 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9238 /* now generate the jump labels */
9239 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9240 jtab = setNextItem(IC_JTLABELS(ic))) {
9241 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9242 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9248 /*-----------------------------------------------------------------*/
9249 /* genMixedOperation - gen code for operators between mixed types */
9250 /*-----------------------------------------------------------------*/
9252 TSD - Written for the PIC port - but this unfortunately is buggy.
9253 This routine is good in that it is able to efficiently promote
9254 types to different (larger) sizes. Unfortunately, the temporary
9255 variables that are optimized out by this routine are sometimes
9256 used in other places. So until I know how to really parse the
9257 iCode tree, I'm going to not be using this routine :(.
9259 static int genMixedOperation (iCode *ic)
9262 operand *result = IC_RESULT(ic);
9263 sym_link *ctype = operandType(IC_LEFT(ic));
9264 operand *right = IC_RIGHT(ic);
9270 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9272 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9278 nextright = IC_RIGHT(nextic);
9279 nextleft = IC_LEFT(nextic);
9280 nextresult = IC_RESULT(nextic);
9282 aopOp(right,ic,FALSE);
9283 aopOp(result,ic,FALSE);
9284 aopOp(nextright, nextic, FALSE);
9285 aopOp(nextleft, nextic, FALSE);
9286 aopOp(nextresult, nextic, FALSE);
9288 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9294 pic14_emitcode(";remove right +","");
9296 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9302 pic14_emitcode(";remove left +","");
9306 big = AOP_SIZE(nextleft);
9307 small = AOP_SIZE(nextright);
9309 switch(nextic->op) {
9312 pic14_emitcode(";optimize a +","");
9313 /* if unsigned or not an integral type */
9314 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9315 pic14_emitcode(";add a bit to something","");
9318 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9320 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9321 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9322 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9324 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9332 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9333 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9334 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9337 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9339 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9340 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9341 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9342 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9343 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9346 pic14_emitcode("rlf","known_zero,w");
9353 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9354 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9355 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9357 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9367 freeAsmop(right,NULL,ic,TRUE);
9368 freeAsmop(result,NULL,ic,TRUE);
9369 freeAsmop(nextright,NULL,ic,TRUE);
9370 freeAsmop(nextleft,NULL,ic,TRUE);
9372 nextic->generated = 1;
9379 /*-----------------------------------------------------------------*/
9380 /* genCast - gen code for casting */
9381 /*-----------------------------------------------------------------*/
9382 static void genCast (iCode *ic)
9384 operand *result = IC_RESULT(ic);
9385 sym_link *ctype = operandType(IC_LEFT(ic));
9386 sym_link *rtype = operandType(IC_RIGHT(ic));
9387 operand *right = IC_RIGHT(ic);
9390 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9391 /* if they are equivalent then do nothing */
9392 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9395 aopOp(right,ic,FALSE) ;
9396 aopOp(result,ic,FALSE);
9398 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9400 /* if the result is a bit */
9401 if (AOP_TYPE(result) == AOP_CRY) {
9402 /* if the right size is a literal then
9403 we know what the value is */
9404 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9405 if (AOP_TYPE(right) == AOP_LIT) {
9407 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9408 popGet(AOP(result),0));
9410 if (((int) operandLitValue(right)))
9411 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9412 AOP(result)->aopu.aop_dir,
9413 AOP(result)->aopu.aop_dir);
9415 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9416 AOP(result)->aopu.aop_dir,
9417 AOP(result)->aopu.aop_dir);
9422 /* the right is also a bit variable */
9423 if (AOP_TYPE(right) == AOP_CRY) {
9426 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9428 pic14_emitcode("clrc","");
9429 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9430 AOP(right)->aopu.aop_dir,
9431 AOP(right)->aopu.aop_dir);
9432 aopPut(AOP(result),"c",0);
9437 if (AOP_TYPE(right) == AOP_REG) {
9438 emitpcode(POC_BCF, popGet(AOP(result),0));
9439 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9440 emitpcode(POC_BSF, popGet(AOP(result),0));
9442 pic14_toBoolean(right);
9443 aopPut(AOP(result),"a",0);
9447 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9449 size = AOP_SIZE(result);
9451 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9453 emitpcode(POC_CLRF, popGet(AOP(result),0));
9454 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9455 emitpcode(POC_INCF, popGet(AOP(result),0));
9458 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9463 /* if they are the same size : or less */
9464 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9466 /* if they are in the same place */
9467 if (pic14_sameRegs(AOP(right),AOP(result)))
9470 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9471 if (IS_PTR_CONST(rtype))
9472 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9473 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9474 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9476 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9477 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9478 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9479 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9480 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9481 if(AOP_SIZE(result) <2)
9482 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9486 /* if they in different places then copy */
9487 size = AOP_SIZE(result);
9490 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9491 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9493 //aopPut(AOP(result),
9494 // aopGet(AOP(right),offset,FALSE,FALSE),
9504 /* if the result is of type pointer */
9505 if (IS_PTR(ctype)) {
9508 sym_link *type = operandType(right);
9509 sym_link *etype = getSpec(type);
9510 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9512 /* pointer to generic pointer */
9513 if (IS_GENPTR(ctype)) {
9517 p_type = DCL_TYPE(type);
9519 /* we have to go by the storage class */
9520 p_type = PTR_TYPE(SPEC_OCLS(etype));
9522 /* if (SPEC_OCLS(etype)->codesp ) */
9523 /* p_type = CPOINTER ; */
9525 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9526 /* p_type = FPOINTER ; */
9528 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9529 /* p_type = PPOINTER; */
9531 /* if (SPEC_OCLS(etype) == idata ) */
9532 /* p_type = IPOINTER ; */
9534 /* p_type = POINTER ; */
9537 /* the first two bytes are known */
9538 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9539 size = GPTRSIZE - 1;
9542 if(offset < AOP_SIZE(right)) {
9543 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9544 if ((AOP_TYPE(right) == AOP_PCODE) &&
9545 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9546 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9547 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9550 aopGet(AOP(right),offset,FALSE,FALSE),
9554 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9557 /* the last byte depending on type */
9561 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9564 pic14_emitcode(";BUG!? ","%d",__LINE__);
9568 pic14_emitcode(";BUG!? ","%d",__LINE__);
9572 pic14_emitcode(";BUG!? ","%d",__LINE__);
9577 /* this should never happen */
9578 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9579 "got unknown pointer type");
9582 //aopPut(AOP(result),l, GPTRSIZE - 1);
9586 /* just copy the pointers */
9587 size = AOP_SIZE(result);
9591 aopGet(AOP(right),offset,FALSE,FALSE),
9600 /* so we now know that the size of destination is greater
9601 than the size of the source.
9602 Now, if the next iCode is an operator then we might be
9603 able to optimize the operation without performing a cast.
9605 if(genMixedOperation(ic))
9608 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9610 /* we move to result for the size of source */
9611 size = AOP_SIZE(right);
9614 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9615 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9619 /* now depending on the sign of the destination */
9620 size = AOP_SIZE(result) - AOP_SIZE(right);
9621 /* if unsigned or not an integral type */
9622 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9624 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9626 /* we need to extend the sign :{ */
9629 /* Save one instruction of casting char to int */
9630 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9631 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9632 emitpcode(POC_DECF, popGet(AOP(result),offset));
9634 emitpcodeNULLop(POC_CLRW);
9637 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9639 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9641 emitpcode(POC_MOVLW, popGetLit(0xff));
9644 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9649 freeAsmop(right,NULL,ic,TRUE);
9650 freeAsmop(result,NULL,ic,TRUE);
9654 /*-----------------------------------------------------------------*/
9655 /* genDjnz - generate decrement & jump if not zero instrucion */
9656 /*-----------------------------------------------------------------*/
9657 static int genDjnz (iCode *ic, iCode *ifx)
9660 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9665 /* if the if condition has a false label
9666 then we cannot save */
9670 /* if the minus is not of the form
9672 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9673 !IS_OP_LITERAL(IC_RIGHT(ic)))
9676 if (operandLitValue(IC_RIGHT(ic)) != 1)
9679 /* if the size of this greater than one then no
9681 if (getSize(operandType(IC_RESULT(ic))) > 1)
9684 /* otherwise we can save BIG */
9685 lbl = newiTempLabel(NULL);
9686 lbl1= newiTempLabel(NULL);
9688 aopOp(IC_RESULT(ic),ic,FALSE);
9690 if (IS_AOP_PREG(IC_RESULT(ic))) {
9691 pic14_emitcode("dec","%s",
9692 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9693 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9694 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9698 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9699 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9701 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9702 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9705 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9706 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9707 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9708 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9711 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9716 /*-----------------------------------------------------------------*/
9717 /* genReceive - generate code for a receive iCode */
9718 /*-----------------------------------------------------------------*/
9719 static void genReceive (iCode *ic)
9721 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9723 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9724 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9725 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9727 int size = getSize(operandType(IC_RESULT(ic)));
9728 int offset = fReturnSizePic - size;
9730 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9731 fReturn[fReturnSizePic - offset - 1] : "acc"));
9734 aopOp(IC_RESULT(ic),ic,FALSE);
9735 size = AOP_SIZE(IC_RESULT(ic));
9738 pic14_emitcode ("pop","acc");
9739 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9744 aopOp(IC_RESULT(ic),ic,FALSE);
9746 assignResultValue(IC_RESULT(ic));
9749 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9752 /*-----------------------------------------------------------------*/
9753 /* genpic14Code - generate code for pic14 based controllers */
9754 /*-----------------------------------------------------------------*/
9756 * At this point, ralloc.c has gone through the iCode and attempted
9757 * to optimize in a way suitable for a PIC. Now we've got to generate
9758 * PIC instructions that correspond to the iCode.
9760 * Once the instructions are generated, we'll pass through both the
9761 * peep hole optimizer and the pCode optimizer.
9762 *-----------------------------------------------------------------*/
9764 void genpic14Code (iCode *lic)
9769 lineHead = lineCurr = NULL;
9771 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9774 /* if debug information required */
9775 if (options.debug && currFunc) {
9777 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9779 if (IS_STATIC(currFunc->etype)) {
9780 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9781 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9783 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9784 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9791 for (ic = lic ; ic ; ic = ic->next ) {
9793 DEBUGpic14_emitcode(";ic","");
9794 if ( cln != ic->lineno ) {
9795 if ( options.debug ) {
9797 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9798 FileBaseName(ic->filename),ic->lineno,
9799 ic->level,ic->block);
9803 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9804 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9805 printCLine(ic->filename, ic->lineno));
9808 newpCodeCSource(ic->lineno,
9810 printCLine(ic->filename, ic->lineno)));
9814 /* if the result is marked as
9815 spilt and rematerializable or code for
9816 this has already been generated then
9818 if (resultRemat(ic) || ic->generated )
9821 /* depending on the operation */
9840 /* IPOP happens only when trying to restore a
9841 spilt live range, if there is an ifx statement
9842 following this pop then the if statement might
9843 be using some of the registers being popped which
9844 would destory the contents of the register so
9845 we need to check for this condition and handle it */
9847 ic->next->op == IFX &&
9848 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9849 genIfx (ic->next,ic);
9867 genEndFunction (ic);
9887 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9904 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9908 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9915 /* note these two are xlated by algebraic equivalence
9916 during parsing SDCC.y */
9917 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9918 "got '>=' or '<=' shouldn't have come here");
9922 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9934 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9938 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9942 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9969 case GET_VALUE_AT_ADDRESS:
9974 if (POINTER_SET(ic))
10001 addSet(&_G.sendSet,ic);
10010 /* now we are ready to call the
10011 peep hole optimizer */
10012 if (!options.nopeep) {
10013 peepHole (&lineHead);
10015 /* now do the actual printing */
10016 printLine (lineHead,codeOutFile);
10019 DFPRINTF((stderr,"printing pBlock\n\n"));
10020 printpBlock(stdout,pb);