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(";","%d: rname %s, val %d, const = %d",
562 __LINE__,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(";","%d: rname %s, val %d, const = %d",
617 __LINE__,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 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1659 if ( aop->type == AOP_PCODE ||
1660 aop->type == AOP_LIT )
1661 emitpcode(POC_MOVLW,popGet(aop,offset));
1663 emitpcode(POC_MOVFW,popGet(aop,offset));
1667 /*-----------------------------------------------------------------*/
1668 /* reAdjustPreg - points a register back to where it should */
1669 /*-----------------------------------------------------------------*/
1670 static void reAdjustPreg (asmop *aop)
1674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1676 if ((size = aop->size) <= 1)
1679 switch (aop->type) {
1683 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1687 if (aop->type == AOP_DPTR2)
1693 pic14_emitcode("lcall","__decdptr");
1696 if (aop->type == AOP_DPTR2)
1706 /*-----------------------------------------------------------------*/
1707 /* genNotFloat - generates not for float operations */
1708 /*-----------------------------------------------------------------*/
1709 static void genNotFloat (operand *op, operand *res)
1715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1716 /* we will put 127 in the first byte of
1718 aopPut(AOP(res),"#127",0);
1719 size = AOP_SIZE(op) - 1;
1722 l = aopGet(op->aop,offset++,FALSE,FALSE);
1726 pic14_emitcode("orl","a,%s",
1728 offset++,FALSE,FALSE));
1730 tlbl = newiTempLabel(NULL);
1732 tlbl = newiTempLabel(NULL);
1733 aopPut(res->aop,one,1);
1734 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1735 aopPut(res->aop,zero,1);
1736 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1738 size = res->aop->size - 2;
1740 /* put zeros in the rest */
1742 aopPut(res->aop,zero,offset++);
1746 /*-----------------------------------------------------------------*/
1747 /* opIsGptr: returns non-zero if the passed operand is */
1748 /* a generic pointer type. */
1749 /*-----------------------------------------------------------------*/
1750 static int opIsGptr(operand *op)
1752 sym_link *type = operandType(op);
1754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1755 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1763 /*-----------------------------------------------------------------*/
1764 /* pic14_getDataSize - get the operand data size */
1765 /*-----------------------------------------------------------------*/
1766 int pic14_getDataSize(operand *op)
1768 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1771 return AOP_SIZE(op);
1773 // tsd- in the pic port, the genptr size is 1, so this code here
1774 // fails. ( in the 8051 port, the size was 4).
1777 size = AOP_SIZE(op);
1778 if (size == GPTRSIZE)
1780 sym_link *type = operandType(op);
1781 if (IS_GENPTR(type))
1783 /* generic pointer; arithmetic operations
1784 * should ignore the high byte (pointer type).
1787 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1794 /*-----------------------------------------------------------------*/
1795 /* pic14_outAcc - output Acc */
1796 /*-----------------------------------------------------------------*/
1797 void pic14_outAcc(operand *result)
1800 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1801 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1804 size = pic14_getDataSize(result);
1806 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1809 /* unsigned or positive */
1811 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1816 /*-----------------------------------------------------------------*/
1817 /* pic14_outBitC - output a bit C */
1818 /*-----------------------------------------------------------------*/
1819 void pic14_outBitC(operand *result)
1822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1823 /* if the result is bit */
1824 if (AOP_TYPE(result) == AOP_CRY)
1825 aopPut(AOP(result),"c",0);
1827 pic14_emitcode("clr","a ; %d", __LINE__);
1828 pic14_emitcode("rlc","a");
1829 pic14_outAcc(result);
1833 /*-----------------------------------------------------------------*/
1834 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1835 /*-----------------------------------------------------------------*/
1836 void pic14_toBoolean(operand *oper)
1838 int size = AOP_SIZE(oper) - 1;
1841 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1843 if ( AOP_TYPE(oper) != AOP_ACC) {
1844 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1847 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1852 /*-----------------------------------------------------------------*/
1853 /* genNot - generate code for ! operation */
1854 /*-----------------------------------------------------------------*/
1855 static void genNot (iCode *ic)
1858 sym_link *optype = operandType(IC_LEFT(ic));
1861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1862 /* assign asmOps to operand & result */
1863 aopOp (IC_LEFT(ic),ic,FALSE);
1864 aopOp (IC_RESULT(ic),ic,TRUE);
1866 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1867 /* if in bit space then a special case */
1868 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1869 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1870 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1871 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1873 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1874 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1875 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1880 /* if type float then do float */
1881 if (IS_FLOAT(optype)) {
1882 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1886 size = AOP_SIZE(IC_RESULT(ic));
1888 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1889 emitpcode(POC_ANDLW,popGetLit(1));
1890 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1893 pic14_toBoolean(IC_LEFT(ic));
1895 tlbl = newiTempLabel(NULL);
1896 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1897 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1898 pic14_outBitC(IC_RESULT(ic));
1901 /* release the aops */
1902 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1903 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1907 /*-----------------------------------------------------------------*/
1908 /* genCpl - generate code for complement */
1909 /*-----------------------------------------------------------------*/
1910 static void genCpl (iCode *ic)
1916 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1917 /* assign asmOps to operand & result */
1918 aopOp (IC_LEFT(ic),ic,FALSE);
1919 aopOp (IC_RESULT(ic),ic,TRUE);
1921 /* if both are in bit space then
1923 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1924 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1926 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1927 pic14_emitcode("cpl","c");
1928 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1932 size = AOP_SIZE(IC_RESULT(ic));
1934 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1936 pic14_emitcode("cpl","a");
1937 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1942 /* release the aops */
1943 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1944 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1947 /*-----------------------------------------------------------------*/
1948 /* genUminusFloat - unary minus for floating points */
1949 /*-----------------------------------------------------------------*/
1950 static void genUminusFloat(operand *op,operand *result)
1952 int size ,offset =0 ;
1955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1956 /* for this we just need to flip the
1957 first it then copy the rest in place */
1958 size = AOP_SIZE(op) - 1;
1959 l = aopGet(AOP(op),3,FALSE,FALSE);
1963 pic14_emitcode("cpl","acc.7");
1964 aopPut(AOP(result),"a",3);
1968 aopGet(AOP(op),offset,FALSE,FALSE),
1974 /*-----------------------------------------------------------------*/
1975 /* genUminus - unary minus code generation */
1976 /*-----------------------------------------------------------------*/
1977 static void genUminus (iCode *ic)
1980 sym_link *optype, *rtype;
1983 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1985 aopOp(IC_LEFT(ic),ic,FALSE);
1986 aopOp(IC_RESULT(ic),ic,TRUE);
1988 /* if both in bit space then special
1990 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1991 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1993 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1994 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1995 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
2000 optype = operandType(IC_LEFT(ic));
2001 rtype = operandType(IC_RESULT(ic));
2003 /* if float then do float stuff */
2004 if (IS_FLOAT(optype)) {
2005 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2009 /* otherwise subtract from zero by taking the 2's complement */
2010 size = AOP_SIZE(IC_LEFT(ic));
2012 for(i=0; i<size; i++) {
2013 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2014 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2016 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2017 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2021 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2022 for(i=1; i<size; i++) {
2024 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2028 /* release the aops */
2029 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2030 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2033 /*-----------------------------------------------------------------*/
2034 /* saveRegisters - will look for a call and save the registers */
2035 /*-----------------------------------------------------------------*/
2036 static void saveRegisters(iCode *lic)
2043 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2045 for (ic = lic ; ic ; ic = ic->next)
2046 if (ic->op == CALL || ic->op == PCALL)
2050 fprintf(stderr,"found parameter push with no function call\n");
2054 /* if the registers have been saved already then
2056 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2059 /* find the registers in use at this time
2060 and push them away to safety */
2061 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2065 if (options.useXstack) {
2066 if (bitVectBitValue(rsave,R0_IDX))
2067 pic14_emitcode("mov","b,r0");
2068 pic14_emitcode("mov","r0,%s",spname);
2069 for (i = 0 ; i < pic14_nRegs ; i++) {
2070 if (bitVectBitValue(rsave,i)) {
2072 pic14_emitcode("mov","a,b");
2074 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2075 pic14_emitcode("movx","@r0,a");
2076 pic14_emitcode("inc","r0");
2079 pic14_emitcode("mov","%s,r0",spname);
2080 if (bitVectBitValue(rsave,R0_IDX))
2081 pic14_emitcode("mov","r0,b");
2083 //for (i = 0 ; i < pic14_nRegs ; i++) {
2084 // if (bitVectBitValue(rsave,i))
2085 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2088 dtype = operandType(IC_LEFT(ic));
2089 if (currFunc && dtype &&
2090 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2091 IFFUNC_ISISR(currFunc->type) &&
2094 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2097 /*-----------------------------------------------------------------*/
2098 /* unsaveRegisters - pop the pushed registers */
2099 /*-----------------------------------------------------------------*/
2100 static void unsaveRegisters (iCode *ic)
2105 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2106 /* find the registers in use at this time
2107 and push them away to safety */
2108 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2111 if (options.useXstack) {
2112 pic14_emitcode("mov","r0,%s",spname);
2113 for (i = pic14_nRegs ; i >= 0 ; i--) {
2114 if (bitVectBitValue(rsave,i)) {
2115 pic14_emitcode("dec","r0");
2116 pic14_emitcode("movx","a,@r0");
2118 pic14_emitcode("mov","b,a");
2120 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2124 pic14_emitcode("mov","%s,r0",spname);
2125 if (bitVectBitValue(rsave,R0_IDX))
2126 pic14_emitcode("mov","r0,b");
2128 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2129 // if (bitVectBitValue(rsave,i))
2130 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2136 /*-----------------------------------------------------------------*/
2138 /*-----------------------------------------------------------------*/
2139 static void pushSide(operand * oper, int size)
2143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2145 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2146 if (AOP_TYPE(oper) != AOP_REG &&
2147 AOP_TYPE(oper) != AOP_DIR &&
2149 pic14_emitcode("mov","a,%s",l);
2150 pic14_emitcode("push","acc");
2152 pic14_emitcode("push","%s",l);
2157 /*-----------------------------------------------------------------*/
2158 /* assignResultValue - */
2159 /*-----------------------------------------------------------------*/
2160 static void assignResultValue(operand * oper)
2162 int size = AOP_SIZE(oper);
2164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2166 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2168 if(!GpsuedoStkPtr) {
2169 /* The last byte in the assignment is in W */
2171 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2176 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2178 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2183 /*-----------------------------------------------------------------*/
2184 /* genIpush - genrate code for pushing this gets a little complex */
2185 /*-----------------------------------------------------------------*/
2186 static void genIpush (iCode *ic)
2189 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2191 int size, offset = 0 ;
2195 /* if this is not a parm push : ie. it is spill push
2196 and spill push is always done on the local stack */
2197 if (!ic->parmPush) {
2199 /* and the item is spilt then do nothing */
2200 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2203 aopOp(IC_LEFT(ic),ic,FALSE);
2204 size = AOP_SIZE(IC_LEFT(ic));
2205 /* push it on the stack */
2207 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2212 pic14_emitcode("push","%s",l);
2217 /* this is a paramter push: in this case we call
2218 the routine to find the call and save those
2219 registers that need to be saved */
2222 /* then do the push */
2223 aopOp(IC_LEFT(ic),ic,FALSE);
2226 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2227 size = AOP_SIZE(IC_LEFT(ic));
2230 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2231 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2232 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2234 pic14_emitcode("mov","a,%s",l);
2235 pic14_emitcode("push","acc");
2237 pic14_emitcode("push","%s",l);
2240 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2244 /*-----------------------------------------------------------------*/
2245 /* genIpop - recover the registers: can happen only for spilling */
2246 /*-----------------------------------------------------------------*/
2247 static void genIpop (iCode *ic)
2249 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2254 /* if the temp was not pushed then */
2255 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2258 aopOp(IC_LEFT(ic),ic,FALSE);
2259 size = AOP_SIZE(IC_LEFT(ic));
2262 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2265 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2269 /*-----------------------------------------------------------------*/
2270 /* unsaverbank - restores the resgister bank from stack */
2271 /*-----------------------------------------------------------------*/
2272 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2274 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2282 if (options.useXstack) {
2284 r = getFreePtr(ic,&aop,FALSE);
2287 pic14_emitcode("mov","%s,_spx",r->name);
2288 pic14_emitcode("movx","a,@%s",r->name);
2289 pic14_emitcode("mov","psw,a");
2290 pic14_emitcode("dec","%s",r->name);
2293 pic14_emitcode ("pop","psw");
2296 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2297 if (options.useXstack) {
2298 pic14_emitcode("movx","a,@%s",r->name);
2299 //pic14_emitcode("mov","(%s+%d),a",
2300 // regspic14[i].base,8*bank+regspic14[i].offset);
2301 pic14_emitcode("dec","%s",r->name);
2304 pic14_emitcode("pop",""); //"(%s+%d)",
2305 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2308 if (options.useXstack) {
2310 pic14_emitcode("mov","_spx,%s",r->name);
2311 freeAsmop(NULL,aop,ic,TRUE);
2317 /*-----------------------------------------------------------------*/
2318 /* saverbank - saves an entire register bank on the stack */
2319 /*-----------------------------------------------------------------*/
2320 static void saverbank (int bank, iCode *ic, bool pushPsw)
2322 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2329 if (options.useXstack) {
2332 r = getFreePtr(ic,&aop,FALSE);
2333 pic14_emitcode("mov","%s,_spx",r->name);
2337 for (i = 0 ; i < pic14_nRegs ;i++) {
2338 if (options.useXstack) {
2339 pic14_emitcode("inc","%s",r->name);
2340 //pic14_emitcode("mov","a,(%s+%d)",
2341 // regspic14[i].base,8*bank+regspic14[i].offset);
2342 pic14_emitcode("movx","@%s,a",r->name);
2344 pic14_emitcode("push","");// "(%s+%d)",
2345 //regspic14[i].base,8*bank+regspic14[i].offset);
2349 if (options.useXstack) {
2350 pic14_emitcode("mov","a,psw");
2351 pic14_emitcode("movx","@%s,a",r->name);
2352 pic14_emitcode("inc","%s",r->name);
2353 pic14_emitcode("mov","_spx,%s",r->name);
2354 freeAsmop (NULL,aop,ic,TRUE);
2357 pic14_emitcode("push","psw");
2359 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2365 /*-----------------------------------------------------------------*/
2366 /* genCall - generates a call statement */
2367 /*-----------------------------------------------------------------*/
2368 static void genCall (iCode *ic)
2372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2374 /* if caller saves & we have not saved then */
2378 /* if we are calling a function that is not using
2379 the same register bank then we need to save the
2380 destination registers on the stack */
2381 dtype = operandType(IC_LEFT(ic));
2382 if (currFunc && dtype &&
2383 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2384 IFFUNC_ISISR(currFunc->type) &&
2387 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2389 /* if send set is not empty the assign */
2392 /* For the Pic port, there is no data stack.
2393 * So parameters passed to functions are stored
2394 * in registers. (The pCode optimizer will get
2395 * rid of most of these :).
2397 int psuedoStkPtr=-1;
2398 int firstTimeThruLoop = 1;
2400 _G.sendSet = reverseSet(_G.sendSet);
2402 /* First figure how many parameters are getting passed */
2403 for (sic = setFirstItem(_G.sendSet) ; sic ;
2404 sic = setNextItem(_G.sendSet)) {
2406 aopOp(IC_LEFT(sic),sic,FALSE);
2407 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2408 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2411 for (sic = setFirstItem(_G.sendSet) ; sic ;
2412 sic = setNextItem(_G.sendSet)) {
2413 int size, offset = 0;
2415 aopOp(IC_LEFT(sic),sic,FALSE);
2416 size = AOP_SIZE(IC_LEFT(sic));
2419 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2420 AopType(AOP_TYPE(IC_LEFT(sic))));
2422 if(!firstTimeThruLoop) {
2423 /* If this is not the first time we've been through the loop
2424 * then we need to save the parameter in a temporary
2425 * register. The last byte of the last parameter is
2427 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2430 firstTimeThruLoop=0;
2432 //if (strcmp(l,fReturn[offset])) {
2433 mov2w (AOP(IC_LEFT(sic)), offset);
2435 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2436 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2437 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2439 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2444 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2449 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2450 OP_SYMBOL(IC_LEFT(ic))->rname :
2451 OP_SYMBOL(IC_LEFT(ic))->name));
2454 /* if we need assign a result value */
2455 if ((IS_ITEMP(IC_RESULT(ic)) &&
2456 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2457 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2458 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2461 aopOp(IC_RESULT(ic),ic,FALSE);
2464 assignResultValue(IC_RESULT(ic));
2466 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2467 AopType(AOP_TYPE(IC_RESULT(ic))));
2469 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2472 /* adjust the stack for parameters if
2474 if (ic->parmBytes) {
2476 if (ic->parmBytes > 3) {
2477 pic14_emitcode("mov","a,%s",spname);
2478 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2479 pic14_emitcode("mov","%s,a",spname);
2481 for ( i = 0 ; i < ic->parmBytes ;i++)
2482 pic14_emitcode("dec","%s",spname);
2486 /* if register bank was saved then pop them */
2488 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2490 /* if we hade saved some registers then unsave them */
2491 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2492 unsaveRegisters (ic);
2497 /*-----------------------------------------------------------------*/
2498 /* genPcall - generates a call by pointer statement */
2499 /*-----------------------------------------------------------------*/
2500 static void genPcall (iCode *ic)
2503 symbol *rlbl = newiTempLabel(NULL);
2506 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2507 /* if caller saves & we have not saved then */
2511 /* if we are calling a function that is not using
2512 the same register bank then we need to save the
2513 destination registers on the stack */
2514 dtype = operandType(IC_LEFT(ic));
2515 if (currFunc && dtype &&
2516 IFFUNC_ISISR(currFunc->type) &&
2517 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2518 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2521 /* push the return address on to the stack */
2522 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2523 pic14_emitcode("push","acc");
2524 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2525 pic14_emitcode("push","acc");
2527 if (options.model == MODEL_FLAT24)
2529 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2530 pic14_emitcode("push","acc");
2533 /* now push the calling address */
2534 aopOp(IC_LEFT(ic),ic,FALSE);
2536 pushSide(IC_LEFT(ic), FPTRSIZE);
2538 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2540 /* if send set is not empty the assign */
2544 for (sic = setFirstItem(_G.sendSet) ; sic ;
2545 sic = setNextItem(_G.sendSet)) {
2546 int size, offset = 0;
2547 aopOp(IC_LEFT(sic),sic,FALSE);
2548 size = AOP_SIZE(IC_LEFT(sic));
2550 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2552 if (strcmp(l,fReturn[offset]))
2553 pic14_emitcode("mov","%s,%s",
2558 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2563 pic14_emitcode("ret","");
2564 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2567 /* if we need assign a result value */
2568 if ((IS_ITEMP(IC_RESULT(ic)) &&
2569 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2570 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2571 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2574 aopOp(IC_RESULT(ic),ic,FALSE);
2577 assignResultValue(IC_RESULT(ic));
2579 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2582 /* adjust the stack for parameters if
2584 if (ic->parmBytes) {
2586 if (ic->parmBytes > 3) {
2587 pic14_emitcode("mov","a,%s",spname);
2588 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2589 pic14_emitcode("mov","%s,a",spname);
2591 for ( i = 0 ; i < ic->parmBytes ;i++)
2592 pic14_emitcode("dec","%s",spname);
2596 /* if register bank was saved then unsave them */
2597 if (currFunc && dtype &&
2598 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2599 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2601 /* if we hade saved some registers then
2604 unsaveRegisters (ic);
2608 /*-----------------------------------------------------------------*/
2609 /* resultRemat - result is rematerializable */
2610 /*-----------------------------------------------------------------*/
2611 static int resultRemat (iCode *ic)
2613 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2614 if (SKIP_IC(ic) || ic->op == IFX)
2617 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2618 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2619 if (sym->remat && !POINTER_SET(ic))
2626 #if defined(__BORLANDC__) || defined(_MSC_VER)
2627 #define STRCASECMP stricmp
2629 #define STRCASECMP strcasecmp
2633 /*-----------------------------------------------------------------*/
2634 /* inExcludeList - return 1 if the string is in exclude Reg list */
2635 /*-----------------------------------------------------------------*/
2636 static bool inExcludeList(char *s)
2638 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2641 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2642 if (options.excludeRegs[i] &&
2643 STRCASECMP(options.excludeRegs[i],"none") == 0)
2646 for ( i = 0 ; options.excludeRegs[i]; i++) {
2647 if (options.excludeRegs[i] &&
2648 STRCASECMP(s,options.excludeRegs[i]) == 0)
2655 /*-----------------------------------------------------------------*/
2656 /* genFunction - generated code for function entry */
2657 /*-----------------------------------------------------------------*/
2658 static void genFunction (iCode *ic)
2663 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2665 labelOffset += (max_key+4);
2669 /* create the function header */
2670 pic14_emitcode(";","-----------------------------------------");
2671 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2672 pic14_emitcode(";","-----------------------------------------");
2674 pic14_emitcode("","%s:",sym->rname);
2675 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2677 ftype = operandType(IC_LEFT(ic));
2679 /* if critical function then turn interrupts off */
2680 if (IFFUNC_ISCRITICAL(ftype))
2681 pic14_emitcode("clr","ea");
2683 /* here we need to generate the equates for the
2684 register bank if required */
2686 if (FUNC_REGBANK(ftype) != rbank) {
2689 rbank = FUNC_REGBANK(ftype);
2690 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2691 if (strcmp(regspic14[i].base,"0") == 0)
2692 pic14_emitcode("","%s = 0x%02x",
2694 8*rbank+regspic14[i].offset);
2696 pic14_emitcode ("","%s = %s + 0x%02x",
2699 8*rbank+regspic14[i].offset);
2704 /* if this is an interrupt service routine then
2705 save acc, b, dpl, dph */
2706 if (IFFUNC_ISISR(sym->type)) {
2707 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2708 emitpcodeNULLop(POC_NOP);
2709 emitpcodeNULLop(POC_NOP);
2710 emitpcodeNULLop(POC_NOP);
2711 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2712 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2713 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2714 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2716 pBlockConvert2ISR(pb);
2718 if (!inExcludeList("acc"))
2719 pic14_emitcode ("push","acc");
2720 if (!inExcludeList("b"))
2721 pic14_emitcode ("push","b");
2722 if (!inExcludeList("dpl"))
2723 pic14_emitcode ("push","dpl");
2724 if (!inExcludeList("dph"))
2725 pic14_emitcode ("push","dph");
2726 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2728 pic14_emitcode ("push", "dpx");
2729 /* Make sure we're using standard DPTR */
2730 pic14_emitcode ("push", "dps");
2731 pic14_emitcode ("mov", "dps, #0x00");
2732 if (options.stack10bit)
2734 /* This ISR could conceivably use DPTR2. Better save it. */
2735 pic14_emitcode ("push", "dpl1");
2736 pic14_emitcode ("push", "dph1");
2737 pic14_emitcode ("push", "dpx1");
2740 /* if this isr has no bank i.e. is going to
2741 run with bank 0 , then we need to save more
2743 if (!FUNC_REGBANK(sym->type)) {
2745 /* if this function does not call any other
2746 function then we can be economical and
2747 save only those registers that are used */
2748 if (! IFFUNC_HASFCALL(sym->type)) {
2751 /* if any registers used */
2752 if (sym->regsUsed) {
2753 /* save the registers used */
2754 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2755 if (bitVectBitValue(sym->regsUsed,i) ||
2756 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2757 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2762 /* this function has a function call cannot
2763 determines register usage so we will have the
2765 saverbank(0,ic,FALSE);
2770 /* if callee-save to be used for this function
2771 then save the registers being used in this function */
2772 if (IFFUNC_CALLEESAVES(sym->type)) {
2775 /* if any registers used */
2776 if (sym->regsUsed) {
2777 /* save the registers used */
2778 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2779 if (bitVectBitValue(sym->regsUsed,i) ||
2780 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2781 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2789 /* set the register bank to the desired value */
2790 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2791 pic14_emitcode("push","psw");
2792 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2795 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2797 if (options.useXstack) {
2798 pic14_emitcode("mov","r0,%s",spname);
2799 pic14_emitcode("mov","a,_bp");
2800 pic14_emitcode("movx","@r0,a");
2801 pic14_emitcode("inc","%s",spname);
2805 /* set up the stack */
2806 pic14_emitcode ("push","_bp"); /* save the callers stack */
2808 pic14_emitcode ("mov","_bp,%s",spname);
2811 /* adjust the stack for the function */
2816 werror(W_STACK_OVERFLOW,sym->name);
2818 if (i > 3 && sym->recvSize < 4) {
2820 pic14_emitcode ("mov","a,sp");
2821 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2822 pic14_emitcode ("mov","sp,a");
2827 pic14_emitcode("inc","sp");
2832 pic14_emitcode ("mov","a,_spx");
2833 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2834 pic14_emitcode ("mov","_spx,a");
2839 /*-----------------------------------------------------------------*/
2840 /* genEndFunction - generates epilogue for functions */
2841 /*-----------------------------------------------------------------*/
2842 static void genEndFunction (iCode *ic)
2844 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2848 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2850 pic14_emitcode ("mov","%s,_bp",spname);
2853 /* if use external stack but some variables were
2854 added to the local stack then decrement the
2856 if (options.useXstack && sym->stack) {
2857 pic14_emitcode("mov","a,sp");
2858 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2859 pic14_emitcode("mov","sp,a");
2863 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2864 if (options.useXstack) {
2865 pic14_emitcode("mov","r0,%s",spname);
2866 pic14_emitcode("movx","a,@r0");
2867 pic14_emitcode("mov","_bp,a");
2868 pic14_emitcode("dec","%s",spname);
2872 pic14_emitcode ("pop","_bp");
2876 /* restore the register bank */
2877 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2878 pic14_emitcode ("pop","psw");
2880 if (IFFUNC_ISISR(sym->type)) {
2882 /* now we need to restore the registers */
2883 /* if this isr has no bank i.e. is going to
2884 run with bank 0 , then we need to save more
2886 if (!FUNC_REGBANK(sym->type)) {
2888 /* if this function does not call any other
2889 function then we can be economical and
2890 save only those registers that are used */
2891 if (! IFFUNC_HASFCALL(sym->type)) {
2894 /* if any registers used */
2895 if (sym->regsUsed) {
2896 /* save the registers used */
2897 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2898 if (bitVectBitValue(sym->regsUsed,i) ||
2899 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2900 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2905 /* this function has a function call cannot
2906 determines register usage so we will have the
2908 unsaverbank(0,ic,FALSE);
2912 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2914 if (options.stack10bit)
2916 pic14_emitcode ("pop", "dpx1");
2917 pic14_emitcode ("pop", "dph1");
2918 pic14_emitcode ("pop", "dpl1");
2920 pic14_emitcode ("pop", "dps");
2921 pic14_emitcode ("pop", "dpx");
2923 if (!inExcludeList("dph"))
2924 pic14_emitcode ("pop","dph");
2925 if (!inExcludeList("dpl"))
2926 pic14_emitcode ("pop","dpl");
2927 if (!inExcludeList("b"))
2928 pic14_emitcode ("pop","b");
2929 if (!inExcludeList("acc"))
2930 pic14_emitcode ("pop","acc");
2932 if (IFFUNC_ISCRITICAL(sym->type))
2933 pic14_emitcode("setb","ea");
2936 /* if debug then send end of function */
2937 /* if (options.debug && currFunc) { */
2940 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2941 FileBaseName(ic->filename),currFunc->lastLine,
2942 ic->level,ic->block);
2943 if (IS_STATIC(currFunc->etype))
2944 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2946 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2950 pic14_emitcode ("reti","");
2952 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2953 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2954 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2955 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2956 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2957 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2959 emitpcodeNULLop(POC_RETFIE);
2963 if (IFFUNC_ISCRITICAL(sym->type))
2964 pic14_emitcode("setb","ea");
2966 if (IFFUNC_CALLEESAVES(sym->type)) {
2969 /* if any registers used */
2970 if (sym->regsUsed) {
2971 /* save the registers used */
2972 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2973 if (bitVectBitValue(sym->regsUsed,i) ||
2974 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2975 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2981 /* if debug then send end of function */
2984 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2985 FileBaseName(ic->filename),currFunc->lastLine,
2986 ic->level,ic->block);
2987 if (IS_STATIC(currFunc->etype))
2988 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2990 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2994 pic14_emitcode ("return","");
2995 emitpcodeNULLop(POC_RETURN);
2997 /* Mark the end of a function */
2998 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
3003 /*-----------------------------------------------------------------*/
3004 /* genRet - generate code for return statement */
3005 /*-----------------------------------------------------------------*/
3006 static void genRet (iCode *ic)
3008 int size,offset = 0 , pushed = 0;
3010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3011 /* if we have no return value then
3012 just generate the "ret" */
3016 /* we have something to return then
3017 move the return value into place */
3018 aopOp(IC_LEFT(ic),ic,FALSE);
3019 size = AOP_SIZE(IC_LEFT(ic));
3023 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3025 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3027 pic14_emitcode("push","%s",l);
3030 l = aopGet(AOP(IC_LEFT(ic)),offset,
3032 if (strcmp(fReturn[offset],l)) {
3033 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3034 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3035 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3037 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3040 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3050 if (strcmp(fReturn[pushed],"a"))
3051 pic14_emitcode("pop",fReturn[pushed]);
3053 pic14_emitcode("pop","acc");
3056 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3059 /* generate a jump to the return label
3060 if the next is not the return statement */
3061 if (!(ic->next && ic->next->op == LABEL &&
3062 IC_LABEL(ic->next) == returnLabel)) {
3064 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3065 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3070 /*-----------------------------------------------------------------*/
3071 /* genLabel - generates a label */
3072 /*-----------------------------------------------------------------*/
3073 static void genLabel (iCode *ic)
3075 /* special case never generate */
3076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3077 if (IC_LABEL(ic) == entryLabel)
3080 emitpLabel(IC_LABEL(ic)->key);
3081 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3084 /*-----------------------------------------------------------------*/
3085 /* genGoto - generates a goto */
3086 /*-----------------------------------------------------------------*/
3088 static void genGoto (iCode *ic)
3090 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3091 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3095 /*-----------------------------------------------------------------*/
3096 /* genMultbits :- multiplication of bits */
3097 /*-----------------------------------------------------------------*/
3098 static void genMultbits (operand *left,
3102 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3104 if(!pic14_sameRegs(AOP(result),AOP(right)))
3105 emitpcode(POC_BSF, popGet(AOP(result),0));
3107 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3108 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3109 emitpcode(POC_BCF, popGet(AOP(result),0));
3114 /*-----------------------------------------------------------------*/
3115 /* genMultOneByte : 8 bit multiplication & division */
3116 /*-----------------------------------------------------------------*/
3117 static void genMultOneByte (operand *left,
3121 sym_link *opetype = operandType(result);
3126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3127 DEBUGpic14_AopType(__LINE__,left,right,result);
3128 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3130 /* (if two literals, the value is computed before) */
3131 /* if one literal, literal on the right */
3132 if (AOP_TYPE(left) == AOP_LIT){
3138 size = AOP_SIZE(result);
3141 if (AOP_TYPE(right) == AOP_LIT){
3142 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3143 aopGet(AOP(right),0,FALSE,FALSE),
3144 aopGet(AOP(left),0,FALSE,FALSE),
3145 aopGet(AOP(result),0,FALSE,FALSE));
3146 pic14_emitcode("call","genMultLit");
3148 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3149 aopGet(AOP(right),0,FALSE,FALSE),
3150 aopGet(AOP(left),0,FALSE,FALSE),
3151 aopGet(AOP(result),0,FALSE,FALSE));
3152 pic14_emitcode("call","genMult8X8_8");
3155 genMult8X8_8 (left, right,result);
3158 /* signed or unsigned */
3159 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3160 //l = aopGet(AOP(left),0,FALSE,FALSE);
3162 //pic14_emitcode("mul","ab");
3163 /* if result size = 1, mul signed = mul unsigned */
3164 //aopPut(AOP(result),"a",0);
3166 } else { // (size > 1)
3168 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3169 aopGet(AOP(right),0,FALSE,FALSE),
3170 aopGet(AOP(left),0,FALSE,FALSE),
3171 aopGet(AOP(result),0,FALSE,FALSE));
3173 if (SPEC_USIGN(opetype)){
3174 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3175 genUMult8X8_16 (left, right, result, NULL);
3178 /* for filling the MSBs */
3179 emitpcode(POC_CLRF, popGet(AOP(result),2));
3180 emitpcode(POC_CLRF, popGet(AOP(result),3));
3184 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3186 pic14_emitcode("mov","a,b");
3188 /* adjust the MSB if left or right neg */
3190 /* if one literal */
3191 if (AOP_TYPE(right) == AOP_LIT){
3192 pic14_emitcode("multiply ","right is a lit");
3193 /* AND literal negative */
3194 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3195 /* adjust MSB (c==0 after mul) */
3196 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3200 genSMult8X8_16 (left, right, result, NULL);
3204 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3206 pic14_emitcode("rlc","a");
3207 pic14_emitcode("subb","a,acc");
3215 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3216 //aopPut(AOP(result),"a",offset++);
3220 /*-----------------------------------------------------------------*/
3221 /* genMult - generates code for multiplication */
3222 /*-----------------------------------------------------------------*/
3223 static void genMult (iCode *ic)
3225 operand *left = IC_LEFT(ic);
3226 operand *right = IC_RIGHT(ic);
3227 operand *result= IC_RESULT(ic);
3229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3230 /* assign the amsops */
3231 aopOp (left,ic,FALSE);
3232 aopOp (right,ic,FALSE);
3233 aopOp (result,ic,TRUE);
3235 DEBUGpic14_AopType(__LINE__,left,right,result);
3237 /* special cases first */
3239 if (AOP_TYPE(left) == AOP_CRY &&
3240 AOP_TYPE(right)== AOP_CRY) {
3241 genMultbits(left,right,result);
3245 /* if both are of size == 1 */
3246 if (AOP_SIZE(left) == 1 &&
3247 AOP_SIZE(right) == 1 ) {
3248 genMultOneByte(left,right,result);
3252 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3254 /* should have been converted to function call */
3258 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3259 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3260 freeAsmop(result,NULL,ic,TRUE);
3263 /*-----------------------------------------------------------------*/
3264 /* genDivbits :- division of bits */
3265 /*-----------------------------------------------------------------*/
3266 static void genDivbits (operand *left,
3273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3274 /* the result must be bit */
3275 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3276 l = aopGet(AOP(left),0,FALSE,FALSE);
3280 pic14_emitcode("div","ab");
3281 pic14_emitcode("rrc","a");
3282 aopPut(AOP(result),"c",0);
3285 /*-----------------------------------------------------------------*/
3286 /* genDivOneByte : 8 bit division */
3287 /*-----------------------------------------------------------------*/
3288 static void genDivOneByte (operand *left,
3292 sym_link *opetype = operandType(result);
3297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3298 size = AOP_SIZE(result) - 1;
3300 /* signed or unsigned */
3301 if (SPEC_USIGN(opetype)) {
3302 /* unsigned is easy */
3303 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3304 l = aopGet(AOP(left),0,FALSE,FALSE);
3306 pic14_emitcode("div","ab");
3307 aopPut(AOP(result),"a",0);
3309 aopPut(AOP(result),zero,offset++);
3313 /* signed is a little bit more difficult */
3315 /* save the signs of the operands */
3316 l = aopGet(AOP(left),0,FALSE,FALSE);
3318 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3319 pic14_emitcode("push","acc"); /* save it on the stack */
3321 /* now sign adjust for both left & right */
3322 l = aopGet(AOP(right),0,FALSE,FALSE);
3324 lbl = newiTempLabel(NULL);
3325 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3326 pic14_emitcode("cpl","a");
3327 pic14_emitcode("inc","a");
3328 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3329 pic14_emitcode("mov","b,a");
3331 /* sign adjust left side */
3332 l = aopGet(AOP(left),0,FALSE,FALSE);
3335 lbl = newiTempLabel(NULL);
3336 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3337 pic14_emitcode("cpl","a");
3338 pic14_emitcode("inc","a");
3339 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3341 /* now the division */
3342 pic14_emitcode("div","ab");
3343 /* we are interested in the lower order
3345 pic14_emitcode("mov","b,a");
3346 lbl = newiTempLabel(NULL);
3347 pic14_emitcode("pop","acc");
3348 /* if there was an over flow we don't
3349 adjust the sign of the result */
3350 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3351 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3353 pic14_emitcode("clr","a");
3354 pic14_emitcode("subb","a,b");
3355 pic14_emitcode("mov","b,a");
3356 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3358 /* now we are done */
3359 aopPut(AOP(result),"b",0);
3361 pic14_emitcode("mov","c,b.7");
3362 pic14_emitcode("subb","a,acc");
3365 aopPut(AOP(result),"a",offset++);
3369 /*-----------------------------------------------------------------*/
3370 /* genDiv - generates code for division */
3371 /*-----------------------------------------------------------------*/
3372 static void genDiv (iCode *ic)
3374 operand *left = IC_LEFT(ic);
3375 operand *right = IC_RIGHT(ic);
3376 operand *result= IC_RESULT(ic);
3378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3379 /* assign the amsops */
3380 aopOp (left,ic,FALSE);
3381 aopOp (right,ic,FALSE);
3382 aopOp (result,ic,TRUE);
3384 /* special cases first */
3386 if (AOP_TYPE(left) == AOP_CRY &&
3387 AOP_TYPE(right)== AOP_CRY) {
3388 genDivbits(left,right,result);
3392 /* if both are of size == 1 */
3393 if (AOP_SIZE(left) == 1 &&
3394 AOP_SIZE(right) == 1 ) {
3395 genDivOneByte(left,right,result);
3399 /* should have been converted to function call */
3402 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3403 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3404 freeAsmop(result,NULL,ic,TRUE);
3407 /*-----------------------------------------------------------------*/
3408 /* genModbits :- modulus of bits */
3409 /*-----------------------------------------------------------------*/
3410 static void genModbits (operand *left,
3417 /* the result must be bit */
3418 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3419 l = aopGet(AOP(left),0,FALSE,FALSE);
3423 pic14_emitcode("div","ab");
3424 pic14_emitcode("mov","a,b");
3425 pic14_emitcode("rrc","a");
3426 aopPut(AOP(result),"c",0);
3429 /*-----------------------------------------------------------------*/
3430 /* genModOneByte : 8 bit modulus */
3431 /*-----------------------------------------------------------------*/
3432 static void genModOneByte (operand *left,
3436 sym_link *opetype = operandType(result);
3440 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3441 /* signed or unsigned */
3442 if (SPEC_USIGN(opetype)) {
3443 /* unsigned is easy */
3444 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3445 l = aopGet(AOP(left),0,FALSE,FALSE);
3447 pic14_emitcode("div","ab");
3448 aopPut(AOP(result),"b",0);
3452 /* signed is a little bit more difficult */
3454 /* save the signs of the operands */
3455 l = aopGet(AOP(left),0,FALSE,FALSE);
3458 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3459 pic14_emitcode("push","acc"); /* save it on the stack */
3461 /* now sign adjust for both left & right */
3462 l = aopGet(AOP(right),0,FALSE,FALSE);
3465 lbl = newiTempLabel(NULL);
3466 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3467 pic14_emitcode("cpl","a");
3468 pic14_emitcode("inc","a");
3469 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3470 pic14_emitcode("mov","b,a");
3472 /* sign adjust left side */
3473 l = aopGet(AOP(left),0,FALSE,FALSE);
3476 lbl = newiTempLabel(NULL);
3477 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3478 pic14_emitcode("cpl","a");
3479 pic14_emitcode("inc","a");
3480 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3482 /* now the multiplication */
3483 pic14_emitcode("div","ab");
3484 /* we are interested in the lower order
3486 lbl = newiTempLabel(NULL);
3487 pic14_emitcode("pop","acc");
3488 /* if there was an over flow we don't
3489 adjust the sign of the result */
3490 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3491 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3493 pic14_emitcode("clr","a");
3494 pic14_emitcode("subb","a,b");
3495 pic14_emitcode("mov","b,a");
3496 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3498 /* now we are done */
3499 aopPut(AOP(result),"b",0);
3503 /*-----------------------------------------------------------------*/
3504 /* genMod - generates code for division */
3505 /*-----------------------------------------------------------------*/
3506 static void genMod (iCode *ic)
3508 operand *left = IC_LEFT(ic);
3509 operand *right = IC_RIGHT(ic);
3510 operand *result= IC_RESULT(ic);
3512 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3513 /* assign the amsops */
3514 aopOp (left,ic,FALSE);
3515 aopOp (right,ic,FALSE);
3516 aopOp (result,ic,TRUE);
3518 /* special cases first */
3520 if (AOP_TYPE(left) == AOP_CRY &&
3521 AOP_TYPE(right)== AOP_CRY) {
3522 genModbits(left,right,result);
3526 /* if both are of size == 1 */
3527 if (AOP_SIZE(left) == 1 &&
3528 AOP_SIZE(right) == 1 ) {
3529 genModOneByte(left,right,result);
3533 /* should have been converted to function call */
3537 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3538 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3539 freeAsmop(result,NULL,ic,TRUE);
3542 /*-----------------------------------------------------------------*/
3543 /* genIfxJump :- will create a jump depending on the ifx */
3544 /*-----------------------------------------------------------------*/
3546 note: May need to add parameter to indicate when a variable is in bit space.
3548 static void genIfxJump (iCode *ic, char *jval)
3551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3552 /* if true label then we jump if condition
3554 if ( IC_TRUE(ic) ) {
3556 if(strcmp(jval,"a") == 0)
3558 else if (strcmp(jval,"c") == 0)
3561 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3562 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3565 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3566 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3570 /* false label is present */
3571 if(strcmp(jval,"a") == 0)
3573 else if (strcmp(jval,"c") == 0)
3576 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3577 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3580 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3581 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3586 /* mark the icode as generated */
3590 /*-----------------------------------------------------------------*/
3592 /*-----------------------------------------------------------------*/
3593 static void genSkip(iCode *ifx,int status_bit)
3598 if ( IC_TRUE(ifx) ) {
3599 switch(status_bit) {
3614 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3615 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3619 switch(status_bit) {
3633 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3634 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3640 /*-----------------------------------------------------------------*/
3642 /*-----------------------------------------------------------------*/
3643 static void genSkipc(resolvedIfx *rifx)
3653 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3654 rifx->generated = 1;
3657 /*-----------------------------------------------------------------*/
3659 /*-----------------------------------------------------------------*/
3660 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3665 if( (rifx->condition ^ invert_condition) & 1)
3670 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3671 rifx->generated = 1;
3674 /*-----------------------------------------------------------------*/
3676 /*-----------------------------------------------------------------*/
3677 static void genSkipz(iCode *ifx, int condition)
3688 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3690 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3693 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3695 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3698 /*-----------------------------------------------------------------*/
3700 /*-----------------------------------------------------------------*/
3701 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3707 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3709 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3712 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3713 rifx->generated = 1;
3717 /*-----------------------------------------------------------------*/
3718 /* genChkZeroes :- greater or less than comparison */
3719 /* For each byte in a literal that is zero, inclusive or the */
3720 /* the corresponding byte in the operand with W */
3721 /* returns true if any of the bytes are zero */
3722 /*-----------------------------------------------------------------*/
3723 static int genChkZeroes(operand *op, int lit, int size)
3730 i = (lit >> (size*8)) & 0xff;
3734 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3736 emitpcode(POC_IORFW, popGet(AOP(op),size));
3745 /*-----------------------------------------------------------------*/
3746 /* genCmp :- greater or less than comparison */
3747 /*-----------------------------------------------------------------*/
3748 static void genCmp (operand *left,operand *right,
3749 operand *result, iCode *ifx, int sign)
3751 int size; //, offset = 0 ;
3752 unsigned long lit = 0L,i = 0;
3753 resolvedIfx rFalseIfx;
3754 // resolvedIfx rTrueIfx;
3756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3759 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3760 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3764 resolveIfx(&rFalseIfx,ifx);
3765 truelbl = newiTempLabel(NULL);
3766 size = max(AOP_SIZE(left),AOP_SIZE(right));
3768 DEBUGpic14_AopType(__LINE__,left,right,result);
3772 /* if literal is on the right then swap with left */
3773 if ((AOP_TYPE(right) == AOP_LIT)) {
3774 operand *tmp = right ;
3775 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3776 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3779 lit = (lit - 1) & mask;
3782 rFalseIfx.condition ^= 1;
3785 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3786 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3790 //if(IC_TRUE(ifx) == NULL)
3791 /* if left & right are bit variables */
3792 if (AOP_TYPE(left) == AOP_CRY &&
3793 AOP_TYPE(right) == AOP_CRY ) {
3794 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3795 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3797 /* subtract right from left if at the
3798 end the carry flag is set then we know that
3799 left is greater than right */
3803 symbol *lbl = newiTempLabel(NULL);
3806 if(AOP_TYPE(right) == AOP_LIT) {
3808 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3810 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3817 genSkipCond(&rFalseIfx,left,size-1,7);
3819 /* no need to compare to 0...*/
3820 /* NOTE: this is a de-generate compare that most certainly
3821 * creates some dead code. */
3822 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3824 if(ifx) ifx->generated = 1;
3831 //i = (lit >> (size*8)) & 0xff;
3832 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3834 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3836 i = ((0-lit) & 0xff);
3839 /* lit is 0x7f, all signed chars are less than
3840 * this except for 0x7f itself */
3841 emitpcode(POC_XORLW, popGetLit(0x7f));
3842 genSkipz2(&rFalseIfx,0);
3844 emitpcode(POC_ADDLW, popGetLit(0x80));
3845 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3846 genSkipc(&rFalseIfx);
3851 genSkipz2(&rFalseIfx,1);
3853 emitpcode(POC_ADDLW, popGetLit(i));
3854 genSkipc(&rFalseIfx);
3858 if(ifx) ifx->generated = 1;
3862 /* chars are out of the way. now do ints and longs */
3865 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3872 genSkipCond(&rFalseIfx,left,size,7);
3873 if(ifx) ifx->generated = 1;
3878 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3880 //rFalseIfx.condition ^= 1;
3881 //genSkipCond(&rFalseIfx,left,size,7);
3882 //rFalseIfx.condition ^= 1;
3884 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3885 if(rFalseIfx.condition)
3886 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3888 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3890 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3891 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3892 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3895 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3897 if(rFalseIfx.condition) {
3899 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3905 genSkipc(&rFalseIfx);
3906 emitpLabel(truelbl->key);
3907 if(ifx) ifx->generated = 1;
3914 if( (lit & 0xff) == 0) {
3915 /* lower byte is zero */
3916 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3917 i = ((lit >> 8) & 0xff) ^0x80;
3918 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3919 emitpcode(POC_ADDLW, popGetLit( 0x80));
3920 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3921 genSkipc(&rFalseIfx);
3924 if(ifx) ifx->generated = 1;
3929 /* Special cases for signed longs */
3930 if( (lit & 0xffffff) == 0) {
3931 /* lower byte is zero */
3932 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3933 i = ((lit >> 8*3) & 0xff) ^0x80;
3934 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3935 emitpcode(POC_ADDLW, popGetLit( 0x80));
3936 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3937 genSkipc(&rFalseIfx);
3940 if(ifx) ifx->generated = 1;
3948 if(lit & (0x80 << (size*8))) {
3949 /* lit is negative */
3950 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3952 //genSkipCond(&rFalseIfx,left,size,7);
3954 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3956 if(rFalseIfx.condition)
3957 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3959 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3963 /* lit is positive */
3964 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3965 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3966 if(rFalseIfx.condition)
3967 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3969 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3974 This works, but is only good for ints.
3975 It also requires a "known zero" register.
3976 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3977 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3978 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3979 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3980 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3981 genSkipc(&rFalseIfx);
3983 emitpLabel(truelbl->key);
3984 if(ifx) ifx->generated = 1;
3988 /* There are no more special cases, so perform a general compare */
3990 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3991 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3995 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3997 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3999 //rFalseIfx.condition ^= 1;
4000 genSkipc(&rFalseIfx);
4002 emitpLabel(truelbl->key);
4004 if(ifx) ifx->generated = 1;
4011 /* sign is out of the way. So now do an unsigned compare */
4012 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4015 /* General case - compare to an unsigned literal on the right.*/
4017 i = (lit >> (size*8)) & 0xff;
4018 emitpcode(POC_MOVLW, popGetLit(i));
4019 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4021 i = (lit >> (size*8)) & 0xff;
4024 emitpcode(POC_MOVLW, popGetLit(i));
4026 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4028 /* this byte of the lit is zero,
4029 *if it's not the last then OR in the variable */
4031 emitpcode(POC_IORFW, popGet(AOP(left),size));
4036 emitpLabel(lbl->key);
4037 //if(emitFinalCheck)
4038 genSkipc(&rFalseIfx);
4040 emitpLabel(truelbl->key);
4042 if(ifx) ifx->generated = 1;
4049 if(AOP_TYPE(left) == AOP_LIT) {
4050 //symbol *lbl = newiTempLabel(NULL);
4052 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4055 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4058 if((lit == 0) && (sign == 0)){
4061 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4063 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4065 genSkipz2(&rFalseIfx,0);
4066 if(ifx) ifx->generated = 1;
4073 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4074 /* degenerate compare can never be true */
4075 if(rFalseIfx.condition == 0)
4076 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4078 if(ifx) ifx->generated = 1;
4083 /* signed comparisons to a literal byte */
4085 int lp1 = (lit+1) & 0xff;
4087 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4090 rFalseIfx.condition ^= 1;
4091 genSkipCond(&rFalseIfx,right,0,7);
4094 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4095 emitpcode(POC_XORLW, popGetLit(0x7f));
4096 genSkipz2(&rFalseIfx,1);
4099 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4100 emitpcode(POC_ADDLW, popGetLit(0x80));
4101 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4102 rFalseIfx.condition ^= 1;
4103 genSkipc(&rFalseIfx);
4107 /* unsigned comparisons to a literal byte */
4109 switch(lit & 0xff ) {
4111 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4112 genSkipz2(&rFalseIfx,0);
4115 rFalseIfx.condition ^= 1;
4116 genSkipCond(&rFalseIfx,right,0,7);
4120 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4121 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4123 rFalseIfx.condition ^= 1;
4124 if (AOP_TYPE(result) == AOP_CRY)
4125 genSkipc(&rFalseIfx);
4127 emitpcode(POC_CLRF, popGet(AOP(result),0));
4128 emitpcode(POC_RLF, popGet(AOP(result),0));
4134 if(ifx) ifx->generated = 1;
4140 /* Size is greater than 1 */
4148 /* this means lit = 0xffffffff, or -1 */
4151 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4152 rFalseIfx.condition ^= 1;
4153 genSkipCond(&rFalseIfx,right,size,7);
4154 if(ifx) ifx->generated = 1;
4161 if(rFalseIfx.condition) {
4162 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4163 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4166 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4168 emitpcode(POC_IORFW, popGet(AOP(right),size));
4172 if(rFalseIfx.condition) {
4173 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4174 emitpLabel(truelbl->key);
4176 rFalseIfx.condition ^= 1;
4177 genSkipCond(&rFalseIfx,right,s,7);
4180 if(ifx) ifx->generated = 1;
4184 if((size == 1) && (0 == (lp1&0xff))) {
4185 /* lower byte of signed word is zero */
4186 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4187 i = ((lp1 >> 8) & 0xff) ^0x80;
4188 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4189 emitpcode(POC_ADDLW, popGetLit( 0x80));
4190 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4191 rFalseIfx.condition ^= 1;
4192 genSkipc(&rFalseIfx);
4195 if(ifx) ifx->generated = 1;
4199 if(lit & (0x80 << (size*8))) {
4200 /* Lit is less than zero */
4201 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4202 //rFalseIfx.condition ^= 1;
4203 //genSkipCond(&rFalseIfx,left,size,7);
4204 //rFalseIfx.condition ^= 1;
4205 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4206 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4208 if(rFalseIfx.condition)
4209 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4211 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4215 /* Lit is greater than or equal to zero */
4216 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4217 //rFalseIfx.condition ^= 1;
4218 //genSkipCond(&rFalseIfx,right,size,7);
4219 //rFalseIfx.condition ^= 1;
4221 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4222 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4224 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4225 if(rFalseIfx.condition)
4226 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4228 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4233 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4234 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4238 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4240 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4242 rFalseIfx.condition ^= 1;
4243 //rFalseIfx.condition = 1;
4244 genSkipc(&rFalseIfx);
4246 emitpLabel(truelbl->key);
4248 if(ifx) ifx->generated = 1;
4253 /* compare word or long to an unsigned literal on the right.*/
4258 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4261 break; /* handled above */
4264 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4266 emitpcode(POC_IORFW, popGet(AOP(right),size));
4267 genSkipz2(&rFalseIfx,0);
4271 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4273 emitpcode(POC_IORFW, popGet(AOP(right),size));
4276 if(rFalseIfx.condition)
4277 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4279 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4282 emitpcode(POC_MOVLW, popGetLit(lit+1));
4283 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4285 rFalseIfx.condition ^= 1;
4286 genSkipc(&rFalseIfx);
4289 emitpLabel(truelbl->key);
4291 if(ifx) ifx->generated = 1;
4297 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4298 i = (lit >> (size*8)) & 0xff;
4300 emitpcode(POC_MOVLW, popGetLit(i));
4301 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4304 i = (lit >> (size*8)) & 0xff;
4307 emitpcode(POC_MOVLW, popGetLit(i));
4309 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4311 /* this byte of the lit is zero,
4312 *if it's not the last then OR in the variable */
4314 emitpcode(POC_IORFW, popGet(AOP(right),size));
4319 emitpLabel(lbl->key);
4321 rFalseIfx.condition ^= 1;
4322 genSkipc(&rFalseIfx);
4326 emitpLabel(truelbl->key);
4327 if(ifx) ifx->generated = 1;
4331 /* Compare two variables */
4333 DEBUGpic14_emitcode(";sign","%d",sign);
4337 /* Sigh. thus sucks... */
4339 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4340 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4341 emitpcode(POC_MOVLW, popGetLit(0x80));
4342 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4343 emitpcode(POC_XORFW, popGet(AOP(right),size));
4344 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4346 /* Signed char comparison */
4347 /* Special thanks to Nikolai Golovchenko for this snippet */
4348 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4349 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4350 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4351 emitpcode(POC_XORFW, popGet(AOP(left),0));
4352 emitpcode(POC_XORFW, popGet(AOP(right),0));
4353 emitpcode(POC_ADDLW, popGetLit(0x80));
4355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4356 genSkipc(&rFalseIfx);
4358 if(ifx) ifx->generated = 1;
4364 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4365 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4369 /* The rest of the bytes of a multi-byte compare */
4373 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4376 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4377 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4382 emitpLabel(lbl->key);
4384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4385 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4386 (AOP_TYPE(result) == AOP_REG)) {
4387 emitpcode(POC_CLRF, popGet(AOP(result),0));
4388 emitpcode(POC_RLF, popGet(AOP(result),0));
4390 genSkipc(&rFalseIfx);
4392 //genSkipc(&rFalseIfx);
4393 if(ifx) ifx->generated = 1;
4400 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4402 pic14_outBitC(result);
4404 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4405 /* if the result is used in the next
4406 ifx conditional branch then generate
4407 code a little differently */
4409 genIfxJump (ifx,"c");
4411 pic14_outBitC(result);
4412 /* leave the result in acc */
4417 /*-----------------------------------------------------------------*/
4418 /* genCmpGt :- greater than comparison */
4419 /*-----------------------------------------------------------------*/
4420 static void genCmpGt (iCode *ic, iCode *ifx)
4422 operand *left, *right, *result;
4423 sym_link *letype , *retype;
4426 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4428 right= IC_RIGHT(ic);
4429 result = IC_RESULT(ic);
4431 letype = getSpec(operandType(left));
4432 retype =getSpec(operandType(right));
4433 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4434 /* assign the amsops */
4435 aopOp (left,ic,FALSE);
4436 aopOp (right,ic,FALSE);
4437 aopOp (result,ic,TRUE);
4439 genCmp(right, left, result, ifx, sign);
4441 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4443 freeAsmop(result,NULL,ic,TRUE);
4446 /*-----------------------------------------------------------------*/
4447 /* genCmpLt - less than comparisons */
4448 /*-----------------------------------------------------------------*/
4449 static void genCmpLt (iCode *ic, iCode *ifx)
4451 operand *left, *right, *result;
4452 sym_link *letype , *retype;
4455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4457 right= IC_RIGHT(ic);
4458 result = IC_RESULT(ic);
4460 letype = getSpec(operandType(left));
4461 retype =getSpec(operandType(right));
4462 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4464 /* assign the amsops */
4465 aopOp (left,ic,FALSE);
4466 aopOp (right,ic,FALSE);
4467 aopOp (result,ic,TRUE);
4469 genCmp(left, right, result, ifx, sign);
4471 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4472 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4473 freeAsmop(result,NULL,ic,TRUE);
4476 /*-----------------------------------------------------------------*/
4477 /* genc16bit2lit - compare a 16 bit value to a literal */
4478 /*-----------------------------------------------------------------*/
4479 static void genc16bit2lit(operand *op, int lit, int offset)
4483 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4484 if( (lit&0xff) == 0)
4489 switch( BYTEofLONG(lit,i)) {
4491 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4494 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4497 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4500 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4501 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4506 switch( BYTEofLONG(lit,i)) {
4508 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4512 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4516 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4519 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4521 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4527 /*-----------------------------------------------------------------*/
4528 /* gencjneshort - compare and jump if not equal */
4529 /*-----------------------------------------------------------------*/
4530 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4532 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4534 int res_offset = 0; /* the result may be a different size then left or right */
4535 int res_size = AOP_SIZE(result);
4539 unsigned long lit = 0L;
4540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4541 DEBUGpic14_AopType(__LINE__,left,right,result);
4543 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4544 resolveIfx(&rIfx,ifx);
4545 lbl = newiTempLabel(NULL);
4548 /* if the left side is a literal or
4549 if the right is in a pointer register and left
4551 if ((AOP_TYPE(left) == AOP_LIT) ||
4552 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4557 if(AOP_TYPE(right) == AOP_LIT)
4558 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4560 /* if the right side is a literal then anything goes */
4561 if (AOP_TYPE(right) == AOP_LIT &&
4562 AOP_TYPE(left) != AOP_DIR ) {
4565 genc16bit2lit(left, lit, 0);
4567 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4572 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4573 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4575 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4579 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4581 if(res_offset < res_size-1)
4589 /* if the right side is in a register or in direct space or
4590 if the left is a pointer register & right is not */
4591 else if (AOP_TYPE(right) == AOP_REG ||
4592 AOP_TYPE(right) == AOP_DIR ||
4593 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4594 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4595 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4596 int lbl_key = lbl->key;
4599 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4600 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4602 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4603 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4604 __FUNCTION__,__LINE__);
4608 /* switch(size) { */
4610 /* genc16bit2lit(left, lit, 0); */
4612 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4617 if((AOP_TYPE(left) == AOP_DIR) &&
4618 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4620 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4621 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4623 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4625 switch (lit & 0xff) {
4627 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4630 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4631 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4632 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4636 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4637 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4638 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4639 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4643 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4644 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4649 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4652 if(AOP_TYPE(result) == AOP_CRY) {
4653 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4658 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4660 /* fix me. probably need to check result size too */
4661 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4666 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4667 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4674 if(res_offset < res_size-1)
4679 } else if(AOP_TYPE(right) == AOP_REG &&
4680 AOP_TYPE(left) != AOP_DIR){
4683 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4684 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4685 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4690 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4692 if(res_offset < res_size-1)
4697 /* right is a pointer reg need both a & b */
4699 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4701 pic14_emitcode("mov","b,%s",l);
4702 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4703 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4708 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4710 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4712 emitpLabel(lbl->key);
4714 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4721 /*-----------------------------------------------------------------*/
4722 /* gencjne - compare and jump if not equal */
4723 /*-----------------------------------------------------------------*/
4724 static void gencjne(operand *left, operand *right, iCode *ifx)
4726 symbol *tlbl = newiTempLabel(NULL);
4728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4729 gencjneshort(left, right, lbl);
4731 pic14_emitcode("mov","a,%s",one);
4732 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4733 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4734 pic14_emitcode("clr","a");
4735 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4737 emitpLabel(lbl->key);
4738 emitpLabel(tlbl->key);
4743 /*-----------------------------------------------------------------*/
4744 /* genCmpEq - generates code for equal to */
4745 /*-----------------------------------------------------------------*/
4746 static void genCmpEq (iCode *ic, iCode *ifx)
4748 operand *left, *right, *result;
4749 unsigned long lit = 0L;
4752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4755 DEBUGpic14_emitcode ("; ifx is non-null","");
4757 DEBUGpic14_emitcode ("; ifx is null","");
4759 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4760 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4761 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4763 size = max(AOP_SIZE(left),AOP_SIZE(right));
4765 DEBUGpic14_AopType(__LINE__,left,right,result);
4767 /* if literal, literal on the right or
4768 if the right is in a pointer register and left
4770 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4771 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4772 operand *tmp = right ;
4778 if(ifx && !AOP_SIZE(result)){
4780 /* if they are both bit variables */
4781 if (AOP_TYPE(left) == AOP_CRY &&
4782 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4783 if(AOP_TYPE(right) == AOP_LIT){
4784 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4786 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4787 pic14_emitcode("cpl","c");
4788 } else if(lit == 1L) {
4789 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4791 pic14_emitcode("clr","c");
4793 /* AOP_TYPE(right) == AOP_CRY */
4795 symbol *lbl = newiTempLabel(NULL);
4796 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4797 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4798 pic14_emitcode("cpl","c");
4799 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4801 /* if true label then we jump if condition
4803 tlbl = newiTempLabel(NULL);
4804 if ( IC_TRUE(ifx) ) {
4805 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4806 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4808 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4809 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4811 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4814 /* left and right are both bit variables, result is carry */
4817 resolveIfx(&rIfx,ifx);
4819 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4820 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4821 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4822 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4827 /* They're not both bit variables. Is the right a literal? */
4828 if(AOP_TYPE(right) == AOP_LIT) {
4829 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4834 switch(lit & 0xff) {
4836 if ( IC_TRUE(ifx) ) {
4837 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4839 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4841 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4842 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4846 if ( IC_TRUE(ifx) ) {
4847 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4849 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4851 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4852 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4856 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4858 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4863 /* end of size == 1 */
4867 genc16bit2lit(left,lit,offset);
4870 /* end of size == 2 */
4875 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4876 emitpcode(POC_IORFW,popGet(AOP(left),1));
4877 emitpcode(POC_IORFW,popGet(AOP(left),2));
4878 emitpcode(POC_IORFW,popGet(AOP(left),3));
4882 /* search for patterns that can be optimized */
4884 genc16bit2lit(left,lit,0);
4887 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4889 genc16bit2lit(left,lit,2);
4891 emitpcode(POC_IORFW,popGet(AOP(left),2));
4892 emitpcode(POC_IORFW,popGet(AOP(left),3));
4905 } else if(AOP_TYPE(right) == AOP_CRY ) {
4906 /* we know the left is not a bit, but that the right is */
4907 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4908 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4909 popGet(AOP(right),offset));
4910 emitpcode(POC_XORLW,popGetLit(1));
4912 /* if the two are equal, then W will be 0 and the Z bit is set
4913 * we could test Z now, or go ahead and check the high order bytes if
4914 * the variable we're comparing is larger than a byte. */
4917 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4919 if ( IC_TRUE(ifx) ) {
4921 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4922 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4925 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4926 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4930 /* They're both variables that are larger than bits */
4933 tlbl = newiTempLabel(NULL);
4936 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4937 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4939 if ( IC_TRUE(ifx) ) {
4942 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4943 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4946 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4947 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4951 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4952 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4956 if(s>1 && IC_TRUE(ifx)) {
4957 emitpLabel(tlbl->key);
4958 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4962 /* mark the icode as generated */
4967 /* if they are both bit variables */
4968 if (AOP_TYPE(left) == AOP_CRY &&
4969 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4970 if(AOP_TYPE(right) == AOP_LIT){
4971 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4973 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4974 pic14_emitcode("cpl","c");
4975 } else if(lit == 1L) {
4976 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4978 pic14_emitcode("clr","c");
4980 /* AOP_TYPE(right) == AOP_CRY */
4982 symbol *lbl = newiTempLabel(NULL);
4983 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4984 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4985 pic14_emitcode("cpl","c");
4986 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4989 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4990 pic14_outBitC(result);
4994 genIfxJump (ifx,"c");
4997 /* if the result is used in an arithmetic operation
4998 then put the result in place */
4999 pic14_outBitC(result);
5002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5003 gencjne(left,right,result,ifx);
5006 gencjne(left,right,newiTempLabel(NULL));
5008 if(IC_TRUE(ifx)->key)
5009 gencjne(left,right,IC_TRUE(ifx)->key);
5011 gencjne(left,right,IC_FALSE(ifx)->key);
5015 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5016 aopPut(AOP(result),"a",0);
5021 genIfxJump (ifx,"a");
5025 /* if the result is used in an arithmetic operation
5026 then put the result in place */
5028 if (AOP_TYPE(result) != AOP_CRY)
5029 pic14_outAcc(result);
5031 /* leave the result in acc */
5035 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5036 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5037 freeAsmop(result,NULL,ic,TRUE);
5040 /*-----------------------------------------------------------------*/
5041 /* ifxForOp - returns the icode containing the ifx for operand */
5042 /*-----------------------------------------------------------------*/
5043 static iCode *ifxForOp ( operand *op, iCode *ic )
5045 /* if true symbol then needs to be assigned */
5046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5047 if (IS_TRUE_SYMOP(op))
5050 /* if this has register type condition and
5051 the next instruction is ifx with the same operand
5052 and live to of the operand is upto the ifx only then */
5054 ic->next->op == IFX &&
5055 IC_COND(ic->next)->key == op->key &&
5056 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5060 ic->next->op == IFX &&
5061 IC_COND(ic->next)->key == op->key) {
5062 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5066 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5068 ic->next->op == IFX)
5069 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5072 ic->next->op == IFX &&
5073 IC_COND(ic->next)->key == op->key) {
5074 DEBUGpic14_emitcode ("; "," key is okay");
5075 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5076 OP_SYMBOL(op)->liveTo,
5083 /*-----------------------------------------------------------------*/
5084 /* genAndOp - for && operation */
5085 /*-----------------------------------------------------------------*/
5086 static void genAndOp (iCode *ic)
5088 operand *left,*right, *result;
5091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5092 /* note here that && operations that are in an
5093 if statement are taken away by backPatchLabels
5094 only those used in arthmetic operations remain */
5095 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5096 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5097 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5099 DEBUGpic14_AopType(__LINE__,left,right,result);
5101 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5102 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5103 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5105 /* if both are bit variables */
5106 /* if (AOP_TYPE(left) == AOP_CRY && */
5107 /* AOP_TYPE(right) == AOP_CRY ) { */
5108 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5109 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5110 /* pic14_outBitC(result); */
5112 /* tlbl = newiTempLabel(NULL); */
5113 /* pic14_toBoolean(left); */
5114 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5115 /* pic14_toBoolean(right); */
5116 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5117 /* pic14_outBitAcc(result); */
5120 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5121 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5122 freeAsmop(result,NULL,ic,TRUE);
5126 /*-----------------------------------------------------------------*/
5127 /* genOrOp - for || operation */
5128 /*-----------------------------------------------------------------*/
5131 modified this code, but it doesn't appear to ever get called
5134 static void genOrOp (iCode *ic)
5136 operand *left,*right, *result;
5139 /* note here that || operations that are in an
5140 if statement are taken away by backPatchLabels
5141 only those used in arthmetic operations remain */
5142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5143 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5144 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5145 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5147 DEBUGpic14_AopType(__LINE__,left,right,result);
5149 /* if both are bit variables */
5150 if (AOP_TYPE(left) == AOP_CRY &&
5151 AOP_TYPE(right) == AOP_CRY ) {
5152 pic14_emitcode("clrc","");
5153 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5154 AOP(left)->aopu.aop_dir,
5155 AOP(left)->aopu.aop_dir);
5156 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5157 AOP(right)->aopu.aop_dir,
5158 AOP(right)->aopu.aop_dir);
5159 pic14_emitcode("setc","");
5162 tlbl = newiTempLabel(NULL);
5163 pic14_toBoolean(left);
5165 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5166 pic14_toBoolean(right);
5167 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5169 pic14_outBitAcc(result);
5172 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5173 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5174 freeAsmop(result,NULL,ic,TRUE);
5177 /*-----------------------------------------------------------------*/
5178 /* isLiteralBit - test if lit == 2^n */
5179 /*-----------------------------------------------------------------*/
5180 static int isLiteralBit(unsigned long lit)
5182 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5183 0x100L,0x200L,0x400L,0x800L,
5184 0x1000L,0x2000L,0x4000L,0x8000L,
5185 0x10000L,0x20000L,0x40000L,0x80000L,
5186 0x100000L,0x200000L,0x400000L,0x800000L,
5187 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5188 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5192 for(idx = 0; idx < 32; idx++)
5198 /*-----------------------------------------------------------------*/
5199 /* continueIfTrue - */
5200 /*-----------------------------------------------------------------*/
5201 static void continueIfTrue (iCode *ic)
5203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5205 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5209 /*-----------------------------------------------------------------*/
5211 /*-----------------------------------------------------------------*/
5212 static void jumpIfTrue (iCode *ic)
5214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5216 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5220 /*-----------------------------------------------------------------*/
5221 /* jmpTrueOrFalse - */
5222 /*-----------------------------------------------------------------*/
5223 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5225 // ugly but optimized by peephole
5226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5228 symbol *nlbl = newiTempLabel(NULL);
5229 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5230 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5231 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5232 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5235 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5236 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5241 /*-----------------------------------------------------------------*/
5242 /* genAnd - code for and */
5243 /*-----------------------------------------------------------------*/
5244 static void genAnd (iCode *ic, iCode *ifx)
5246 operand *left, *right, *result;
5248 unsigned long lit = 0L;
5253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5254 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5255 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5256 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5258 resolveIfx(&rIfx,ifx);
5260 /* if left is a literal & right is not then exchange them */
5261 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5262 AOP_NEEDSACC(left)) {
5263 operand *tmp = right ;
5268 /* if result = right then exchange them */
5269 if(pic14_sameRegs(AOP(result),AOP(right))){
5270 operand *tmp = right ;
5275 /* if right is bit then exchange them */
5276 if (AOP_TYPE(right) == AOP_CRY &&
5277 AOP_TYPE(left) != AOP_CRY){
5278 operand *tmp = right ;
5282 if(AOP_TYPE(right) == AOP_LIT)
5283 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5285 size = AOP_SIZE(result);
5287 DEBUGpic14_AopType(__LINE__,left,right,result);
5290 // result = bit & yy;
5291 if (AOP_TYPE(left) == AOP_CRY){
5292 // c = bit & literal;
5293 if(AOP_TYPE(right) == AOP_LIT){
5295 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5298 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5301 if(size && (AOP_TYPE(result) == AOP_CRY)){
5302 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5305 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5309 pic14_emitcode("clr","c");
5312 if (AOP_TYPE(right) == AOP_CRY){
5314 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5315 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5318 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5320 pic14_emitcode("rrc","a");
5321 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5327 pic14_outBitC(result);
5329 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5330 genIfxJump(ifx, "c");
5334 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5335 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5336 if((AOP_TYPE(right) == AOP_LIT) &&
5337 (AOP_TYPE(result) == AOP_CRY) &&
5338 (AOP_TYPE(left) != AOP_CRY)){
5339 int posbit = isLiteralBit(lit);
5343 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5346 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5352 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5353 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5355 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5356 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5359 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5360 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5361 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5368 symbol *tlbl = newiTempLabel(NULL);
5369 int sizel = AOP_SIZE(left);
5371 pic14_emitcode("setb","c");
5373 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5374 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5376 if((posbit = isLiteralBit(bytelit)) != 0)
5377 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5379 if(bytelit != 0x0FFL)
5380 pic14_emitcode("anl","a,%s",
5381 aopGet(AOP(right),offset,FALSE,TRUE));
5382 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5387 // bit = left & literal
5389 pic14_emitcode("clr","c");
5390 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5392 // if(left & literal)
5395 jmpTrueOrFalse(ifx, tlbl);
5399 pic14_outBitC(result);
5403 /* if left is same as result */
5404 if(pic14_sameRegs(AOP(result),AOP(left))){
5406 for(;size--; offset++,lit>>=8) {
5407 if(AOP_TYPE(right) == AOP_LIT){
5408 switch(lit & 0xff) {
5410 /* and'ing with 0 has clears the result */
5411 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5412 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5415 /* and'ing with 0xff is a nop when the result and left are the same */
5420 int p = my_powof2( (~lit) & 0xff );
5422 /* only one bit is set in the literal, so use a bcf instruction */
5423 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5424 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5427 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5428 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5429 if(know_W != (lit&0xff))
5430 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5432 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5437 if (AOP_TYPE(left) == AOP_ACC) {
5438 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5440 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5441 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5448 // left & result in different registers
5449 if(AOP_TYPE(result) == AOP_CRY){
5451 // if(size), result in bit
5452 // if(!size && ifx), conditional oper: if(left & right)
5453 symbol *tlbl = newiTempLabel(NULL);
5454 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5456 pic14_emitcode("setb","c");
5458 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5459 pic14_emitcode("anl","a,%s",
5460 aopGet(AOP(left),offset,FALSE,FALSE));
5461 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5466 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5467 pic14_outBitC(result);
5469 jmpTrueOrFalse(ifx, tlbl);
5471 for(;(size--);offset++) {
5473 // result = left & right
5474 if(AOP_TYPE(right) == AOP_LIT){
5475 int t = (lit >> (offset*8)) & 0x0FFL;
5478 pic14_emitcode("clrf","%s",
5479 aopGet(AOP(result),offset,FALSE,FALSE));
5480 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5483 pic14_emitcode("movf","%s,w",
5484 aopGet(AOP(left),offset,FALSE,FALSE));
5485 pic14_emitcode("movwf","%s",
5486 aopGet(AOP(result),offset,FALSE,FALSE));
5487 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5488 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5491 pic14_emitcode("movlw","0x%x",t);
5492 pic14_emitcode("andwf","%s,w",
5493 aopGet(AOP(left),offset,FALSE,FALSE));
5494 pic14_emitcode("movwf","%s",
5495 aopGet(AOP(result),offset,FALSE,FALSE));
5497 emitpcode(POC_MOVLW, popGetLit(t));
5498 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5499 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5504 if (AOP_TYPE(left) == AOP_ACC) {
5505 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5506 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5508 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5509 pic14_emitcode("andwf","%s,w",
5510 aopGet(AOP(left),offset,FALSE,FALSE));
5511 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5512 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5514 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5515 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5521 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5522 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5523 freeAsmop(result,NULL,ic,TRUE);
5526 /*-----------------------------------------------------------------*/
5527 /* genOr - code for or */
5528 /*-----------------------------------------------------------------*/
5529 static void genOr (iCode *ic, iCode *ifx)
5531 operand *left, *right, *result;
5533 unsigned long lit = 0L;
5535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5537 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5538 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5539 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5541 DEBUGpic14_AopType(__LINE__,left,right,result);
5543 /* if left is a literal & right is not then exchange them */
5544 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5545 AOP_NEEDSACC(left)) {
5546 operand *tmp = right ;
5551 /* if result = right then exchange them */
5552 if(pic14_sameRegs(AOP(result),AOP(right))){
5553 operand *tmp = right ;
5558 /* if right is bit then exchange them */
5559 if (AOP_TYPE(right) == AOP_CRY &&
5560 AOP_TYPE(left) != AOP_CRY){
5561 operand *tmp = right ;
5566 DEBUGpic14_AopType(__LINE__,left,right,result);
5568 if(AOP_TYPE(right) == AOP_LIT)
5569 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5571 size = AOP_SIZE(result);
5575 if (AOP_TYPE(left) == AOP_CRY){
5576 if(AOP_TYPE(right) == AOP_LIT){
5577 // c = bit & literal;
5579 // lit != 0 => result = 1
5580 if(AOP_TYPE(result) == AOP_CRY){
5582 emitpcode(POC_BSF, popGet(AOP(result),0));
5583 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5584 // AOP(result)->aopu.aop_dir,
5585 // AOP(result)->aopu.aop_dir);
5587 continueIfTrue(ifx);
5591 // lit == 0 => result = left
5592 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5594 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5597 if (AOP_TYPE(right) == AOP_CRY){
5598 if(pic14_sameRegs(AOP(result),AOP(left))){
5600 emitpcode(POC_BCF, popGet(AOP(result),0));
5601 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5602 emitpcode(POC_BSF, popGet(AOP(result),0));
5604 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5605 AOP(result)->aopu.aop_dir,
5606 AOP(result)->aopu.aop_dir);
5607 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5608 AOP(right)->aopu.aop_dir,
5609 AOP(right)->aopu.aop_dir);
5610 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5611 AOP(result)->aopu.aop_dir,
5612 AOP(result)->aopu.aop_dir);
5614 if( AOP_TYPE(result) == AOP_ACC) {
5615 emitpcode(POC_MOVLW, popGetLit(0));
5616 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5617 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5618 emitpcode(POC_MOVLW, popGetLit(1));
5622 emitpcode(POC_BCF, popGet(AOP(result),0));
5623 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5624 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5625 emitpcode(POC_BSF, popGet(AOP(result),0));
5627 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5628 AOP(result)->aopu.aop_dir,
5629 AOP(result)->aopu.aop_dir);
5630 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5631 AOP(right)->aopu.aop_dir,
5632 AOP(right)->aopu.aop_dir);
5633 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5634 AOP(left)->aopu.aop_dir,
5635 AOP(left)->aopu.aop_dir);
5636 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5637 AOP(result)->aopu.aop_dir,
5638 AOP(result)->aopu.aop_dir);
5643 symbol *tlbl = newiTempLabel(NULL);
5644 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5647 emitpcode(POC_BCF, popGet(AOP(result),0));
5648 if( AOP_TYPE(right) == AOP_ACC) {
5649 emitpcode(POC_IORLW, popGetLit(0));
5651 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5652 emitpcode(POC_BSF, popGet(AOP(result),0));
5657 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5658 pic14_emitcode(";XXX setb","c");
5659 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5660 AOP(left)->aopu.aop_dir,tlbl->key+100);
5661 pic14_toBoolean(right);
5662 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5663 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5664 jmpTrueOrFalse(ifx, tlbl);
5668 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5675 pic14_outBitC(result);
5677 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5678 genIfxJump(ifx, "c");
5682 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5683 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5684 if((AOP_TYPE(right) == AOP_LIT) &&
5685 (AOP_TYPE(result) == AOP_CRY) &&
5686 (AOP_TYPE(left) != AOP_CRY)){
5688 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5691 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5693 continueIfTrue(ifx);
5696 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5697 // lit = 0, result = boolean(left)
5699 pic14_emitcode(";XXX setb","c");
5700 pic14_toBoolean(right);
5702 symbol *tlbl = newiTempLabel(NULL);
5703 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5707 genIfxJump (ifx,"a");
5711 pic14_outBitC(result);
5715 /* if left is same as result */
5716 if(pic14_sameRegs(AOP(result),AOP(left))){
5718 for(;size--; offset++,lit>>=8) {
5719 if(AOP_TYPE(right) == AOP_LIT){
5720 if((lit & 0xff) == 0)
5721 /* or'ing with 0 has no effect */
5724 int p = my_powof2(lit & 0xff);
5726 /* only one bit is set in the literal, so use a bsf instruction */
5728 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5730 if(know_W != (lit & 0xff))
5731 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5732 know_W = lit & 0xff;
5733 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5738 if (AOP_TYPE(left) == AOP_ACC) {
5739 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5740 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5742 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5743 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5745 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5746 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5752 // left & result in different registers
5753 if(AOP_TYPE(result) == AOP_CRY){
5755 // if(size), result in bit
5756 // if(!size && ifx), conditional oper: if(left | right)
5757 symbol *tlbl = newiTempLabel(NULL);
5758 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5759 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5763 pic14_emitcode(";XXX setb","c");
5765 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5766 pic14_emitcode(";XXX orl","a,%s",
5767 aopGet(AOP(left),offset,FALSE,FALSE));
5768 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5773 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5774 pic14_outBitC(result);
5776 jmpTrueOrFalse(ifx, tlbl);
5777 } else for(;(size--);offset++){
5779 // result = left & right
5780 if(AOP_TYPE(right) == AOP_LIT){
5781 int t = (lit >> (offset*8)) & 0x0FFL;
5784 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5785 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5787 pic14_emitcode("movf","%s,w",
5788 aopGet(AOP(left),offset,FALSE,FALSE));
5789 pic14_emitcode("movwf","%s",
5790 aopGet(AOP(result),offset,FALSE,FALSE));
5793 emitpcode(POC_MOVLW, popGetLit(t));
5794 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5795 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5797 pic14_emitcode("movlw","0x%x",t);
5798 pic14_emitcode("iorwf","%s,w",
5799 aopGet(AOP(left),offset,FALSE,FALSE));
5800 pic14_emitcode("movwf","%s",
5801 aopGet(AOP(result),offset,FALSE,FALSE));
5807 // faster than result <- left, anl result,right
5808 // and better if result is SFR
5809 if (AOP_TYPE(left) == AOP_ACC) {
5810 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5811 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5813 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5814 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5816 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5817 pic14_emitcode("iorwf","%s,w",
5818 aopGet(AOP(left),offset,FALSE,FALSE));
5820 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5821 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5826 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5827 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5828 freeAsmop(result,NULL,ic,TRUE);
5831 /*-----------------------------------------------------------------*/
5832 /* genXor - code for xclusive or */
5833 /*-----------------------------------------------------------------*/
5834 static void genXor (iCode *ic, iCode *ifx)
5836 operand *left, *right, *result;
5838 unsigned long lit = 0L;
5840 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5842 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5843 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5844 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5846 /* if left is a literal & right is not ||
5847 if left needs acc & right does not */
5848 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5849 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5850 operand *tmp = right ;
5855 /* if result = right then exchange them */
5856 if(pic14_sameRegs(AOP(result),AOP(right))){
5857 operand *tmp = right ;
5862 /* if right is bit then exchange them */
5863 if (AOP_TYPE(right) == AOP_CRY &&
5864 AOP_TYPE(left) != AOP_CRY){
5865 operand *tmp = right ;
5869 if(AOP_TYPE(right) == AOP_LIT)
5870 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5872 size = AOP_SIZE(result);
5876 if (AOP_TYPE(left) == AOP_CRY){
5877 if(AOP_TYPE(right) == AOP_LIT){
5878 // c = bit & literal;
5880 // lit>>1 != 0 => result = 1
5881 if(AOP_TYPE(result) == AOP_CRY){
5883 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5884 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5886 continueIfTrue(ifx);
5889 pic14_emitcode("setb","c");
5893 // lit == 0, result = left
5894 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5896 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5898 // lit == 1, result = not(left)
5899 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5900 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5901 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5902 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5905 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5906 pic14_emitcode("cpl","c");
5913 symbol *tlbl = newiTempLabel(NULL);
5914 if (AOP_TYPE(right) == AOP_CRY){
5916 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5919 int sizer = AOP_SIZE(right);
5921 // if val>>1 != 0, result = 1
5922 pic14_emitcode("setb","c");
5924 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5926 // test the msb of the lsb
5927 pic14_emitcode("anl","a,#0xfe");
5928 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5932 pic14_emitcode("rrc","a");
5934 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5935 pic14_emitcode("cpl","c");
5936 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5941 pic14_outBitC(result);
5943 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5944 genIfxJump(ifx, "c");
5948 if(pic14_sameRegs(AOP(result),AOP(left))){
5949 /* if left is same as result */
5950 for(;size--; offset++) {
5951 if(AOP_TYPE(right) == AOP_LIT){
5952 int t = (lit >> (offset*8)) & 0x0FFL;
5956 if (IS_AOP_PREG(left)) {
5957 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5958 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5959 aopPut(AOP(result),"a",offset);
5961 emitpcode(POC_MOVLW, popGetLit(t));
5962 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5963 pic14_emitcode("xrl","%s,%s",
5964 aopGet(AOP(left),offset,FALSE,TRUE),
5965 aopGet(AOP(right),offset,FALSE,FALSE));
5968 if (AOP_TYPE(left) == AOP_ACC)
5969 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5971 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5972 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5974 if (IS_AOP_PREG(left)) {
5975 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5976 aopPut(AOP(result),"a",offset);
5978 pic14_emitcode("xrl","%s,a",
5979 aopGet(AOP(left),offset,FALSE,TRUE));
5985 // left & result in different registers
5986 if(AOP_TYPE(result) == AOP_CRY){
5988 // if(size), result in bit
5989 // if(!size && ifx), conditional oper: if(left ^ right)
5990 symbol *tlbl = newiTempLabel(NULL);
5991 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5993 pic14_emitcode("setb","c");
5995 if((AOP_TYPE(right) == AOP_LIT) &&
5996 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5997 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5999 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6000 pic14_emitcode("xrl","a,%s",
6001 aopGet(AOP(left),offset,FALSE,FALSE));
6003 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6008 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6009 pic14_outBitC(result);
6011 jmpTrueOrFalse(ifx, tlbl);
6012 } else for(;(size--);offset++){
6014 // result = left & right
6015 if(AOP_TYPE(right) == AOP_LIT){
6016 int t = (lit >> (offset*8)) & 0x0FFL;
6019 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6020 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6021 pic14_emitcode("movf","%s,w",
6022 aopGet(AOP(left),offset,FALSE,FALSE));
6023 pic14_emitcode("movwf","%s",
6024 aopGet(AOP(result),offset,FALSE,FALSE));
6027 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6028 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6029 pic14_emitcode("comf","%s,w",
6030 aopGet(AOP(left),offset,FALSE,FALSE));
6031 pic14_emitcode("movwf","%s",
6032 aopGet(AOP(result),offset,FALSE,FALSE));
6035 emitpcode(POC_MOVLW, popGetLit(t));
6036 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6037 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6038 pic14_emitcode("movlw","0x%x",t);
6039 pic14_emitcode("xorwf","%s,w",
6040 aopGet(AOP(left),offset,FALSE,FALSE));
6041 pic14_emitcode("movwf","%s",
6042 aopGet(AOP(result),offset,FALSE,FALSE));
6048 // faster than result <- left, anl result,right
6049 // and better if result is SFR
6050 if (AOP_TYPE(left) == AOP_ACC) {
6051 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6052 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6054 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6055 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6056 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6057 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6059 if ( AOP_TYPE(result) != AOP_ACC){
6060 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6061 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6067 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6068 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6069 freeAsmop(result,NULL,ic,TRUE);
6072 /*-----------------------------------------------------------------*/
6073 /* genInline - write the inline code out */
6074 /*-----------------------------------------------------------------*/
6075 static void genInline (iCode *ic)
6077 char *buffer, *bp, *bp1;
6079 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6081 _G.inLine += (!options.asmpeep);
6083 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6084 strcpy(buffer,IC_INLINE(ic));
6086 /* emit each line as a code */
6092 addpCode2pBlock(pb,AssembleLine(bp1));
6099 pic14_emitcode(bp1,"");
6105 if ((bp1 != bp) && *bp1)
6106 addpCode2pBlock(pb,AssembleLine(bp1));
6110 _G.inLine -= (!options.asmpeep);
6113 /*-----------------------------------------------------------------*/
6114 /* genRRC - rotate right with carry */
6115 /*-----------------------------------------------------------------*/
6116 static void genRRC (iCode *ic)
6118 operand *left , *result ;
6119 int size, offset = 0, same;
6121 /* rotate right with carry */
6123 result=IC_RESULT(ic);
6124 aopOp (left,ic,FALSE);
6125 aopOp (result,ic,FALSE);
6127 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6129 same = pic14_sameRegs(AOP(result),AOP(left));
6131 size = AOP_SIZE(result);
6133 /* get the lsb and put it into the carry */
6134 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6141 emitpcode(POC_RRF, popGet(AOP(left),offset));
6143 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6144 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6150 freeAsmop(left,NULL,ic,TRUE);
6151 freeAsmop(result,NULL,ic,TRUE);
6154 /*-----------------------------------------------------------------*/
6155 /* genRLC - generate code for rotate left with carry */
6156 /*-----------------------------------------------------------------*/
6157 static void genRLC (iCode *ic)
6159 operand *left , *result ;
6160 int size, offset = 0;
6163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6164 /* rotate right with carry */
6166 result=IC_RESULT(ic);
6167 aopOp (left,ic,FALSE);
6168 aopOp (result,ic,FALSE);
6170 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6172 same = pic14_sameRegs(AOP(result),AOP(left));
6174 /* move it to the result */
6175 size = AOP_SIZE(result);
6177 /* get the msb and put it into the carry */
6178 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6185 emitpcode(POC_RLF, popGet(AOP(left),offset));
6187 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6188 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6195 freeAsmop(left,NULL,ic,TRUE);
6196 freeAsmop(result,NULL,ic,TRUE);
6199 /*-----------------------------------------------------------------*/
6200 /* genGetHbit - generates code get highest order bit */
6201 /*-----------------------------------------------------------------*/
6202 static void genGetHbit (iCode *ic)
6204 operand *left, *result;
6206 result=IC_RESULT(ic);
6207 aopOp (left,ic,FALSE);
6208 aopOp (result,ic,FALSE);
6210 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6211 /* get the highest order byte into a */
6212 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6213 if(AOP_TYPE(result) == AOP_CRY){
6214 pic14_emitcode("rlc","a");
6215 pic14_outBitC(result);
6218 pic14_emitcode("rl","a");
6219 pic14_emitcode("anl","a,#0x01");
6220 pic14_outAcc(result);
6224 freeAsmop(left,NULL,ic,TRUE);
6225 freeAsmop(result,NULL,ic,TRUE);
6228 /*-----------------------------------------------------------------*/
6229 /* AccRol - rotate left accumulator by known count */
6230 /*-----------------------------------------------------------------*/
6231 static void AccRol (int shCount)
6233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6234 shCount &= 0x0007; // shCount : 0..7
6239 pic14_emitcode("rl","a");
6242 pic14_emitcode("rl","a");
6243 pic14_emitcode("rl","a");
6246 pic14_emitcode("swap","a");
6247 pic14_emitcode("rr","a");
6250 pic14_emitcode("swap","a");
6253 pic14_emitcode("swap","a");
6254 pic14_emitcode("rl","a");
6257 pic14_emitcode("rr","a");
6258 pic14_emitcode("rr","a");
6261 pic14_emitcode("rr","a");
6266 /*-----------------------------------------------------------------*/
6267 /* AccLsh - left shift accumulator by known count */
6268 /*-----------------------------------------------------------------*/
6269 static void AccLsh (int shCount)
6271 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6274 pic14_emitcode("add","a,acc");
6277 pic14_emitcode("add","a,acc");
6278 pic14_emitcode("add","a,acc");
6280 /* rotate left accumulator */
6282 /* and kill the lower order bits */
6283 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6288 /*-----------------------------------------------------------------*/
6289 /* AccRsh - right shift accumulator by known count */
6290 /*-----------------------------------------------------------------*/
6291 static void AccRsh (int shCount)
6293 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6297 pic14_emitcode("rrc","a");
6299 /* rotate right accumulator */
6300 AccRol(8 - shCount);
6301 /* and kill the higher order bits */
6302 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6308 /*-----------------------------------------------------------------*/
6309 /* AccSRsh - signed right shift accumulator by known count */
6310 /*-----------------------------------------------------------------*/
6311 static void AccSRsh (int shCount)
6314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6317 pic14_emitcode("mov","c,acc.7");
6318 pic14_emitcode("rrc","a");
6319 } else if(shCount == 2){
6320 pic14_emitcode("mov","c,acc.7");
6321 pic14_emitcode("rrc","a");
6322 pic14_emitcode("mov","c,acc.7");
6323 pic14_emitcode("rrc","a");
6325 tlbl = newiTempLabel(NULL);
6326 /* rotate right accumulator */
6327 AccRol(8 - shCount);
6328 /* and kill the higher order bits */
6329 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6330 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6331 pic14_emitcode("orl","a,#0x%02x",
6332 (unsigned char)~SRMask[shCount]);
6333 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6338 /*-----------------------------------------------------------------*/
6339 /* shiftR1Left2Result - shift right one byte from left to result */
6340 /*-----------------------------------------------------------------*/
6341 static void shiftR1Left2ResultSigned (operand *left, int offl,
6342 operand *result, int offr,
6347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6349 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6353 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6355 emitpcode(POC_RRF, popGet(AOP(result),offr));
6357 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6358 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6364 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6366 emitpcode(POC_RRF, popGet(AOP(result),offr));
6368 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6369 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6371 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6372 emitpcode(POC_RRF, popGet(AOP(result),offr));
6378 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6380 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6381 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6384 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6385 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6386 emitpcode(POC_ANDLW, popGetLit(0x1f));
6388 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6389 emitpcode(POC_IORLW, popGetLit(0xe0));
6391 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6395 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6396 emitpcode(POC_ANDLW, popGetLit(0x0f));
6397 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6398 emitpcode(POC_IORLW, popGetLit(0xf0));
6399 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6403 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6405 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6406 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6408 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6409 emitpcode(POC_ANDLW, popGetLit(0x07));
6410 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6411 emitpcode(POC_IORLW, popGetLit(0xf8));
6412 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6417 emitpcode(POC_MOVLW, popGetLit(0x00));
6418 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6419 emitpcode(POC_MOVLW, popGetLit(0xfe));
6420 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6421 emitpcode(POC_IORLW, popGetLit(0x01));
6422 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6424 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6425 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6426 emitpcode(POC_DECF, popGet(AOP(result),offr));
6427 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6428 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6434 emitpcode(POC_MOVLW, popGetLit(0x00));
6435 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6436 emitpcode(POC_MOVLW, popGetLit(0xff));
6437 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6439 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6440 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6441 emitpcode(POC_DECF, popGet(AOP(result),offr));
6449 /*-----------------------------------------------------------------*/
6450 /* shiftR1Left2Result - shift right one byte from left to result */
6451 /*-----------------------------------------------------------------*/
6452 static void shiftR1Left2Result (operand *left, int offl,
6453 operand *result, int offr,
6454 int shCount, int sign)
6458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6460 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6462 /* Copy the msb into the carry if signed. */
6464 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6474 emitpcode(POC_RRF, popGet(AOP(result),offr));
6476 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6477 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483 emitpcode(POC_RRF, popGet(AOP(result),offr));
6485 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6486 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6489 emitpcode(POC_RRF, popGet(AOP(result),offr));
6494 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6496 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6497 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6500 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6501 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6502 emitpcode(POC_ANDLW, popGetLit(0x1f));
6503 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6507 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6508 emitpcode(POC_ANDLW, popGetLit(0x0f));
6509 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6513 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6514 emitpcode(POC_ANDLW, popGetLit(0x0f));
6515 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6517 emitpcode(POC_RRF, popGet(AOP(result),offr));
6522 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6523 emitpcode(POC_ANDLW, popGetLit(0x80));
6524 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6525 emitpcode(POC_RLF, popGet(AOP(result),offr));
6526 emitpcode(POC_RLF, popGet(AOP(result),offr));
6531 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6532 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6533 emitpcode(POC_RLF, popGet(AOP(result),offr));
6542 /*-----------------------------------------------------------------*/
6543 /* shiftL1Left2Result - shift left one byte from left to result */
6544 /*-----------------------------------------------------------------*/
6545 static void shiftL1Left2Result (operand *left, int offl,
6546 operand *result, int offr, int shCount)
6551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6553 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6554 DEBUGpic14_emitcode ("; ***","same = %d",same);
6555 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6557 /* shift left accumulator */
6558 //AccLsh(shCount); // don't comment out just yet...
6559 // aopPut(AOP(result),"a",offr);
6563 /* Shift left 1 bit position */
6564 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6566 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6568 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6569 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6573 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6574 emitpcode(POC_ANDLW,popGetLit(0x7e));
6575 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6576 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6579 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6580 emitpcode(POC_ANDLW,popGetLit(0x3e));
6581 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6582 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6583 emitpcode(POC_RLF, popGet(AOP(result),offr));
6586 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6587 emitpcode(POC_ANDLW, popGetLit(0xf0));
6588 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6591 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6592 emitpcode(POC_ANDLW, popGetLit(0xf0));
6593 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6594 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6597 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6598 emitpcode(POC_ANDLW, popGetLit(0x30));
6599 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6600 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6601 emitpcode(POC_RLF, popGet(AOP(result),offr));
6604 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6605 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6606 emitpcode(POC_RRF, popGet(AOP(result),offr));
6610 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6615 /*-----------------------------------------------------------------*/
6616 /* movLeft2Result - move byte from left to result */
6617 /*-----------------------------------------------------------------*/
6618 static void movLeft2Result (operand *left, int offl,
6619 operand *result, int offr)
6622 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6623 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6624 l = aopGet(AOP(left),offl,FALSE,FALSE);
6626 if (*l == '@' && (IS_AOP_PREG(result))) {
6627 pic14_emitcode("mov","a,%s",l);
6628 aopPut(AOP(result),"a",offr);
6630 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6631 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6636 /*-----------------------------------------------------------------*/
6637 /* shiftL2Left2Result - shift left two bytes from left to result */
6638 /*-----------------------------------------------------------------*/
6639 static void shiftL2Left2Result (operand *left, int offl,
6640 operand *result, int offr, int shCount)
6644 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6646 if(pic14_sameRegs(AOP(result), AOP(left))) {
6654 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6655 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6656 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6660 emitpcode(POC_RLF, popGet(AOP(result),offr));
6661 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_MOVLW, popGetLit(0x0f));
6668 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6669 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6671 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6672 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6673 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6675 emitpcode(POC_RLF, popGet(AOP(result),offr));
6676 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_RRF, popGet(AOP(result),offr));
6682 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_RRF, popGet(AOP(result),offr));
6684 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6685 emitpcode(POC_ANDLW,popGetLit(0xc0));
6686 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6688 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6689 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6693 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6694 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6695 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6696 emitpcode(POC_RRF, popGet(AOP(result),offr));
6706 /* note, use a mov/add for the shift since the mov has a
6707 chance of getting optimized out */
6708 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6709 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6710 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6711 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6712 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6716 emitpcode(POC_RLF, popGet(AOP(result),offr));
6717 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6723 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6724 emitpcode(POC_ANDLW, popGetLit(0xF0));
6725 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6726 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6727 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6728 emitpcode(POC_ANDLW, popGetLit(0xF0));
6729 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6730 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6734 emitpcode(POC_RLF, popGet(AOP(result),offr));
6735 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6740 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6742 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6744 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6745 emitpcode(POC_RRF, popGet(AOP(result),offr));
6746 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6747 emitpcode(POC_ANDLW,popGetLit(0xc0));
6748 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6749 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6750 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6751 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6754 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6755 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6756 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6757 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6758 emitpcode(POC_RRF, popGet(AOP(result),offr));
6763 /*-----------------------------------------------------------------*/
6764 /* shiftR2Left2Result - shift right two bytes from left to result */
6765 /*-----------------------------------------------------------------*/
6766 static void shiftR2Left2Result (operand *left, int offl,
6767 operand *result, int offr,
6768 int shCount, int sign)
6772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6773 same = pic14_sameRegs(AOP(result), AOP(left));
6775 if(same && ((offl + MSB16) == offr)){
6777 /* don't crash result[offr] */
6778 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6779 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6782 movLeft2Result(left,offl, result, offr);
6783 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6786 /* a:x >> shCount (x = lsb(result))*/
6789 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6791 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6800 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6805 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6806 emitpcode(POC_RRF,popGet(AOP(result),offr));
6808 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6809 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6810 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6811 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6816 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6819 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6820 emitpcode(POC_RRF,popGet(AOP(result),offr));
6827 emitpcode(POC_MOVLW, popGetLit(0xf0));
6828 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6829 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6831 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6832 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6834 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6836 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6837 emitpcode(POC_ANDLW, popGetLit(0x0f));
6838 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6840 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6841 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6842 emitpcode(POC_ANDLW, popGetLit(0xf0));
6843 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6844 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6848 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6849 emitpcode(POC_RRF, popGet(AOP(result),offr));
6853 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6854 emitpcode(POC_BTFSC,
6855 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6856 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6864 emitpcode(POC_RLF, popGet(AOP(result),offr));
6865 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6867 emitpcode(POC_RLF, popGet(AOP(result),offr));
6868 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6869 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6870 emitpcode(POC_ANDLW,popGetLit(0x03));
6872 emitpcode(POC_BTFSC,
6873 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6874 emitpcode(POC_IORLW,popGetLit(0xfc));
6876 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6878 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6879 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6881 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6882 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6883 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6884 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6885 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6886 emitpcode(POC_RLF, popGet(AOP(result),offr));
6887 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6888 emitpcode(POC_ANDLW,popGetLit(0x03));
6890 emitpcode(POC_BTFSC,
6891 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6892 emitpcode(POC_IORLW,popGetLit(0xfc));
6894 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6895 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6902 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6903 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6904 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6905 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6908 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6910 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6915 /*-----------------------------------------------------------------*/
6916 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6917 /*-----------------------------------------------------------------*/
6918 static void shiftLLeftOrResult (operand *left, int offl,
6919 operand *result, int offr, int shCount)
6921 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6922 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6923 /* shift left accumulator */
6925 /* or with result */
6926 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6927 /* back to result */
6928 aopPut(AOP(result),"a",offr);
6931 /*-----------------------------------------------------------------*/
6932 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6933 /*-----------------------------------------------------------------*/
6934 static void shiftRLeftOrResult (operand *left, int offl,
6935 operand *result, int offr, int shCount)
6937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6938 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6939 /* shift right accumulator */
6941 /* or with result */
6942 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6943 /* back to result */
6944 aopPut(AOP(result),"a",offr);
6947 /*-----------------------------------------------------------------*/
6948 /* genlshOne - left shift a one byte quantity by known count */
6949 /*-----------------------------------------------------------------*/
6950 static void genlshOne (operand *result, operand *left, int shCount)
6952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6953 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6956 /*-----------------------------------------------------------------*/
6957 /* genlshTwo - left shift two bytes by known amount != 0 */
6958 /*-----------------------------------------------------------------*/
6959 static void genlshTwo (operand *result,operand *left, int shCount)
6963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6964 size = pic14_getDataSize(result);
6966 /* if shCount >= 8 */
6972 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6974 movLeft2Result(left, LSB, result, MSB16);
6976 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6979 /* 1 <= shCount <= 7 */
6982 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6984 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6988 /*-----------------------------------------------------------------*/
6989 /* shiftLLong - shift left one long from left to result */
6990 /* offl = LSB or MSB16 */
6991 /*-----------------------------------------------------------------*/
6992 static void shiftLLong (operand *left, operand *result, int offr )
6995 int size = AOP_SIZE(result);
6997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6998 if(size >= LSB+offr){
6999 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7001 pic14_emitcode("add","a,acc");
7002 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7003 size >= MSB16+offr && offr != LSB )
7004 pic14_emitcode("xch","a,%s",
7005 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7007 aopPut(AOP(result),"a",LSB+offr);
7010 if(size >= MSB16+offr){
7011 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7012 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7015 pic14_emitcode("rlc","a");
7016 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7017 size >= MSB24+offr && offr != LSB)
7018 pic14_emitcode("xch","a,%s",
7019 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7021 aopPut(AOP(result),"a",MSB16+offr);
7024 if(size >= MSB24+offr){
7025 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7026 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7029 pic14_emitcode("rlc","a");
7030 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7031 size >= MSB32+offr && offr != LSB )
7032 pic14_emitcode("xch","a,%s",
7033 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7035 aopPut(AOP(result),"a",MSB24+offr);
7038 if(size > MSB32+offr){
7039 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7040 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7043 pic14_emitcode("rlc","a");
7044 aopPut(AOP(result),"a",MSB32+offr);
7047 aopPut(AOP(result),zero,LSB);
7050 /*-----------------------------------------------------------------*/
7051 /* genlshFour - shift four byte by a known amount != 0 */
7052 /*-----------------------------------------------------------------*/
7053 static void genlshFour (operand *result, operand *left, int shCount)
7057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7058 size = AOP_SIZE(result);
7060 /* if shifting more that 3 bytes */
7061 if (shCount >= 24 ) {
7064 /* lowest order of left goes to the highest
7065 order of the destination */
7066 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7068 movLeft2Result(left, LSB, result, MSB32);
7069 aopPut(AOP(result),zero,LSB);
7070 aopPut(AOP(result),zero,MSB16);
7071 aopPut(AOP(result),zero,MSB32);
7075 /* more than two bytes */
7076 else if ( shCount >= 16 ) {
7077 /* lower order two bytes goes to higher order two bytes */
7079 /* if some more remaining */
7081 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7083 movLeft2Result(left, MSB16, result, MSB32);
7084 movLeft2Result(left, LSB, result, MSB24);
7086 aopPut(AOP(result),zero,MSB16);
7087 aopPut(AOP(result),zero,LSB);
7091 /* if more than 1 byte */
7092 else if ( shCount >= 8 ) {
7093 /* lower order three bytes goes to higher order three bytes */
7097 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7099 movLeft2Result(left, LSB, result, MSB16);
7101 else{ /* size = 4 */
7103 movLeft2Result(left, MSB24, result, MSB32);
7104 movLeft2Result(left, MSB16, result, MSB24);
7105 movLeft2Result(left, LSB, result, MSB16);
7106 aopPut(AOP(result),zero,LSB);
7108 else if(shCount == 1)
7109 shiftLLong(left, result, MSB16);
7111 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7112 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7113 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7114 aopPut(AOP(result),zero,LSB);
7119 /* 1 <= shCount <= 7 */
7120 else if(shCount <= 2){
7121 shiftLLong(left, result, LSB);
7123 shiftLLong(result, result, LSB);
7125 /* 3 <= shCount <= 7, optimize */
7127 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7128 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7129 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7133 /*-----------------------------------------------------------------*/
7134 /* genLeftShiftLiteral - left shifting by known count */
7135 /*-----------------------------------------------------------------*/
7136 static void genLeftShiftLiteral (operand *left,
7141 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7144 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7145 freeAsmop(right,NULL,ic,TRUE);
7147 aopOp(left,ic,FALSE);
7148 aopOp(result,ic,FALSE);
7150 size = getSize(operandType(result));
7153 pic14_emitcode("; shift left ","result %d, left %d",size,
7157 /* I suppose that the left size >= result size */
7160 movLeft2Result(left, size, result, size);
7164 else if(shCount >= (size * 8))
7166 aopPut(AOP(result),zero,size);
7170 genlshOne (result,left,shCount);
7175 genlshTwo (result,left,shCount);
7179 genlshFour (result,left,shCount);
7183 freeAsmop(left,NULL,ic,TRUE);
7184 freeAsmop(result,NULL,ic,TRUE);
7187 /*-----------------------------------------------------------------*
7188 * genMultiAsm - repeat assembly instruction for size of register.
7189 * if endian == 1, then the high byte (i.e base address + size of
7190 * register) is used first else the low byte is used first;
7191 *-----------------------------------------------------------------*/
7192 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7210 emitpcode(poc, popGet(AOP(reg),offset));
7215 /*-----------------------------------------------------------------*/
7216 /* genLeftShift - generates code for left shifting */
7217 /*-----------------------------------------------------------------*/
7218 static void genLeftShift (iCode *ic)
7220 operand *left,*right, *result;
7223 symbol *tlbl , *tlbl1;
7226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7228 right = IC_RIGHT(ic);
7230 result = IC_RESULT(ic);
7232 aopOp(right,ic,FALSE);
7234 /* if the shift count is known then do it
7235 as efficiently as possible */
7236 if (AOP_TYPE(right) == AOP_LIT) {
7237 genLeftShiftLiteral (left,right,result,ic);
7241 /* shift count is unknown then we have to form
7242 a loop get the loop count in B : Note: we take
7243 only the lower order byte since shifting
7244 more that 32 bits make no sense anyway, ( the
7245 largest size of an object can be only 32 bits ) */
7248 aopOp(left,ic,FALSE);
7249 aopOp(result,ic,FALSE);
7251 /* now move the left to the result if they are not the
7253 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7254 AOP_SIZE(result) > 1) {
7256 size = AOP_SIZE(result);
7259 l = aopGet(AOP(left),offset,FALSE,TRUE);
7260 if (*l == '@' && (IS_AOP_PREG(result))) {
7262 pic14_emitcode("mov","a,%s",l);
7263 aopPut(AOP(result),"a",offset);
7265 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7266 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7267 //aopPut(AOP(result),l,offset);
7273 size = AOP_SIZE(result);
7275 /* if it is only one byte then */
7277 if(optimized_for_speed) {
7278 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7279 emitpcode(POC_ANDLW, popGetLit(0xf0));
7280 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7281 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7282 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7283 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7284 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7285 emitpcode(POC_RLFW, popGet(AOP(result),0));
7286 emitpcode(POC_ANDLW, popGetLit(0xfe));
7287 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7288 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7289 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7292 tlbl = newiTempLabel(NULL);
7293 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7294 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7295 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7298 emitpcode(POC_COMFW, popGet(AOP(right),0));
7299 emitpcode(POC_RRF, popGet(AOP(result),0));
7300 emitpLabel(tlbl->key);
7301 emitpcode(POC_RLF, popGet(AOP(result),0));
7302 emitpcode(POC_ADDLW, popGetLit(1));
7304 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7309 if (pic14_sameRegs(AOP(left),AOP(result))) {
7311 tlbl = newiTempLabel(NULL);
7312 emitpcode(POC_COMFW, popGet(AOP(right),0));
7313 genMultiAsm(POC_RRF, result, size,1);
7314 emitpLabel(tlbl->key);
7315 genMultiAsm(POC_RLF, result, size,0);
7316 emitpcode(POC_ADDLW, popGetLit(1));
7318 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7322 //tlbl = newiTempLabel(NULL);
7324 //tlbl1 = newiTempLabel(NULL);
7326 //reAdjustPreg(AOP(result));
7328 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7329 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7330 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7332 //pic14_emitcode("add","a,acc");
7333 //aopPut(AOP(result),"a",offset++);
7335 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7337 // pic14_emitcode("rlc","a");
7338 // aopPut(AOP(result),"a",offset++);
7340 //reAdjustPreg(AOP(result));
7342 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7343 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7346 tlbl = newiTempLabel(NULL);
7347 tlbl1= newiTempLabel(NULL);
7349 size = AOP_SIZE(result);
7352 pctemp = popGetTempReg(); /* grab a temporary working register. */
7354 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7356 /* offset should be 0, 1 or 3 */
7357 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7359 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7361 emitpcode(POC_MOVWF, pctemp);
7364 emitpLabel(tlbl->key);
7367 emitpcode(POC_RLF, popGet(AOP(result),0));
7369 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7371 emitpcode(POC_DECFSZ, pctemp);
7372 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7373 emitpLabel(tlbl1->key);
7375 popReleaseTempReg(pctemp);
7379 freeAsmop (right,NULL,ic,TRUE);
7380 freeAsmop(left,NULL,ic,TRUE);
7381 freeAsmop(result,NULL,ic,TRUE);
7384 /*-----------------------------------------------------------------*/
7385 /* genrshOne - right shift a one byte quantity by known count */
7386 /*-----------------------------------------------------------------*/
7387 static void genrshOne (operand *result, operand *left,
7388 int shCount, int sign)
7390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7391 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7394 /*-----------------------------------------------------------------*/
7395 /* genrshTwo - right shift two bytes by known amount != 0 */
7396 /*-----------------------------------------------------------------*/
7397 static void genrshTwo (operand *result,operand *left,
7398 int shCount, int sign)
7400 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7401 /* if shCount >= 8 */
7405 shiftR1Left2Result(left, MSB16, result, LSB,
7408 movLeft2Result(left, MSB16, result, LSB);
7410 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7413 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7414 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7418 /* 1 <= shCount <= 7 */
7420 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7423 /*-----------------------------------------------------------------*/
7424 /* shiftRLong - shift right one long from left to result */
7425 /* offl = LSB or MSB16 */
7426 /*-----------------------------------------------------------------*/
7427 static void shiftRLong (operand *left, int offl,
7428 operand *result, int sign)
7430 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7432 pic14_emitcode("clr","c");
7433 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7435 pic14_emitcode("mov","c,acc.7");
7436 pic14_emitcode("rrc","a");
7437 aopPut(AOP(result),"a",MSB32-offl);
7439 /* add sign of "a" */
7440 addSign(result, MSB32, sign);
7442 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7443 pic14_emitcode("rrc","a");
7444 aopPut(AOP(result),"a",MSB24-offl);
7446 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7447 pic14_emitcode("rrc","a");
7448 aopPut(AOP(result),"a",MSB16-offl);
7451 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7452 pic14_emitcode("rrc","a");
7453 aopPut(AOP(result),"a",LSB);
7457 /*-----------------------------------------------------------------*/
7458 /* genrshFour - shift four byte by a known amount != 0 */
7459 /*-----------------------------------------------------------------*/
7460 static void genrshFour (operand *result, operand *left,
7461 int shCount, int sign)
7463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7464 /* if shifting more that 3 bytes */
7465 if(shCount >= 24 ) {
7468 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7470 movLeft2Result(left, MSB32, result, LSB);
7472 addSign(result, MSB16, sign);
7474 else if(shCount >= 16){
7477 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7479 movLeft2Result(left, MSB24, result, LSB);
7480 movLeft2Result(left, MSB32, result, MSB16);
7482 addSign(result, MSB24, sign);
7484 else if(shCount >= 8){
7487 shiftRLong(left, MSB16, result, sign);
7488 else if(shCount == 0){
7489 movLeft2Result(left, MSB16, result, LSB);
7490 movLeft2Result(left, MSB24, result, MSB16);
7491 movLeft2Result(left, MSB32, result, MSB24);
7492 addSign(result, MSB32, sign);
7495 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7496 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7497 /* the last shift is signed */
7498 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7499 addSign(result, MSB32, sign);
7502 else{ /* 1 <= shCount <= 7 */
7504 shiftRLong(left, LSB, result, sign);
7506 shiftRLong(result, LSB, result, sign);
7509 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7510 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7511 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7516 /*-----------------------------------------------------------------*/
7517 /* genRightShiftLiteral - right shifting by known count */
7518 /*-----------------------------------------------------------------*/
7519 static void genRightShiftLiteral (operand *left,
7525 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7529 freeAsmop(right,NULL,ic,TRUE);
7531 aopOp(left,ic,FALSE);
7532 aopOp(result,ic,FALSE);
7535 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7539 lsize = pic14_getDataSize(left);
7540 res_size = pic14_getDataSize(result);
7541 /* test the LEFT size !!! */
7543 /* I suppose that the left size >= result size */
7546 movLeft2Result(left, lsize, result, res_size);
7549 else if(shCount >= (lsize * 8)){
7552 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7554 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7555 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7560 emitpcode(POC_MOVLW, popGetLit(0));
7561 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7562 emitpcode(POC_MOVLW, popGetLit(0xff));
7564 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7569 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7576 genrshOne (result,left,shCount,sign);
7580 genrshTwo (result,left,shCount,sign);
7584 genrshFour (result,left,shCount,sign);
7592 freeAsmop(left,NULL,ic,TRUE);
7593 freeAsmop(result,NULL,ic,TRUE);
7596 /*-----------------------------------------------------------------*/
7597 /* genSignedRightShift - right shift of signed number */
7598 /*-----------------------------------------------------------------*/
7599 static void genSignedRightShift (iCode *ic)
7601 operand *right, *left, *result;
7604 symbol *tlbl, *tlbl1 ;
7607 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7609 /* we do it the hard way put the shift count in b
7610 and loop thru preserving the sign */
7611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7613 right = IC_RIGHT(ic);
7615 result = IC_RESULT(ic);
7617 aopOp(right,ic,FALSE);
7618 aopOp(left,ic,FALSE);
7619 aopOp(result,ic,FALSE);
7622 if ( AOP_TYPE(right) == AOP_LIT) {
7623 genRightShiftLiteral (left,right,result,ic,1);
7626 /* shift count is unknown then we have to form
7627 a loop get the loop count in B : Note: we take
7628 only the lower order byte since shifting
7629 more that 32 bits make no sense anyway, ( the
7630 largest size of an object can be only 32 bits ) */
7632 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7633 //pic14_emitcode("inc","b");
7634 //freeAsmop (right,NULL,ic,TRUE);
7635 //aopOp(left,ic,FALSE);
7636 //aopOp(result,ic,FALSE);
7638 /* now move the left to the result if they are not the
7640 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7641 AOP_SIZE(result) > 1) {
7643 size = AOP_SIZE(result);
7647 l = aopGet(AOP(left),offset,FALSE,TRUE);
7648 if (*l == '@' && IS_AOP_PREG(result)) {
7650 pic14_emitcode("mov","a,%s",l);
7651 aopPut(AOP(result),"a",offset);
7653 aopPut(AOP(result),l,offset);
7655 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7656 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7662 /* mov the highest order bit to OVR */
7663 tlbl = newiTempLabel(NULL);
7664 tlbl1= newiTempLabel(NULL);
7666 size = AOP_SIZE(result);
7669 pctemp = popGetTempReg(); /* grab a temporary working register. */
7671 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7673 /* offset should be 0, 1 or 3 */
7674 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7676 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7678 emitpcode(POC_MOVWF, pctemp);
7681 emitpLabel(tlbl->key);
7683 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7684 emitpcode(POC_RRF, popGet(AOP(result),offset));
7687 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7690 emitpcode(POC_DECFSZ, pctemp);
7691 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7692 emitpLabel(tlbl1->key);
7694 popReleaseTempReg(pctemp);
7696 size = AOP_SIZE(result);
7698 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7699 pic14_emitcode("rlc","a");
7700 pic14_emitcode("mov","ov,c");
7701 /* if it is only one byte then */
7703 l = aopGet(AOP(left),0,FALSE,FALSE);
7705 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7706 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7707 pic14_emitcode("mov","c,ov");
7708 pic14_emitcode("rrc","a");
7709 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7710 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7711 aopPut(AOP(result),"a",0);
7715 reAdjustPreg(AOP(result));
7716 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7717 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7718 pic14_emitcode("mov","c,ov");
7720 l = aopGet(AOP(result),offset,FALSE,FALSE);
7722 pic14_emitcode("rrc","a");
7723 aopPut(AOP(result),"a",offset--);
7725 reAdjustPreg(AOP(result));
7726 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7727 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7732 freeAsmop(left,NULL,ic,TRUE);
7733 freeAsmop(result,NULL,ic,TRUE);
7734 freeAsmop(right,NULL,ic,TRUE);
7737 /*-----------------------------------------------------------------*/
7738 /* genRightShift - generate code for right shifting */
7739 /*-----------------------------------------------------------------*/
7740 static void genRightShift (iCode *ic)
7742 operand *right, *left, *result;
7746 symbol *tlbl, *tlbl1 ;
7748 /* if signed then we do it the hard way preserve the
7749 sign bit moving it inwards */
7750 retype = getSpec(operandType(IC_RESULT(ic)));
7751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7753 if (!SPEC_USIGN(retype)) {
7754 genSignedRightShift (ic);
7758 /* signed & unsigned types are treated the same : i.e. the
7759 signed is NOT propagated inwards : quoting from the
7760 ANSI - standard : "for E1 >> E2, is equivalent to division
7761 by 2**E2 if unsigned or if it has a non-negative value,
7762 otherwise the result is implementation defined ", MY definition
7763 is that the sign does not get propagated */
7765 right = IC_RIGHT(ic);
7767 result = IC_RESULT(ic);
7769 aopOp(right,ic,FALSE);
7771 /* if the shift count is known then do it
7772 as efficiently as possible */
7773 if (AOP_TYPE(right) == AOP_LIT) {
7774 genRightShiftLiteral (left,right,result,ic, 0);
7778 /* shift count is unknown then we have to form
7779 a loop get the loop count in B : Note: we take
7780 only the lower order byte since shifting
7781 more that 32 bits make no sense anyway, ( the
7782 largest size of an object can be only 32 bits ) */
7784 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7785 pic14_emitcode("inc","b");
7786 aopOp(left,ic,FALSE);
7787 aopOp(result,ic,FALSE);
7789 /* now move the left to the result if they are not the
7791 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7792 AOP_SIZE(result) > 1) {
7794 size = AOP_SIZE(result);
7797 l = aopGet(AOP(left),offset,FALSE,TRUE);
7798 if (*l == '@' && IS_AOP_PREG(result)) {
7800 pic14_emitcode("mov","a,%s",l);
7801 aopPut(AOP(result),"a",offset);
7803 aopPut(AOP(result),l,offset);
7808 tlbl = newiTempLabel(NULL);
7809 tlbl1= newiTempLabel(NULL);
7810 size = AOP_SIZE(result);
7813 /* if it is only one byte then */
7816 tlbl = newiTempLabel(NULL);
7817 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7818 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7819 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7822 emitpcode(POC_COMFW, popGet(AOP(right),0));
7823 emitpcode(POC_RLF, popGet(AOP(result),0));
7824 emitpLabel(tlbl->key);
7825 emitpcode(POC_RRF, popGet(AOP(result),0));
7826 emitpcode(POC_ADDLW, popGetLit(1));
7828 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7833 reAdjustPreg(AOP(result));
7834 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7835 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7838 l = aopGet(AOP(result),offset,FALSE,FALSE);
7840 pic14_emitcode("rrc","a");
7841 aopPut(AOP(result),"a",offset--);
7843 reAdjustPreg(AOP(result));
7845 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7846 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7849 freeAsmop(left,NULL,ic,TRUE);
7850 freeAsmop (right,NULL,ic,TRUE);
7851 freeAsmop(result,NULL,ic,TRUE);
7854 /*-----------------------------------------------------------------*/
7855 /* genUnpackBits - generates code for unpacking bits */
7856 /*-----------------------------------------------------------------*/
7857 static void genUnpackBits (operand *result, char *rname, int ptype)
7864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7865 etype = getSpec(operandType(result));
7867 /* read the first byte */
7872 pic14_emitcode("mov","a,@%s",rname);
7876 pic14_emitcode("movx","a,@%s",rname);
7880 pic14_emitcode("movx","a,@dptr");
7884 pic14_emitcode("clr","a");
7885 pic14_emitcode("movc","a","@a+dptr");
7889 pic14_emitcode("lcall","__gptrget");
7893 /* if we have bitdisplacement then it fits */
7894 /* into this byte completely or if length is */
7895 /* less than a byte */
7896 if ((shCnt = SPEC_BSTR(etype)) ||
7897 (SPEC_BLEN(etype) <= 8)) {
7899 /* shift right acc */
7902 pic14_emitcode("anl","a,#0x%02x",
7903 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7904 aopPut(AOP(result),"a",offset);
7908 /* bit field did not fit in a byte */
7909 rlen = SPEC_BLEN(etype) - 8;
7910 aopPut(AOP(result),"a",offset++);
7917 pic14_emitcode("inc","%s",rname);
7918 pic14_emitcode("mov","a,@%s",rname);
7922 pic14_emitcode("inc","%s",rname);
7923 pic14_emitcode("movx","a,@%s",rname);
7927 pic14_emitcode("inc","dptr");
7928 pic14_emitcode("movx","a,@dptr");
7932 pic14_emitcode("clr","a");
7933 pic14_emitcode("inc","dptr");
7934 pic14_emitcode("movc","a","@a+dptr");
7938 pic14_emitcode("inc","dptr");
7939 pic14_emitcode("lcall","__gptrget");
7944 /* if we are done */
7948 aopPut(AOP(result),"a",offset++);
7953 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7954 aopPut(AOP(result),"a",offset);
7961 /*-----------------------------------------------------------------*/
7962 /* genDataPointerGet - generates code when ptr offset is known */
7963 /*-----------------------------------------------------------------*/
7964 static void genDataPointerGet (operand *left,
7968 int size , offset = 0;
7971 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7974 /* optimization - most of the time, left and result are the same
7975 * address, but different types. for the pic code, we could omit
7979 aopOp(result,ic,TRUE);
7981 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7983 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7985 size = AOP_SIZE(result);
7988 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7992 freeAsmop(left,NULL,ic,TRUE);
7993 freeAsmop(result,NULL,ic,TRUE);
7996 /*-----------------------------------------------------------------*/
7997 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7998 /*-----------------------------------------------------------------*/
7999 static void genNearPointerGet (operand *left,
8004 //regs *preg = NULL ;
8006 sym_link *rtype, *retype;
8007 sym_link *ltype = operandType(left);
8010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8012 rtype = operandType(result);
8013 retype= getSpec(rtype);
8015 aopOp(left,ic,FALSE);
8017 /* if left is rematerialisable and
8018 result is not bit variable type and
8019 the left is pointer to data space i.e
8020 lower 128 bytes of space */
8021 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8022 !IS_BITVAR(retype) &&
8023 DCL_TYPE(ltype) == POINTER) {
8024 //genDataPointerGet (left,result,ic);
8028 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8030 /* if the value is already in a pointer register
8031 then don't need anything more */
8032 if (!AOP_INPREG(AOP(left))) {
8033 /* otherwise get a free pointer register */
8034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8037 preg = getFreePtr(ic,&aop,FALSE);
8038 pic14_emitcode("mov","%s,%s",
8040 aopGet(AOP(left),0,FALSE,TRUE));
8041 rname = preg->name ;
8045 rname = aopGet(AOP(left),0,FALSE,FALSE);
8047 aopOp (result,ic,FALSE);
8049 /* if bitfield then unpack the bits */
8050 if (IS_BITVAR(retype))
8051 genUnpackBits (result,rname,POINTER);
8053 /* we have can just get the values */
8054 int size = AOP_SIZE(result);
8057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8059 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8060 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8062 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8063 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8065 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8069 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8071 pic14_emitcode("mov","a,@%s",rname);
8072 aopPut(AOP(result),"a",offset);
8074 sprintf(buffer,"@%s",rname);
8075 aopPut(AOP(result),buffer,offset);
8079 pic14_emitcode("inc","%s",rname);
8084 /* now some housekeeping stuff */
8086 /* we had to allocate for this iCode */
8087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8088 freeAsmop(NULL,aop,ic,TRUE);
8090 /* we did not allocate which means left
8091 already in a pointer register, then
8092 if size > 0 && this could be used again
8093 we have to point it back to where it
8095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8096 if (AOP_SIZE(result) > 1 &&
8097 !OP_SYMBOL(left)->remat &&
8098 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8100 int size = AOP_SIZE(result) - 1;
8102 pic14_emitcode("dec","%s",rname);
8107 freeAsmop(left,NULL,ic,TRUE);
8108 freeAsmop(result,NULL,ic,TRUE);
8112 /*-----------------------------------------------------------------*/
8113 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8114 /*-----------------------------------------------------------------*/
8115 static void genPagedPointerGet (operand *left,
8122 sym_link *rtype, *retype;
8124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8126 rtype = operandType(result);
8127 retype= getSpec(rtype);
8129 aopOp(left,ic,FALSE);
8131 /* if the value is already in a pointer register
8132 then don't need anything more */
8133 if (!AOP_INPREG(AOP(left))) {
8134 /* otherwise get a free pointer register */
8136 preg = getFreePtr(ic,&aop,FALSE);
8137 pic14_emitcode("mov","%s,%s",
8139 aopGet(AOP(left),0,FALSE,TRUE));
8140 rname = preg->name ;
8142 rname = aopGet(AOP(left),0,FALSE,FALSE);
8144 freeAsmop(left,NULL,ic,TRUE);
8145 aopOp (result,ic,FALSE);
8147 /* if bitfield then unpack the bits */
8148 if (IS_BITVAR(retype))
8149 genUnpackBits (result,rname,PPOINTER);
8151 /* we have can just get the values */
8152 int size = AOP_SIZE(result);
8157 pic14_emitcode("movx","a,@%s",rname);
8158 aopPut(AOP(result),"a",offset);
8163 pic14_emitcode("inc","%s",rname);
8167 /* now some housekeeping stuff */
8169 /* we had to allocate for this iCode */
8170 freeAsmop(NULL,aop,ic,TRUE);
8172 /* we did not allocate which means left
8173 already in a pointer register, then
8174 if size > 0 && this could be used again
8175 we have to point it back to where it
8177 if (AOP_SIZE(result) > 1 &&
8178 !OP_SYMBOL(left)->remat &&
8179 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8181 int size = AOP_SIZE(result) - 1;
8183 pic14_emitcode("dec","%s",rname);
8188 freeAsmop(result,NULL,ic,TRUE);
8193 /*-----------------------------------------------------------------*/
8194 /* genFarPointerGet - gget value from far space */
8195 /*-----------------------------------------------------------------*/
8196 static void genFarPointerGet (operand *left,
8197 operand *result, iCode *ic)
8200 sym_link *retype = getSpec(operandType(result));
8202 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8204 aopOp(left,ic,FALSE);
8206 /* if the operand is already in dptr
8207 then we do nothing else we move the value to dptr */
8208 if (AOP_TYPE(left) != AOP_STR) {
8209 /* if this is remateriazable */
8210 if (AOP_TYPE(left) == AOP_IMMD)
8211 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8212 else { /* we need to get it byte by byte */
8213 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8214 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8215 if (options.model == MODEL_FLAT24)
8217 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8221 /* so dptr know contains the address */
8222 freeAsmop(left,NULL,ic,TRUE);
8223 aopOp(result,ic,FALSE);
8225 /* if bit then unpack */
8226 if (IS_BITVAR(retype))
8227 genUnpackBits(result,"dptr",FPOINTER);
8229 size = AOP_SIZE(result);
8233 pic14_emitcode("movx","a,@dptr");
8234 aopPut(AOP(result),"a",offset++);
8236 pic14_emitcode("inc","dptr");
8240 freeAsmop(result,NULL,ic,TRUE);
8243 /*-----------------------------------------------------------------*/
8244 /* genCodePointerGet - get value from code space */
8245 /*-----------------------------------------------------------------*/
8246 static void genCodePointerGet (operand *left,
8247 operand *result, iCode *ic)
8250 sym_link *retype = getSpec(operandType(result));
8252 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8254 aopOp(left,ic,FALSE);
8256 /* if the operand is already in dptr
8257 then we do nothing else we move the value to dptr */
8258 if (AOP_TYPE(left) != AOP_STR) {
8259 /* if this is remateriazable */
8260 if (AOP_TYPE(left) == AOP_IMMD)
8261 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8262 else { /* we need to get it byte by byte */
8263 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8264 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8265 if (options.model == MODEL_FLAT24)
8267 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8271 /* so dptr know contains the address */
8272 freeAsmop(left,NULL,ic,TRUE);
8273 aopOp(result,ic,FALSE);
8275 /* if bit then unpack */
8276 if (IS_BITVAR(retype))
8277 genUnpackBits(result,"dptr",CPOINTER);
8279 size = AOP_SIZE(result);
8283 pic14_emitcode("clr","a");
8284 pic14_emitcode("movc","a,@a+dptr");
8285 aopPut(AOP(result),"a",offset++);
8287 pic14_emitcode("inc","dptr");
8291 freeAsmop(result,NULL,ic,TRUE);
8294 /*-----------------------------------------------------------------*/
8295 /* genGenPointerGet - gget value from generic pointer space */
8296 /*-----------------------------------------------------------------*/
8297 static void genGenPointerGet (operand *left,
8298 operand *result, iCode *ic)
8301 sym_link *retype = getSpec(operandType(result));
8303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8304 aopOp(left,ic,FALSE);
8305 aopOp(result,ic,FALSE);
8308 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8310 /* if the operand is already in dptr
8311 then we do nothing else we move the value to dptr */
8312 // if (AOP_TYPE(left) != AOP_STR) {
8313 /* if this is remateriazable */
8314 if (AOP_TYPE(left) == AOP_IMMD) {
8315 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8316 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8318 else { /* we need to get it byte by byte */
8320 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8321 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8323 size = AOP_SIZE(result);
8327 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8328 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8330 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8335 /* so dptr know contains the address */
8337 /* if bit then unpack */
8338 //if (IS_BITVAR(retype))
8339 // genUnpackBits(result,"dptr",GPOINTER);
8342 freeAsmop(left,NULL,ic,TRUE);
8343 freeAsmop(result,NULL,ic,TRUE);
8347 /*-----------------------------------------------------------------*/
8348 /* genConstPointerGet - get value from const generic pointer space */
8349 /*-----------------------------------------------------------------*/
8350 static void genConstPointerGet (operand *left,
8351 operand *result, iCode *ic)
8353 //sym_link *retype = getSpec(operandType(result));
8354 symbol *albl = newiTempLabel(NULL);
8355 symbol *blbl = newiTempLabel(NULL);
8358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8359 aopOp(left,ic,FALSE);
8360 aopOp(result,ic,FALSE);
8363 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8365 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8367 emitpcode(POC_CALL,popGetLabel(albl->key));
8368 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8369 emitpLabel(albl->key);
8371 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8373 emitpcode(poc,popGet(AOP(left),1));
8374 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8375 emitpcode(poc,popGet(AOP(left),0));
8376 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8378 emitpLabel(blbl->key);
8380 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8383 freeAsmop(left,NULL,ic,TRUE);
8384 freeAsmop(result,NULL,ic,TRUE);
8387 /*-----------------------------------------------------------------*/
8388 /* genPointerGet - generate code for pointer get */
8389 /*-----------------------------------------------------------------*/
8390 static void genPointerGet (iCode *ic)
8392 operand *left, *result ;
8393 sym_link *type, *etype;
8396 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8399 result = IC_RESULT(ic) ;
8401 /* depending on the type of pointer we need to
8402 move it to the correct pointer register */
8403 type = operandType(left);
8404 etype = getSpec(type);
8406 if (IS_PTR_CONST(type))
8407 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8409 /* if left is of type of pointer then it is simple */
8410 if (IS_PTR(type) && !IS_FUNC(type->next))
8411 p_type = DCL_TYPE(type);
8413 /* we have to go by the storage class */
8414 p_type = PTR_TYPE(SPEC_OCLS(etype));
8416 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8418 if (SPEC_OCLS(etype)->codesp ) {
8419 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8420 //p_type = CPOINTER ;
8423 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8424 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8425 /*p_type = FPOINTER ;*/
8427 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8428 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8429 /* p_type = PPOINTER; */
8431 if (SPEC_OCLS(etype) == idata )
8432 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8433 /* p_type = IPOINTER; */
8435 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8436 /* p_type = POINTER ; */
8439 /* now that we have the pointer type we assign
8440 the pointer values */
8445 genNearPointerGet (left,result,ic);
8449 genPagedPointerGet(left,result,ic);
8453 genFarPointerGet (left,result,ic);
8457 genConstPointerGet (left,result,ic);
8458 //pic14_emitcodePointerGet (left,result,ic);
8462 if (IS_PTR_CONST(type))
8463 genConstPointerGet (left,result,ic);
8465 genGenPointerGet (left,result,ic);
8471 /*-----------------------------------------------------------------*/
8472 /* genPackBits - generates code for packed bit storage */
8473 /*-----------------------------------------------------------------*/
8474 static void genPackBits (sym_link *etype ,
8476 char *rname, int p_type)
8484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8485 blen = SPEC_BLEN(etype);
8486 bstr = SPEC_BSTR(etype);
8488 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8491 /* if the bit lenth is less than or */
8492 /* it exactly fits a byte then */
8493 if (SPEC_BLEN(etype) <= 8 ) {
8494 shCount = SPEC_BSTR(etype) ;
8496 /* shift left acc */
8499 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8504 pic14_emitcode ("mov","b,a");
8505 pic14_emitcode("mov","a,@%s",rname);
8509 pic14_emitcode ("mov","b,a");
8510 pic14_emitcode("movx","a,@dptr");
8514 pic14_emitcode ("push","b");
8515 pic14_emitcode ("push","acc");
8516 pic14_emitcode ("lcall","__gptrget");
8517 pic14_emitcode ("pop","b");
8521 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8522 ((unsigned char)(0xFF << (blen+bstr)) |
8523 (unsigned char)(0xFF >> (8-bstr)) ) );
8524 pic14_emitcode ("orl","a,b");
8525 if (p_type == GPOINTER)
8526 pic14_emitcode("pop","b");
8532 pic14_emitcode("mov","@%s,a",rname);
8536 pic14_emitcode("movx","@dptr,a");
8540 DEBUGpic14_emitcode(";lcall","__gptrput");
8545 if ( SPEC_BLEN(etype) <= 8 )
8548 pic14_emitcode("inc","%s",rname);
8549 rLen = SPEC_BLEN(etype) ;
8551 /* now generate for lengths greater than one byte */
8554 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8564 pic14_emitcode("mov","@%s,a",rname);
8566 pic14_emitcode("mov","@%s,%s",rname,l);
8571 pic14_emitcode("movx","@dptr,a");
8576 DEBUGpic14_emitcode(";lcall","__gptrput");
8579 pic14_emitcode ("inc","%s",rname);
8584 /* last last was not complete */
8586 /* save the byte & read byte */
8589 pic14_emitcode ("mov","b,a");
8590 pic14_emitcode("mov","a,@%s",rname);
8594 pic14_emitcode ("mov","b,a");
8595 pic14_emitcode("movx","a,@dptr");
8599 pic14_emitcode ("push","b");
8600 pic14_emitcode ("push","acc");
8601 pic14_emitcode ("lcall","__gptrget");
8602 pic14_emitcode ("pop","b");
8606 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8607 pic14_emitcode ("orl","a,b");
8610 if (p_type == GPOINTER)
8611 pic14_emitcode("pop","b");
8616 pic14_emitcode("mov","@%s,a",rname);
8620 pic14_emitcode("movx","@dptr,a");
8624 DEBUGpic14_emitcode(";lcall","__gptrput");
8628 /*-----------------------------------------------------------------*/
8629 /* genDataPointerSet - remat pointer to data space */
8630 /*-----------------------------------------------------------------*/
8631 static void genDataPointerSet(operand *right,
8635 int size, offset = 0 ;
8636 char *l, buffer[256];
8638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8639 aopOp(right,ic,FALSE);
8641 l = aopGet(AOP(result),0,FALSE,TRUE);
8642 size = AOP_SIZE(right);
8644 if ( AOP_TYPE(result) == AOP_PCODE) {
8645 fprintf(stderr,"genDataPointerSet %s, %d\n",
8646 AOP(result)->aopu.pcop->name,
8647 PCOI(AOP(result)->aopu.pcop)->offset);
8651 // tsd, was l+1 - the underline `_' prefix was being stripped
8654 sprintf(buffer,"(%s + %d)",l,offset);
8655 fprintf(stderr,"oops %s\n",buffer);
8657 sprintf(buffer,"%s",l);
8659 if (AOP_TYPE(right) == AOP_LIT) {
8660 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8661 lit = lit >> (8*offset);
8663 pic14_emitcode("movlw","%d",lit);
8664 pic14_emitcode("movwf","%s",buffer);
8666 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8667 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8668 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8671 pic14_emitcode("clrf","%s",buffer);
8672 //emitpcode(POC_CLRF, popRegFromString(buffer));
8673 emitpcode(POC_CLRF, popGet(AOP(result),0));
8676 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8677 pic14_emitcode("movwf","%s",buffer);
8679 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8680 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8681 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8688 freeAsmop(right,NULL,ic,TRUE);
8689 freeAsmop(result,NULL,ic,TRUE);
8692 /*-----------------------------------------------------------------*/
8693 /* genNearPointerSet - pic14_emitcode for near pointer put */
8694 /*-----------------------------------------------------------------*/
8695 static void genNearPointerSet (operand *right,
8702 sym_link *ptype = operandType(result);
8705 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8706 retype= getSpec(operandType(right));
8708 aopOp(result,ic,FALSE);
8711 /* if the result is rematerializable &
8712 in data space & not a bit variable */
8713 //if (AOP_TYPE(result) == AOP_IMMD &&
8714 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8715 DCL_TYPE(ptype) == POINTER &&
8716 !IS_BITVAR(retype)) {
8717 genDataPointerSet (right,result,ic);
8718 freeAsmop(result,NULL,ic,TRUE);
8722 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8723 aopOp(right,ic,FALSE);
8724 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8726 /* if the value is already in a pointer register
8727 then don't need anything more */
8728 if (!AOP_INPREG(AOP(result))) {
8729 /* otherwise get a free pointer register */
8730 //aop = newAsmop(0);
8731 //preg = getFreePtr(ic,&aop,FALSE);
8732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8733 //pic14_emitcode("mov","%s,%s",
8735 // aopGet(AOP(result),0,FALSE,TRUE));
8736 //rname = preg->name ;
8737 //pic14_emitcode("movwf","fsr");
8738 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8739 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8740 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8741 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8745 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8748 /* if bitfield then unpack the bits */
8749 if (IS_BITVAR(retype)) {
8750 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8751 "The programmer is obviously confused");
8752 //genPackBits (retype,right,rname,POINTER);
8756 /* we have can just get the values */
8757 int size = AOP_SIZE(right);
8760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8762 l = aopGet(AOP(right),offset,FALSE,TRUE);
8765 //pic14_emitcode("mov","@%s,a",rname);
8766 pic14_emitcode("movf","indf,w ;1");
8769 if (AOP_TYPE(right) == AOP_LIT) {
8770 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8772 pic14_emitcode("movlw","%s",l);
8773 pic14_emitcode("movwf","indf ;2");
8775 pic14_emitcode("clrf","indf");
8777 pic14_emitcode("movf","%s,w",l);
8778 pic14_emitcode("movwf","indf ;2");
8780 //pic14_emitcode("mov","@%s,%s",rname,l);
8783 pic14_emitcode("incf","fsr,f ;3");
8784 //pic14_emitcode("inc","%s",rname);
8789 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8790 /* now some housekeeping stuff */
8792 /* we had to allocate for this iCode */
8793 freeAsmop(NULL,aop,ic,TRUE);
8795 /* we did not allocate which means left
8796 already in a pointer register, then
8797 if size > 0 && this could be used again
8798 we have to point it back to where it
8800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8801 if (AOP_SIZE(right) > 1 &&
8802 !OP_SYMBOL(result)->remat &&
8803 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8805 int size = AOP_SIZE(right) - 1;
8807 pic14_emitcode("decf","fsr,f");
8808 //pic14_emitcode("dec","%s",rname);
8812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8815 freeAsmop(right,NULL,ic,TRUE);
8816 freeAsmop(result,NULL,ic,TRUE);
8819 /*-----------------------------------------------------------------*/
8820 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8821 /*-----------------------------------------------------------------*/
8822 static void genPagedPointerSet (operand *right,
8831 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8833 retype= getSpec(operandType(right));
8835 aopOp(result,ic,FALSE);
8837 /* if the value is already in a pointer register
8838 then don't need anything more */
8839 if (!AOP_INPREG(AOP(result))) {
8840 /* otherwise get a free pointer register */
8842 preg = getFreePtr(ic,&aop,FALSE);
8843 pic14_emitcode("mov","%s,%s",
8845 aopGet(AOP(result),0,FALSE,TRUE));
8846 rname = preg->name ;
8848 rname = aopGet(AOP(result),0,FALSE,FALSE);
8850 freeAsmop(result,NULL,ic,TRUE);
8851 aopOp (right,ic,FALSE);
8853 /* if bitfield then unpack the bits */
8854 if (IS_BITVAR(retype))
8855 genPackBits (retype,right,rname,PPOINTER);
8857 /* we have can just get the values */
8858 int size = AOP_SIZE(right);
8862 l = aopGet(AOP(right),offset,FALSE,TRUE);
8865 pic14_emitcode("movx","@%s,a",rname);
8868 pic14_emitcode("inc","%s",rname);
8874 /* now some housekeeping stuff */
8876 /* we had to allocate for this iCode */
8877 freeAsmop(NULL,aop,ic,TRUE);
8879 /* we did not allocate which means left
8880 already in a pointer register, then
8881 if size > 0 && this could be used again
8882 we have to point it back to where it
8884 if (AOP_SIZE(right) > 1 &&
8885 !OP_SYMBOL(result)->remat &&
8886 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8888 int size = AOP_SIZE(right) - 1;
8890 pic14_emitcode("dec","%s",rname);
8895 freeAsmop(right,NULL,ic,TRUE);
8900 /*-----------------------------------------------------------------*/
8901 /* genFarPointerSet - set value from far space */
8902 /*-----------------------------------------------------------------*/
8903 static void genFarPointerSet (operand *right,
8904 operand *result, iCode *ic)
8907 sym_link *retype = getSpec(operandType(right));
8909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8910 aopOp(result,ic,FALSE);
8912 /* if the operand is already in dptr
8913 then we do nothing else we move the value to dptr */
8914 if (AOP_TYPE(result) != AOP_STR) {
8915 /* if this is remateriazable */
8916 if (AOP_TYPE(result) == AOP_IMMD)
8917 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8918 else { /* we need to get it byte by byte */
8919 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8920 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8921 if (options.model == MODEL_FLAT24)
8923 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8927 /* so dptr know contains the address */
8928 freeAsmop(result,NULL,ic,TRUE);
8929 aopOp(right,ic,FALSE);
8931 /* if bit then unpack */
8932 if (IS_BITVAR(retype))
8933 genPackBits(retype,right,"dptr",FPOINTER);
8935 size = AOP_SIZE(right);
8939 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8941 pic14_emitcode("movx","@dptr,a");
8943 pic14_emitcode("inc","dptr");
8947 freeAsmop(right,NULL,ic,TRUE);
8950 /*-----------------------------------------------------------------*/
8951 /* genGenPointerSet - set value from generic pointer space */
8952 /*-----------------------------------------------------------------*/
8953 static void genGenPointerSet (operand *right,
8954 operand *result, iCode *ic)
8957 sym_link *retype = getSpec(operandType(right));
8959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8961 aopOp(result,ic,FALSE);
8962 aopOp(right,ic,FALSE);
8963 size = AOP_SIZE(right);
8965 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8967 /* if the operand is already in dptr
8968 then we do nothing else we move the value to dptr */
8969 if (AOP_TYPE(result) != AOP_STR) {
8970 /* if this is remateriazable */
8971 if (AOP_TYPE(result) == AOP_IMMD) {
8972 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8973 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8975 else { /* we need to get it byte by byte */
8976 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8977 size = AOP_SIZE(right);
8980 /* hack hack! see if this the FSR. If so don't load W */
8981 if(AOP_TYPE(right) != AOP_ACC) {
8984 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8985 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8987 if(AOP_SIZE(result) > 1) {
8988 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8989 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8990 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8995 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8997 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8998 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9002 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9003 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9006 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9013 if(aopIdx(AOP(result),0) != 4) {
9015 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9019 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9024 /* so dptr know contains the address */
9027 /* if bit then unpack */
9028 if (IS_BITVAR(retype))
9029 genPackBits(retype,right,"dptr",GPOINTER);
9031 size = AOP_SIZE(right);
9034 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9038 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9039 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9041 if (AOP_TYPE(right) == AOP_LIT)
9042 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9044 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9046 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9053 freeAsmop(right,NULL,ic,TRUE);
9054 freeAsmop(result,NULL,ic,TRUE);
9057 /*-----------------------------------------------------------------*/
9058 /* genPointerSet - stores the value into a pointer location */
9059 /*-----------------------------------------------------------------*/
9060 static void genPointerSet (iCode *ic)
9062 operand *right, *result ;
9063 sym_link *type, *etype;
9066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9068 right = IC_RIGHT(ic);
9069 result = IC_RESULT(ic) ;
9071 /* depending on the type of pointer we need to
9072 move it to the correct pointer register */
9073 type = operandType(result);
9074 etype = getSpec(type);
9075 /* if left is of type of pointer then it is simple */
9076 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9077 p_type = DCL_TYPE(type);
9080 /* we have to go by the storage class */
9081 p_type = PTR_TYPE(SPEC_OCLS(etype));
9083 /* if (SPEC_OCLS(etype)->codesp ) { */
9084 /* p_type = CPOINTER ; */
9087 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9088 /* p_type = FPOINTER ; */
9090 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9091 /* p_type = PPOINTER ; */
9093 /* if (SPEC_OCLS(etype) == idata ) */
9094 /* p_type = IPOINTER ; */
9096 /* p_type = POINTER ; */
9099 /* now that we have the pointer type we assign
9100 the pointer values */
9105 genNearPointerSet (right,result,ic);
9109 genPagedPointerSet (right,result,ic);
9113 genFarPointerSet (right,result,ic);
9117 genGenPointerSet (right,result,ic);
9121 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9122 "genPointerSet: illegal pointer type");
9126 /*-----------------------------------------------------------------*/
9127 /* genIfx - generate code for Ifx statement */
9128 /*-----------------------------------------------------------------*/
9129 static void genIfx (iCode *ic, iCode *popIc)
9131 operand *cond = IC_COND(ic);
9134 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9136 aopOp(cond,ic,FALSE);
9138 /* get the value into acc */
9139 if (AOP_TYPE(cond) != AOP_CRY)
9140 pic14_toBoolean(cond);
9143 /* the result is now in the accumulator */
9144 freeAsmop(cond,NULL,ic,TRUE);
9146 /* if there was something to be popped then do it */
9150 /* if the condition is a bit variable */
9151 if (isbit && IS_ITEMP(cond) &&
9153 genIfxJump(ic,SPIL_LOC(cond)->rname);
9154 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9157 if (isbit && !IS_ITEMP(cond))
9158 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9166 /*-----------------------------------------------------------------*/
9167 /* genAddrOf - generates code for address of */
9168 /*-----------------------------------------------------------------*/
9169 static void genAddrOf (iCode *ic)
9171 operand *right, *result, *left;
9174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9177 //aopOp(IC_RESULT(ic),ic,FALSE);
9179 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9180 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9181 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9183 DEBUGpic14_AopType(__LINE__,left,right,result);
9185 size = AOP_SIZE(IC_RESULT(ic));
9189 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9190 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9194 freeAsmop(left,NULL,ic,FALSE);
9195 freeAsmop(result,NULL,ic,TRUE);
9200 /*-----------------------------------------------------------------*/
9201 /* genFarFarAssign - assignment when both are in far space */
9202 /*-----------------------------------------------------------------*/
9203 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9205 int size = AOP_SIZE(right);
9208 /* first push the right side on to the stack */
9210 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9212 pic14_emitcode ("push","acc");
9215 freeAsmop(right,NULL,ic,FALSE);
9216 /* now assign DPTR to result */
9217 aopOp(result,ic,FALSE);
9218 size = AOP_SIZE(result);
9220 pic14_emitcode ("pop","acc");
9221 aopPut(AOP(result),"a",--offset);
9223 freeAsmop(result,NULL,ic,FALSE);
9228 /*-----------------------------------------------------------------*/
9229 /* genAssign - generate code for assignment */
9230 /*-----------------------------------------------------------------*/
9231 static void genAssign (iCode *ic)
9233 operand *result, *right;
9234 int size, offset,know_W;
9235 unsigned long lit = 0L;
9237 result = IC_RESULT(ic);
9238 right = IC_RIGHT(ic) ;
9240 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9242 /* if they are the same */
9243 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9246 aopOp(right,ic,FALSE);
9247 aopOp(result,ic,TRUE);
9249 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9251 /* if they are the same registers */
9252 if (pic14_sameRegs(AOP(right),AOP(result)))
9255 /* if the result is a bit */
9256 if (AOP_TYPE(result) == AOP_CRY) {
9258 /* if the right size is a literal then
9259 we know what the value is */
9260 if (AOP_TYPE(right) == AOP_LIT) {
9262 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9263 popGet(AOP(result),0));
9265 if (((int) operandLitValue(right)))
9266 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9267 AOP(result)->aopu.aop_dir,
9268 AOP(result)->aopu.aop_dir);
9270 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9271 AOP(result)->aopu.aop_dir,
9272 AOP(result)->aopu.aop_dir);
9276 /* the right is also a bit variable */
9277 if (AOP_TYPE(right) == AOP_CRY) {
9278 emitpcode(POC_BCF, popGet(AOP(result),0));
9279 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9280 emitpcode(POC_BSF, popGet(AOP(result),0));
9282 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9283 AOP(result)->aopu.aop_dir,
9284 AOP(result)->aopu.aop_dir);
9285 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9286 AOP(right)->aopu.aop_dir,
9287 AOP(right)->aopu.aop_dir);
9288 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9289 AOP(result)->aopu.aop_dir,
9290 AOP(result)->aopu.aop_dir);
9295 emitpcode(POC_BCF, popGet(AOP(result),0));
9296 pic14_toBoolean(right);
9298 emitpcode(POC_BSF, popGet(AOP(result),0));
9299 //aopPut(AOP(result),"a",0);
9303 /* bit variables done */
9305 size = AOP_SIZE(result);
9307 if(AOP_TYPE(right) == AOP_LIT)
9308 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9310 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9312 if(aopIdx(AOP(result),0) == 4) {
9313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9314 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9315 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9318 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9324 if(AOP_TYPE(right) == AOP_LIT) {
9326 if(know_W != (lit&0xff))
9327 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9329 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9331 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9335 } else if (AOP_TYPE(right) == AOP_CRY) {
9336 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9338 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9339 emitpcode(POC_INCF, popGet(AOP(result),0));
9342 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9343 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9344 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9352 freeAsmop (right,NULL,ic,FALSE);
9353 freeAsmop (result,NULL,ic,TRUE);
9356 /*-----------------------------------------------------------------*/
9357 /* genJumpTab - genrates code for jump table */
9358 /*-----------------------------------------------------------------*/
9359 static void genJumpTab (iCode *ic)
9364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9366 aopOp(IC_JTCOND(ic),ic,FALSE);
9367 /* get the condition into accumulator */
9368 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9370 /* multiply by three */
9371 pic14_emitcode("add","a,acc");
9372 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9374 jtab = newiTempLabel(NULL);
9375 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9376 pic14_emitcode("jmp","@a+dptr");
9377 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9379 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9380 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9382 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9383 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9384 emitpLabel(jtab->key);
9386 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9388 /* now generate the jump labels */
9389 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9390 jtab = setNextItem(IC_JTLABELS(ic))) {
9391 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9392 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9398 /*-----------------------------------------------------------------*/
9399 /* genMixedOperation - gen code for operators between mixed types */
9400 /*-----------------------------------------------------------------*/
9402 TSD - Written for the PIC port - but this unfortunately is buggy.
9403 This routine is good in that it is able to efficiently promote
9404 types to different (larger) sizes. Unfortunately, the temporary
9405 variables that are optimized out by this routine are sometimes
9406 used in other places. So until I know how to really parse the
9407 iCode tree, I'm going to not be using this routine :(.
9409 static int genMixedOperation (iCode *ic)
9412 operand *result = IC_RESULT(ic);
9413 sym_link *ctype = operandType(IC_LEFT(ic));
9414 operand *right = IC_RIGHT(ic);
9420 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9422 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9428 nextright = IC_RIGHT(nextic);
9429 nextleft = IC_LEFT(nextic);
9430 nextresult = IC_RESULT(nextic);
9432 aopOp(right,ic,FALSE);
9433 aopOp(result,ic,FALSE);
9434 aopOp(nextright, nextic, FALSE);
9435 aopOp(nextleft, nextic, FALSE);
9436 aopOp(nextresult, nextic, FALSE);
9438 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9444 pic14_emitcode(";remove right +","");
9446 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9452 pic14_emitcode(";remove left +","");
9456 big = AOP_SIZE(nextleft);
9457 small = AOP_SIZE(nextright);
9459 switch(nextic->op) {
9462 pic14_emitcode(";optimize a +","");
9463 /* if unsigned or not an integral type */
9464 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9465 pic14_emitcode(";add a bit to something","");
9468 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9470 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9471 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9472 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9474 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9482 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9483 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9484 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9487 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9489 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9490 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9491 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9492 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9493 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9496 pic14_emitcode("rlf","known_zero,w");
9503 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9504 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9505 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9507 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9517 freeAsmop(right,NULL,ic,TRUE);
9518 freeAsmop(result,NULL,ic,TRUE);
9519 freeAsmop(nextright,NULL,ic,TRUE);
9520 freeAsmop(nextleft,NULL,ic,TRUE);
9522 nextic->generated = 1;
9529 /*-----------------------------------------------------------------*/
9530 /* genCast - gen code for casting */
9531 /*-----------------------------------------------------------------*/
9532 static void genCast (iCode *ic)
9534 operand *result = IC_RESULT(ic);
9535 sym_link *ctype = operandType(IC_LEFT(ic));
9536 sym_link *rtype = operandType(IC_RIGHT(ic));
9537 operand *right = IC_RIGHT(ic);
9540 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9541 /* if they are equivalent then do nothing */
9542 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9545 aopOp(right,ic,FALSE) ;
9546 aopOp(result,ic,FALSE);
9548 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9550 /* if the result is a bit */
9551 if (AOP_TYPE(result) == AOP_CRY) {
9552 /* if the right size is a literal then
9553 we know what the value is */
9554 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9555 if (AOP_TYPE(right) == AOP_LIT) {
9557 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9558 popGet(AOP(result),0));
9560 if (((int) operandLitValue(right)))
9561 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9562 AOP(result)->aopu.aop_dir,
9563 AOP(result)->aopu.aop_dir);
9565 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9566 AOP(result)->aopu.aop_dir,
9567 AOP(result)->aopu.aop_dir);
9572 /* the right is also a bit variable */
9573 if (AOP_TYPE(right) == AOP_CRY) {
9576 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9578 pic14_emitcode("clrc","");
9579 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9580 AOP(right)->aopu.aop_dir,
9581 AOP(right)->aopu.aop_dir);
9582 aopPut(AOP(result),"c",0);
9587 if (AOP_TYPE(right) == AOP_REG) {
9588 emitpcode(POC_BCF, popGet(AOP(result),0));
9589 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9590 emitpcode(POC_BSF, popGet(AOP(result),0));
9592 pic14_toBoolean(right);
9593 aopPut(AOP(result),"a",0);
9597 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9599 size = AOP_SIZE(result);
9601 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9603 emitpcode(POC_CLRF, popGet(AOP(result),0));
9604 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9605 emitpcode(POC_INCF, popGet(AOP(result),0));
9608 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9613 /* if they are the same size : or less */
9614 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9616 /* if they are in the same place */
9617 if (pic14_sameRegs(AOP(right),AOP(result)))
9620 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9621 if (IS_PTR_CONST(rtype))
9622 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9623 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9624 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9626 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9627 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9628 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9629 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9630 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9631 if(AOP_SIZE(result) <2)
9632 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9636 /* if they in different places then copy */
9637 size = AOP_SIZE(result);
9640 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9641 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9643 //aopPut(AOP(result),
9644 // aopGet(AOP(right),offset,FALSE,FALSE),
9654 /* if the result is of type pointer */
9655 if (IS_PTR(ctype)) {
9658 sym_link *type = operandType(right);
9659 sym_link *etype = getSpec(type);
9660 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9662 /* pointer to generic pointer */
9663 if (IS_GENPTR(ctype)) {
9667 p_type = DCL_TYPE(type);
9669 /* we have to go by the storage class */
9670 p_type = PTR_TYPE(SPEC_OCLS(etype));
9672 /* if (SPEC_OCLS(etype)->codesp ) */
9673 /* p_type = CPOINTER ; */
9675 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9676 /* p_type = FPOINTER ; */
9678 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9679 /* p_type = PPOINTER; */
9681 /* if (SPEC_OCLS(etype) == idata ) */
9682 /* p_type = IPOINTER ; */
9684 /* p_type = POINTER ; */
9687 /* the first two bytes are known */
9688 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9689 size = GPTRSIZE - 1;
9692 if(offset < AOP_SIZE(right)) {
9693 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9694 if ((AOP_TYPE(right) == AOP_PCODE) &&
9695 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9696 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9697 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9700 aopGet(AOP(right),offset,FALSE,FALSE),
9704 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9707 /* the last byte depending on type */
9711 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9714 pic14_emitcode(";BUG!? ","%d",__LINE__);
9718 pic14_emitcode(";BUG!? ","%d",__LINE__);
9722 pic14_emitcode(";BUG!? ","%d",__LINE__);
9727 /* this should never happen */
9728 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9729 "got unknown pointer type");
9732 //aopPut(AOP(result),l, GPTRSIZE - 1);
9736 /* just copy the pointers */
9737 size = AOP_SIZE(result);
9741 aopGet(AOP(right),offset,FALSE,FALSE),
9750 /* so we now know that the size of destination is greater
9751 than the size of the source.
9752 Now, if the next iCode is an operator then we might be
9753 able to optimize the operation without performing a cast.
9755 if(genMixedOperation(ic))
9758 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9760 /* we move to result for the size of source */
9761 size = AOP_SIZE(right);
9764 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9765 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9769 /* now depending on the sign of the destination */
9770 size = AOP_SIZE(result) - AOP_SIZE(right);
9771 /* if unsigned or not an integral type */
9772 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9774 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9776 /* we need to extend the sign :{ */
9779 /* Save one instruction of casting char to int */
9780 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9781 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9782 emitpcode(POC_DECF, popGet(AOP(result),offset));
9784 emitpcodeNULLop(POC_CLRW);
9787 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9789 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9791 emitpcode(POC_MOVLW, popGetLit(0xff));
9794 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9799 freeAsmop(right,NULL,ic,TRUE);
9800 freeAsmop(result,NULL,ic,TRUE);
9804 /*-----------------------------------------------------------------*/
9805 /* genDjnz - generate decrement & jump if not zero instrucion */
9806 /*-----------------------------------------------------------------*/
9807 static int genDjnz (iCode *ic, iCode *ifx)
9810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9815 /* if the if condition has a false label
9816 then we cannot save */
9820 /* if the minus is not of the form
9822 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9823 !IS_OP_LITERAL(IC_RIGHT(ic)))
9826 if (operandLitValue(IC_RIGHT(ic)) != 1)
9829 /* if the size of this greater than one then no
9831 if (getSize(operandType(IC_RESULT(ic))) > 1)
9834 /* otherwise we can save BIG */
9835 lbl = newiTempLabel(NULL);
9836 lbl1= newiTempLabel(NULL);
9838 aopOp(IC_RESULT(ic),ic,FALSE);
9840 if (IS_AOP_PREG(IC_RESULT(ic))) {
9841 pic14_emitcode("dec","%s",
9842 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9844 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9848 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9849 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9851 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9852 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9855 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9856 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9857 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9858 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9861 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9866 /*-----------------------------------------------------------------*/
9867 /* genReceive - generate code for a receive iCode */
9868 /*-----------------------------------------------------------------*/
9869 static void genReceive (iCode *ic)
9871 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9873 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9874 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9875 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9877 int size = getSize(operandType(IC_RESULT(ic)));
9878 int offset = fReturnSizePic - size;
9880 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9881 fReturn[fReturnSizePic - offset - 1] : "acc"));
9884 aopOp(IC_RESULT(ic),ic,FALSE);
9885 size = AOP_SIZE(IC_RESULT(ic));
9888 pic14_emitcode ("pop","acc");
9889 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9894 aopOp(IC_RESULT(ic),ic,FALSE);
9896 assignResultValue(IC_RESULT(ic));
9899 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9902 /*-----------------------------------------------------------------*/
9903 /* genpic14Code - generate code for pic14 based controllers */
9904 /*-----------------------------------------------------------------*/
9906 * At this point, ralloc.c has gone through the iCode and attempted
9907 * to optimize in a way suitable for a PIC. Now we've got to generate
9908 * PIC instructions that correspond to the iCode.
9910 * Once the instructions are generated, we'll pass through both the
9911 * peep hole optimizer and the pCode optimizer.
9912 *-----------------------------------------------------------------*/
9914 void genpic14Code (iCode *lic)
9919 lineHead = lineCurr = NULL;
9921 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9924 /* if debug information required */
9925 if (options.debug && currFunc) {
9927 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9929 if (IS_STATIC(currFunc->etype)) {
9930 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9931 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9933 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9934 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9941 for (ic = lic ; ic ; ic = ic->next ) {
9943 DEBUGpic14_emitcode(";ic","");
9944 if ( cln != ic->lineno ) {
9945 if ( options.debug ) {
9947 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9948 FileBaseName(ic->filename),ic->lineno,
9949 ic->level,ic->block);
9953 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9954 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9955 printCLine(ic->filename, ic->lineno));
9958 newpCodeCSource(ic->lineno,
9960 printCLine(ic->filename, ic->lineno)));
9964 /* if the result is marked as
9965 spilt and rematerializable or code for
9966 this has already been generated then
9968 if (resultRemat(ic) || ic->generated )
9971 /* depending on the operation */
9990 /* IPOP happens only when trying to restore a
9991 spilt live range, if there is an ifx statement
9992 following this pop then the if statement might
9993 be using some of the registers being popped which
9994 would destory the contents of the register so
9995 we need to check for this condition and handle it */
9997 ic->next->op == IFX &&
9998 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9999 genIfx (ic->next,ic);
10017 genEndFunction (ic);
10037 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10054 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10058 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10065 /* note these two are xlated by algebraic equivalence
10066 during parsing SDCC.y */
10067 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10068 "got '>=' or '<=' shouldn't have come here");
10072 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10084 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10088 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10092 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10116 genRightShift (ic);
10119 case GET_VALUE_AT_ADDRESS:
10124 if (POINTER_SET(ic))
10151 addSet(&_G.sendSet,ic);
10160 /* now we are ready to call the
10161 peep hole optimizer */
10162 if (!options.nopeep) {
10163 peepHole (&lineHead);
10165 /* now do the actual printing */
10166 printLine (lineHead,codeOutFile);
10169 DFPRINTF((stderr,"printing pBlock\n\n"));
10170 printpBlock(stdout,pb);