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 *);
66 pCode *AssembleLine(char *line);
67 extern void printpBlock(FILE *of, pBlock *pb);
69 static int labelOffset=0;
70 extern int debug_verbose;
71 static int optimized_for_speed = 0;
73 /* max_key keeps track of the largest label number used in
74 a function. This is then used to adjust the label offset
75 for the next function.
78 static int GpsuedoStkPtr=0;
80 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
81 unsigned int pic14aopLiteral (value *val, int offset);
82 const char *AopType(short type);
83 static iCode *ifxForOp ( operand *op, iCode *ic );
85 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
87 /* this is the down and dirty file with all kinds of
88 kludgy & hacky stuff. This is what it is all about
89 CODE GENERATION for a specific MCU . some of the
90 routines may be reusable, will have to see */
92 static char *zero = "#0x00";
93 static char *one = "#0x01";
94 static char *spname = "sp";
96 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
97 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
98 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
99 static char **fReturn = fReturnpic14;
101 static char *accUse[] = {"a","b"};
103 //static short rbank = -1;
115 /* Resolved ifx structure. This structure stores information
116 about an iCode ifx that makes it easier to generate code.
118 typedef struct resolvedIfx {
119 symbol *lbl; /* pointer to a label */
120 int condition; /* true or false ifx */
121 int generated; /* set true when the code associated with the ifx
125 extern int pic14_ptrRegReq ;
126 extern int pic14_nRegs;
127 extern FILE *codeOutFile;
128 static void saverbank (int, iCode *,bool);
130 static lineNode *lineHead = NULL;
131 static lineNode *lineCurr = NULL;
133 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
134 0xE0, 0xC0, 0x80, 0x00};
135 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
136 0x07, 0x03, 0x01, 0x00};
140 /*-----------------------------------------------------------------*/
141 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
142 /* exponent of 2 is returned, otherwise -1 is */
144 /* note that this is similar to the function `powof2' in SDCCsymt */
148 /*-----------------------------------------------------------------*/
149 static int my_powof2 (unsigned long num)
152 if( (num & (num-1)) == 0) {
165 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
168 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
170 ((result) ? AopType(AOP_TYPE(result)) : "-"),
171 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
172 ((left) ? AopType(AOP_TYPE(left)) : "-"),
173 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
174 ((right) ? AopType(AOP_TYPE(right)) : "-"),
175 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
176 ((result) ? AOP_SIZE(result) : 0));
180 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
183 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
185 ((result) ? AopType(AOP_TYPE(result)) : "-"),
186 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
187 ((left) ? AopType(AOP_TYPE(left)) : "-"),
188 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
189 ((right) ? AopType(AOP_TYPE(right)) : "-"),
190 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
194 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
197 char lb[INITIAL_INLINEASM];
207 sprintf(lb,"%s\t",inst);
209 sprintf(lb,"%s",inst);
210 vsprintf(lb+(strlen(lb)),fmt,ap);
214 while (isspace(*lbp)) lbp++;
217 lineCurr = (lineCurr ?
218 connectLine(lineCurr,newLineNode(lb)) :
219 (lineHead = newLineNode(lb)));
220 lineCurr->isInline = _G.inLine;
221 lineCurr->isDebug = _G.debugLine;
223 addpCode2pBlock(pb,newpCodeCharP(lb));
229 void emitpLabel(int key)
231 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
234 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
238 addpCode2pBlock(pb,newpCode(poc,pcop));
240 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
243 void emitpcodeNULLop(PIC_OPCODE poc)
246 addpCode2pBlock(pb,newpCode(poc,NULL));
250 /*-----------------------------------------------------------------*/
251 /* pic14_emitcode - writes the code into a file : for now it is simple */
252 /*-----------------------------------------------------------------*/
253 void pic14_emitcode (char *inst,char *fmt, ...)
256 char lb[INITIAL_INLINEASM];
263 sprintf(lb,"%s\t",inst);
265 sprintf(lb,"%s",inst);
266 vsprintf(lb+(strlen(lb)),fmt,ap);
270 while (isspace(*lbp)) lbp++;
273 lineCurr = (lineCurr ?
274 connectLine(lineCurr,newLineNode(lb)) :
275 (lineHead = newLineNode(lb)));
276 lineCurr->isInline = _G.inLine;
277 lineCurr->isDebug = _G.debugLine;
280 addpCode2pBlock(pb,newpCodeCharP(lb));
286 /*-----------------------------------------------------------------*/
287 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
288 /*-----------------------------------------------------------------*/
289 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
291 bool r0iu = FALSE , r1iu = FALSE;
292 bool r0ou = FALSE , r1ou = FALSE;
294 /* the logic: if r0 & r1 used in the instruction
295 then we are in trouble otherwise */
297 /* first check if r0 & r1 are used by this
298 instruction, in which case we are in trouble */
299 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
305 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
308 /* if no usage of r0 then return it */
309 if (!r0iu && !r0ou) {
310 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311 (*aopp)->type = AOP_R0;
313 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
316 /* if no usage of r1 then return it */
317 if (!r1iu && !r1ou) {
318 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319 (*aopp)->type = AOP_R1;
321 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
324 /* now we know they both have usage */
325 /* if r0 not used in this instruction */
327 /* push it if not already pushed */
329 //pic14_emitcode ("push","%s",
330 // pic14_regWithIdx(R0_IDX)->dname);
334 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335 (*aopp)->type = AOP_R0;
337 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
340 /* if r1 not used then */
343 /* push it if not already pushed */
345 //pic14_emitcode ("push","%s",
346 // pic14_regWithIdx(R1_IDX)->dname);
350 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351 (*aopp)->type = AOP_R1;
352 return pic14_regWithIdx(R1_IDX);
356 /* I said end of world but not quite end of world yet */
357 /* if this is a result then we can push it on the stack*/
359 (*aopp)->type = AOP_STK;
363 /* other wise this is true end of the world */
364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365 "getFreePtr should never reach here");
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp */
371 /*-----------------------------------------------------------------*/
372 asmop *newAsmop (short type)
376 aop = Safe_calloc(1,sizeof(asmop));
381 static void genSetDPTR(int n)
385 pic14_emitcode(";", "Select standard DPTR");
386 pic14_emitcode("mov", "dps, #0x00");
390 pic14_emitcode(";", "Select alternate DPTR");
391 pic14_emitcode("mov", "dps, #0x01");
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for */
397 /* generating code */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
404 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
406 resIfx->condition = 1; /* assume that the ifx is true */
407 resIfx->generated = 0; /* indicate that the ifx has not been used */
410 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
412 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
413 __FUNCTION__,__LINE__,resIfx->lbl->key);
417 resIfx->lbl = IC_TRUE(ifx);
419 resIfx->lbl = IC_FALSE(ifx);
420 resIfx->condition = 0;
424 DEBUGpic14_emitcode("; ***","ifx true is non-null");
426 DEBUGpic14_emitcode("; ***","ifx false is non-null");
430 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
439 return PTR_TYPE(SPEC_OCLS(etype));
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
449 memmap *space= SPEC_OCLS(sym->etype);
451 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452 /* if already has one */
456 /* assign depending on the storage class */
457 /* if it is on the stack or indirectly addressable */
458 /* space we need to assign either r0 or r1 to it */
459 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
460 sym->aop = aop = newAsmop(0);
461 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
462 aop->size = getSize(sym->type);
464 /* now assign the address of the variable to
465 the pointer register */
466 if (aop->type != AOP_STK) {
470 pic14_emitcode("push","acc");
472 pic14_emitcode("mov","a,_bp");
473 pic14_emitcode("add","a,#0x%02x",
475 ((char)(sym->stack - _G.nRegsSaved )) :
476 ((char)sym->stack)) & 0xff);
477 pic14_emitcode("mov","%s,a",
478 aop->aopu.aop_ptr->name);
481 pic14_emitcode("pop","acc");
483 pic14_emitcode("mov","%s,#%s",
484 aop->aopu.aop_ptr->name,
486 aop->paged = space->paged;
488 aop->aopu.aop_stk = sym->stack;
492 if (sym->onStack && options.stack10bit)
494 /* It's on the 10 bit stack, which is located in
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
501 pic14_emitcode("push","acc");
503 pic14_emitcode("mov","a,_bp");
504 pic14_emitcode("add","a,#0x%02x",
506 ((char)(sym->stack - _G.nRegsSaved )) :
507 ((char)sym->stack)) & 0xff);
510 pic14_emitcode ("mov","dpx1,#0x40");
511 pic14_emitcode ("mov","dph1,#0x00");
512 pic14_emitcode ("mov","dpl1, a");
516 pic14_emitcode("pop","acc");
518 sym->aop = aop = newAsmop(AOP_DPTR2);
519 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d",__LINE__);
524 /* if in bit space */
525 if (IN_BITSPACE(space)) {
526 sym->aop = aop = newAsmop (AOP_CRY);
527 aop->aopu.aop_dir = sym->rname ;
528 aop->size = getSize(sym->type);
529 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
532 /* if it is in direct space */
533 if (IN_DIRSPACE(space)) {
534 sym->aop = aop = newAsmop (AOP_DIR);
535 aop->aopu.aop_dir = sym->rname ;
536 aop->size = getSize(sym->type);
537 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
541 /* special case for a function */
542 if (IS_FUNC(sym->type)) {
543 sym->aop = aop = newAsmop(AOP_IMMD);
544 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
545 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
546 strcpy(aop->aopu.aop_immd,sym->rname);
547 aop->size = FPTRSIZE;
548 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
553 /* only remaining is far space */
554 /* in which case DPTR gets the address */
555 sym->aop = aop = newAsmop(AOP_PCODE);
557 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
558 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
559 PCOI(aop->aopu.pcop)->index = 0;
561 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
562 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
564 allocDirReg (IC_LEFT(ic));
566 aop->size = FPTRSIZE;
568 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
569 sym->aop = aop = newAsmop(AOP_DPTR);
570 pic14_emitcode ("mov","dptr,#%s", sym->rname);
571 aop->size = getSize(sym->type);
573 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
576 /* if it is in code space */
577 if (IN_CODESPACE(space))
583 /*-----------------------------------------------------------------*/
584 /* aopForRemat - rematerialzes an object */
585 /*-----------------------------------------------------------------*/
586 static asmop *aopForRemat (operand *op) // x symbol *sym)
588 symbol *sym = OP_SYMBOL(op);
590 asmop *aop = newAsmop(AOP_PCODE);
594 ic = sym->rematiCode;
596 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
597 if(IS_OP_POINTER(op)) {
598 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
602 val += (int) operandLitValue(IC_RIGHT(ic));
603 } else if (ic->op == '-') {
604 val -= (int) operandLitValue(IC_RIGHT(ic));
608 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
611 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
612 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
613 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
614 PCOI(aop->aopu.pcop)->index = val;
616 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
617 OP_SYMBOL(IC_LEFT(ic))->rname,
618 val, IS_PTR_CONST(operandType(op)));
620 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
622 allocDirReg (IC_LEFT(ic));
627 int aopIdx (asmop *aop, int offset)
632 if(aop->type != AOP_REG)
635 return aop->aopu.aop_reg[offset]->rIdx;
638 /*-----------------------------------------------------------------*/
639 /* regsInCommon - two operands have some registers in common */
640 /*-----------------------------------------------------------------*/
641 static bool regsInCommon (operand *op1, operand *op2)
646 /* if they have registers in common */
647 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
650 sym1 = OP_SYMBOL(op1);
651 sym2 = OP_SYMBOL(op2);
653 if (sym1->nRegs == 0 || sym2->nRegs == 0)
656 for (i = 0 ; i < sym1->nRegs ; i++) {
661 for (j = 0 ; j < sym2->nRegs ;j++ ) {
665 if (sym2->regs[j] == sym1->regs[i])
673 /*-----------------------------------------------------------------*/
674 /* operandsEqu - equivalent */
675 /*-----------------------------------------------------------------*/
676 static bool operandsEqu ( operand *op1, operand *op2)
680 /* if they not symbols */
681 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
684 sym1 = OP_SYMBOL(op1);
685 sym2 = OP_SYMBOL(op2);
687 /* if both are itemps & one is spilt
688 and the other is not then false */
689 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
690 sym1->isspilt != sym2->isspilt )
693 /* if they are the same */
697 if (strcmp(sym1->rname,sym2->rname) == 0)
701 /* if left is a tmp & right is not */
705 (sym1->usl.spillLoc == sym2))
712 (sym2->usl.spillLoc == sym1))
718 /*-----------------------------------------------------------------*/
719 /* pic14_sameRegs - two asmops have the same registers */
720 /*-----------------------------------------------------------------*/
721 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
728 if (aop1->type != AOP_REG ||
729 aop2->type != AOP_REG )
732 if (aop1->size != aop2->size )
735 for (i = 0 ; i < aop1->size ; i++ )
736 if (aop1->aopu.aop_reg[i] !=
737 aop2->aopu.aop_reg[i] )
743 /*-----------------------------------------------------------------*/
744 /* aopOp - allocates an asmop for an operand : */
745 /*-----------------------------------------------------------------*/
746 void aopOp (operand *op, iCode *ic, bool result)
755 // DEBUGpic14_emitcode(";","%d",__LINE__);
756 /* if this a literal */
757 if (IS_OP_LITERAL(op)) {
758 op->aop = aop = newAsmop(AOP_LIT);
759 aop->aopu.aop_lit = op->operand.valOperand;
760 aop->size = getSize(operandType(op));
765 sym_link *type = operandType(op);
766 if(IS_PTR_CONST(type))
767 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
770 /* if already has a asmop then continue */
774 /* if the underlying symbol has a aop */
775 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
776 DEBUGpic14_emitcode(";","%d",__LINE__);
777 op->aop = OP_SYMBOL(op)->aop;
781 /* if this is a true symbol */
782 if (IS_TRUE_SYMOP(op)) {
783 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
784 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
788 /* this is a temporary : this has
794 e) can be a return use only */
799 /* if the type is a conditional */
800 if (sym->regType == REG_CND) {
801 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
806 /* if it is spilt then two situations
808 b) has a spill location */
809 if (sym->isspilt || sym->nRegs == 0) {
811 DEBUGpic14_emitcode(";","%d",__LINE__);
812 /* rematerialize it NOW */
815 sym->aop = op->aop = aop =
817 aop->size = getSize(sym->type);
818 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
824 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825 aop->size = getSize(sym->type);
826 for ( i = 0 ; i < 2 ; i++ )
827 aop->aopu.aop_str[i] = accUse[i];
828 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
834 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
835 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
836 //allocDirReg (IC_LEFT(ic));
837 aop->size = getSize(sym->type);
842 aop = op->aop = sym->aop = newAsmop(AOP_STR);
843 aop->size = getSize(sym->type);
844 for ( i = 0 ; i < fReturnSizePic ; i++ )
845 aop->aopu.aop_str[i] = fReturn[i];
847 DEBUGpic14_emitcode(";","%d",__LINE__);
851 /* else spill location */
852 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
853 /* force a new aop if sizes differ */
854 sym->usl.spillLoc->aop = NULL;
856 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
857 __FUNCTION__,__LINE__,
858 sym->usl.spillLoc->rname,
859 sym->rname, sym->usl.spillLoc->offset);
861 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
862 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
863 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
865 sym->usl.spillLoc->offset);
866 aop->size = getSize(sym->type);
872 sym_link *type = operandType(op);
873 if(IS_PTR_CONST(type))
874 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
877 /* must be in a register */
878 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
879 sym->aop = op->aop = aop = newAsmop(AOP_REG);
880 aop->size = sym->nRegs;
881 for ( i = 0 ; i < sym->nRegs ;i++)
882 aop->aopu.aop_reg[i] = sym->regs[i];
885 /*-----------------------------------------------------------------*/
886 /* freeAsmop - free up the asmop given to an operand */
887 /*----------------------------------------------------------------*/
888 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
905 /* depending on the asmop type only three cases need work AOP_RO
906 , AOP_R1 && AOP_STK */
912 pic14_emitcode ("pop","ar0");
916 bitVectUnSetBit(ic->rUsed,R0_IDX);
922 pic14_emitcode ("pop","ar1");
926 bitVectUnSetBit(ic->rUsed,R1_IDX);
932 int stk = aop->aopu.aop_stk + aop->size;
933 bitVectUnSetBit(ic->rUsed,R0_IDX);
934 bitVectUnSetBit(ic->rUsed,R1_IDX);
936 getFreePtr(ic,&aop,FALSE);
938 if (options.stack10bit)
940 /* I'm not sure what to do here yet... */
943 "*** Warning: probably generating bad code for "
944 "10 bit stack mode.\n");
948 pic14_emitcode ("mov","a,_bp");
949 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
950 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
952 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
956 pic14_emitcode("pop","acc");
957 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
959 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
962 freeAsmop(op,NULL,ic,TRUE);
964 pic14_emitcode("pop","ar0");
969 pic14_emitcode("pop","ar1");
977 /* all other cases just dealloc */
981 OP_SYMBOL(op)->aop = NULL;
982 /* if the symbol has a spill */
984 SPIL_LOC(op)->aop = NULL;
989 /*-----------------------------------------------------------------*/
990 /* aopGet - for fetching value of the aop */
991 /*-----------------------------------------------------------------*/
992 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
997 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
998 /* offset is greater than
1000 if (offset > (aop->size - 1) &&
1001 aop->type != AOP_LIT)
1004 /* depending on type */
1005 switch (aop->type) {
1009 DEBUGpic14_emitcode(";","%d",__LINE__);
1010 /* if we need to increment it */
1011 while (offset > aop->coff) {
1012 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1016 while (offset < aop->coff) {
1017 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1021 aop->coff = offset ;
1023 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1024 return (dname ? "acc" : "a");
1026 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1027 rs = Safe_calloc(1,strlen(s)+1);
1033 DEBUGpic14_emitcode(";","%d",__LINE__);
1034 if (aop->type == AOP_DPTR2)
1039 while (offset > aop->coff) {
1040 pic14_emitcode ("inc","dptr");
1044 while (offset < aop->coff) {
1045 pic14_emitcode("lcall","__decdptr");
1051 pic14_emitcode("clr","a");
1052 pic14_emitcode("movc","a,@a+dptr");
1055 pic14_emitcode("movx","a,@dptr");
1058 if (aop->type == AOP_DPTR2)
1063 return (dname ? "acc" : "a");
1068 sprintf (s,"%s",aop->aopu.aop_immd);
1071 sprintf(s,"(%s >> %d)",
1076 aop->aopu.aop_immd);
1077 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1078 rs = Safe_calloc(1,strlen(s)+1);
1084 sprintf(s,"(%s + %d)",
1087 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1089 sprintf(s,"%s",aop->aopu.aop_dir);
1090 rs = Safe_calloc(1,strlen(s)+1);
1096 // return aop->aopu.aop_reg[offset]->dname;
1098 return aop->aopu.aop_reg[offset]->name;
1101 //pic14_emitcode(";","%d",__LINE__);
1102 return aop->aopu.aop_dir;
1105 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1106 return "AOP_accumulator_bug";
1109 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1110 rs = Safe_calloc(1,strlen(s)+1);
1115 aop->coff = offset ;
1116 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1119 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1121 return aop->aopu.aop_str[offset];
1125 pCodeOp *pcop = aop->aopu.pcop;
1126 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1128 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1129 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1130 sprintf(s,"%s", pcop->name);
1132 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1135 rs = Safe_calloc(1,strlen(s)+1);
1141 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1142 "aopget got unsupported aop->type");
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp */
1149 /*-----------------------------------------------------------------*/
1150 pCodeOp *popGetTempReg(void)
1155 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1156 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1157 PCOR(pcop)->r->wasUsed=1;
1158 PCOR(pcop)->r->isFree=0;
1164 /*-----------------------------------------------------------------*/
1165 /* popGetTempReg - create a new temporary pCodeOp */
1166 /*-----------------------------------------------------------------*/
1167 void popReleaseTempReg(pCodeOp *pcop)
1170 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1171 PCOR(pcop)->r->isFree = 1;
1174 /*-----------------------------------------------------------------*/
1175 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1176 /*-----------------------------------------------------------------*/
1177 pCodeOp *popGetLabel(unsigned int key)
1180 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1185 return newpCodeOpLabel(NULL,key+100+labelOffset);
1188 /*-----------------------------------------------------------------*/
1189 /* popCopyReg - copy a pcode operator */
1190 /*-----------------------------------------------------------------*/
1191 pCodeOp *popCopyReg(pCodeOpReg *pc)
1195 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1196 pcor->pcop.type = pc->pcop.type;
1198 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1199 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1201 pcor->pcop.name = NULL;
1204 pcor->rIdx = pc->rIdx;
1207 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetLit(unsigned int lit)
1217 return newpCodeOpLit(lit);
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1227 return newpCodeOpImmd(name, offset,index, 0);
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str)
1240 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1244 pcop = newpCodeOp(str,PO_STR);
1249 /*-----------------------------------------------------------------*/
1250 /* popRegFromString - */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popRegFromString(char *str, int size, int offset)
1255 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1256 pcop->type = PO_DIR;
1258 DEBUGpic14_emitcode(";","%d",__LINE__);
1263 pcop->name = Safe_calloc(1,strlen(str)+1);
1264 strcpy(pcop->name,str);
1266 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1268 PCOR(pcop)->r = dirregWithName(pcop->name);
1269 if(PCOR(pcop)->r == NULL) {
1270 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1271 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1272 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1274 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1276 PCOR(pcop)->instance = offset;
1281 pCodeOp *popRegFromIdx(int rIdx)
1285 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1286 __FUNCTION__,__LINE__,rIdx);
1288 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1290 PCOR(pcop)->rIdx = rIdx;
1291 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1292 PCOR(pcop)->r->isFree = 0;
1293 PCOR(pcop)->r->wasUsed = 1;
1295 pcop->type = PCOR(pcop)->r->pc_type;
1300 /*-----------------------------------------------------------------*/
1301 /* popGet - asm operator to pcode operator conversion */
1302 /*-----------------------------------------------------------------*/
1303 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1305 //char *s = buffer ;
1310 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1311 /* offset is greater than
1314 if (offset > (aop->size - 1) &&
1315 aop->type != AOP_LIT)
1316 return NULL; //zero;
1318 /* depending on type */
1319 switch (aop->type) {
1326 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1330 DEBUGpic14_emitcode(";","%d",__LINE__);
1331 return popGetImmd(aop->aopu.aop_immd,offset,0);
1334 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1336 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1337 pcop->type = PO_DIR;
1341 sprintf(s,"(%s + %d)",
1345 sprintf(s,"%s",aop->aopu.aop_dir);
1346 pcop->name = Safe_calloc(1,strlen(s)+1);
1347 strcpy(pcop->name,s);
1349 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1350 strcpy(pcop->name,aop->aopu.aop_dir);
1351 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1352 if(PCOR(pcop)->r == NULL) {
1353 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1354 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1355 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1357 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1359 PCOR(pcop)->instance = offset;
1366 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1368 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1369 PCOR(pcop)->rIdx = rIdx;
1370 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1371 PCOR(pcop)->r->wasUsed=1;
1372 PCOR(pcop)->r->isFree=0;
1374 PCOR(pcop)->instance = offset;
1375 pcop->type = PCOR(pcop)->r->pc_type;
1376 //rs = aop->aopu.aop_reg[offset]->name;
1377 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1382 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1383 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1384 //if(PCOR(pcop)->r == NULL)
1385 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1389 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1392 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1393 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1395 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1396 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1397 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1398 pcop->type = PCOR(pcop)->r->pc_type;
1399 pcop->name = PCOR(pcop)->r->name;
1405 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1407 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1408 pcop = pCodeOpCopy(aop->aopu.pcop);
1409 PCOI(pcop)->offset = offset;
1413 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1414 "popGet got unsupported aop->type");
1417 /*-----------------------------------------------------------------*/
1418 /* aopPut - puts a string for a aop */
1419 /*-----------------------------------------------------------------*/
1420 void aopPut (asmop *aop, char *s, int offset)
1425 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1427 if (aop->size && offset > ( aop->size - 1)) {
1428 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1429 "aopPut got offset > aop->size");
1433 /* will assign value to value */
1434 /* depending on where it is ofcourse */
1435 switch (aop->type) {
1438 sprintf(d,"(%s + %d)",
1439 aop->aopu.aop_dir,offset);
1440 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1443 sprintf(d,"%s",aop->aopu.aop_dir);
1446 DEBUGpic14_emitcode(";","%d",__LINE__);
1448 pic14_emitcode("movf","%s,w",s);
1449 pic14_emitcode("movwf","%s",d);
1452 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1453 if(offset >= aop->size) {
1454 emitpcode(POC_CLRF,popGet(aop,offset));
1457 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1460 emitpcode(POC_MOVWF,popGet(aop,offset));
1467 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1468 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1471 strcmp(s,"r0") == 0 ||
1472 strcmp(s,"r1") == 0 ||
1473 strcmp(s,"r2") == 0 ||
1474 strcmp(s,"r3") == 0 ||
1475 strcmp(s,"r4") == 0 ||
1476 strcmp(s,"r5") == 0 ||
1477 strcmp(s,"r6") == 0 ||
1478 strcmp(s,"r7") == 0 )
1479 pic14_emitcode("mov","%s,%s ; %d",
1480 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1484 if(strcmp(s,"W")==0 )
1485 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1487 pic14_emitcode("movwf","%s",
1488 aop->aopu.aop_reg[offset]->name);
1490 if(strcmp(s,zero)==0) {
1491 emitpcode(POC_CLRF,popGet(aop,offset));
1493 } else if(strcmp(s,"W")==0) {
1494 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1495 pcop->type = PO_GPR_REGISTER;
1497 PCOR(pcop)->rIdx = -1;
1498 PCOR(pcop)->r = NULL;
1500 DEBUGpic14_emitcode(";","%d",__LINE__);
1501 pcop->name = Safe_strdup(s);
1502 emitpcode(POC_MOVFW,pcop);
1503 emitpcode(POC_MOVWF,popGet(aop,offset));
1504 } else if(strcmp(s,one)==0) {
1505 emitpcode(POC_CLRF,popGet(aop,offset));
1506 emitpcode(POC_INCF,popGet(aop,offset));
1508 emitpcode(POC_MOVWF,popGet(aop,offset));
1516 if (aop->type == AOP_DPTR2)
1522 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1523 "aopPut writting to code space");
1527 while (offset > aop->coff) {
1529 pic14_emitcode ("inc","dptr");
1532 while (offset < aop->coff) {
1534 pic14_emitcode("lcall","__decdptr");
1539 /* if not in accumulater */
1542 pic14_emitcode ("movx","@dptr,a");
1544 if (aop->type == AOP_DPTR2)
1552 while (offset > aop->coff) {
1554 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1556 while (offset < aop->coff) {
1558 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1564 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1569 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1571 if (strcmp(s,"r0") == 0 ||
1572 strcmp(s,"r1") == 0 ||
1573 strcmp(s,"r2") == 0 ||
1574 strcmp(s,"r3") == 0 ||
1575 strcmp(s,"r4") == 0 ||
1576 strcmp(s,"r5") == 0 ||
1577 strcmp(s,"r6") == 0 ||
1578 strcmp(s,"r7") == 0 ) {
1580 sprintf(buffer,"a%s",s);
1581 pic14_emitcode("mov","@%s,%s",
1582 aop->aopu.aop_ptr->name,buffer);
1584 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1589 if (strcmp(s,"a") == 0)
1590 pic14_emitcode("push","acc");
1592 pic14_emitcode("push","%s",s);
1597 /* if bit variable */
1598 if (!aop->aopu.aop_dir) {
1599 pic14_emitcode("clr","a");
1600 pic14_emitcode("rlc","a");
1603 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1606 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1609 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1611 lbl = newiTempLabel(NULL);
1613 if (strcmp(s,"a")) {
1616 pic14_emitcode("clr","c");
1617 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1618 pic14_emitcode("cpl","c");
1619 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1620 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1627 if (strcmp(aop->aopu.aop_str[offset],s))
1628 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1633 if (!offset && (strcmp(s,"acc") == 0))
1636 if (strcmp(aop->aopu.aop_str[offset],s))
1637 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1641 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1642 "aopPut got unsupported aop->type");
1648 /*-----------------------------------------------------------------*/
1649 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1650 /*-----------------------------------------------------------------*/
1651 void mov2w (asmop *aop, int offset)
1657 if ( aop->type == AOP_PCODE ||
1658 aop->type == AOP_LIT )
1659 emitpcode(POC_MOVLW,popGet(aop,offset));
1661 emitpcode(POC_MOVFW,popGet(aop,offset));
1665 /*-----------------------------------------------------------------*/
1666 /* reAdjustPreg - points a register back to where it should */
1667 /*-----------------------------------------------------------------*/
1668 static void reAdjustPreg (asmop *aop)
1672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1674 if ((size = aop->size) <= 1)
1677 switch (aop->type) {
1681 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1685 if (aop->type == AOP_DPTR2)
1691 pic14_emitcode("lcall","__decdptr");
1694 if (aop->type == AOP_DPTR2)
1704 /*-----------------------------------------------------------------*/
1705 /* genNotFloat - generates not for float operations */
1706 /*-----------------------------------------------------------------*/
1707 static void genNotFloat (operand *op, operand *res)
1713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1714 /* we will put 127 in the first byte of
1716 aopPut(AOP(res),"#127",0);
1717 size = AOP_SIZE(op) - 1;
1720 l = aopGet(op->aop,offset++,FALSE,FALSE);
1724 pic14_emitcode("orl","a,%s",
1726 offset++,FALSE,FALSE));
1728 tlbl = newiTempLabel(NULL);
1730 tlbl = newiTempLabel(NULL);
1731 aopPut(res->aop,one,1);
1732 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1733 aopPut(res->aop,zero,1);
1734 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1736 size = res->aop->size - 2;
1738 /* put zeros in the rest */
1740 aopPut(res->aop,zero,offset++);
1744 /*-----------------------------------------------------------------*/
1745 /* opIsGptr: returns non-zero if the passed operand is */
1746 /* a generic pointer type. */
1747 /*-----------------------------------------------------------------*/
1748 static int opIsGptr(operand *op)
1750 sym_link *type = operandType(op);
1752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1753 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1761 /*-----------------------------------------------------------------*/
1762 /* pic14_getDataSize - get the operand data size */
1763 /*-----------------------------------------------------------------*/
1764 int pic14_getDataSize(operand *op)
1766 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1769 return AOP_SIZE(op);
1771 // tsd- in the pic port, the genptr size is 1, so this code here
1772 // fails. ( in the 8051 port, the size was 4).
1775 size = AOP_SIZE(op);
1776 if (size == GPTRSIZE)
1778 sym_link *type = operandType(op);
1779 if (IS_GENPTR(type))
1781 /* generic pointer; arithmetic operations
1782 * should ignore the high byte (pointer type).
1785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_outAcc - output Acc */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_outAcc(operand *result)
1798 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1799 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1802 size = pic14_getDataSize(result);
1804 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1807 /* unsigned or positive */
1809 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1814 /*-----------------------------------------------------------------*/
1815 /* pic14_outBitC - output a bit C */
1816 /*-----------------------------------------------------------------*/
1817 void pic14_outBitC(operand *result)
1820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1821 /* if the result is bit */
1822 if (AOP_TYPE(result) == AOP_CRY)
1823 aopPut(AOP(result),"c",0);
1825 pic14_emitcode("clr","a ; %d", __LINE__);
1826 pic14_emitcode("rlc","a");
1827 pic14_outAcc(result);
1831 /*-----------------------------------------------------------------*/
1832 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1833 /*-----------------------------------------------------------------*/
1834 void pic14_toBoolean(operand *oper)
1836 int size = AOP_SIZE(oper) - 1;
1839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1841 if ( AOP_TYPE(oper) != AOP_ACC) {
1842 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1845 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1850 /*-----------------------------------------------------------------*/
1851 /* genNot - generate code for ! operation */
1852 /*-----------------------------------------------------------------*/
1853 static void genNot (iCode *ic)
1856 sym_link *optype = operandType(IC_LEFT(ic));
1859 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1860 /* assign asmOps to operand & result */
1861 aopOp (IC_LEFT(ic),ic,FALSE);
1862 aopOp (IC_RESULT(ic),ic,TRUE);
1864 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1865 /* if in bit space then a special case */
1866 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1867 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1868 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1869 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1871 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1872 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1873 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1878 /* if type float then do float */
1879 if (IS_FLOAT(optype)) {
1880 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1884 size = AOP_SIZE(IC_RESULT(ic));
1886 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1887 emitpcode(POC_ANDLW,popGetLit(1));
1888 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1891 pic14_toBoolean(IC_LEFT(ic));
1893 tlbl = newiTempLabel(NULL);
1894 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1895 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1896 pic14_outBitC(IC_RESULT(ic));
1899 /* release the aops */
1900 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1901 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1905 /*-----------------------------------------------------------------*/
1906 /* genCpl - generate code for complement */
1907 /*-----------------------------------------------------------------*/
1908 static void genCpl (iCode *ic)
1914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1915 /* assign asmOps to operand & result */
1916 aopOp (IC_LEFT(ic),ic,FALSE);
1917 aopOp (IC_RESULT(ic),ic,TRUE);
1919 /* if both are in bit space then
1921 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1922 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1924 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1925 pic14_emitcode("cpl","c");
1926 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1930 size = AOP_SIZE(IC_RESULT(ic));
1932 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1934 pic14_emitcode("cpl","a");
1935 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1940 /* release the aops */
1941 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1942 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1945 /*-----------------------------------------------------------------*/
1946 /* genUminusFloat - unary minus for floating points */
1947 /*-----------------------------------------------------------------*/
1948 static void genUminusFloat(operand *op,operand *result)
1950 int size ,offset =0 ;
1953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1954 /* for this we just need to flip the
1955 first it then copy the rest in place */
1956 size = AOP_SIZE(op) - 1;
1957 l = aopGet(AOP(op),3,FALSE,FALSE);
1961 pic14_emitcode("cpl","acc.7");
1962 aopPut(AOP(result),"a",3);
1966 aopGet(AOP(op),offset,FALSE,FALSE),
1972 /*-----------------------------------------------------------------*/
1973 /* genUminus - unary minus code generation */
1974 /*-----------------------------------------------------------------*/
1975 static void genUminus (iCode *ic)
1978 sym_link *optype, *rtype;
1981 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1983 aopOp(IC_LEFT(ic),ic,FALSE);
1984 aopOp(IC_RESULT(ic),ic,TRUE);
1986 /* if both in bit space then special
1988 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1989 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1991 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1992 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1993 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1998 optype = operandType(IC_LEFT(ic));
1999 rtype = operandType(IC_RESULT(ic));
2001 /* if float then do float stuff */
2002 if (IS_FLOAT(optype)) {
2003 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2007 /* otherwise subtract from zero by taking the 2's complement */
2008 size = AOP_SIZE(IC_LEFT(ic));
2010 for(i=0; i<size; i++) {
2011 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2012 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2014 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2015 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2019 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2020 for(i=1; i<size; i++) {
2022 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2026 /* release the aops */
2027 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2028 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2031 /*-----------------------------------------------------------------*/
2032 /* saveRegisters - will look for a call and save the registers */
2033 /*-----------------------------------------------------------------*/
2034 static void saveRegisters(iCode *lic)
2041 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2043 for (ic = lic ; ic ; ic = ic->next)
2044 if (ic->op == CALL || ic->op == PCALL)
2048 fprintf(stderr,"found parameter push with no function call\n");
2052 /* if the registers have been saved already then
2054 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2057 /* find the registers in use at this time
2058 and push them away to safety */
2059 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2063 if (options.useXstack) {
2064 if (bitVectBitValue(rsave,R0_IDX))
2065 pic14_emitcode("mov","b,r0");
2066 pic14_emitcode("mov","r0,%s",spname);
2067 for (i = 0 ; i < pic14_nRegs ; i++) {
2068 if (bitVectBitValue(rsave,i)) {
2070 pic14_emitcode("mov","a,b");
2072 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2073 pic14_emitcode("movx","@r0,a");
2074 pic14_emitcode("inc","r0");
2077 pic14_emitcode("mov","%s,r0",spname);
2078 if (bitVectBitValue(rsave,R0_IDX))
2079 pic14_emitcode("mov","r0,b");
2081 //for (i = 0 ; i < pic14_nRegs ; i++) {
2082 // if (bitVectBitValue(rsave,i))
2083 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2086 dtype = operandType(IC_LEFT(ic));
2087 if (currFunc && dtype &&
2088 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2089 IFFUNC_ISISR(currFunc->type) &&
2092 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2095 /*-----------------------------------------------------------------*/
2096 /* unsaveRegisters - pop the pushed registers */
2097 /*-----------------------------------------------------------------*/
2098 static void unsaveRegisters (iCode *ic)
2103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2104 /* find the registers in use at this time
2105 and push them away to safety */
2106 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2109 if (options.useXstack) {
2110 pic14_emitcode("mov","r0,%s",spname);
2111 for (i = pic14_nRegs ; i >= 0 ; i--) {
2112 if (bitVectBitValue(rsave,i)) {
2113 pic14_emitcode("dec","r0");
2114 pic14_emitcode("movx","a,@r0");
2116 pic14_emitcode("mov","b,a");
2118 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2122 pic14_emitcode("mov","%s,r0",spname);
2123 if (bitVectBitValue(rsave,R0_IDX))
2124 pic14_emitcode("mov","r0,b");
2126 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2127 // if (bitVectBitValue(rsave,i))
2128 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2134 /*-----------------------------------------------------------------*/
2136 /*-----------------------------------------------------------------*/
2137 static void pushSide(operand * oper, int size)
2141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2143 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2144 if (AOP_TYPE(oper) != AOP_REG &&
2145 AOP_TYPE(oper) != AOP_DIR &&
2147 pic14_emitcode("mov","a,%s",l);
2148 pic14_emitcode("push","acc");
2150 pic14_emitcode("push","%s",l);
2155 /*-----------------------------------------------------------------*/
2156 /* assignResultValue - */
2157 /*-----------------------------------------------------------------*/
2158 static void assignResultValue(operand * oper)
2160 int size = AOP_SIZE(oper);
2162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2164 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2166 if(!GpsuedoStkPtr) {
2167 /* The last byte in the assignment is in W */
2169 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2174 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2176 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2181 /*-----------------------------------------------------------------*/
2182 /* genIpush - genrate code for pushing this gets a little complex */
2183 /*-----------------------------------------------------------------*/
2184 static void genIpush (iCode *ic)
2187 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2189 int size, offset = 0 ;
2193 /* if this is not a parm push : ie. it is spill push
2194 and spill push is always done on the local stack */
2195 if (!ic->parmPush) {
2197 /* and the item is spilt then do nothing */
2198 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2201 aopOp(IC_LEFT(ic),ic,FALSE);
2202 size = AOP_SIZE(IC_LEFT(ic));
2203 /* push it on the stack */
2205 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2210 pic14_emitcode("push","%s",l);
2215 /* this is a paramter push: in this case we call
2216 the routine to find the call and save those
2217 registers that need to be saved */
2220 /* then do the push */
2221 aopOp(IC_LEFT(ic),ic,FALSE);
2224 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2225 size = AOP_SIZE(IC_LEFT(ic));
2228 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2229 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2230 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2232 pic14_emitcode("mov","a,%s",l);
2233 pic14_emitcode("push","acc");
2235 pic14_emitcode("push","%s",l);
2238 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2242 /*-----------------------------------------------------------------*/
2243 /* genIpop - recover the registers: can happen only for spilling */
2244 /*-----------------------------------------------------------------*/
2245 static void genIpop (iCode *ic)
2247 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2252 /* if the temp was not pushed then */
2253 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2256 aopOp(IC_LEFT(ic),ic,FALSE);
2257 size = AOP_SIZE(IC_LEFT(ic));
2260 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2263 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2267 /*-----------------------------------------------------------------*/
2268 /* unsaverbank - restores the resgister bank from stack */
2269 /*-----------------------------------------------------------------*/
2270 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2272 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2280 if (options.useXstack) {
2282 r = getFreePtr(ic,&aop,FALSE);
2285 pic14_emitcode("mov","%s,_spx",r->name);
2286 pic14_emitcode("movx","a,@%s",r->name);
2287 pic14_emitcode("mov","psw,a");
2288 pic14_emitcode("dec","%s",r->name);
2291 pic14_emitcode ("pop","psw");
2294 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2295 if (options.useXstack) {
2296 pic14_emitcode("movx","a,@%s",r->name);
2297 //pic14_emitcode("mov","(%s+%d),a",
2298 // regspic14[i].base,8*bank+regspic14[i].offset);
2299 pic14_emitcode("dec","%s",r->name);
2302 pic14_emitcode("pop",""); //"(%s+%d)",
2303 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2306 if (options.useXstack) {
2308 pic14_emitcode("mov","_spx,%s",r->name);
2309 freeAsmop(NULL,aop,ic,TRUE);
2315 /*-----------------------------------------------------------------*/
2316 /* saverbank - saves an entire register bank on the stack */
2317 /*-----------------------------------------------------------------*/
2318 static void saverbank (int bank, iCode *ic, bool pushPsw)
2320 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2326 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2327 if (options.useXstack) {
2330 r = getFreePtr(ic,&aop,FALSE);
2331 pic14_emitcode("mov","%s,_spx",r->name);
2335 for (i = 0 ; i < pic14_nRegs ;i++) {
2336 if (options.useXstack) {
2337 pic14_emitcode("inc","%s",r->name);
2338 //pic14_emitcode("mov","a,(%s+%d)",
2339 // regspic14[i].base,8*bank+regspic14[i].offset);
2340 pic14_emitcode("movx","@%s,a",r->name);
2342 pic14_emitcode("push","");// "(%s+%d)",
2343 //regspic14[i].base,8*bank+regspic14[i].offset);
2347 if (options.useXstack) {
2348 pic14_emitcode("mov","a,psw");
2349 pic14_emitcode("movx","@%s,a",r->name);
2350 pic14_emitcode("inc","%s",r->name);
2351 pic14_emitcode("mov","_spx,%s",r->name);
2352 freeAsmop (NULL,aop,ic,TRUE);
2355 pic14_emitcode("push","psw");
2357 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2363 /*-----------------------------------------------------------------*/
2364 /* genCall - generates a call statement */
2365 /*-----------------------------------------------------------------*/
2366 static void genCall (iCode *ic)
2370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2372 /* if caller saves & we have not saved then */
2376 /* if we are calling a function that is not using
2377 the same register bank then we need to save the
2378 destination registers on the stack */
2379 dtype = operandType(IC_LEFT(ic));
2380 if (currFunc && dtype &&
2381 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2382 IFFUNC_ISISR(currFunc->type) &&
2385 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2387 /* if send set is not empty the assign */
2390 /* For the Pic port, there is no data stack.
2391 * So parameters passed to functions are stored
2392 * in registers. (The pCode optimizer will get
2393 * rid of most of these :).
2395 int psuedoStkPtr=-1;
2396 int firstTimeThruLoop = 1;
2398 _G.sendSet = reverseSet(_G.sendSet);
2400 /* First figure how many parameters are getting passed */
2401 for (sic = setFirstItem(_G.sendSet) ; sic ;
2402 sic = setNextItem(_G.sendSet)) {
2404 aopOp(IC_LEFT(sic),sic,FALSE);
2405 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2406 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2409 for (sic = setFirstItem(_G.sendSet) ; sic ;
2410 sic = setNextItem(_G.sendSet)) {
2411 int size, offset = 0;
2413 aopOp(IC_LEFT(sic),sic,FALSE);
2414 size = AOP_SIZE(IC_LEFT(sic));
2417 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2418 AopType(AOP_TYPE(IC_LEFT(sic))));
2420 if(!firstTimeThruLoop) {
2421 /* If this is not the first time we've been through the loop
2422 * then we need to save the parameter in a temporary
2423 * register. The last byte of the last parameter is
2425 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2428 firstTimeThruLoop=0;
2430 //if (strcmp(l,fReturn[offset])) {
2431 mov2w (AOP(IC_LEFT(sic)), offset);
2433 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2434 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2435 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2437 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2442 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2447 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2448 OP_SYMBOL(IC_LEFT(ic))->rname :
2449 OP_SYMBOL(IC_LEFT(ic))->name));
2452 /* if we need assign a result value */
2453 if ((IS_ITEMP(IC_RESULT(ic)) &&
2454 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2455 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2456 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2459 aopOp(IC_RESULT(ic),ic,FALSE);
2462 assignResultValue(IC_RESULT(ic));
2464 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2465 AopType(AOP_TYPE(IC_RESULT(ic))));
2467 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2470 /* adjust the stack for parameters if
2472 if (ic->parmBytes) {
2474 if (ic->parmBytes > 3) {
2475 pic14_emitcode("mov","a,%s",spname);
2476 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2477 pic14_emitcode("mov","%s,a",spname);
2479 for ( i = 0 ; i < ic->parmBytes ;i++)
2480 pic14_emitcode("dec","%s",spname);
2484 /* if register bank was saved then pop them */
2486 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2488 /* if we hade saved some registers then unsave them */
2489 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2490 unsaveRegisters (ic);
2495 /*-----------------------------------------------------------------*/
2496 /* genPcall - generates a call by pointer statement */
2497 /*-----------------------------------------------------------------*/
2498 static void genPcall (iCode *ic)
2501 symbol *rlbl = newiTempLabel(NULL);
2504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2505 /* if caller saves & we have not saved then */
2509 /* if we are calling a function that is not using
2510 the same register bank then we need to save the
2511 destination registers on the stack */
2512 dtype = operandType(IC_LEFT(ic));
2513 if (currFunc && dtype &&
2514 IFFUNC_ISISR(currFunc->type) &&
2515 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2516 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2519 /* push the return address on to the stack */
2520 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2521 pic14_emitcode("push","acc");
2522 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2523 pic14_emitcode("push","acc");
2525 if (options.model == MODEL_FLAT24)
2527 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2528 pic14_emitcode("push","acc");
2531 /* now push the calling address */
2532 aopOp(IC_LEFT(ic),ic,FALSE);
2534 pushSide(IC_LEFT(ic), FPTRSIZE);
2536 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2538 /* if send set is not empty the assign */
2542 for (sic = setFirstItem(_G.sendSet) ; sic ;
2543 sic = setNextItem(_G.sendSet)) {
2544 int size, offset = 0;
2545 aopOp(IC_LEFT(sic),sic,FALSE);
2546 size = AOP_SIZE(IC_LEFT(sic));
2548 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2550 if (strcmp(l,fReturn[offset]))
2551 pic14_emitcode("mov","%s,%s",
2556 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2561 pic14_emitcode("ret","");
2562 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2565 /* if we need assign a result value */
2566 if ((IS_ITEMP(IC_RESULT(ic)) &&
2567 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2568 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2569 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2572 aopOp(IC_RESULT(ic),ic,FALSE);
2575 assignResultValue(IC_RESULT(ic));
2577 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2580 /* adjust the stack for parameters if
2582 if (ic->parmBytes) {
2584 if (ic->parmBytes > 3) {
2585 pic14_emitcode("mov","a,%s",spname);
2586 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2587 pic14_emitcode("mov","%s,a",spname);
2589 for ( i = 0 ; i < ic->parmBytes ;i++)
2590 pic14_emitcode("dec","%s",spname);
2594 /* if register bank was saved then unsave them */
2595 if (currFunc && dtype &&
2596 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2597 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2599 /* if we hade saved some registers then
2602 unsaveRegisters (ic);
2606 /*-----------------------------------------------------------------*/
2607 /* resultRemat - result is rematerializable */
2608 /*-----------------------------------------------------------------*/
2609 static int resultRemat (iCode *ic)
2611 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2612 if (SKIP_IC(ic) || ic->op == IFX)
2615 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2616 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2617 if (sym->remat && !POINTER_SET(ic))
2624 #if defined(__BORLANDC__) || defined(_MSC_VER)
2625 #define STRCASECMP stricmp
2627 #define STRCASECMP strcasecmp
2631 /*-----------------------------------------------------------------*/
2632 /* inExcludeList - return 1 if the string is in exclude Reg list */
2633 /*-----------------------------------------------------------------*/
2634 static bool inExcludeList(char *s)
2636 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2640 if (options.excludeRegs[i] &&
2641 STRCASECMP(options.excludeRegs[i],"none") == 0)
2644 for ( i = 0 ; options.excludeRegs[i]; i++) {
2645 if (options.excludeRegs[i] &&
2646 STRCASECMP(s,options.excludeRegs[i]) == 0)
2653 /*-----------------------------------------------------------------*/
2654 /* genFunction - generated code for function entry */
2655 /*-----------------------------------------------------------------*/
2656 static void genFunction (iCode *ic)
2661 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2663 labelOffset += (max_key+4);
2667 /* create the function header */
2668 pic14_emitcode(";","-----------------------------------------");
2669 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2670 pic14_emitcode(";","-----------------------------------------");
2672 pic14_emitcode("","%s:",sym->rname);
2673 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2675 ftype = operandType(IC_LEFT(ic));
2677 /* if critical function then turn interrupts off */
2678 if (IFFUNC_ISCRITICAL(ftype))
2679 pic14_emitcode("clr","ea");
2681 /* here we need to generate the equates for the
2682 register bank if required */
2684 if (FUNC_REGBANK(ftype) != rbank) {
2687 rbank = FUNC_REGBANK(ftype);
2688 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2689 if (strcmp(regspic14[i].base,"0") == 0)
2690 pic14_emitcode("","%s = 0x%02x",
2692 8*rbank+regspic14[i].offset);
2694 pic14_emitcode ("","%s = %s + 0x%02x",
2697 8*rbank+regspic14[i].offset);
2702 /* if this is an interrupt service routine then
2703 save acc, b, dpl, dph */
2704 if (IFFUNC_ISISR(sym->type)) {
2705 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2706 emitpcodeNULLop(POC_NOP);
2707 emitpcodeNULLop(POC_NOP);
2708 emitpcodeNULLop(POC_NOP);
2709 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2710 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2711 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2712 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2714 pBlockConvert2ISR(pb);
2716 if (!inExcludeList("acc"))
2717 pic14_emitcode ("push","acc");
2718 if (!inExcludeList("b"))
2719 pic14_emitcode ("push","b");
2720 if (!inExcludeList("dpl"))
2721 pic14_emitcode ("push","dpl");
2722 if (!inExcludeList("dph"))
2723 pic14_emitcode ("push","dph");
2724 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2726 pic14_emitcode ("push", "dpx");
2727 /* Make sure we're using standard DPTR */
2728 pic14_emitcode ("push", "dps");
2729 pic14_emitcode ("mov", "dps, #0x00");
2730 if (options.stack10bit)
2732 /* This ISR could conceivably use DPTR2. Better save it. */
2733 pic14_emitcode ("push", "dpl1");
2734 pic14_emitcode ("push", "dph1");
2735 pic14_emitcode ("push", "dpx1");
2738 /* if this isr has no bank i.e. is going to
2739 run with bank 0 , then we need to save more
2741 if (!FUNC_REGBANK(sym->type)) {
2743 /* if this function does not call any other
2744 function then we can be economical and
2745 save only those registers that are used */
2746 if (! IFFUNC_HASFCALL(sym->type)) {
2749 /* if any registers used */
2750 if (sym->regsUsed) {
2751 /* save the registers used */
2752 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2753 if (bitVectBitValue(sym->regsUsed,i) ||
2754 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2755 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2760 /* this function has a function call cannot
2761 determines register usage so we will have the
2763 saverbank(0,ic,FALSE);
2768 /* if callee-save to be used for this function
2769 then save the registers being used in this function */
2770 if (IFFUNC_CALLEESAVES(sym->type)) {
2773 /* if any registers used */
2774 if (sym->regsUsed) {
2775 /* save the registers used */
2776 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2777 if (bitVectBitValue(sym->regsUsed,i) ||
2778 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2779 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2787 /* set the register bank to the desired value */
2788 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2789 pic14_emitcode("push","psw");
2790 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2793 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2795 if (options.useXstack) {
2796 pic14_emitcode("mov","r0,%s",spname);
2797 pic14_emitcode("mov","a,_bp");
2798 pic14_emitcode("movx","@r0,a");
2799 pic14_emitcode("inc","%s",spname);
2803 /* set up the stack */
2804 pic14_emitcode ("push","_bp"); /* save the callers stack */
2806 pic14_emitcode ("mov","_bp,%s",spname);
2809 /* adjust the stack for the function */
2814 werror(W_STACK_OVERFLOW,sym->name);
2816 if (i > 3 && sym->recvSize < 4) {
2818 pic14_emitcode ("mov","a,sp");
2819 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2820 pic14_emitcode ("mov","sp,a");
2825 pic14_emitcode("inc","sp");
2830 pic14_emitcode ("mov","a,_spx");
2831 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2832 pic14_emitcode ("mov","_spx,a");
2837 /*-----------------------------------------------------------------*/
2838 /* genEndFunction - generates epilogue for functions */
2839 /*-----------------------------------------------------------------*/
2840 static void genEndFunction (iCode *ic)
2842 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2846 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2848 pic14_emitcode ("mov","%s,_bp",spname);
2851 /* if use external stack but some variables were
2852 added to the local stack then decrement the
2854 if (options.useXstack && sym->stack) {
2855 pic14_emitcode("mov","a,sp");
2856 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2857 pic14_emitcode("mov","sp,a");
2861 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2862 if (options.useXstack) {
2863 pic14_emitcode("mov","r0,%s",spname);
2864 pic14_emitcode("movx","a,@r0");
2865 pic14_emitcode("mov","_bp,a");
2866 pic14_emitcode("dec","%s",spname);
2870 pic14_emitcode ("pop","_bp");
2874 /* restore the register bank */
2875 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2876 pic14_emitcode ("pop","psw");
2878 if (IFFUNC_ISISR(sym->type)) {
2880 /* now we need to restore the registers */
2881 /* if this isr has no bank i.e. is going to
2882 run with bank 0 , then we need to save more
2884 if (!FUNC_REGBANK(sym->type)) {
2886 /* if this function does not call any other
2887 function then we can be economical and
2888 save only those registers that are used */
2889 if (! IFFUNC_HASFCALL(sym->type)) {
2892 /* if any registers used */
2893 if (sym->regsUsed) {
2894 /* save the registers used */
2895 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2896 if (bitVectBitValue(sym->regsUsed,i) ||
2897 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2898 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2903 /* this function has a function call cannot
2904 determines register usage so we will have the
2906 unsaverbank(0,ic,FALSE);
2910 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2912 if (options.stack10bit)
2914 pic14_emitcode ("pop", "dpx1");
2915 pic14_emitcode ("pop", "dph1");
2916 pic14_emitcode ("pop", "dpl1");
2918 pic14_emitcode ("pop", "dps");
2919 pic14_emitcode ("pop", "dpx");
2921 if (!inExcludeList("dph"))
2922 pic14_emitcode ("pop","dph");
2923 if (!inExcludeList("dpl"))
2924 pic14_emitcode ("pop","dpl");
2925 if (!inExcludeList("b"))
2926 pic14_emitcode ("pop","b");
2927 if (!inExcludeList("acc"))
2928 pic14_emitcode ("pop","acc");
2930 if (IFFUNC_ISCRITICAL(sym->type))
2931 pic14_emitcode("setb","ea");
2934 /* if debug then send end of function */
2935 /* if (options.debug && currFunc) { */
2938 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2939 FileBaseName(ic->filename),currFunc->lastLine,
2940 ic->level,ic->block);
2941 if (IS_STATIC(currFunc->etype))
2942 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2944 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2948 pic14_emitcode ("reti","");
2950 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2951 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2952 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2953 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2954 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2955 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2957 emitpcodeNULLop(POC_RETFIE);
2961 if (IFFUNC_ISCRITICAL(sym->type))
2962 pic14_emitcode("setb","ea");
2964 if (IFFUNC_CALLEESAVES(sym->type)) {
2967 /* if any registers used */
2968 if (sym->regsUsed) {
2969 /* save the registers used */
2970 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2971 if (bitVectBitValue(sym->regsUsed,i) ||
2972 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2973 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2979 /* if debug then send end of function */
2982 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2983 FileBaseName(ic->filename),currFunc->lastLine,
2984 ic->level,ic->block);
2985 if (IS_STATIC(currFunc->etype))
2986 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2988 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2992 pic14_emitcode ("return","");
2993 emitpcodeNULLop(POC_RETURN);
2995 /* Mark the end of a function */
2996 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
3001 /*-----------------------------------------------------------------*/
3002 /* genRet - generate code for return statement */
3003 /*-----------------------------------------------------------------*/
3004 static void genRet (iCode *ic)
3006 int size,offset = 0 , pushed = 0;
3008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3009 /* if we have no return value then
3010 just generate the "ret" */
3014 /* we have something to return then
3015 move the return value into place */
3016 aopOp(IC_LEFT(ic),ic,FALSE);
3017 size = AOP_SIZE(IC_LEFT(ic));
3021 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3023 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3025 pic14_emitcode("push","%s",l);
3028 l = aopGet(AOP(IC_LEFT(ic)),offset,
3030 if (strcmp(fReturn[offset],l)) {
3031 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3032 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3033 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3035 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3038 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3048 if (strcmp(fReturn[pushed],"a"))
3049 pic14_emitcode("pop",fReturn[pushed]);
3051 pic14_emitcode("pop","acc");
3054 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3057 /* generate a jump to the return label
3058 if the next is not the return statement */
3059 if (!(ic->next && ic->next->op == LABEL &&
3060 IC_LABEL(ic->next) == returnLabel)) {
3062 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3063 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3068 /*-----------------------------------------------------------------*/
3069 /* genLabel - generates a label */
3070 /*-----------------------------------------------------------------*/
3071 static void genLabel (iCode *ic)
3073 /* special case never generate */
3074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3075 if (IC_LABEL(ic) == entryLabel)
3078 emitpLabel(IC_LABEL(ic)->key);
3079 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3082 /*-----------------------------------------------------------------*/
3083 /* genGoto - generates a goto */
3084 /*-----------------------------------------------------------------*/
3086 static void genGoto (iCode *ic)
3088 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3089 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3093 /*-----------------------------------------------------------------*/
3094 /* genMultbits :- multiplication of bits */
3095 /*-----------------------------------------------------------------*/
3096 static void genMultbits (operand *left,
3100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3102 if(!pic14_sameRegs(AOP(result),AOP(right)))
3103 emitpcode(POC_BSF, popGet(AOP(result),0));
3105 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3106 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3107 emitpcode(POC_BCF, popGet(AOP(result),0));
3112 /*-----------------------------------------------------------------*/
3113 /* genMultOneByte : 8 bit multiplication & division */
3114 /*-----------------------------------------------------------------*/
3115 static void genMultOneByte (operand *left,
3119 sym_link *opetype = operandType(result);
3124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3125 DEBUGpic14_AopType(__LINE__,left,right,result);
3126 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3128 /* (if two literals, the value is computed before) */
3129 /* if one literal, literal on the right */
3130 if (AOP_TYPE(left) == AOP_LIT){
3136 size = AOP_SIZE(result);
3139 if (AOP_TYPE(right) == AOP_LIT){
3140 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3141 aopGet(AOP(right),0,FALSE,FALSE),
3142 aopGet(AOP(left),0,FALSE,FALSE),
3143 aopGet(AOP(result),0,FALSE,FALSE));
3144 pic14_emitcode("call","genMultLit");
3146 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3147 aopGet(AOP(right),0,FALSE,FALSE),
3148 aopGet(AOP(left),0,FALSE,FALSE),
3149 aopGet(AOP(result),0,FALSE,FALSE));
3150 pic14_emitcode("call","genMult8X8_8");
3153 genMult8X8_8 (left, right,result);
3156 /* signed or unsigned */
3157 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3158 //l = aopGet(AOP(left),0,FALSE,FALSE);
3160 //pic14_emitcode("mul","ab");
3161 /* if result size = 1, mul signed = mul unsigned */
3162 //aopPut(AOP(result),"a",0);
3164 } else { // (size > 1)
3166 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3167 aopGet(AOP(right),0,FALSE,FALSE),
3168 aopGet(AOP(left),0,FALSE,FALSE),
3169 aopGet(AOP(result),0,FALSE,FALSE));
3171 if (SPEC_USIGN(opetype)){
3172 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3173 genUMult8X8_16 (left, right, result, NULL);
3176 /* for filling the MSBs */
3177 emitpcode(POC_CLRF, popGet(AOP(result),2));
3178 emitpcode(POC_CLRF, popGet(AOP(result),3));
3182 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3184 pic14_emitcode("mov","a,b");
3186 /* adjust the MSB if left or right neg */
3188 /* if one literal */
3189 if (AOP_TYPE(right) == AOP_LIT){
3190 pic14_emitcode("multiply ","right is a lit");
3191 /* AND literal negative */
3192 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3193 /* adjust MSB (c==0 after mul) */
3194 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3198 genSMult8X8_16 (left, right, result, NULL);
3202 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3204 pic14_emitcode("rlc","a");
3205 pic14_emitcode("subb","a,acc");
3213 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3214 //aopPut(AOP(result),"a",offset++);
3218 /*-----------------------------------------------------------------*/
3219 /* genMult - generates code for multiplication */
3220 /*-----------------------------------------------------------------*/
3221 static void genMult (iCode *ic)
3223 operand *left = IC_LEFT(ic);
3224 operand *right = IC_RIGHT(ic);
3225 operand *result= IC_RESULT(ic);
3227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3228 /* assign the amsops */
3229 aopOp (left,ic,FALSE);
3230 aopOp (right,ic,FALSE);
3231 aopOp (result,ic,TRUE);
3233 DEBUGpic14_AopType(__LINE__,left,right,result);
3235 /* special cases first */
3237 if (AOP_TYPE(left) == AOP_CRY &&
3238 AOP_TYPE(right)== AOP_CRY) {
3239 genMultbits(left,right,result);
3243 /* if both are of size == 1 */
3244 if (AOP_SIZE(left) == 1 &&
3245 AOP_SIZE(right) == 1 ) {
3246 genMultOneByte(left,right,result);
3250 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3252 /* should have been converted to function call */
3256 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3257 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3258 freeAsmop(result,NULL,ic,TRUE);
3261 /*-----------------------------------------------------------------*/
3262 /* genDivbits :- division of bits */
3263 /*-----------------------------------------------------------------*/
3264 static void genDivbits (operand *left,
3271 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3272 /* the result must be bit */
3273 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3274 l = aopGet(AOP(left),0,FALSE,FALSE);
3278 pic14_emitcode("div","ab");
3279 pic14_emitcode("rrc","a");
3280 aopPut(AOP(result),"c",0);
3283 /*-----------------------------------------------------------------*/
3284 /* genDivOneByte : 8 bit division */
3285 /*-----------------------------------------------------------------*/
3286 static void genDivOneByte (operand *left,
3290 sym_link *opetype = operandType(result);
3295 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3296 size = AOP_SIZE(result) - 1;
3298 /* signed or unsigned */
3299 if (SPEC_USIGN(opetype)) {
3300 /* unsigned is easy */
3301 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3302 l = aopGet(AOP(left),0,FALSE,FALSE);
3304 pic14_emitcode("div","ab");
3305 aopPut(AOP(result),"a",0);
3307 aopPut(AOP(result),zero,offset++);
3311 /* signed is a little bit more difficult */
3313 /* save the signs of the operands */
3314 l = aopGet(AOP(left),0,FALSE,FALSE);
3316 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3317 pic14_emitcode("push","acc"); /* save it on the stack */
3319 /* now sign adjust for both left & right */
3320 l = aopGet(AOP(right),0,FALSE,FALSE);
3322 lbl = newiTempLabel(NULL);
3323 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3324 pic14_emitcode("cpl","a");
3325 pic14_emitcode("inc","a");
3326 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3327 pic14_emitcode("mov","b,a");
3329 /* sign adjust left side */
3330 l = aopGet(AOP(left),0,FALSE,FALSE);
3333 lbl = newiTempLabel(NULL);
3334 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3335 pic14_emitcode("cpl","a");
3336 pic14_emitcode("inc","a");
3337 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3339 /* now the division */
3340 pic14_emitcode("div","ab");
3341 /* we are interested in the lower order
3343 pic14_emitcode("mov","b,a");
3344 lbl = newiTempLabel(NULL);
3345 pic14_emitcode("pop","acc");
3346 /* if there was an over flow we don't
3347 adjust the sign of the result */
3348 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3349 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3351 pic14_emitcode("clr","a");
3352 pic14_emitcode("subb","a,b");
3353 pic14_emitcode("mov","b,a");
3354 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3356 /* now we are done */
3357 aopPut(AOP(result),"b",0);
3359 pic14_emitcode("mov","c,b.7");
3360 pic14_emitcode("subb","a,acc");
3363 aopPut(AOP(result),"a",offset++);
3367 /*-----------------------------------------------------------------*/
3368 /* genDiv - generates code for division */
3369 /*-----------------------------------------------------------------*/
3370 static void genDiv (iCode *ic)
3372 operand *left = IC_LEFT(ic);
3373 operand *right = IC_RIGHT(ic);
3374 operand *result= IC_RESULT(ic);
3376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3377 /* assign the amsops */
3378 aopOp (left,ic,FALSE);
3379 aopOp (right,ic,FALSE);
3380 aopOp (result,ic,TRUE);
3382 /* special cases first */
3384 if (AOP_TYPE(left) == AOP_CRY &&
3385 AOP_TYPE(right)== AOP_CRY) {
3386 genDivbits(left,right,result);
3390 /* if both are of size == 1 */
3391 if (AOP_SIZE(left) == 1 &&
3392 AOP_SIZE(right) == 1 ) {
3393 genDivOneByte(left,right,result);
3397 /* should have been converted to function call */
3400 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3401 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3402 freeAsmop(result,NULL,ic,TRUE);
3405 /*-----------------------------------------------------------------*/
3406 /* genModbits :- modulus of bits */
3407 /*-----------------------------------------------------------------*/
3408 static void genModbits (operand *left,
3415 /* the result must be bit */
3416 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3417 l = aopGet(AOP(left),0,FALSE,FALSE);
3421 pic14_emitcode("div","ab");
3422 pic14_emitcode("mov","a,b");
3423 pic14_emitcode("rrc","a");
3424 aopPut(AOP(result),"c",0);
3427 /*-----------------------------------------------------------------*/
3428 /* genModOneByte : 8 bit modulus */
3429 /*-----------------------------------------------------------------*/
3430 static void genModOneByte (operand *left,
3434 sym_link *opetype = operandType(result);
3438 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3439 /* signed or unsigned */
3440 if (SPEC_USIGN(opetype)) {
3441 /* unsigned is easy */
3442 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3443 l = aopGet(AOP(left),0,FALSE,FALSE);
3445 pic14_emitcode("div","ab");
3446 aopPut(AOP(result),"b",0);
3450 /* signed is a little bit more difficult */
3452 /* save the signs of the operands */
3453 l = aopGet(AOP(left),0,FALSE,FALSE);
3456 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3457 pic14_emitcode("push","acc"); /* save it on the stack */
3459 /* now sign adjust for both left & right */
3460 l = aopGet(AOP(right),0,FALSE,FALSE);
3463 lbl = newiTempLabel(NULL);
3464 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3465 pic14_emitcode("cpl","a");
3466 pic14_emitcode("inc","a");
3467 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3468 pic14_emitcode("mov","b,a");
3470 /* sign adjust left side */
3471 l = aopGet(AOP(left),0,FALSE,FALSE);
3474 lbl = newiTempLabel(NULL);
3475 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3476 pic14_emitcode("cpl","a");
3477 pic14_emitcode("inc","a");
3478 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3480 /* now the multiplication */
3481 pic14_emitcode("div","ab");
3482 /* we are interested in the lower order
3484 lbl = newiTempLabel(NULL);
3485 pic14_emitcode("pop","acc");
3486 /* if there was an over flow we don't
3487 adjust the sign of the result */
3488 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3489 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3491 pic14_emitcode("clr","a");
3492 pic14_emitcode("subb","a,b");
3493 pic14_emitcode("mov","b,a");
3494 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3496 /* now we are done */
3497 aopPut(AOP(result),"b",0);
3501 /*-----------------------------------------------------------------*/
3502 /* genMod - generates code for division */
3503 /*-----------------------------------------------------------------*/
3504 static void genMod (iCode *ic)
3506 operand *left = IC_LEFT(ic);
3507 operand *right = IC_RIGHT(ic);
3508 operand *result= IC_RESULT(ic);
3510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3511 /* assign the amsops */
3512 aopOp (left,ic,FALSE);
3513 aopOp (right,ic,FALSE);
3514 aopOp (result,ic,TRUE);
3516 /* special cases first */
3518 if (AOP_TYPE(left) == AOP_CRY &&
3519 AOP_TYPE(right)== AOP_CRY) {
3520 genModbits(left,right,result);
3524 /* if both are of size == 1 */
3525 if (AOP_SIZE(left) == 1 &&
3526 AOP_SIZE(right) == 1 ) {
3527 genModOneByte(left,right,result);
3531 /* should have been converted to function call */
3535 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3536 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3537 freeAsmop(result,NULL,ic,TRUE);
3540 /*-----------------------------------------------------------------*/
3541 /* genIfxJump :- will create a jump depending on the ifx */
3542 /*-----------------------------------------------------------------*/
3544 note: May need to add parameter to indicate when a variable is in bit space.
3546 static void genIfxJump (iCode *ic, char *jval)
3549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3550 /* if true label then we jump if condition
3552 if ( IC_TRUE(ic) ) {
3554 if(strcmp(jval,"a") == 0)
3556 else if (strcmp(jval,"c") == 0)
3559 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3560 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3563 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3564 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3568 /* false label is present */
3569 if(strcmp(jval,"a") == 0)
3571 else if (strcmp(jval,"c") == 0)
3574 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3575 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3578 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3579 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3584 /* mark the icode as generated */
3588 /*-----------------------------------------------------------------*/
3590 /*-----------------------------------------------------------------*/
3591 static void genSkip(iCode *ifx,int status_bit)
3596 if ( IC_TRUE(ifx) ) {
3597 switch(status_bit) {
3612 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3613 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3617 switch(status_bit) {
3631 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3632 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3638 /*-----------------------------------------------------------------*/
3640 /*-----------------------------------------------------------------*/
3641 static void genSkipc(resolvedIfx *rifx)
3651 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3652 rifx->generated = 1;
3655 /*-----------------------------------------------------------------*/
3657 /*-----------------------------------------------------------------*/
3658 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3663 if( (rifx->condition ^ invert_condition) & 1)
3668 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3669 rifx->generated = 1;
3672 /*-----------------------------------------------------------------*/
3674 /*-----------------------------------------------------------------*/
3675 static void genSkipz(iCode *ifx, int condition)
3686 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3688 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3691 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3693 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3696 /*-----------------------------------------------------------------*/
3698 /*-----------------------------------------------------------------*/
3699 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3705 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3707 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3710 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3711 rifx->generated = 1;
3715 /*-----------------------------------------------------------------*/
3716 /* genChkZeroes :- greater or less than comparison */
3717 /* For each byte in a literal that is zero, inclusive or the */
3718 /* the corresponding byte in the operand with W */
3719 /* returns true if any of the bytes are zero */
3720 /*-----------------------------------------------------------------*/
3721 static int genChkZeroes(operand *op, int lit, int size)
3728 i = (lit >> (size*8)) & 0xff;
3732 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3734 emitpcode(POC_IORFW, popGet(AOP(op),size));
3743 /*-----------------------------------------------------------------*/
3744 /* genCmp :- greater or less than comparison */
3745 /*-----------------------------------------------------------------*/
3746 static void genCmp (operand *left,operand *right,
3747 operand *result, iCode *ifx, int sign)
3749 int size; //, offset = 0 ;
3750 unsigned long lit = 0L,i = 0;
3751 resolvedIfx rFalseIfx;
3752 // resolvedIfx rTrueIfx;
3754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3757 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3758 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3762 resolveIfx(&rFalseIfx,ifx);
3763 truelbl = newiTempLabel(NULL);
3764 size = max(AOP_SIZE(left),AOP_SIZE(right));
3766 DEBUGpic14_AopType(__LINE__,left,right,result);
3770 /* if literal is on the right then swap with left */
3771 if ((AOP_TYPE(right) == AOP_LIT)) {
3772 operand *tmp = right ;
3773 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3774 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3777 lit = (lit - 1) & mask;
3780 rFalseIfx.condition ^= 1;
3783 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3784 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3788 //if(IC_TRUE(ifx) == NULL)
3789 /* if left & right are bit variables */
3790 if (AOP_TYPE(left) == AOP_CRY &&
3791 AOP_TYPE(right) == AOP_CRY ) {
3792 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3793 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3795 /* subtract right from left if at the
3796 end the carry flag is set then we know that
3797 left is greater than right */
3801 symbol *lbl = newiTempLabel(NULL);
3804 if(AOP_TYPE(right) == AOP_LIT) {
3806 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3808 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3815 genSkipCond(&rFalseIfx,left,size-1,7);
3817 /* no need to compare to 0...*/
3818 /* NOTE: this is a de-generate compare that most certainly
3819 * creates some dead code. */
3820 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3822 if(ifx) ifx->generated = 1;
3829 //i = (lit >> (size*8)) & 0xff;
3830 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3832 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3834 i = ((0-lit) & 0xff);
3837 /* lit is 0x7f, all signed chars are less than
3838 * this except for 0x7f itself */
3839 emitpcode(POC_XORLW, popGetLit(0x7f));
3840 genSkipz2(&rFalseIfx,0);
3842 emitpcode(POC_ADDLW, popGetLit(0x80));
3843 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3844 genSkipc(&rFalseIfx);
3849 genSkipz2(&rFalseIfx,1);
3851 emitpcode(POC_ADDLW, popGetLit(i));
3852 genSkipc(&rFalseIfx);
3856 if(ifx) ifx->generated = 1;
3860 /* chars are out of the way. now do ints and longs */
3863 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3870 genSkipCond(&rFalseIfx,left,size,7);
3871 if(ifx) ifx->generated = 1;
3876 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3878 //rFalseIfx.condition ^= 1;
3879 //genSkipCond(&rFalseIfx,left,size,7);
3880 //rFalseIfx.condition ^= 1;
3882 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3883 if(rFalseIfx.condition)
3884 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3886 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3888 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3889 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3890 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3893 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3895 if(rFalseIfx.condition) {
3897 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3903 genSkipc(&rFalseIfx);
3904 emitpLabel(truelbl->key);
3905 if(ifx) ifx->generated = 1;
3912 if( (lit & 0xff) == 0) {
3913 /* lower byte is zero */
3914 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3915 i = ((lit >> 8) & 0xff) ^0x80;
3916 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3917 emitpcode(POC_ADDLW, popGetLit( 0x80));
3918 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3919 genSkipc(&rFalseIfx);
3922 if(ifx) ifx->generated = 1;
3927 /* Special cases for signed longs */
3928 if( (lit & 0xffffff) == 0) {
3929 /* lower byte is zero */
3930 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3931 i = ((lit >> 8*3) & 0xff) ^0x80;
3932 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3933 emitpcode(POC_ADDLW, popGetLit( 0x80));
3934 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3935 genSkipc(&rFalseIfx);
3938 if(ifx) ifx->generated = 1;
3946 if(lit & (0x80 << (size*8))) {
3947 /* lit is negative */
3948 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3950 //genSkipCond(&rFalseIfx,left,size,7);
3952 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3954 if(rFalseIfx.condition)
3955 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3957 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3961 /* lit is positive */
3962 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3963 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3964 if(rFalseIfx.condition)
3965 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3967 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3972 This works, but is only good for ints.
3973 It also requires a "known zero" register.
3974 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3975 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3976 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3977 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3978 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3979 genSkipc(&rFalseIfx);
3981 emitpLabel(truelbl->key);
3982 if(ifx) ifx->generated = 1;
3986 /* There are no more special cases, so perform a general compare */
3988 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3989 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3993 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3995 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3997 //rFalseIfx.condition ^= 1;
3998 genSkipc(&rFalseIfx);
4000 emitpLabel(truelbl->key);
4002 if(ifx) ifx->generated = 1;
4009 /* sign is out of the way. So now do an unsigned compare */
4010 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4013 /* General case - compare to an unsigned literal on the right.*/
4015 i = (lit >> (size*8)) & 0xff;
4016 emitpcode(POC_MOVLW, popGetLit(i));
4017 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4019 i = (lit >> (size*8)) & 0xff;
4022 emitpcode(POC_MOVLW, popGetLit(i));
4024 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4026 /* this byte of the lit is zero,
4027 *if it's not the last then OR in the variable */
4029 emitpcode(POC_IORFW, popGet(AOP(left),size));
4034 emitpLabel(lbl->key);
4035 //if(emitFinalCheck)
4036 genSkipc(&rFalseIfx);
4038 emitpLabel(truelbl->key);
4040 if(ifx) ifx->generated = 1;
4047 if(AOP_TYPE(left) == AOP_LIT) {
4048 //symbol *lbl = newiTempLabel(NULL);
4050 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4053 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4056 if((lit == 0) && (sign == 0)){
4059 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4061 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4063 genSkipz2(&rFalseIfx,0);
4064 if(ifx) ifx->generated = 1;
4071 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4072 /* degenerate compare can never be true */
4073 if(rFalseIfx.condition == 0)
4074 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4076 if(ifx) ifx->generated = 1;
4081 /* signed comparisons to a literal byte */
4083 int lp1 = (lit+1) & 0xff;
4085 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4088 rFalseIfx.condition ^= 1;
4089 genSkipCond(&rFalseIfx,right,0,7);
4092 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4093 emitpcode(POC_XORLW, popGetLit(0x7f));
4094 genSkipz2(&rFalseIfx,1);
4097 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4098 emitpcode(POC_ADDLW, popGetLit(0x80));
4099 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4100 rFalseIfx.condition ^= 1;
4101 genSkipc(&rFalseIfx);
4105 /* unsigned comparisons to a literal byte */
4107 switch(lit & 0xff ) {
4109 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4110 genSkipz2(&rFalseIfx,0);
4113 rFalseIfx.condition ^= 1;
4114 genSkipCond(&rFalseIfx,right,0,7);
4118 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4119 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4121 rFalseIfx.condition ^= 1;
4122 if (AOP_TYPE(result) == AOP_CRY)
4123 genSkipc(&rFalseIfx);
4125 emitpcode(POC_CLRF, popGet(AOP(result),0));
4126 emitpcode(POC_RLF, popGet(AOP(result),0));
4132 if(ifx) ifx->generated = 1;
4138 /* Size is greater than 1 */
4146 /* this means lit = 0xffffffff, or -1 */
4149 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4150 rFalseIfx.condition ^= 1;
4151 genSkipCond(&rFalseIfx,right,size,7);
4152 if(ifx) ifx->generated = 1;
4159 if(rFalseIfx.condition) {
4160 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4161 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4164 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4166 emitpcode(POC_IORFW, popGet(AOP(right),size));
4170 if(rFalseIfx.condition) {
4171 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4172 emitpLabel(truelbl->key);
4174 rFalseIfx.condition ^= 1;
4175 genSkipCond(&rFalseIfx,right,s,7);
4178 if(ifx) ifx->generated = 1;
4182 if((size == 1) && (0 == (lp1&0xff))) {
4183 /* lower byte of signed word is zero */
4184 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4185 i = ((lp1 >> 8) & 0xff) ^0x80;
4186 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4187 emitpcode(POC_ADDLW, popGetLit( 0x80));
4188 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4189 rFalseIfx.condition ^= 1;
4190 genSkipc(&rFalseIfx);
4193 if(ifx) ifx->generated = 1;
4197 if(lit & (0x80 << (size*8))) {
4198 /* Lit is less than zero */
4199 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4200 //rFalseIfx.condition ^= 1;
4201 //genSkipCond(&rFalseIfx,left,size,7);
4202 //rFalseIfx.condition ^= 1;
4203 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4206 if(rFalseIfx.condition)
4207 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4209 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4213 /* Lit is greater than or equal to zero */
4214 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4215 //rFalseIfx.condition ^= 1;
4216 //genSkipCond(&rFalseIfx,right,size,7);
4217 //rFalseIfx.condition ^= 1;
4219 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4220 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4222 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4223 if(rFalseIfx.condition)
4224 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4226 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4231 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4232 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4236 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4238 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4240 rFalseIfx.condition ^= 1;
4241 //rFalseIfx.condition = 1;
4242 genSkipc(&rFalseIfx);
4244 emitpLabel(truelbl->key);
4246 if(ifx) ifx->generated = 1;
4251 /* compare word or long to an unsigned literal on the right.*/
4256 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4259 break; /* handled above */
4262 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4264 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265 genSkipz2(&rFalseIfx,0);
4269 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4271 emitpcode(POC_IORFW, popGet(AOP(right),size));
4274 if(rFalseIfx.condition)
4275 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4277 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4280 emitpcode(POC_MOVLW, popGetLit(lit+1));
4281 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4283 rFalseIfx.condition ^= 1;
4284 genSkipc(&rFalseIfx);
4287 emitpLabel(truelbl->key);
4289 if(ifx) ifx->generated = 1;
4295 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4296 i = (lit >> (size*8)) & 0xff;
4298 emitpcode(POC_MOVLW, popGetLit(i));
4299 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4302 i = (lit >> (size*8)) & 0xff;
4305 emitpcode(POC_MOVLW, popGetLit(i));
4307 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4309 /* this byte of the lit is zero,
4310 *if it's not the last then OR in the variable */
4312 emitpcode(POC_IORFW, popGet(AOP(right),size));
4317 emitpLabel(lbl->key);
4319 rFalseIfx.condition ^= 1;
4320 genSkipc(&rFalseIfx);
4324 emitpLabel(truelbl->key);
4325 if(ifx) ifx->generated = 1;
4329 /* Compare two variables */
4331 DEBUGpic14_emitcode(";sign","%d",sign);
4335 /* Sigh. thus sucks... */
4337 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4338 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4339 emitpcode(POC_MOVLW, popGetLit(0x80));
4340 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4341 emitpcode(POC_XORFW, popGet(AOP(right),size));
4342 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4344 /* Signed char comparison */
4345 /* Special thanks to Nikolai Golovchenko for this snippet */
4346 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4347 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4348 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4349 emitpcode(POC_XORFW, popGet(AOP(left),0));
4350 emitpcode(POC_XORFW, popGet(AOP(right),0));
4351 emitpcode(POC_ADDLW, popGetLit(0x80));
4353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4354 genSkipc(&rFalseIfx);
4356 if(ifx) ifx->generated = 1;
4362 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4363 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4367 /* The rest of the bytes of a multi-byte compare */
4371 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4374 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4375 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4380 emitpLabel(lbl->key);
4382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4383 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4384 (AOP_TYPE(result) == AOP_REG)) {
4385 emitpcode(POC_CLRF, popGet(AOP(result),0));
4386 emitpcode(POC_RLF, popGet(AOP(result),0));
4388 genSkipc(&rFalseIfx);
4390 //genSkipc(&rFalseIfx);
4391 if(ifx) ifx->generated = 1;
4398 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4400 pic14_outBitC(result);
4402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4403 /* if the result is used in the next
4404 ifx conditional branch then generate
4405 code a little differently */
4407 genIfxJump (ifx,"c");
4409 pic14_outBitC(result);
4410 /* leave the result in acc */
4415 /*-----------------------------------------------------------------*/
4416 /* genCmpGt :- greater than comparison */
4417 /*-----------------------------------------------------------------*/
4418 static void genCmpGt (iCode *ic, iCode *ifx)
4420 operand *left, *right, *result;
4421 sym_link *letype , *retype;
4424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4426 right= IC_RIGHT(ic);
4427 result = IC_RESULT(ic);
4429 letype = getSpec(operandType(left));
4430 retype =getSpec(operandType(right));
4431 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4432 /* assign the amsops */
4433 aopOp (left,ic,FALSE);
4434 aopOp (right,ic,FALSE);
4435 aopOp (result,ic,TRUE);
4437 genCmp(right, left, result, ifx, sign);
4439 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 freeAsmop(result,NULL,ic,TRUE);
4444 /*-----------------------------------------------------------------*/
4445 /* genCmpLt - less than comparisons */
4446 /*-----------------------------------------------------------------*/
4447 static void genCmpLt (iCode *ic, iCode *ifx)
4449 operand *left, *right, *result;
4450 sym_link *letype , *retype;
4453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4455 right= IC_RIGHT(ic);
4456 result = IC_RESULT(ic);
4458 letype = getSpec(operandType(left));
4459 retype =getSpec(operandType(right));
4460 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4462 /* assign the amsops */
4463 aopOp (left,ic,FALSE);
4464 aopOp (right,ic,FALSE);
4465 aopOp (result,ic,TRUE);
4467 genCmp(left, right, result, ifx, sign);
4469 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4470 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471 freeAsmop(result,NULL,ic,TRUE);
4474 /*-----------------------------------------------------------------*/
4475 /* genc16bit2lit - compare a 16 bit value to a literal */
4476 /*-----------------------------------------------------------------*/
4477 static void genc16bit2lit(operand *op, int lit, int offset)
4481 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4482 if( (lit&0xff) == 0)
4487 switch( BYTEofLONG(lit,i)) {
4489 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4492 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4495 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4498 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4499 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4504 switch( BYTEofLONG(lit,i)) {
4506 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4510 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4514 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4517 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4519 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4525 /*-----------------------------------------------------------------*/
4526 /* gencjneshort - compare and jump if not equal */
4527 /*-----------------------------------------------------------------*/
4528 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4530 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4532 int res_offset = 0; /* the result may be a different size then left or right */
4533 int res_size = AOP_SIZE(result);
4537 unsigned long lit = 0L;
4538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4539 DEBUGpic14_AopType(__LINE__,left,right,result);
4541 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4542 resolveIfx(&rIfx,ifx);
4543 lbl = newiTempLabel(NULL);
4546 /* if the left side is a literal or
4547 if the right is in a pointer register and left
4549 if ((AOP_TYPE(left) == AOP_LIT) ||
4550 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4555 if(AOP_TYPE(right) == AOP_LIT)
4556 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4558 /* if the right side is a literal then anything goes */
4559 if (AOP_TYPE(right) == AOP_LIT &&
4560 AOP_TYPE(left) != AOP_DIR ) {
4563 genc16bit2lit(left, lit, 0);
4565 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4570 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4571 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4573 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4577 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4579 if(res_offset < res_size-1)
4587 /* if the right side is in a register or in direct space or
4588 if the left is a pointer register & right is not */
4589 else if (AOP_TYPE(right) == AOP_REG ||
4590 AOP_TYPE(right) == AOP_DIR ||
4591 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4592 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4593 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4594 int lbl_key = lbl->key;
4597 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4598 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4600 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4601 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4602 __FUNCTION__,__LINE__);
4606 /* switch(size) { */
4608 /* genc16bit2lit(left, lit, 0); */
4610 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4615 if((AOP_TYPE(left) == AOP_DIR) &&
4616 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4618 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4621 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4623 switch (lit & 0xff) {
4625 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4628 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4629 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4634 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4635 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4636 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4637 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4641 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4642 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4647 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4650 if(AOP_TYPE(result) == AOP_CRY) {
4651 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4656 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4658 /* fix me. probably need to check result size too */
4659 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4664 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4665 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4672 if(res_offset < res_size-1)
4677 } else if(AOP_TYPE(right) == AOP_REG &&
4678 AOP_TYPE(left) != AOP_DIR){
4681 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4682 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4683 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4688 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4690 if(res_offset < res_size-1)
4695 /* right is a pointer reg need both a & b */
4697 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4699 pic14_emitcode("mov","b,%s",l);
4700 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4701 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4706 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4708 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4710 emitpLabel(lbl->key);
4712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4719 /*-----------------------------------------------------------------*/
4720 /* gencjne - compare and jump if not equal */
4721 /*-----------------------------------------------------------------*/
4722 static void gencjne(operand *left, operand *right, iCode *ifx)
4724 symbol *tlbl = newiTempLabel(NULL);
4726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4727 gencjneshort(left, right, lbl);
4729 pic14_emitcode("mov","a,%s",one);
4730 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4731 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4732 pic14_emitcode("clr","a");
4733 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4735 emitpLabel(lbl->key);
4736 emitpLabel(tlbl->key);
4741 /*-----------------------------------------------------------------*/
4742 /* genCmpEq - generates code for equal to */
4743 /*-----------------------------------------------------------------*/
4744 static void genCmpEq (iCode *ic, iCode *ifx)
4746 operand *left, *right, *result;
4747 unsigned long lit = 0L;
4750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4753 DEBUGpic14_emitcode ("; ifx is non-null","");
4755 DEBUGpic14_emitcode ("; ifx is null","");
4757 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4758 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4759 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4761 size = max(AOP_SIZE(left),AOP_SIZE(right));
4763 DEBUGpic14_AopType(__LINE__,left,right,result);
4765 /* if literal, literal on the right or
4766 if the right is in a pointer register and left
4768 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4769 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4770 operand *tmp = right ;
4776 if(ifx && !AOP_SIZE(result)){
4778 /* if they are both bit variables */
4779 if (AOP_TYPE(left) == AOP_CRY &&
4780 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4781 if(AOP_TYPE(right) == AOP_LIT){
4782 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4784 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785 pic14_emitcode("cpl","c");
4786 } else if(lit == 1L) {
4787 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789 pic14_emitcode("clr","c");
4791 /* AOP_TYPE(right) == AOP_CRY */
4793 symbol *lbl = newiTempLabel(NULL);
4794 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4795 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4796 pic14_emitcode("cpl","c");
4797 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4799 /* if true label then we jump if condition
4801 tlbl = newiTempLabel(NULL);
4802 if ( IC_TRUE(ifx) ) {
4803 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4804 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4806 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4807 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4809 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4812 /* left and right are both bit variables, result is carry */
4815 resolveIfx(&rIfx,ifx);
4817 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4818 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4819 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4820 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4825 /* They're not both bit variables. Is the right a literal? */
4826 if(AOP_TYPE(right) == AOP_LIT) {
4827 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4832 switch(lit & 0xff) {
4834 if ( IC_TRUE(ifx) ) {
4835 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4837 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4839 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4840 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4844 if ( IC_TRUE(ifx) ) {
4845 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4847 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4849 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4850 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4854 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4856 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4861 /* end of size == 1 */
4865 genc16bit2lit(left,lit,offset);
4868 /* end of size == 2 */
4873 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4874 emitpcode(POC_IORFW,popGet(AOP(left),1));
4875 emitpcode(POC_IORFW,popGet(AOP(left),2));
4876 emitpcode(POC_IORFW,popGet(AOP(left),3));
4880 /* search for patterns that can be optimized */
4882 genc16bit2lit(left,lit,0);
4885 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4887 genc16bit2lit(left,lit,2);
4889 emitpcode(POC_IORFW,popGet(AOP(left),2));
4890 emitpcode(POC_IORFW,popGet(AOP(left),3));
4903 } else if(AOP_TYPE(right) == AOP_CRY ) {
4904 /* we know the left is not a bit, but that the right is */
4905 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4906 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4907 popGet(AOP(right),offset));
4908 emitpcode(POC_XORLW,popGetLit(1));
4910 /* if the two are equal, then W will be 0 and the Z bit is set
4911 * we could test Z now, or go ahead and check the high order bytes if
4912 * the variable we're comparing is larger than a byte. */
4915 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4917 if ( IC_TRUE(ifx) ) {
4919 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4920 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4923 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4924 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4928 /* They're both variables that are larger than bits */
4931 tlbl = newiTempLabel(NULL);
4934 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4935 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4937 if ( IC_TRUE(ifx) ) {
4940 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4941 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4944 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4945 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4949 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4950 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4954 if(s>1 && IC_TRUE(ifx)) {
4955 emitpLabel(tlbl->key);
4956 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4960 /* mark the icode as generated */
4965 /* if they are both bit variables */
4966 if (AOP_TYPE(left) == AOP_CRY &&
4967 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4968 if(AOP_TYPE(right) == AOP_LIT){
4969 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4971 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972 pic14_emitcode("cpl","c");
4973 } else if(lit == 1L) {
4974 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976 pic14_emitcode("clr","c");
4978 /* AOP_TYPE(right) == AOP_CRY */
4980 symbol *lbl = newiTempLabel(NULL);
4981 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4982 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4983 pic14_emitcode("cpl","c");
4984 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4987 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4988 pic14_outBitC(result);
4992 genIfxJump (ifx,"c");
4995 /* if the result is used in an arithmetic operation
4996 then put the result in place */
4997 pic14_outBitC(result);
5000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5001 gencjne(left,right,result,ifx);
5004 gencjne(left,right,newiTempLabel(NULL));
5006 if(IC_TRUE(ifx)->key)
5007 gencjne(left,right,IC_TRUE(ifx)->key);
5009 gencjne(left,right,IC_FALSE(ifx)->key);
5013 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5014 aopPut(AOP(result),"a",0);
5019 genIfxJump (ifx,"a");
5023 /* if the result is used in an arithmetic operation
5024 then put the result in place */
5026 if (AOP_TYPE(result) != AOP_CRY)
5027 pic14_outAcc(result);
5029 /* leave the result in acc */
5033 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5034 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035 freeAsmop(result,NULL,ic,TRUE);
5038 /*-----------------------------------------------------------------*/
5039 /* ifxForOp - returns the icode containing the ifx for operand */
5040 /*-----------------------------------------------------------------*/
5041 static iCode *ifxForOp ( operand *op, iCode *ic )
5043 /* if true symbol then needs to be assigned */
5044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5045 if (IS_TRUE_SYMOP(op))
5048 /* if this has register type condition and
5049 the next instruction is ifx with the same operand
5050 and live to of the operand is upto the ifx only then */
5052 ic->next->op == IFX &&
5053 IC_COND(ic->next)->key == op->key &&
5054 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5058 ic->next->op == IFX &&
5059 IC_COND(ic->next)->key == op->key) {
5060 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5064 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5066 ic->next->op == IFX)
5067 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5070 ic->next->op == IFX &&
5071 IC_COND(ic->next)->key == op->key) {
5072 DEBUGpic14_emitcode ("; "," key is okay");
5073 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5074 OP_SYMBOL(op)->liveTo,
5081 /*-----------------------------------------------------------------*/
5082 /* genAndOp - for && operation */
5083 /*-----------------------------------------------------------------*/
5084 static void genAndOp (iCode *ic)
5086 operand *left,*right, *result;
5089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5090 /* note here that && operations that are in an
5091 if statement are taken away by backPatchLabels
5092 only those used in arthmetic operations remain */
5093 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5094 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5095 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5097 DEBUGpic14_AopType(__LINE__,left,right,result);
5099 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5100 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5101 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5103 /* if both are bit variables */
5104 /* if (AOP_TYPE(left) == AOP_CRY && */
5105 /* AOP_TYPE(right) == AOP_CRY ) { */
5106 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5107 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5108 /* pic14_outBitC(result); */
5110 /* tlbl = newiTempLabel(NULL); */
5111 /* pic14_toBoolean(left); */
5112 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5113 /* pic14_toBoolean(right); */
5114 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5115 /* pic14_outBitAcc(result); */
5118 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5119 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5120 freeAsmop(result,NULL,ic,TRUE);
5124 /*-----------------------------------------------------------------*/
5125 /* genOrOp - for || operation */
5126 /*-----------------------------------------------------------------*/
5129 modified this code, but it doesn't appear to ever get called
5132 static void genOrOp (iCode *ic)
5134 operand *left,*right, *result;
5137 /* note here that || operations that are in an
5138 if statement are taken away by backPatchLabels
5139 only those used in arthmetic operations remain */
5140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5141 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5142 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5143 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5145 DEBUGpic14_AopType(__LINE__,left,right,result);
5147 /* if both are bit variables */
5148 if (AOP_TYPE(left) == AOP_CRY &&
5149 AOP_TYPE(right) == AOP_CRY ) {
5150 pic14_emitcode("clrc","");
5151 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5152 AOP(left)->aopu.aop_dir,
5153 AOP(left)->aopu.aop_dir);
5154 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5155 AOP(right)->aopu.aop_dir,
5156 AOP(right)->aopu.aop_dir);
5157 pic14_emitcode("setc","");
5160 tlbl = newiTempLabel(NULL);
5161 pic14_toBoolean(left);
5163 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5164 pic14_toBoolean(right);
5165 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5167 pic14_outBitAcc(result);
5170 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5171 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5172 freeAsmop(result,NULL,ic,TRUE);
5175 /*-----------------------------------------------------------------*/
5176 /* isLiteralBit - test if lit == 2^n */
5177 /*-----------------------------------------------------------------*/
5178 static int isLiteralBit(unsigned long lit)
5180 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5181 0x100L,0x200L,0x400L,0x800L,
5182 0x1000L,0x2000L,0x4000L,0x8000L,
5183 0x10000L,0x20000L,0x40000L,0x80000L,
5184 0x100000L,0x200000L,0x400000L,0x800000L,
5185 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5186 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5189 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5190 for(idx = 0; idx < 32; idx++)
5196 /*-----------------------------------------------------------------*/
5197 /* continueIfTrue - */
5198 /*-----------------------------------------------------------------*/
5199 static void continueIfTrue (iCode *ic)
5201 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5203 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5207 /*-----------------------------------------------------------------*/
5209 /*-----------------------------------------------------------------*/
5210 static void jumpIfTrue (iCode *ic)
5212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5214 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5218 /*-----------------------------------------------------------------*/
5219 /* jmpTrueOrFalse - */
5220 /*-----------------------------------------------------------------*/
5221 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5223 // ugly but optimized by peephole
5224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5226 symbol *nlbl = newiTempLabel(NULL);
5227 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5228 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5229 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5230 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5233 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5234 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5239 /*-----------------------------------------------------------------*/
5240 /* genAnd - code for and */
5241 /*-----------------------------------------------------------------*/
5242 static void genAnd (iCode *ic, iCode *ifx)
5244 operand *left, *right, *result;
5246 unsigned long lit = 0L;
5251 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5252 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5253 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5254 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5256 resolveIfx(&rIfx,ifx);
5258 /* if left is a literal & right is not then exchange them */
5259 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5260 AOP_NEEDSACC(left)) {
5261 operand *tmp = right ;
5266 /* if result = right then exchange them */
5267 if(pic14_sameRegs(AOP(result),AOP(right))){
5268 operand *tmp = right ;
5273 /* if right is bit then exchange them */
5274 if (AOP_TYPE(right) == AOP_CRY &&
5275 AOP_TYPE(left) != AOP_CRY){
5276 operand *tmp = right ;
5280 if(AOP_TYPE(right) == AOP_LIT)
5281 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5283 size = AOP_SIZE(result);
5285 DEBUGpic14_AopType(__LINE__,left,right,result);
5288 // result = bit & yy;
5289 if (AOP_TYPE(left) == AOP_CRY){
5290 // c = bit & literal;
5291 if(AOP_TYPE(right) == AOP_LIT){
5293 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5296 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5299 if(size && (AOP_TYPE(result) == AOP_CRY)){
5300 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5303 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5307 pic14_emitcode("clr","c");
5310 if (AOP_TYPE(right) == AOP_CRY){
5312 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5313 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5316 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5318 pic14_emitcode("rrc","a");
5319 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5325 pic14_outBitC(result);
5327 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5328 genIfxJump(ifx, "c");
5332 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5333 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5334 if((AOP_TYPE(right) == AOP_LIT) &&
5335 (AOP_TYPE(result) == AOP_CRY) &&
5336 (AOP_TYPE(left) != AOP_CRY)){
5337 int posbit = isLiteralBit(lit);
5341 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5344 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5350 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5351 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5353 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5354 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5357 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5358 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5359 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5366 symbol *tlbl = newiTempLabel(NULL);
5367 int sizel = AOP_SIZE(left);
5369 pic14_emitcode("setb","c");
5371 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5372 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5374 if((posbit = isLiteralBit(bytelit)) != 0)
5375 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5377 if(bytelit != 0x0FFL)
5378 pic14_emitcode("anl","a,%s",
5379 aopGet(AOP(right),offset,FALSE,TRUE));
5380 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5385 // bit = left & literal
5387 pic14_emitcode("clr","c");
5388 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5390 // if(left & literal)
5393 jmpTrueOrFalse(ifx, tlbl);
5397 pic14_outBitC(result);
5401 /* if left is same as result */
5402 if(pic14_sameRegs(AOP(result),AOP(left))){
5404 for(;size--; offset++,lit>>=8) {
5405 if(AOP_TYPE(right) == AOP_LIT){
5406 switch(lit & 0xff) {
5408 /* and'ing with 0 has clears the result */
5409 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5410 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5413 /* and'ing with 0xff is a nop when the result and left are the same */
5418 int p = my_powof2( (~lit) & 0xff );
5420 /* only one bit is set in the literal, so use a bcf instruction */
5421 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5422 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5425 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5426 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5427 if(know_W != (lit&0xff))
5428 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5430 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5435 if (AOP_TYPE(left) == AOP_ACC) {
5436 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5438 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5439 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5446 // left & result in different registers
5447 if(AOP_TYPE(result) == AOP_CRY){
5449 // if(size), result in bit
5450 // if(!size && ifx), conditional oper: if(left & right)
5451 symbol *tlbl = newiTempLabel(NULL);
5452 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5454 pic14_emitcode("setb","c");
5456 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5457 pic14_emitcode("anl","a,%s",
5458 aopGet(AOP(left),offset,FALSE,FALSE));
5459 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5464 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5465 pic14_outBitC(result);
5467 jmpTrueOrFalse(ifx, tlbl);
5469 for(;(size--);offset++) {
5471 // result = left & right
5472 if(AOP_TYPE(right) == AOP_LIT){
5473 int t = (lit >> (offset*8)) & 0x0FFL;
5476 pic14_emitcode("clrf","%s",
5477 aopGet(AOP(result),offset,FALSE,FALSE));
5478 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5481 pic14_emitcode("movf","%s,w",
5482 aopGet(AOP(left),offset,FALSE,FALSE));
5483 pic14_emitcode("movwf","%s",
5484 aopGet(AOP(result),offset,FALSE,FALSE));
5485 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5486 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5489 pic14_emitcode("movlw","0x%x",t);
5490 pic14_emitcode("andwf","%s,w",
5491 aopGet(AOP(left),offset,FALSE,FALSE));
5492 pic14_emitcode("movwf","%s",
5493 aopGet(AOP(result),offset,FALSE,FALSE));
5495 emitpcode(POC_MOVLW, popGetLit(t));
5496 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5497 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5502 if (AOP_TYPE(left) == AOP_ACC) {
5503 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5504 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5506 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5507 pic14_emitcode("andwf","%s,w",
5508 aopGet(AOP(left),offset,FALSE,FALSE));
5509 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5510 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5512 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5513 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5519 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5520 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521 freeAsmop(result,NULL,ic,TRUE);
5524 /*-----------------------------------------------------------------*/
5525 /* genOr - code for or */
5526 /*-----------------------------------------------------------------*/
5527 static void genOr (iCode *ic, iCode *ifx)
5529 operand *left, *right, *result;
5531 unsigned long lit = 0L;
5533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5535 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5536 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5537 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5539 DEBUGpic14_AopType(__LINE__,left,right,result);
5541 /* if left is a literal & right is not then exchange them */
5542 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5543 AOP_NEEDSACC(left)) {
5544 operand *tmp = right ;
5549 /* if result = right then exchange them */
5550 if(pic14_sameRegs(AOP(result),AOP(right))){
5551 operand *tmp = right ;
5556 /* if right is bit then exchange them */
5557 if (AOP_TYPE(right) == AOP_CRY &&
5558 AOP_TYPE(left) != AOP_CRY){
5559 operand *tmp = right ;
5564 DEBUGpic14_AopType(__LINE__,left,right,result);
5566 if(AOP_TYPE(right) == AOP_LIT)
5567 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5569 size = AOP_SIZE(result);
5573 if (AOP_TYPE(left) == AOP_CRY){
5574 if(AOP_TYPE(right) == AOP_LIT){
5575 // c = bit & literal;
5577 // lit != 0 => result = 1
5578 if(AOP_TYPE(result) == AOP_CRY){
5580 emitpcode(POC_BSF, popGet(AOP(result),0));
5581 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5582 // AOP(result)->aopu.aop_dir,
5583 // AOP(result)->aopu.aop_dir);
5585 continueIfTrue(ifx);
5589 // lit == 0 => result = left
5590 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5592 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5595 if (AOP_TYPE(right) == AOP_CRY){
5596 if(pic14_sameRegs(AOP(result),AOP(left))){
5598 emitpcode(POC_BCF, popGet(AOP(result),0));
5599 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5600 emitpcode(POC_BSF, popGet(AOP(result),0));
5602 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5603 AOP(result)->aopu.aop_dir,
5604 AOP(result)->aopu.aop_dir);
5605 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5606 AOP(right)->aopu.aop_dir,
5607 AOP(right)->aopu.aop_dir);
5608 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5609 AOP(result)->aopu.aop_dir,
5610 AOP(result)->aopu.aop_dir);
5612 if( AOP_TYPE(result) == AOP_ACC) {
5613 emitpcode(POC_MOVLW, popGetLit(0));
5614 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5615 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5616 emitpcode(POC_MOVLW, popGetLit(1));
5620 emitpcode(POC_BCF, popGet(AOP(result),0));
5621 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5622 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5623 emitpcode(POC_BSF, popGet(AOP(result),0));
5625 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5626 AOP(result)->aopu.aop_dir,
5627 AOP(result)->aopu.aop_dir);
5628 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5629 AOP(right)->aopu.aop_dir,
5630 AOP(right)->aopu.aop_dir);
5631 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5632 AOP(left)->aopu.aop_dir,
5633 AOP(left)->aopu.aop_dir);
5634 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5635 AOP(result)->aopu.aop_dir,
5636 AOP(result)->aopu.aop_dir);
5641 symbol *tlbl = newiTempLabel(NULL);
5642 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5645 emitpcode(POC_BCF, popGet(AOP(result),0));
5646 if( AOP_TYPE(right) == AOP_ACC) {
5647 emitpcode(POC_IORLW, popGetLit(0));
5649 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5650 emitpcode(POC_BSF, popGet(AOP(result),0));
5655 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5656 pic14_emitcode(";XXX setb","c");
5657 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5658 AOP(left)->aopu.aop_dir,tlbl->key+100);
5659 pic14_toBoolean(right);
5660 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5661 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5662 jmpTrueOrFalse(ifx, tlbl);
5666 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5673 pic14_outBitC(result);
5675 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5676 genIfxJump(ifx, "c");
5680 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5681 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5682 if((AOP_TYPE(right) == AOP_LIT) &&
5683 (AOP_TYPE(result) == AOP_CRY) &&
5684 (AOP_TYPE(left) != AOP_CRY)){
5686 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5689 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5691 continueIfTrue(ifx);
5694 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5695 // lit = 0, result = boolean(left)
5697 pic14_emitcode(";XXX setb","c");
5698 pic14_toBoolean(right);
5700 symbol *tlbl = newiTempLabel(NULL);
5701 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5703 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5705 genIfxJump (ifx,"a");
5709 pic14_outBitC(result);
5713 /* if left is same as result */
5714 if(pic14_sameRegs(AOP(result),AOP(left))){
5716 for(;size--; offset++,lit>>=8) {
5717 if(AOP_TYPE(right) == AOP_LIT){
5718 if((lit & 0xff) == 0)
5719 /* or'ing with 0 has no effect */
5722 int p = my_powof2(lit & 0xff);
5724 /* only one bit is set in the literal, so use a bsf instruction */
5726 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5728 if(know_W != (lit & 0xff))
5729 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5730 know_W = lit & 0xff;
5731 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5736 if (AOP_TYPE(left) == AOP_ACC) {
5737 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5738 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5740 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5741 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5743 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5744 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5750 // left & result in different registers
5751 if(AOP_TYPE(result) == AOP_CRY){
5753 // if(size), result in bit
5754 // if(!size && ifx), conditional oper: if(left | right)
5755 symbol *tlbl = newiTempLabel(NULL);
5756 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5757 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5761 pic14_emitcode(";XXX setb","c");
5763 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5764 pic14_emitcode(";XXX orl","a,%s",
5765 aopGet(AOP(left),offset,FALSE,FALSE));
5766 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5771 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5772 pic14_outBitC(result);
5774 jmpTrueOrFalse(ifx, tlbl);
5775 } else for(;(size--);offset++){
5777 // result = left & right
5778 if(AOP_TYPE(right) == AOP_LIT){
5779 int t = (lit >> (offset*8)) & 0x0FFL;
5782 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5783 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5785 pic14_emitcode("movf","%s,w",
5786 aopGet(AOP(left),offset,FALSE,FALSE));
5787 pic14_emitcode("movwf","%s",
5788 aopGet(AOP(result),offset,FALSE,FALSE));
5791 emitpcode(POC_MOVLW, popGetLit(t));
5792 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5793 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5795 pic14_emitcode("movlw","0x%x",t);
5796 pic14_emitcode("iorwf","%s,w",
5797 aopGet(AOP(left),offset,FALSE,FALSE));
5798 pic14_emitcode("movwf","%s",
5799 aopGet(AOP(result),offset,FALSE,FALSE));
5805 // faster than result <- left, anl result,right
5806 // and better if result is SFR
5807 if (AOP_TYPE(left) == AOP_ACC) {
5808 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5809 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5811 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5812 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5814 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5815 pic14_emitcode("iorwf","%s,w",
5816 aopGet(AOP(left),offset,FALSE,FALSE));
5818 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5819 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5824 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5825 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826 freeAsmop(result,NULL,ic,TRUE);
5829 /*-----------------------------------------------------------------*/
5830 /* genXor - code for xclusive or */
5831 /*-----------------------------------------------------------------*/
5832 static void genXor (iCode *ic, iCode *ifx)
5834 operand *left, *right, *result;
5836 unsigned long lit = 0L;
5838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5840 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5841 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5842 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5844 /* if left is a literal & right is not ||
5845 if left needs acc & right does not */
5846 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5847 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5848 operand *tmp = right ;
5853 /* if result = right then exchange them */
5854 if(pic14_sameRegs(AOP(result),AOP(right))){
5855 operand *tmp = right ;
5860 /* if right is bit then exchange them */
5861 if (AOP_TYPE(right) == AOP_CRY &&
5862 AOP_TYPE(left) != AOP_CRY){
5863 operand *tmp = right ;
5867 if(AOP_TYPE(right) == AOP_LIT)
5868 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5870 size = AOP_SIZE(result);
5874 if (AOP_TYPE(left) == AOP_CRY){
5875 if(AOP_TYPE(right) == AOP_LIT){
5876 // c = bit & literal;
5878 // lit>>1 != 0 => result = 1
5879 if(AOP_TYPE(result) == AOP_CRY){
5881 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5882 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5884 continueIfTrue(ifx);
5887 pic14_emitcode("setb","c");
5891 // lit == 0, result = left
5892 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5894 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5896 // lit == 1, result = not(left)
5897 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5898 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5899 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5900 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5903 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5904 pic14_emitcode("cpl","c");
5911 symbol *tlbl = newiTempLabel(NULL);
5912 if (AOP_TYPE(right) == AOP_CRY){
5914 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5917 int sizer = AOP_SIZE(right);
5919 // if val>>1 != 0, result = 1
5920 pic14_emitcode("setb","c");
5922 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5924 // test the msb of the lsb
5925 pic14_emitcode("anl","a,#0xfe");
5926 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5930 pic14_emitcode("rrc","a");
5932 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5933 pic14_emitcode("cpl","c");
5934 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5939 pic14_outBitC(result);
5941 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5942 genIfxJump(ifx, "c");
5946 if(pic14_sameRegs(AOP(result),AOP(left))){
5947 /* if left is same as result */
5948 for(;size--; offset++) {
5949 if(AOP_TYPE(right) == AOP_LIT){
5950 int t = (lit >> (offset*8)) & 0x0FFL;
5954 if (IS_AOP_PREG(left)) {
5955 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5956 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5957 aopPut(AOP(result),"a",offset);
5959 emitpcode(POC_MOVLW, popGetLit(t));
5960 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5961 pic14_emitcode("xrl","%s,%s",
5962 aopGet(AOP(left),offset,FALSE,TRUE),
5963 aopGet(AOP(right),offset,FALSE,FALSE));
5966 if (AOP_TYPE(left) == AOP_ACC)
5967 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5969 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5970 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5972 if (IS_AOP_PREG(left)) {
5973 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5974 aopPut(AOP(result),"a",offset);
5976 pic14_emitcode("xrl","%s,a",
5977 aopGet(AOP(left),offset,FALSE,TRUE));
5983 // left & result in different registers
5984 if(AOP_TYPE(result) == AOP_CRY){
5986 // if(size), result in bit
5987 // if(!size && ifx), conditional oper: if(left ^ right)
5988 symbol *tlbl = newiTempLabel(NULL);
5989 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5991 pic14_emitcode("setb","c");
5993 if((AOP_TYPE(right) == AOP_LIT) &&
5994 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5995 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5997 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5998 pic14_emitcode("xrl","a,%s",
5999 aopGet(AOP(left),offset,FALSE,FALSE));
6001 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6006 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6007 pic14_outBitC(result);
6009 jmpTrueOrFalse(ifx, tlbl);
6010 } else for(;(size--);offset++){
6012 // result = left & right
6013 if(AOP_TYPE(right) == AOP_LIT){
6014 int t = (lit >> (offset*8)) & 0x0FFL;
6017 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6018 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6019 pic14_emitcode("movf","%s,w",
6020 aopGet(AOP(left),offset,FALSE,FALSE));
6021 pic14_emitcode("movwf","%s",
6022 aopGet(AOP(result),offset,FALSE,FALSE));
6025 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6026 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027 pic14_emitcode("comf","%s,w",
6028 aopGet(AOP(left),offset,FALSE,FALSE));
6029 pic14_emitcode("movwf","%s",
6030 aopGet(AOP(result),offset,FALSE,FALSE));
6033 emitpcode(POC_MOVLW, popGetLit(t));
6034 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6035 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6036 pic14_emitcode("movlw","0x%x",t);
6037 pic14_emitcode("xorwf","%s,w",
6038 aopGet(AOP(left),offset,FALSE,FALSE));
6039 pic14_emitcode("movwf","%s",
6040 aopGet(AOP(result),offset,FALSE,FALSE));
6046 // faster than result <- left, anl result,right
6047 // and better if result is SFR
6048 if (AOP_TYPE(left) == AOP_ACC) {
6049 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6050 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6052 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6053 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6054 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6055 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6057 if ( AOP_TYPE(result) != AOP_ACC){
6058 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6059 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6065 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6066 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067 freeAsmop(result,NULL,ic,TRUE);
6070 /*-----------------------------------------------------------------*/
6071 /* genInline - write the inline code out */
6072 /*-----------------------------------------------------------------*/
6073 static void genInline (iCode *ic)
6075 char *buffer, *bp, *bp1;
6077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6079 _G.inLine += (!options.asmpeep);
6081 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6082 strcpy(buffer,IC_INLINE(ic));
6084 /* emit each line as a code */
6090 addpCode2pBlock(pb,AssembleLine(bp1));
6097 pic14_emitcode(bp1,"");
6103 if ((bp1 != bp) && *bp1)
6104 addpCode2pBlock(pb,AssembleLine(bp1));
6108 _G.inLine -= (!options.asmpeep);
6111 /*-----------------------------------------------------------------*/
6112 /* genRRC - rotate right with carry */
6113 /*-----------------------------------------------------------------*/
6114 static void genRRC (iCode *ic)
6116 operand *left , *result ;
6117 int size, offset = 0, same;
6119 /* rotate right with carry */
6121 result=IC_RESULT(ic);
6122 aopOp (left,ic,FALSE);
6123 aopOp (result,ic,FALSE);
6125 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6127 same = pic14_sameRegs(AOP(result),AOP(left));
6129 size = AOP_SIZE(result);
6131 /* get the lsb and put it into the carry */
6132 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6139 emitpcode(POC_RRF, popGet(AOP(left),offset));
6141 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6142 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6148 freeAsmop(left,NULL,ic,TRUE);
6149 freeAsmop(result,NULL,ic,TRUE);
6152 /*-----------------------------------------------------------------*/
6153 /* genRLC - generate code for rotate left with carry */
6154 /*-----------------------------------------------------------------*/
6155 static void genRLC (iCode *ic)
6157 operand *left , *result ;
6158 int size, offset = 0;
6161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6162 /* rotate right with carry */
6164 result=IC_RESULT(ic);
6165 aopOp (left,ic,FALSE);
6166 aopOp (result,ic,FALSE);
6168 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6170 same = pic14_sameRegs(AOP(result),AOP(left));
6172 /* move it to the result */
6173 size = AOP_SIZE(result);
6175 /* get the msb and put it into the carry */
6176 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6183 emitpcode(POC_RLF, popGet(AOP(left),offset));
6185 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6186 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6193 freeAsmop(left,NULL,ic,TRUE);
6194 freeAsmop(result,NULL,ic,TRUE);
6197 /*-----------------------------------------------------------------*/
6198 /* genGetHbit - generates code get highest order bit */
6199 /*-----------------------------------------------------------------*/
6200 static void genGetHbit (iCode *ic)
6202 operand *left, *result;
6204 result=IC_RESULT(ic);
6205 aopOp (left,ic,FALSE);
6206 aopOp (result,ic,FALSE);
6208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6209 /* get the highest order byte into a */
6210 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6211 if(AOP_TYPE(result) == AOP_CRY){
6212 pic14_emitcode("rlc","a");
6213 pic14_outBitC(result);
6216 pic14_emitcode("rl","a");
6217 pic14_emitcode("anl","a,#0x01");
6218 pic14_outAcc(result);
6222 freeAsmop(left,NULL,ic,TRUE);
6223 freeAsmop(result,NULL,ic,TRUE);
6226 /*-----------------------------------------------------------------*/
6227 /* AccRol - rotate left accumulator by known count */
6228 /*-----------------------------------------------------------------*/
6229 static void AccRol (int shCount)
6231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6232 shCount &= 0x0007; // shCount : 0..7
6237 pic14_emitcode("rl","a");
6240 pic14_emitcode("rl","a");
6241 pic14_emitcode("rl","a");
6244 pic14_emitcode("swap","a");
6245 pic14_emitcode("rr","a");
6248 pic14_emitcode("swap","a");
6251 pic14_emitcode("swap","a");
6252 pic14_emitcode("rl","a");
6255 pic14_emitcode("rr","a");
6256 pic14_emitcode("rr","a");
6259 pic14_emitcode("rr","a");
6264 /*-----------------------------------------------------------------*/
6265 /* AccLsh - left shift accumulator by known count */
6266 /*-----------------------------------------------------------------*/
6267 static void AccLsh (int shCount)
6269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6272 pic14_emitcode("add","a,acc");
6275 pic14_emitcode("add","a,acc");
6276 pic14_emitcode("add","a,acc");
6278 /* rotate left accumulator */
6280 /* and kill the lower order bits */
6281 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6286 /*-----------------------------------------------------------------*/
6287 /* AccRsh - right shift accumulator by known count */
6288 /*-----------------------------------------------------------------*/
6289 static void AccRsh (int shCount)
6291 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6295 pic14_emitcode("rrc","a");
6297 /* rotate right accumulator */
6298 AccRol(8 - shCount);
6299 /* and kill the higher order bits */
6300 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6306 /*-----------------------------------------------------------------*/
6307 /* AccSRsh - signed right shift accumulator by known count */
6308 /*-----------------------------------------------------------------*/
6309 static void AccSRsh (int shCount)
6312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6315 pic14_emitcode("mov","c,acc.7");
6316 pic14_emitcode("rrc","a");
6317 } else if(shCount == 2){
6318 pic14_emitcode("mov","c,acc.7");
6319 pic14_emitcode("rrc","a");
6320 pic14_emitcode("mov","c,acc.7");
6321 pic14_emitcode("rrc","a");
6323 tlbl = newiTempLabel(NULL);
6324 /* rotate right accumulator */
6325 AccRol(8 - shCount);
6326 /* and kill the higher order bits */
6327 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6328 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6329 pic14_emitcode("orl","a,#0x%02x",
6330 (unsigned char)~SRMask[shCount]);
6331 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6336 /*-----------------------------------------------------------------*/
6337 /* shiftR1Left2Result - shift right one byte from left to result */
6338 /*-----------------------------------------------------------------*/
6339 static void shiftR1Left2ResultSigned (operand *left, int offl,
6340 operand *result, int offr,
6345 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6347 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6351 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6353 emitpcode(POC_RRF, popGet(AOP(result),offr));
6355 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6356 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6362 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6364 emitpcode(POC_RRF, popGet(AOP(result),offr));
6366 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6367 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6369 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6370 emitpcode(POC_RRF, popGet(AOP(result),offr));
6376 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6378 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6379 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6382 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6383 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6384 emitpcode(POC_ANDLW, popGetLit(0x1f));
6386 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6387 emitpcode(POC_IORLW, popGetLit(0xe0));
6389 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6393 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6394 emitpcode(POC_ANDLW, popGetLit(0x0f));
6395 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6396 emitpcode(POC_IORLW, popGetLit(0xf0));
6397 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6401 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6403 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6404 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6407 emitpcode(POC_ANDLW, popGetLit(0x07));
6408 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6409 emitpcode(POC_IORLW, popGetLit(0xf8));
6410 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415 emitpcode(POC_MOVLW, popGetLit(0x00));
6416 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6417 emitpcode(POC_MOVLW, popGetLit(0xfe));
6418 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6419 emitpcode(POC_IORLW, popGetLit(0x01));
6420 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6423 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6424 emitpcode(POC_DECF, popGet(AOP(result),offr));
6425 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6426 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6432 emitpcode(POC_MOVLW, popGetLit(0x00));
6433 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6434 emitpcode(POC_MOVLW, popGetLit(0xff));
6435 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6437 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6438 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6439 emitpcode(POC_DECF, popGet(AOP(result),offr));
6447 /*-----------------------------------------------------------------*/
6448 /* shiftR1Left2Result - shift right one byte from left to result */
6449 /*-----------------------------------------------------------------*/
6450 static void shiftR1Left2Result (operand *left, int offl,
6451 operand *result, int offr,
6452 int shCount, int sign)
6456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6458 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6460 /* Copy the msb into the carry if signed. */
6462 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6472 emitpcode(POC_RRF, popGet(AOP(result),offr));
6474 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6481 emitpcode(POC_RRF, popGet(AOP(result),offr));
6483 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6484 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6487 emitpcode(POC_RRF, popGet(AOP(result),offr));
6492 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6494 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6495 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6498 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6499 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6500 emitpcode(POC_ANDLW, popGetLit(0x1f));
6501 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6506 emitpcode(POC_ANDLW, popGetLit(0x0f));
6507 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6511 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW, popGetLit(0x0f));
6513 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6515 emitpcode(POC_RRF, popGet(AOP(result),offr));
6520 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6521 emitpcode(POC_ANDLW, popGetLit(0x80));
6522 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6523 emitpcode(POC_RLF, popGet(AOP(result),offr));
6524 emitpcode(POC_RLF, popGet(AOP(result),offr));
6529 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6530 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6531 emitpcode(POC_RLF, popGet(AOP(result),offr));
6540 /*-----------------------------------------------------------------*/
6541 /* shiftL1Left2Result - shift left one byte from left to result */
6542 /*-----------------------------------------------------------------*/
6543 static void shiftL1Left2Result (operand *left, int offl,
6544 operand *result, int offr, int shCount)
6549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6551 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6552 DEBUGpic14_emitcode ("; ***","same = %d",same);
6553 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6555 /* shift left accumulator */
6556 //AccLsh(shCount); // don't comment out just yet...
6557 // aopPut(AOP(result),"a",offr);
6561 /* Shift left 1 bit position */
6562 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6564 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6566 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6567 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6571 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6572 emitpcode(POC_ANDLW,popGetLit(0x7e));
6573 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6574 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6577 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6578 emitpcode(POC_ANDLW,popGetLit(0x3e));
6579 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6580 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6581 emitpcode(POC_RLF, popGet(AOP(result),offr));
6584 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6585 emitpcode(POC_ANDLW, popGetLit(0xf0));
6586 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6590 emitpcode(POC_ANDLW, popGetLit(0xf0));
6591 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6592 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6595 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6596 emitpcode(POC_ANDLW, popGetLit(0x30));
6597 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6598 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6599 emitpcode(POC_RLF, popGet(AOP(result),offr));
6602 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6603 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6604 emitpcode(POC_RRF, popGet(AOP(result),offr));
6608 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6613 /*-----------------------------------------------------------------*/
6614 /* movLeft2Result - move byte from left to result */
6615 /*-----------------------------------------------------------------*/
6616 static void movLeft2Result (operand *left, int offl,
6617 operand *result, int offr)
6620 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6621 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6622 l = aopGet(AOP(left),offl,FALSE,FALSE);
6624 if (*l == '@' && (IS_AOP_PREG(result))) {
6625 pic14_emitcode("mov","a,%s",l);
6626 aopPut(AOP(result),"a",offr);
6628 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6629 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6634 /*-----------------------------------------------------------------*/
6635 /* shiftL2Left2Result - shift left two bytes from left to result */
6636 /*-----------------------------------------------------------------*/
6637 static void shiftL2Left2Result (operand *left, int offl,
6638 operand *result, int offr, int shCount)
6642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6644 if(pic14_sameRegs(AOP(result), AOP(left))) {
6652 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6653 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6654 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_RLF, popGet(AOP(result),offr));
6659 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6665 emitpcode(POC_MOVLW, popGetLit(0x0f));
6666 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6669 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6670 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6671 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6673 emitpcode(POC_RLF, popGet(AOP(result),offr));
6674 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6679 emitpcode(POC_RRF, popGet(AOP(result),offr));
6680 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_RRF, popGet(AOP(result),offr));
6682 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_ANDLW,popGetLit(0xc0));
6684 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6685 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6686 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6690 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6691 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6692 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6693 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6694 emitpcode(POC_RRF, popGet(AOP(result),offr));
6704 /* note, use a mov/add for the shift since the mov has a
6705 chance of getting optimized out */
6706 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6707 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6708 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6709 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6710 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6714 emitpcode(POC_RLF, popGet(AOP(result),offr));
6715 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6721 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6722 emitpcode(POC_ANDLW, popGetLit(0xF0));
6723 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6724 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6725 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6726 emitpcode(POC_ANDLW, popGetLit(0xF0));
6727 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6728 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6732 emitpcode(POC_RLF, popGet(AOP(result),offr));
6733 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6737 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6738 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6740 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6742 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_RRF, popGet(AOP(result),offr));
6744 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6745 emitpcode(POC_ANDLW,popGetLit(0xc0));
6746 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6747 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6748 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6749 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6752 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6753 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6754 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6756 emitpcode(POC_RRF, popGet(AOP(result),offr));
6761 /*-----------------------------------------------------------------*/
6762 /* shiftR2Left2Result - shift right two bytes from left to result */
6763 /*-----------------------------------------------------------------*/
6764 static void shiftR2Left2Result (operand *left, int offl,
6765 operand *result, int offr,
6766 int shCount, int sign)
6770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6771 same = pic14_sameRegs(AOP(result), AOP(left));
6773 if(same && ((offl + MSB16) == offr)){
6775 /* don't crash result[offr] */
6776 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6777 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6779 movLeft2Result(left,offl, result, offr);
6780 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6782 /* a:x >> shCount (x = lsb(result))*/
6785 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6787 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6796 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6801 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_RRF,popGet(AOP(result),offr));
6804 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6805 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6806 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6807 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6812 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6815 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_RRF,popGet(AOP(result),offr));
6823 emitpcode(POC_MOVLW, popGetLit(0xf0));
6824 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6825 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6827 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6828 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6829 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6830 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6832 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6833 emitpcode(POC_ANDLW, popGetLit(0x0f));
6834 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6836 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6837 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6838 emitpcode(POC_ANDLW, popGetLit(0xf0));
6839 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6840 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6844 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6845 emitpcode(POC_RRF, popGet(AOP(result),offr));
6849 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6850 emitpcode(POC_BTFSC,
6851 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6852 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6860 emitpcode(POC_RLF, popGet(AOP(result),offr));
6861 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6863 emitpcode(POC_RLF, popGet(AOP(result),offr));
6864 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6865 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6866 emitpcode(POC_ANDLW,popGetLit(0x03));
6868 emitpcode(POC_BTFSC,
6869 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6870 emitpcode(POC_IORLW,popGetLit(0xfc));
6872 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6873 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6874 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6875 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6877 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6878 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6879 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6880 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6881 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6882 emitpcode(POC_ANDLW,popGetLit(0x03));
6884 emitpcode(POC_BTFSC,
6885 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6886 emitpcode(POC_IORLW,popGetLit(0xfc));
6888 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6889 emitpcode(POC_RLF, popGet(AOP(result),offr));
6896 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6897 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6898 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6899 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6902 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6904 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6909 /*-----------------------------------------------------------------*/
6910 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6911 /*-----------------------------------------------------------------*/
6912 static void shiftLLeftOrResult (operand *left, int offl,
6913 operand *result, int offr, int shCount)
6915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6916 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6917 /* shift left accumulator */
6919 /* or with result */
6920 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6921 /* back to result */
6922 aopPut(AOP(result),"a",offr);
6925 /*-----------------------------------------------------------------*/
6926 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6927 /*-----------------------------------------------------------------*/
6928 static void shiftRLeftOrResult (operand *left, int offl,
6929 operand *result, int offr, int shCount)
6931 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6932 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6933 /* shift right accumulator */
6935 /* or with result */
6936 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6937 /* back to result */
6938 aopPut(AOP(result),"a",offr);
6941 /*-----------------------------------------------------------------*/
6942 /* genlshOne - left shift a one byte quantity by known count */
6943 /*-----------------------------------------------------------------*/
6944 static void genlshOne (operand *result, operand *left, int shCount)
6946 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6947 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6950 /*-----------------------------------------------------------------*/
6951 /* genlshTwo - left shift two bytes by known amount != 0 */
6952 /*-----------------------------------------------------------------*/
6953 static void genlshTwo (operand *result,operand *left, int shCount)
6957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6958 size = pic14_getDataSize(result);
6960 /* if shCount >= 8 */
6966 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6968 movLeft2Result(left, LSB, result, MSB16);
6970 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6973 /* 1 <= shCount <= 7 */
6976 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6978 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6982 /*-----------------------------------------------------------------*/
6983 /* shiftLLong - shift left one long from left to result */
6984 /* offl = LSB or MSB16 */
6985 /*-----------------------------------------------------------------*/
6986 static void shiftLLong (operand *left, operand *result, int offr )
6989 int size = AOP_SIZE(result);
6991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6992 if(size >= LSB+offr){
6993 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6995 pic14_emitcode("add","a,acc");
6996 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6997 size >= MSB16+offr && offr != LSB )
6998 pic14_emitcode("xch","a,%s",
6999 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7001 aopPut(AOP(result),"a",LSB+offr);
7004 if(size >= MSB16+offr){
7005 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7006 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7009 pic14_emitcode("rlc","a");
7010 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7011 size >= MSB24+offr && offr != LSB)
7012 pic14_emitcode("xch","a,%s",
7013 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7015 aopPut(AOP(result),"a",MSB16+offr);
7018 if(size >= MSB24+offr){
7019 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7020 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7023 pic14_emitcode("rlc","a");
7024 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7025 size >= MSB32+offr && offr != LSB )
7026 pic14_emitcode("xch","a,%s",
7027 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7029 aopPut(AOP(result),"a",MSB24+offr);
7032 if(size > MSB32+offr){
7033 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7034 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7037 pic14_emitcode("rlc","a");
7038 aopPut(AOP(result),"a",MSB32+offr);
7041 aopPut(AOP(result),zero,LSB);
7044 /*-----------------------------------------------------------------*/
7045 /* genlshFour - shift four byte by a known amount != 0 */
7046 /*-----------------------------------------------------------------*/
7047 static void genlshFour (operand *result, operand *left, int shCount)
7051 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7052 size = AOP_SIZE(result);
7054 /* if shifting more that 3 bytes */
7055 if (shCount >= 24 ) {
7058 /* lowest order of left goes to the highest
7059 order of the destination */
7060 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7062 movLeft2Result(left, LSB, result, MSB32);
7063 aopPut(AOP(result),zero,LSB);
7064 aopPut(AOP(result),zero,MSB16);
7065 aopPut(AOP(result),zero,MSB32);
7069 /* more than two bytes */
7070 else if ( shCount >= 16 ) {
7071 /* lower order two bytes goes to higher order two bytes */
7073 /* if some more remaining */
7075 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7077 movLeft2Result(left, MSB16, result, MSB32);
7078 movLeft2Result(left, LSB, result, MSB24);
7080 aopPut(AOP(result),zero,MSB16);
7081 aopPut(AOP(result),zero,LSB);
7085 /* if more than 1 byte */
7086 else if ( shCount >= 8 ) {
7087 /* lower order three bytes goes to higher order three bytes */
7091 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7093 movLeft2Result(left, LSB, result, MSB16);
7095 else{ /* size = 4 */
7097 movLeft2Result(left, MSB24, result, MSB32);
7098 movLeft2Result(left, MSB16, result, MSB24);
7099 movLeft2Result(left, LSB, result, MSB16);
7100 aopPut(AOP(result),zero,LSB);
7102 else if(shCount == 1)
7103 shiftLLong(left, result, MSB16);
7105 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7106 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7107 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7108 aopPut(AOP(result),zero,LSB);
7113 /* 1 <= shCount <= 7 */
7114 else if(shCount <= 2){
7115 shiftLLong(left, result, LSB);
7117 shiftLLong(result, result, LSB);
7119 /* 3 <= shCount <= 7, optimize */
7121 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7122 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7123 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7127 /*-----------------------------------------------------------------*/
7128 /* genLeftShiftLiteral - left shifting by known count */
7129 /*-----------------------------------------------------------------*/
7130 static void genLeftShiftLiteral (operand *left,
7135 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7139 freeAsmop(right,NULL,ic,TRUE);
7141 aopOp(left,ic,FALSE);
7142 aopOp(result,ic,FALSE);
7144 size = getSize(operandType(result));
7147 pic14_emitcode("; shift left ","result %d, left %d",size,
7151 /* I suppose that the left size >= result size */
7154 movLeft2Result(left, size, result, size);
7158 else if(shCount >= (size * 8))
7160 aopPut(AOP(result),zero,size);
7164 genlshOne (result,left,shCount);
7169 genlshTwo (result,left,shCount);
7173 genlshFour (result,left,shCount);
7177 freeAsmop(left,NULL,ic,TRUE);
7178 freeAsmop(result,NULL,ic,TRUE);
7181 /*-----------------------------------------------------------------*
7182 * genMultiAsm - repeat assembly instruction for size of register.
7183 * if endian == 1, then the high byte (i.e base address + size of
7184 * register) is used first else the low byte is used first;
7185 *-----------------------------------------------------------------*/
7186 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7204 emitpcode(poc, popGet(AOP(reg),offset));
7209 /*-----------------------------------------------------------------*/
7210 /* genLeftShift - generates code for left shifting */
7211 /*-----------------------------------------------------------------*/
7212 static void genLeftShift (iCode *ic)
7214 operand *left,*right, *result;
7217 symbol *tlbl , *tlbl1;
7220 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7222 right = IC_RIGHT(ic);
7224 result = IC_RESULT(ic);
7226 aopOp(right,ic,FALSE);
7228 /* if the shift count is known then do it
7229 as efficiently as possible */
7230 if (AOP_TYPE(right) == AOP_LIT) {
7231 genLeftShiftLiteral (left,right,result,ic);
7235 /* shift count is unknown then we have to form
7236 a loop get the loop count in B : Note: we take
7237 only the lower order byte since shifting
7238 more that 32 bits make no sense anyway, ( the
7239 largest size of an object can be only 32 bits ) */
7242 aopOp(left,ic,FALSE);
7243 aopOp(result,ic,FALSE);
7245 /* now move the left to the result if they are not the
7247 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7248 AOP_SIZE(result) > 1) {
7250 size = AOP_SIZE(result);
7253 l = aopGet(AOP(left),offset,FALSE,TRUE);
7254 if (*l == '@' && (IS_AOP_PREG(result))) {
7256 pic14_emitcode("mov","a,%s",l);
7257 aopPut(AOP(result),"a",offset);
7259 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7260 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7261 //aopPut(AOP(result),l,offset);
7267 size = AOP_SIZE(result);
7269 /* if it is only one byte then */
7271 if(optimized_for_speed) {
7272 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7273 emitpcode(POC_ANDLW, popGetLit(0xf0));
7274 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7275 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7276 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7277 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7278 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7279 emitpcode(POC_RLFW, popGet(AOP(result),0));
7280 emitpcode(POC_ANDLW, popGetLit(0xfe));
7281 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7282 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7283 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7286 tlbl = newiTempLabel(NULL);
7287 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7288 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7289 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7292 emitpcode(POC_COMFW, popGet(AOP(right),0));
7293 emitpcode(POC_RRF, popGet(AOP(result),0));
7294 emitpLabel(tlbl->key);
7295 emitpcode(POC_RLF, popGet(AOP(result),0));
7296 emitpcode(POC_ADDLW, popGetLit(1));
7298 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7303 if (pic14_sameRegs(AOP(left),AOP(result))) {
7305 tlbl = newiTempLabel(NULL);
7306 emitpcode(POC_COMFW, popGet(AOP(right),0));
7307 genMultiAsm(POC_RRF, result, size,1);
7308 emitpLabel(tlbl->key);
7309 genMultiAsm(POC_RLF, result, size,0);
7310 emitpcode(POC_ADDLW, popGetLit(1));
7312 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7316 //tlbl = newiTempLabel(NULL);
7318 //tlbl1 = newiTempLabel(NULL);
7320 //reAdjustPreg(AOP(result));
7322 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7323 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7324 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7326 //pic14_emitcode("add","a,acc");
7327 //aopPut(AOP(result),"a",offset++);
7329 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7331 // pic14_emitcode("rlc","a");
7332 // aopPut(AOP(result),"a",offset++);
7334 //reAdjustPreg(AOP(result));
7336 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7337 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7340 tlbl = newiTempLabel(NULL);
7341 tlbl1= newiTempLabel(NULL);
7343 size = AOP_SIZE(result);
7346 pctemp = popGetTempReg(); /* grab a temporary working register. */
7348 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7350 /* offset should be 0, 1 or 3 */
7351 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7353 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7355 emitpcode(POC_MOVWF, pctemp);
7358 emitpLabel(tlbl->key);
7361 emitpcode(POC_RLF, popGet(AOP(result),0));
7363 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7365 emitpcode(POC_DECFSZ, pctemp);
7366 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7367 emitpLabel(tlbl1->key);
7369 popReleaseTempReg(pctemp);
7373 freeAsmop (right,NULL,ic,TRUE);
7374 freeAsmop(left,NULL,ic,TRUE);
7375 freeAsmop(result,NULL,ic,TRUE);
7378 /*-----------------------------------------------------------------*/
7379 /* genrshOne - right shift a one byte quantity by known count */
7380 /*-----------------------------------------------------------------*/
7381 static void genrshOne (operand *result, operand *left,
7382 int shCount, int sign)
7384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7385 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7388 /*-----------------------------------------------------------------*/
7389 /* genrshTwo - right shift two bytes by known amount != 0 */
7390 /*-----------------------------------------------------------------*/
7391 static void genrshTwo (operand *result,operand *left,
7392 int shCount, int sign)
7394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7395 /* if shCount >= 8 */
7399 shiftR1Left2Result(left, MSB16, result, LSB,
7402 movLeft2Result(left, MSB16, result, LSB);
7404 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7407 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7408 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7412 /* 1 <= shCount <= 7 */
7414 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7417 /*-----------------------------------------------------------------*/
7418 /* shiftRLong - shift right one long from left to result */
7419 /* offl = LSB or MSB16 */
7420 /*-----------------------------------------------------------------*/
7421 static void shiftRLong (operand *left, int offl,
7422 operand *result, int sign)
7424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7426 pic14_emitcode("clr","c");
7427 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7429 pic14_emitcode("mov","c,acc.7");
7430 pic14_emitcode("rrc","a");
7431 aopPut(AOP(result),"a",MSB32-offl);
7433 /* add sign of "a" */
7434 addSign(result, MSB32, sign);
7436 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7437 pic14_emitcode("rrc","a");
7438 aopPut(AOP(result),"a",MSB24-offl);
7440 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7441 pic14_emitcode("rrc","a");
7442 aopPut(AOP(result),"a",MSB16-offl);
7445 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7446 pic14_emitcode("rrc","a");
7447 aopPut(AOP(result),"a",LSB);
7451 /*-----------------------------------------------------------------*/
7452 /* genrshFour - shift four byte by a known amount != 0 */
7453 /*-----------------------------------------------------------------*/
7454 static void genrshFour (operand *result, operand *left,
7455 int shCount, int sign)
7457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7458 /* if shifting more that 3 bytes */
7459 if(shCount >= 24 ) {
7462 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7464 movLeft2Result(left, MSB32, result, LSB);
7466 addSign(result, MSB16, sign);
7468 else if(shCount >= 16){
7471 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7473 movLeft2Result(left, MSB24, result, LSB);
7474 movLeft2Result(left, MSB32, result, MSB16);
7476 addSign(result, MSB24, sign);
7478 else if(shCount >= 8){
7481 shiftRLong(left, MSB16, result, sign);
7482 else if(shCount == 0){
7483 movLeft2Result(left, MSB16, result, LSB);
7484 movLeft2Result(left, MSB24, result, MSB16);
7485 movLeft2Result(left, MSB32, result, MSB24);
7486 addSign(result, MSB32, sign);
7489 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7490 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7491 /* the last shift is signed */
7492 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7493 addSign(result, MSB32, sign);
7496 else{ /* 1 <= shCount <= 7 */
7498 shiftRLong(left, LSB, result, sign);
7500 shiftRLong(result, LSB, result, sign);
7503 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7504 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7505 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7510 /*-----------------------------------------------------------------*/
7511 /* genRightShiftLiteral - right shifting by known count */
7512 /*-----------------------------------------------------------------*/
7513 static void genRightShiftLiteral (operand *left,
7519 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7523 freeAsmop(right,NULL,ic,TRUE);
7525 aopOp(left,ic,FALSE);
7526 aopOp(result,ic,FALSE);
7529 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7533 lsize = pic14_getDataSize(left);
7534 res_size = pic14_getDataSize(result);
7535 /* test the LEFT size !!! */
7537 /* I suppose that the left size >= result size */
7540 movLeft2Result(left, lsize, result, res_size);
7543 else if(shCount >= (lsize * 8)){
7546 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7548 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7549 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7554 emitpcode(POC_MOVLW, popGetLit(0));
7555 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7556 emitpcode(POC_MOVLW, popGetLit(0xff));
7558 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7563 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7570 genrshOne (result,left,shCount,sign);
7574 genrshTwo (result,left,shCount,sign);
7578 genrshFour (result,left,shCount,sign);
7586 freeAsmop(left,NULL,ic,TRUE);
7587 freeAsmop(result,NULL,ic,TRUE);
7590 /*-----------------------------------------------------------------*/
7591 /* genSignedRightShift - right shift of signed number */
7592 /*-----------------------------------------------------------------*/
7593 static void genSignedRightShift (iCode *ic)
7595 operand *right, *left, *result;
7598 symbol *tlbl, *tlbl1 ;
7601 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7603 /* we do it the hard way put the shift count in b
7604 and loop thru preserving the sign */
7605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7607 right = IC_RIGHT(ic);
7609 result = IC_RESULT(ic);
7611 aopOp(right,ic,FALSE);
7612 aopOp(left,ic,FALSE);
7613 aopOp(result,ic,FALSE);
7616 if ( AOP_TYPE(right) == AOP_LIT) {
7617 genRightShiftLiteral (left,right,result,ic,1);
7620 /* shift count is unknown then we have to form
7621 a loop get the loop count in B : Note: we take
7622 only the lower order byte since shifting
7623 more that 32 bits make no sense anyway, ( the
7624 largest size of an object can be only 32 bits ) */
7626 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7627 //pic14_emitcode("inc","b");
7628 //freeAsmop (right,NULL,ic,TRUE);
7629 //aopOp(left,ic,FALSE);
7630 //aopOp(result,ic,FALSE);
7632 /* now move the left to the result if they are not the
7634 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7635 AOP_SIZE(result) > 1) {
7637 size = AOP_SIZE(result);
7641 l = aopGet(AOP(left),offset,FALSE,TRUE);
7642 if (*l == '@' && IS_AOP_PREG(result)) {
7644 pic14_emitcode("mov","a,%s",l);
7645 aopPut(AOP(result),"a",offset);
7647 aopPut(AOP(result),l,offset);
7649 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7650 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7656 /* mov the highest order bit to OVR */
7657 tlbl = newiTempLabel(NULL);
7658 tlbl1= newiTempLabel(NULL);
7660 size = AOP_SIZE(result);
7663 pctemp = popGetTempReg(); /* grab a temporary working register. */
7665 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7667 /* offset should be 0, 1 or 3 */
7668 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7670 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7672 emitpcode(POC_MOVWF, pctemp);
7675 emitpLabel(tlbl->key);
7677 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7678 emitpcode(POC_RRF, popGet(AOP(result),offset));
7681 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7684 emitpcode(POC_DECFSZ, pctemp);
7685 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7686 emitpLabel(tlbl1->key);
7688 popReleaseTempReg(pctemp);
7690 size = AOP_SIZE(result);
7692 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7693 pic14_emitcode("rlc","a");
7694 pic14_emitcode("mov","ov,c");
7695 /* if it is only one byte then */
7697 l = aopGet(AOP(left),0,FALSE,FALSE);
7699 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7700 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7701 pic14_emitcode("mov","c,ov");
7702 pic14_emitcode("rrc","a");
7703 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7704 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7705 aopPut(AOP(result),"a",0);
7709 reAdjustPreg(AOP(result));
7710 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7711 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7712 pic14_emitcode("mov","c,ov");
7714 l = aopGet(AOP(result),offset,FALSE,FALSE);
7716 pic14_emitcode("rrc","a");
7717 aopPut(AOP(result),"a",offset--);
7719 reAdjustPreg(AOP(result));
7720 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7721 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7726 freeAsmop(left,NULL,ic,TRUE);
7727 freeAsmop(result,NULL,ic,TRUE);
7728 freeAsmop(right,NULL,ic,TRUE);
7731 /*-----------------------------------------------------------------*/
7732 /* genRightShift - generate code for right shifting */
7733 /*-----------------------------------------------------------------*/
7734 static void genRightShift (iCode *ic)
7736 operand *right, *left, *result;
7740 symbol *tlbl, *tlbl1 ;
7742 /* if signed then we do it the hard way preserve the
7743 sign bit moving it inwards */
7744 retype = getSpec(operandType(IC_RESULT(ic)));
7745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7747 if (!SPEC_USIGN(retype)) {
7748 genSignedRightShift (ic);
7752 /* signed & unsigned types are treated the same : i.e. the
7753 signed is NOT propagated inwards : quoting from the
7754 ANSI - standard : "for E1 >> E2, is equivalent to division
7755 by 2**E2 if unsigned or if it has a non-negative value,
7756 otherwise the result is implementation defined ", MY definition
7757 is that the sign does not get propagated */
7759 right = IC_RIGHT(ic);
7761 result = IC_RESULT(ic);
7763 aopOp(right,ic,FALSE);
7765 /* if the shift count is known then do it
7766 as efficiently as possible */
7767 if (AOP_TYPE(right) == AOP_LIT) {
7768 genRightShiftLiteral (left,right,result,ic, 0);
7772 /* shift count is unknown then we have to form
7773 a loop get the loop count in B : Note: we take
7774 only the lower order byte since shifting
7775 more that 32 bits make no sense anyway, ( the
7776 largest size of an object can be only 32 bits ) */
7778 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7779 pic14_emitcode("inc","b");
7780 aopOp(left,ic,FALSE);
7781 aopOp(result,ic,FALSE);
7783 /* now move the left to the result if they are not the
7785 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7786 AOP_SIZE(result) > 1) {
7788 size = AOP_SIZE(result);
7791 l = aopGet(AOP(left),offset,FALSE,TRUE);
7792 if (*l == '@' && IS_AOP_PREG(result)) {
7794 pic14_emitcode("mov","a,%s",l);
7795 aopPut(AOP(result),"a",offset);
7797 aopPut(AOP(result),l,offset);
7802 tlbl = newiTempLabel(NULL);
7803 tlbl1= newiTempLabel(NULL);
7804 size = AOP_SIZE(result);
7807 /* if it is only one byte then */
7810 tlbl = newiTempLabel(NULL);
7811 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7812 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7813 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7816 emitpcode(POC_COMFW, popGet(AOP(right),0));
7817 emitpcode(POC_RLF, popGet(AOP(result),0));
7818 emitpLabel(tlbl->key);
7819 emitpcode(POC_RRF, popGet(AOP(result),0));
7820 emitpcode(POC_ADDLW, popGetLit(1));
7822 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7827 reAdjustPreg(AOP(result));
7828 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7829 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7832 l = aopGet(AOP(result),offset,FALSE,FALSE);
7834 pic14_emitcode("rrc","a");
7835 aopPut(AOP(result),"a",offset--);
7837 reAdjustPreg(AOP(result));
7839 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7840 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7843 freeAsmop(left,NULL,ic,TRUE);
7844 freeAsmop (right,NULL,ic,TRUE);
7845 freeAsmop(result,NULL,ic,TRUE);
7848 /*-----------------------------------------------------------------*/
7849 /* genUnpackBits - generates code for unpacking bits */
7850 /*-----------------------------------------------------------------*/
7851 static void genUnpackBits (operand *result, char *rname, int ptype)
7858 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7859 etype = getSpec(operandType(result));
7861 /* read the first byte */
7866 pic14_emitcode("mov","a,@%s",rname);
7870 pic14_emitcode("movx","a,@%s",rname);
7874 pic14_emitcode("movx","a,@dptr");
7878 pic14_emitcode("clr","a");
7879 pic14_emitcode("movc","a","@a+dptr");
7883 pic14_emitcode("lcall","__gptrget");
7887 /* if we have bitdisplacement then it fits */
7888 /* into this byte completely or if length is */
7889 /* less than a byte */
7890 if ((shCnt = SPEC_BSTR(etype)) ||
7891 (SPEC_BLEN(etype) <= 8)) {
7893 /* shift right acc */
7896 pic14_emitcode("anl","a,#0x%02x",
7897 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7898 aopPut(AOP(result),"a",offset);
7902 /* bit field did not fit in a byte */
7903 rlen = SPEC_BLEN(etype) - 8;
7904 aopPut(AOP(result),"a",offset++);
7911 pic14_emitcode("inc","%s",rname);
7912 pic14_emitcode("mov","a,@%s",rname);
7916 pic14_emitcode("inc","%s",rname);
7917 pic14_emitcode("movx","a,@%s",rname);
7921 pic14_emitcode("inc","dptr");
7922 pic14_emitcode("movx","a,@dptr");
7926 pic14_emitcode("clr","a");
7927 pic14_emitcode("inc","dptr");
7928 pic14_emitcode("movc","a","@a+dptr");
7932 pic14_emitcode("inc","dptr");
7933 pic14_emitcode("lcall","__gptrget");
7938 /* if we are done */
7942 aopPut(AOP(result),"a",offset++);
7947 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7948 aopPut(AOP(result),"a",offset);
7955 /*-----------------------------------------------------------------*/
7956 /* genDataPointerGet - generates code when ptr offset is known */
7957 /*-----------------------------------------------------------------*/
7958 static void genDataPointerGet (operand *left,
7962 int size , offset = 0;
7965 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7968 /* optimization - most of the time, left and result are the same
7969 * address, but different types. for the pic code, we could omit
7973 aopOp(result,ic,TRUE);
7975 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7977 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7979 size = AOP_SIZE(result);
7982 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7986 freeAsmop(left,NULL,ic,TRUE);
7987 freeAsmop(result,NULL,ic,TRUE);
7990 /*-----------------------------------------------------------------*/
7991 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7992 /*-----------------------------------------------------------------*/
7993 static void genNearPointerGet (operand *left,
7998 //regs *preg = NULL ;
8000 sym_link *rtype, *retype;
8001 sym_link *ltype = operandType(left);
8004 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8006 rtype = operandType(result);
8007 retype= getSpec(rtype);
8009 aopOp(left,ic,FALSE);
8011 /* if left is rematerialisable and
8012 result is not bit variable type and
8013 the left is pointer to data space i.e
8014 lower 128 bytes of space */
8015 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8016 !IS_BITVAR(retype) &&
8017 DCL_TYPE(ltype) == POINTER) {
8018 //genDataPointerGet (left,result,ic);
8022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8024 /* if the value is already in a pointer register
8025 then don't need anything more */
8026 if (!AOP_INPREG(AOP(left))) {
8027 /* otherwise get a free pointer register */
8028 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8031 preg = getFreePtr(ic,&aop,FALSE);
8032 pic14_emitcode("mov","%s,%s",
8034 aopGet(AOP(left),0,FALSE,TRUE));
8035 rname = preg->name ;
8039 rname = aopGet(AOP(left),0,FALSE,FALSE);
8041 aopOp (result,ic,FALSE);
8043 /* if bitfield then unpack the bits */
8044 if (IS_BITVAR(retype))
8045 genUnpackBits (result,rname,POINTER);
8047 /* we have can just get the values */
8048 int size = AOP_SIZE(result);
8051 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8053 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8054 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8056 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8057 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8059 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8063 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8065 pic14_emitcode("mov","a,@%s",rname);
8066 aopPut(AOP(result),"a",offset);
8068 sprintf(buffer,"@%s",rname);
8069 aopPut(AOP(result),buffer,offset);
8073 pic14_emitcode("inc","%s",rname);
8078 /* now some housekeeping stuff */
8080 /* we had to allocate for this iCode */
8081 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8082 freeAsmop(NULL,aop,ic,TRUE);
8084 /* we did not allocate which means left
8085 already in a pointer register, then
8086 if size > 0 && this could be used again
8087 we have to point it back to where it
8089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8090 if (AOP_SIZE(result) > 1 &&
8091 !OP_SYMBOL(left)->remat &&
8092 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8094 int size = AOP_SIZE(result) - 1;
8096 pic14_emitcode("dec","%s",rname);
8101 freeAsmop(left,NULL,ic,TRUE);
8102 freeAsmop(result,NULL,ic,TRUE);
8106 /*-----------------------------------------------------------------*/
8107 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8108 /*-----------------------------------------------------------------*/
8109 static void genPagedPointerGet (operand *left,
8116 sym_link *rtype, *retype;
8118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8120 rtype = operandType(result);
8121 retype= getSpec(rtype);
8123 aopOp(left,ic,FALSE);
8125 /* if the value is already in a pointer register
8126 then don't need anything more */
8127 if (!AOP_INPREG(AOP(left))) {
8128 /* otherwise get a free pointer register */
8130 preg = getFreePtr(ic,&aop,FALSE);
8131 pic14_emitcode("mov","%s,%s",
8133 aopGet(AOP(left),0,FALSE,TRUE));
8134 rname = preg->name ;
8136 rname = aopGet(AOP(left),0,FALSE,FALSE);
8138 freeAsmop(left,NULL,ic,TRUE);
8139 aopOp (result,ic,FALSE);
8141 /* if bitfield then unpack the bits */
8142 if (IS_BITVAR(retype))
8143 genUnpackBits (result,rname,PPOINTER);
8145 /* we have can just get the values */
8146 int size = AOP_SIZE(result);
8151 pic14_emitcode("movx","a,@%s",rname);
8152 aopPut(AOP(result),"a",offset);
8157 pic14_emitcode("inc","%s",rname);
8161 /* now some housekeeping stuff */
8163 /* we had to allocate for this iCode */
8164 freeAsmop(NULL,aop,ic,TRUE);
8166 /* we did not allocate which means left
8167 already in a pointer register, then
8168 if size > 0 && this could be used again
8169 we have to point it back to where it
8171 if (AOP_SIZE(result) > 1 &&
8172 !OP_SYMBOL(left)->remat &&
8173 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8175 int size = AOP_SIZE(result) - 1;
8177 pic14_emitcode("dec","%s",rname);
8182 freeAsmop(result,NULL,ic,TRUE);
8187 /*-----------------------------------------------------------------*/
8188 /* genFarPointerGet - gget value from far space */
8189 /*-----------------------------------------------------------------*/
8190 static void genFarPointerGet (operand *left,
8191 operand *result, iCode *ic)
8194 sym_link *retype = getSpec(operandType(result));
8196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8198 aopOp(left,ic,FALSE);
8200 /* if the operand is already in dptr
8201 then we do nothing else we move the value to dptr */
8202 if (AOP_TYPE(left) != AOP_STR) {
8203 /* if this is remateriazable */
8204 if (AOP_TYPE(left) == AOP_IMMD)
8205 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8206 else { /* we need to get it byte by byte */
8207 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8208 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8209 if (options.model == MODEL_FLAT24)
8211 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8215 /* so dptr know contains the address */
8216 freeAsmop(left,NULL,ic,TRUE);
8217 aopOp(result,ic,FALSE);
8219 /* if bit then unpack */
8220 if (IS_BITVAR(retype))
8221 genUnpackBits(result,"dptr",FPOINTER);
8223 size = AOP_SIZE(result);
8227 pic14_emitcode("movx","a,@dptr");
8228 aopPut(AOP(result),"a",offset++);
8230 pic14_emitcode("inc","dptr");
8234 freeAsmop(result,NULL,ic,TRUE);
8237 /*-----------------------------------------------------------------*/
8238 /* genCodePointerGet - get value from code space */
8239 /*-----------------------------------------------------------------*/
8240 static void genCodePointerGet (operand *left,
8241 operand *result, iCode *ic)
8244 sym_link *retype = getSpec(operandType(result));
8246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8248 aopOp(left,ic,FALSE);
8250 /* if the operand is already in dptr
8251 then we do nothing else we move the value to dptr */
8252 if (AOP_TYPE(left) != AOP_STR) {
8253 /* if this is remateriazable */
8254 if (AOP_TYPE(left) == AOP_IMMD)
8255 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8256 else { /* we need to get it byte by byte */
8257 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8258 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8259 if (options.model == MODEL_FLAT24)
8261 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8265 /* so dptr know contains the address */
8266 freeAsmop(left,NULL,ic,TRUE);
8267 aopOp(result,ic,FALSE);
8269 /* if bit then unpack */
8270 if (IS_BITVAR(retype))
8271 genUnpackBits(result,"dptr",CPOINTER);
8273 size = AOP_SIZE(result);
8277 pic14_emitcode("clr","a");
8278 pic14_emitcode("movc","a,@a+dptr");
8279 aopPut(AOP(result),"a",offset++);
8281 pic14_emitcode("inc","dptr");
8285 freeAsmop(result,NULL,ic,TRUE);
8288 /*-----------------------------------------------------------------*/
8289 /* genGenPointerGet - gget value from generic pointer space */
8290 /*-----------------------------------------------------------------*/
8291 static void genGenPointerGet (operand *left,
8292 operand *result, iCode *ic)
8295 sym_link *retype = getSpec(operandType(result));
8297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8298 aopOp(left,ic,FALSE);
8299 aopOp(result,ic,FALSE);
8302 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8304 /* if the operand is already in dptr
8305 then we do nothing else we move the value to dptr */
8306 // if (AOP_TYPE(left) != AOP_STR) {
8307 /* if this is remateriazable */
8308 if (AOP_TYPE(left) == AOP_IMMD) {
8309 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8310 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8312 else { /* we need to get it byte by byte */
8314 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8315 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8317 size = AOP_SIZE(result);
8321 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8322 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8324 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8329 /* so dptr know contains the address */
8331 /* if bit then unpack */
8332 //if (IS_BITVAR(retype))
8333 // genUnpackBits(result,"dptr",GPOINTER);
8336 freeAsmop(left,NULL,ic,TRUE);
8337 freeAsmop(result,NULL,ic,TRUE);
8341 /*-----------------------------------------------------------------*/
8342 /* genConstPointerGet - get value from const generic pointer space */
8343 /*-----------------------------------------------------------------*/
8344 static void genConstPointerGet (operand *left,
8345 operand *result, iCode *ic)
8347 //sym_link *retype = getSpec(operandType(result));
8348 symbol *albl = newiTempLabel(NULL);
8349 symbol *blbl = newiTempLabel(NULL);
8352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8353 aopOp(left,ic,FALSE);
8354 aopOp(result,ic,FALSE);
8357 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8359 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8361 emitpcode(POC_CALL,popGetLabel(albl->key));
8362 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8363 emitpLabel(albl->key);
8365 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8367 emitpcode(poc,popGet(AOP(left),1));
8368 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8369 emitpcode(poc,popGet(AOP(left),0));
8370 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8372 emitpLabel(blbl->key);
8374 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8377 freeAsmop(left,NULL,ic,TRUE);
8378 freeAsmop(result,NULL,ic,TRUE);
8381 /*-----------------------------------------------------------------*/
8382 /* genPointerGet - generate code for pointer get */
8383 /*-----------------------------------------------------------------*/
8384 static void genPointerGet (iCode *ic)
8386 operand *left, *result ;
8387 sym_link *type, *etype;
8390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8393 result = IC_RESULT(ic) ;
8395 /* depending on the type of pointer we need to
8396 move it to the correct pointer register */
8397 type = operandType(left);
8398 etype = getSpec(type);
8400 if (IS_PTR_CONST(type))
8401 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8403 /* if left is of type of pointer then it is simple */
8404 if (IS_PTR(type) && !IS_FUNC(type->next))
8405 p_type = DCL_TYPE(type);
8407 /* we have to go by the storage class */
8408 p_type = PTR_TYPE(SPEC_OCLS(etype));
8410 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8412 if (SPEC_OCLS(etype)->codesp ) {
8413 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8414 //p_type = CPOINTER ;
8417 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8418 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8419 /*p_type = FPOINTER ;*/
8421 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8422 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8423 /* p_type = PPOINTER; */
8425 if (SPEC_OCLS(etype) == idata )
8426 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8427 /* p_type = IPOINTER; */
8429 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8430 /* p_type = POINTER ; */
8433 /* now that we have the pointer type we assign
8434 the pointer values */
8439 genNearPointerGet (left,result,ic);
8443 genPagedPointerGet(left,result,ic);
8447 genFarPointerGet (left,result,ic);
8451 genConstPointerGet (left,result,ic);
8452 //pic14_emitcodePointerGet (left,result,ic);
8456 if (IS_PTR_CONST(type))
8457 genConstPointerGet (left,result,ic);
8459 genGenPointerGet (left,result,ic);
8465 /*-----------------------------------------------------------------*/
8466 /* genPackBits - generates code for packed bit storage */
8467 /*-----------------------------------------------------------------*/
8468 static void genPackBits (sym_link *etype ,
8470 char *rname, int p_type)
8478 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8479 blen = SPEC_BLEN(etype);
8480 bstr = SPEC_BSTR(etype);
8482 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8485 /* if the bit lenth is less than or */
8486 /* it exactly fits a byte then */
8487 if (SPEC_BLEN(etype) <= 8 ) {
8488 shCount = SPEC_BSTR(etype) ;
8490 /* shift left acc */
8493 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8498 pic14_emitcode ("mov","b,a");
8499 pic14_emitcode("mov","a,@%s",rname);
8503 pic14_emitcode ("mov","b,a");
8504 pic14_emitcode("movx","a,@dptr");
8508 pic14_emitcode ("push","b");
8509 pic14_emitcode ("push","acc");
8510 pic14_emitcode ("lcall","__gptrget");
8511 pic14_emitcode ("pop","b");
8515 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8516 ((unsigned char)(0xFF << (blen+bstr)) |
8517 (unsigned char)(0xFF >> (8-bstr)) ) );
8518 pic14_emitcode ("orl","a,b");
8519 if (p_type == GPOINTER)
8520 pic14_emitcode("pop","b");
8526 pic14_emitcode("mov","@%s,a",rname);
8530 pic14_emitcode("movx","@dptr,a");
8534 DEBUGpic14_emitcode(";lcall","__gptrput");
8539 if ( SPEC_BLEN(etype) <= 8 )
8542 pic14_emitcode("inc","%s",rname);
8543 rLen = SPEC_BLEN(etype) ;
8545 /* now generate for lengths greater than one byte */
8548 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8558 pic14_emitcode("mov","@%s,a",rname);
8560 pic14_emitcode("mov","@%s,%s",rname,l);
8565 pic14_emitcode("movx","@dptr,a");
8570 DEBUGpic14_emitcode(";lcall","__gptrput");
8573 pic14_emitcode ("inc","%s",rname);
8578 /* last last was not complete */
8580 /* save the byte & read byte */
8583 pic14_emitcode ("mov","b,a");
8584 pic14_emitcode("mov","a,@%s",rname);
8588 pic14_emitcode ("mov","b,a");
8589 pic14_emitcode("movx","a,@dptr");
8593 pic14_emitcode ("push","b");
8594 pic14_emitcode ("push","acc");
8595 pic14_emitcode ("lcall","__gptrget");
8596 pic14_emitcode ("pop","b");
8600 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8601 pic14_emitcode ("orl","a,b");
8604 if (p_type == GPOINTER)
8605 pic14_emitcode("pop","b");
8610 pic14_emitcode("mov","@%s,a",rname);
8614 pic14_emitcode("movx","@dptr,a");
8618 DEBUGpic14_emitcode(";lcall","__gptrput");
8622 /*-----------------------------------------------------------------*/
8623 /* genDataPointerSet - remat pointer to data space */
8624 /*-----------------------------------------------------------------*/
8625 static void genDataPointerSet(operand *right,
8629 int size, offset = 0 ;
8630 char *l, buffer[256];
8632 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8633 aopOp(right,ic,FALSE);
8635 l = aopGet(AOP(result),0,FALSE,TRUE);
8636 size = AOP_SIZE(right);
8638 if ( AOP_TYPE(result) == AOP_PCODE) {
8639 fprintf(stderr,"genDataPointerSet %s, %d\n",
8640 AOP(result)->aopu.pcop->name,
8641 PCOI(AOP(result)->aopu.pcop)->offset);
8645 // tsd, was l+1 - the underline `_' prefix was being stripped
8648 sprintf(buffer,"(%s + %d)",l,offset);
8649 fprintf(stderr,"oops %s\n",buffer);
8651 sprintf(buffer,"%s",l);
8653 if (AOP_TYPE(right) == AOP_LIT) {
8654 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8655 lit = lit >> (8*offset);
8657 pic14_emitcode("movlw","%d",lit);
8658 pic14_emitcode("movwf","%s",buffer);
8660 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8661 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8662 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8665 pic14_emitcode("clrf","%s",buffer);
8666 //emitpcode(POC_CLRF, popRegFromString(buffer));
8667 emitpcode(POC_CLRF, popGet(AOP(result),0));
8670 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8671 pic14_emitcode("movwf","%s",buffer);
8673 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8674 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8675 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8682 freeAsmop(right,NULL,ic,TRUE);
8683 freeAsmop(result,NULL,ic,TRUE);
8686 /*-----------------------------------------------------------------*/
8687 /* genNearPointerSet - pic14_emitcode for near pointer put */
8688 /*-----------------------------------------------------------------*/
8689 static void genNearPointerSet (operand *right,
8696 sym_link *ptype = operandType(result);
8699 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8700 retype= getSpec(operandType(right));
8702 aopOp(result,ic,FALSE);
8705 /* if the result is rematerializable &
8706 in data space & not a bit variable */
8707 //if (AOP_TYPE(result) == AOP_IMMD &&
8708 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8709 DCL_TYPE(ptype) == POINTER &&
8710 !IS_BITVAR(retype)) {
8711 genDataPointerSet (right,result,ic);
8712 freeAsmop(result,NULL,ic,TRUE);
8716 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8717 aopOp(right,ic,FALSE);
8718 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8720 /* if the value is already in a pointer register
8721 then don't need anything more */
8722 if (!AOP_INPREG(AOP(result))) {
8723 /* otherwise get a free pointer register */
8724 //aop = newAsmop(0);
8725 //preg = getFreePtr(ic,&aop,FALSE);
8726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8727 //pic14_emitcode("mov","%s,%s",
8729 // aopGet(AOP(result),0,FALSE,TRUE));
8730 //rname = preg->name ;
8731 //pic14_emitcode("movwf","fsr");
8732 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8733 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8734 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8735 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8739 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8742 /* if bitfield then unpack the bits */
8743 if (IS_BITVAR(retype)) {
8744 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8745 "The programmer is obviously confused");
8746 //genPackBits (retype,right,rname,POINTER);
8750 /* we have can just get the values */
8751 int size = AOP_SIZE(right);
8754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8756 l = aopGet(AOP(right),offset,FALSE,TRUE);
8759 //pic14_emitcode("mov","@%s,a",rname);
8760 pic14_emitcode("movf","indf,w ;1");
8763 if (AOP_TYPE(right) == AOP_LIT) {
8764 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8766 pic14_emitcode("movlw","%s",l);
8767 pic14_emitcode("movwf","indf ;2");
8769 pic14_emitcode("clrf","indf");
8771 pic14_emitcode("movf","%s,w",l);
8772 pic14_emitcode("movwf","indf ;2");
8774 //pic14_emitcode("mov","@%s,%s",rname,l);
8777 pic14_emitcode("incf","fsr,f ;3");
8778 //pic14_emitcode("inc","%s",rname);
8783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8784 /* now some housekeeping stuff */
8786 /* we had to allocate for this iCode */
8787 freeAsmop(NULL,aop,ic,TRUE);
8789 /* we did not allocate which means left
8790 already in a pointer register, then
8791 if size > 0 && this could be used again
8792 we have to point it back to where it
8794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8795 if (AOP_SIZE(right) > 1 &&
8796 !OP_SYMBOL(result)->remat &&
8797 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8799 int size = AOP_SIZE(right) - 1;
8801 pic14_emitcode("decf","fsr,f");
8802 //pic14_emitcode("dec","%s",rname);
8806 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8809 freeAsmop(right,NULL,ic,TRUE);
8810 freeAsmop(result,NULL,ic,TRUE);
8813 /*-----------------------------------------------------------------*/
8814 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8815 /*-----------------------------------------------------------------*/
8816 static void genPagedPointerSet (operand *right,
8825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8827 retype= getSpec(operandType(right));
8829 aopOp(result,ic,FALSE);
8831 /* if the value is already in a pointer register
8832 then don't need anything more */
8833 if (!AOP_INPREG(AOP(result))) {
8834 /* otherwise get a free pointer register */
8836 preg = getFreePtr(ic,&aop,FALSE);
8837 pic14_emitcode("mov","%s,%s",
8839 aopGet(AOP(result),0,FALSE,TRUE));
8840 rname = preg->name ;
8842 rname = aopGet(AOP(result),0,FALSE,FALSE);
8844 freeAsmop(result,NULL,ic,TRUE);
8845 aopOp (right,ic,FALSE);
8847 /* if bitfield then unpack the bits */
8848 if (IS_BITVAR(retype))
8849 genPackBits (retype,right,rname,PPOINTER);
8851 /* we have can just get the values */
8852 int size = AOP_SIZE(right);
8856 l = aopGet(AOP(right),offset,FALSE,TRUE);
8859 pic14_emitcode("movx","@%s,a",rname);
8862 pic14_emitcode("inc","%s",rname);
8868 /* now some housekeeping stuff */
8870 /* we had to allocate for this iCode */
8871 freeAsmop(NULL,aop,ic,TRUE);
8873 /* we did not allocate which means left
8874 already in a pointer register, then
8875 if size > 0 && this could be used again
8876 we have to point it back to where it
8878 if (AOP_SIZE(right) > 1 &&
8879 !OP_SYMBOL(result)->remat &&
8880 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8882 int size = AOP_SIZE(right) - 1;
8884 pic14_emitcode("dec","%s",rname);
8889 freeAsmop(right,NULL,ic,TRUE);
8894 /*-----------------------------------------------------------------*/
8895 /* genFarPointerSet - set value from far space */
8896 /*-----------------------------------------------------------------*/
8897 static void genFarPointerSet (operand *right,
8898 operand *result, iCode *ic)
8901 sym_link *retype = getSpec(operandType(right));
8903 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8904 aopOp(result,ic,FALSE);
8906 /* if the operand is already in dptr
8907 then we do nothing else we move the value to dptr */
8908 if (AOP_TYPE(result) != AOP_STR) {
8909 /* if this is remateriazable */
8910 if (AOP_TYPE(result) == AOP_IMMD)
8911 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8912 else { /* we need to get it byte by byte */
8913 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8914 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8915 if (options.model == MODEL_FLAT24)
8917 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8921 /* so dptr know contains the address */
8922 freeAsmop(result,NULL,ic,TRUE);
8923 aopOp(right,ic,FALSE);
8925 /* if bit then unpack */
8926 if (IS_BITVAR(retype))
8927 genPackBits(retype,right,"dptr",FPOINTER);
8929 size = AOP_SIZE(right);
8933 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8935 pic14_emitcode("movx","@dptr,a");
8937 pic14_emitcode("inc","dptr");
8941 freeAsmop(right,NULL,ic,TRUE);
8944 /*-----------------------------------------------------------------*/
8945 /* genGenPointerSet - set value from generic pointer space */
8946 /*-----------------------------------------------------------------*/
8947 static void genGenPointerSet (operand *right,
8948 operand *result, iCode *ic)
8951 sym_link *retype = getSpec(operandType(right));
8953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8955 aopOp(result,ic,FALSE);
8956 aopOp(right,ic,FALSE);
8957 size = AOP_SIZE(right);
8959 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8961 /* if the operand is already in dptr
8962 then we do nothing else we move the value to dptr */
8963 if (AOP_TYPE(result) != AOP_STR) {
8964 /* if this is remateriazable */
8965 if (AOP_TYPE(result) == AOP_IMMD) {
8966 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8967 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8969 else { /* we need to get it byte by byte */
8970 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8971 size = AOP_SIZE(right);
8974 /* hack hack! see if this the FSR. If so don't load W */
8975 if(AOP_TYPE(right) != AOP_ACC) {
8977 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8978 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8981 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8983 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8984 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8988 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8989 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8992 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8999 if(aopIdx(AOP(result),0) != 4) {
9001 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9005 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9010 /* so dptr know contains the address */
9013 /* if bit then unpack */
9014 if (IS_BITVAR(retype))
9015 genPackBits(retype,right,"dptr",GPOINTER);
9017 size = AOP_SIZE(right);
9020 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9024 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9025 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9027 if (AOP_TYPE(right) == AOP_LIT)
9028 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9030 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9032 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9039 freeAsmop(right,NULL,ic,TRUE);
9040 freeAsmop(result,NULL,ic,TRUE);
9043 /*-----------------------------------------------------------------*/
9044 /* genPointerSet - stores the value into a pointer location */
9045 /*-----------------------------------------------------------------*/
9046 static void genPointerSet (iCode *ic)
9048 operand *right, *result ;
9049 sym_link *type, *etype;
9052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9054 right = IC_RIGHT(ic);
9055 result = IC_RESULT(ic) ;
9057 /* depending on the type of pointer we need to
9058 move it to the correct pointer register */
9059 type = operandType(result);
9060 etype = getSpec(type);
9061 /* if left is of type of pointer then it is simple */
9062 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9063 p_type = DCL_TYPE(type);
9066 /* we have to go by the storage class */
9067 p_type = PTR_TYPE(SPEC_OCLS(etype));
9069 /* if (SPEC_OCLS(etype)->codesp ) { */
9070 /* p_type = CPOINTER ; */
9073 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9074 /* p_type = FPOINTER ; */
9076 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9077 /* p_type = PPOINTER ; */
9079 /* if (SPEC_OCLS(etype) == idata ) */
9080 /* p_type = IPOINTER ; */
9082 /* p_type = POINTER ; */
9085 /* now that we have the pointer type we assign
9086 the pointer values */
9091 genNearPointerSet (right,result,ic);
9095 genPagedPointerSet (right,result,ic);
9099 genFarPointerSet (right,result,ic);
9103 genGenPointerSet (right,result,ic);
9107 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9108 "genPointerSet: illegal pointer type");
9112 /*-----------------------------------------------------------------*/
9113 /* genIfx - generate code for Ifx statement */
9114 /*-----------------------------------------------------------------*/
9115 static void genIfx (iCode *ic, iCode *popIc)
9117 operand *cond = IC_COND(ic);
9120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9122 aopOp(cond,ic,FALSE);
9124 /* get the value into acc */
9125 if (AOP_TYPE(cond) != AOP_CRY)
9126 pic14_toBoolean(cond);
9129 /* the result is now in the accumulator */
9130 freeAsmop(cond,NULL,ic,TRUE);
9132 /* if there was something to be popped then do it */
9136 /* if the condition is a bit variable */
9137 if (isbit && IS_ITEMP(cond) &&
9139 genIfxJump(ic,SPIL_LOC(cond)->rname);
9140 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9143 if (isbit && !IS_ITEMP(cond))
9144 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9152 /*-----------------------------------------------------------------*/
9153 /* genAddrOf - generates code for address of */
9154 /*-----------------------------------------------------------------*/
9155 static void genAddrOf (iCode *ic)
9157 operand *right, *result, *left;
9160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9163 //aopOp(IC_RESULT(ic),ic,FALSE);
9165 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9166 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9167 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9169 DEBUGpic14_AopType(__LINE__,left,right,result);
9171 size = AOP_SIZE(IC_RESULT(ic));
9175 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9176 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9180 freeAsmop(left,NULL,ic,FALSE);
9181 freeAsmop(result,NULL,ic,TRUE);
9186 /*-----------------------------------------------------------------*/
9187 /* genFarFarAssign - assignment when both are in far space */
9188 /*-----------------------------------------------------------------*/
9189 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9191 int size = AOP_SIZE(right);
9194 /* first push the right side on to the stack */
9196 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9198 pic14_emitcode ("push","acc");
9201 freeAsmop(right,NULL,ic,FALSE);
9202 /* now assign DPTR to result */
9203 aopOp(result,ic,FALSE);
9204 size = AOP_SIZE(result);
9206 pic14_emitcode ("pop","acc");
9207 aopPut(AOP(result),"a",--offset);
9209 freeAsmop(result,NULL,ic,FALSE);
9214 /*-----------------------------------------------------------------*/
9215 /* genAssign - generate code for assignment */
9216 /*-----------------------------------------------------------------*/
9217 static void genAssign (iCode *ic)
9219 operand *result, *right;
9220 int size, offset,know_W;
9221 unsigned long lit = 0L;
9223 result = IC_RESULT(ic);
9224 right = IC_RIGHT(ic) ;
9226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9228 /* if they are the same */
9229 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9232 aopOp(right,ic,FALSE);
9233 aopOp(result,ic,TRUE);
9235 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9237 /* if they are the same registers */
9238 if (pic14_sameRegs(AOP(right),AOP(result)))
9241 /* if the result is a bit */
9242 if (AOP_TYPE(result) == AOP_CRY) {
9244 /* if the right size is a literal then
9245 we know what the value is */
9246 if (AOP_TYPE(right) == AOP_LIT) {
9248 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9249 popGet(AOP(result),0));
9251 if (((int) operandLitValue(right)))
9252 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9253 AOP(result)->aopu.aop_dir,
9254 AOP(result)->aopu.aop_dir);
9256 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9257 AOP(result)->aopu.aop_dir,
9258 AOP(result)->aopu.aop_dir);
9262 /* the right is also a bit variable */
9263 if (AOP_TYPE(right) == AOP_CRY) {
9264 emitpcode(POC_BCF, popGet(AOP(result),0));
9265 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9266 emitpcode(POC_BSF, popGet(AOP(result),0));
9268 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9269 AOP(result)->aopu.aop_dir,
9270 AOP(result)->aopu.aop_dir);
9271 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9272 AOP(right)->aopu.aop_dir,
9273 AOP(right)->aopu.aop_dir);
9274 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9275 AOP(result)->aopu.aop_dir,
9276 AOP(result)->aopu.aop_dir);
9281 emitpcode(POC_BCF, popGet(AOP(result),0));
9282 pic14_toBoolean(right);
9284 emitpcode(POC_BSF, popGet(AOP(result),0));
9285 //aopPut(AOP(result),"a",0);
9289 /* bit variables done */
9291 size = AOP_SIZE(result);
9293 if(AOP_TYPE(right) == AOP_LIT)
9294 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9296 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9298 if(aopIdx(AOP(result),0) == 4) {
9299 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9300 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9301 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9304 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9310 if(AOP_TYPE(right) == AOP_LIT) {
9312 if(know_W != (lit&0xff))
9313 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9315 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9317 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9321 } else if (AOP_TYPE(right) == AOP_CRY) {
9322 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9324 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9325 emitpcode(POC_INCF, popGet(AOP(result),0));
9328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9329 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9330 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9338 freeAsmop (right,NULL,ic,FALSE);
9339 freeAsmop (result,NULL,ic,TRUE);
9342 /*-----------------------------------------------------------------*/
9343 /* genJumpTab - genrates code for jump table */
9344 /*-----------------------------------------------------------------*/
9345 static void genJumpTab (iCode *ic)
9350 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9352 aopOp(IC_JTCOND(ic),ic,FALSE);
9353 /* get the condition into accumulator */
9354 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9356 /* multiply by three */
9357 pic14_emitcode("add","a,acc");
9358 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9360 jtab = newiTempLabel(NULL);
9361 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9362 pic14_emitcode("jmp","@a+dptr");
9363 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9365 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9366 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9368 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9369 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9370 emitpLabel(jtab->key);
9372 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9374 /* now generate the jump labels */
9375 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9376 jtab = setNextItem(IC_JTLABELS(ic))) {
9377 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9378 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9384 /*-----------------------------------------------------------------*/
9385 /* genMixedOperation - gen code for operators between mixed types */
9386 /*-----------------------------------------------------------------*/
9388 TSD - Written for the PIC port - but this unfortunately is buggy.
9389 This routine is good in that it is able to efficiently promote
9390 types to different (larger) sizes. Unfortunately, the temporary
9391 variables that are optimized out by this routine are sometimes
9392 used in other places. So until I know how to really parse the
9393 iCode tree, I'm going to not be using this routine :(.
9395 static int genMixedOperation (iCode *ic)
9398 operand *result = IC_RESULT(ic);
9399 sym_link *ctype = operandType(IC_LEFT(ic));
9400 operand *right = IC_RIGHT(ic);
9406 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9408 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9414 nextright = IC_RIGHT(nextic);
9415 nextleft = IC_LEFT(nextic);
9416 nextresult = IC_RESULT(nextic);
9418 aopOp(right,ic,FALSE);
9419 aopOp(result,ic,FALSE);
9420 aopOp(nextright, nextic, FALSE);
9421 aopOp(nextleft, nextic, FALSE);
9422 aopOp(nextresult, nextic, FALSE);
9424 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9430 pic14_emitcode(";remove right +","");
9432 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9438 pic14_emitcode(";remove left +","");
9442 big = AOP_SIZE(nextleft);
9443 small = AOP_SIZE(nextright);
9445 switch(nextic->op) {
9448 pic14_emitcode(";optimize a +","");
9449 /* if unsigned or not an integral type */
9450 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9451 pic14_emitcode(";add a bit to something","");
9454 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9456 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9457 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9458 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9460 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9468 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9469 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9470 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9473 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9475 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9476 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9477 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9478 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9479 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9482 pic14_emitcode("rlf","known_zero,w");
9489 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9490 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9491 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9493 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9503 freeAsmop(right,NULL,ic,TRUE);
9504 freeAsmop(result,NULL,ic,TRUE);
9505 freeAsmop(nextright,NULL,ic,TRUE);
9506 freeAsmop(nextleft,NULL,ic,TRUE);
9508 nextic->generated = 1;
9515 /*-----------------------------------------------------------------*/
9516 /* genCast - gen code for casting */
9517 /*-----------------------------------------------------------------*/
9518 static void genCast (iCode *ic)
9520 operand *result = IC_RESULT(ic);
9521 sym_link *ctype = operandType(IC_LEFT(ic));
9522 sym_link *rtype = operandType(IC_RIGHT(ic));
9523 operand *right = IC_RIGHT(ic);
9526 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9527 /* if they are equivalent then do nothing */
9528 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9531 aopOp(right,ic,FALSE) ;
9532 aopOp(result,ic,FALSE);
9534 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9536 /* if the result is a bit */
9537 if (AOP_TYPE(result) == AOP_CRY) {
9538 /* if the right size is a literal then
9539 we know what the value is */
9540 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9541 if (AOP_TYPE(right) == AOP_LIT) {
9543 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9544 popGet(AOP(result),0));
9546 if (((int) operandLitValue(right)))
9547 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9548 AOP(result)->aopu.aop_dir,
9549 AOP(result)->aopu.aop_dir);
9551 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9552 AOP(result)->aopu.aop_dir,
9553 AOP(result)->aopu.aop_dir);
9558 /* the right is also a bit variable */
9559 if (AOP_TYPE(right) == AOP_CRY) {
9562 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9564 pic14_emitcode("clrc","");
9565 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9566 AOP(right)->aopu.aop_dir,
9567 AOP(right)->aopu.aop_dir);
9568 aopPut(AOP(result),"c",0);
9573 if (AOP_TYPE(right) == AOP_REG) {
9574 emitpcode(POC_BCF, popGet(AOP(result),0));
9575 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9576 emitpcode(POC_BSF, popGet(AOP(result),0));
9578 pic14_toBoolean(right);
9579 aopPut(AOP(result),"a",0);
9583 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9585 size = AOP_SIZE(result);
9587 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9589 emitpcode(POC_CLRF, popGet(AOP(result),0));
9590 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9591 emitpcode(POC_INCF, popGet(AOP(result),0));
9594 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9599 /* if they are the same size : or less */
9600 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9602 /* if they are in the same place */
9603 if (pic14_sameRegs(AOP(right),AOP(result)))
9606 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9607 if (IS_PTR_CONST(rtype))
9608 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9609 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9610 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9612 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9613 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9614 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9615 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9616 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9617 if(AOP_SIZE(result) <2)
9618 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9622 /* if they in different places then copy */
9623 size = AOP_SIZE(result);
9626 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9627 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9629 //aopPut(AOP(result),
9630 // aopGet(AOP(right),offset,FALSE,FALSE),
9640 /* if the result is of type pointer */
9641 if (IS_PTR(ctype)) {
9644 sym_link *type = operandType(right);
9645 sym_link *etype = getSpec(type);
9646 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9648 /* pointer to generic pointer */
9649 if (IS_GENPTR(ctype)) {
9653 p_type = DCL_TYPE(type);
9655 /* we have to go by the storage class */
9656 p_type = PTR_TYPE(SPEC_OCLS(etype));
9658 /* if (SPEC_OCLS(etype)->codesp ) */
9659 /* p_type = CPOINTER ; */
9661 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9662 /* p_type = FPOINTER ; */
9664 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9665 /* p_type = PPOINTER; */
9667 /* if (SPEC_OCLS(etype) == idata ) */
9668 /* p_type = IPOINTER ; */
9670 /* p_type = POINTER ; */
9673 /* the first two bytes are known */
9674 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9675 size = GPTRSIZE - 1;
9678 if(offset < AOP_SIZE(right)) {
9679 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9680 if ((AOP_TYPE(right) == AOP_PCODE) &&
9681 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9682 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9683 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9686 aopGet(AOP(right),offset,FALSE,FALSE),
9690 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9693 /* the last byte depending on type */
9697 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9700 pic14_emitcode(";BUG!? ","%d",__LINE__);
9704 pic14_emitcode(";BUG!? ","%d",__LINE__);
9708 pic14_emitcode(";BUG!? ","%d",__LINE__);
9713 /* this should never happen */
9714 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9715 "got unknown pointer type");
9718 //aopPut(AOP(result),l, GPTRSIZE - 1);
9722 /* just copy the pointers */
9723 size = AOP_SIZE(result);
9727 aopGet(AOP(right),offset,FALSE,FALSE),
9736 /* so we now know that the size of destination is greater
9737 than the size of the source.
9738 Now, if the next iCode is an operator then we might be
9739 able to optimize the operation without performing a cast.
9741 if(genMixedOperation(ic))
9744 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9746 /* we move to result for the size of source */
9747 size = AOP_SIZE(right);
9750 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9751 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9755 /* now depending on the sign of the destination */
9756 size = AOP_SIZE(result) - AOP_SIZE(right);
9757 /* if unsigned or not an integral type */
9758 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9760 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9762 /* we need to extend the sign :{ */
9765 /* Save one instruction of casting char to int */
9766 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9767 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9768 emitpcode(POC_DECF, popGet(AOP(result),offset));
9770 emitpcodeNULLop(POC_CLRW);
9773 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9775 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9777 emitpcode(POC_MOVLW, popGetLit(0xff));
9780 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9785 freeAsmop(right,NULL,ic,TRUE);
9786 freeAsmop(result,NULL,ic,TRUE);
9790 /*-----------------------------------------------------------------*/
9791 /* genDjnz - generate decrement & jump if not zero instrucion */
9792 /*-----------------------------------------------------------------*/
9793 static int genDjnz (iCode *ic, iCode *ifx)
9796 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9801 /* if the if condition has a false label
9802 then we cannot save */
9806 /* if the minus is not of the form
9808 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9809 !IS_OP_LITERAL(IC_RIGHT(ic)))
9812 if (operandLitValue(IC_RIGHT(ic)) != 1)
9815 /* if the size of this greater than one then no
9817 if (getSize(operandType(IC_RESULT(ic))) > 1)
9820 /* otherwise we can save BIG */
9821 lbl = newiTempLabel(NULL);
9822 lbl1= newiTempLabel(NULL);
9824 aopOp(IC_RESULT(ic),ic,FALSE);
9826 if (IS_AOP_PREG(IC_RESULT(ic))) {
9827 pic14_emitcode("dec","%s",
9828 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9829 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9830 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9834 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9835 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9837 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9838 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9841 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9842 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9843 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9844 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9847 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9852 /*-----------------------------------------------------------------*/
9853 /* genReceive - generate code for a receive iCode */
9854 /*-----------------------------------------------------------------*/
9855 static void genReceive (iCode *ic)
9857 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9859 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9860 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9861 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9863 int size = getSize(operandType(IC_RESULT(ic)));
9864 int offset = fReturnSizePic - size;
9866 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9867 fReturn[fReturnSizePic - offset - 1] : "acc"));
9870 aopOp(IC_RESULT(ic),ic,FALSE);
9871 size = AOP_SIZE(IC_RESULT(ic));
9874 pic14_emitcode ("pop","acc");
9875 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9880 aopOp(IC_RESULT(ic),ic,FALSE);
9882 assignResultValue(IC_RESULT(ic));
9885 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9888 /*-----------------------------------------------------------------*/
9889 /* genpic14Code - generate code for pic14 based controllers */
9890 /*-----------------------------------------------------------------*/
9892 * At this point, ralloc.c has gone through the iCode and attempted
9893 * to optimize in a way suitable for a PIC. Now we've got to generate
9894 * PIC instructions that correspond to the iCode.
9896 * Once the instructions are generated, we'll pass through both the
9897 * peep hole optimizer and the pCode optimizer.
9898 *-----------------------------------------------------------------*/
9900 void genpic14Code (iCode *lic)
9905 lineHead = lineCurr = NULL;
9907 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9910 /* if debug information required */
9911 if (options.debug && currFunc) {
9913 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9915 if (IS_STATIC(currFunc->etype)) {
9916 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9917 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9919 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9920 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9927 for (ic = lic ; ic ; ic = ic->next ) {
9929 DEBUGpic14_emitcode(";ic","");
9930 if ( cln != ic->lineno ) {
9931 if ( options.debug ) {
9933 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9934 FileBaseName(ic->filename),ic->lineno,
9935 ic->level,ic->block);
9939 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9940 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9941 printCLine(ic->filename, ic->lineno));
9944 newpCodeCSource(ic->lineno,
9946 printCLine(ic->filename, ic->lineno)));
9950 /* if the result is marked as
9951 spilt and rematerializable or code for
9952 this has already been generated then
9954 if (resultRemat(ic) || ic->generated )
9957 /* depending on the operation */
9976 /* IPOP happens only when trying to restore a
9977 spilt live range, if there is an ifx statement
9978 following this pop then the if statement might
9979 be using some of the registers being popped which
9980 would destory the contents of the register so
9981 we need to check for this condition and handle it */
9983 ic->next->op == IFX &&
9984 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9985 genIfx (ic->next,ic);
10003 genEndFunction (ic);
10023 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10040 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10044 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10051 /* note these two are xlated by algebraic equivalence
10052 during parsing SDCC.y */
10053 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10054 "got '>=' or '<=' shouldn't have come here");
10058 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10070 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10074 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10078 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10102 genRightShift (ic);
10105 case GET_VALUE_AT_ADDRESS:
10110 if (POINTER_SET(ic))
10137 addSet(&_G.sendSet,ic);
10146 /* now we are ready to call the
10147 peep hole optimizer */
10148 if (!options.nopeep) {
10149 peepHole (&lineHead);
10151 /* now do the actual printing */
10152 printLine (lineHead,codeOutFile);
10155 DFPRINTF((stderr,"printing pBlock\n\n"));
10156 printpBlock(stdout,pb);