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));
6781 movLeft2Result(left,offl, result, offr);
6782 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6784 /* a:x >> shCount (x = lsb(result))*/
6787 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6789 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6798 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6804 emitpcode(POC_RRF,popGet(AOP(result),offr));
6806 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6807 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6809 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6814 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6818 emitpcode(POC_RRF,popGet(AOP(result),offr));
6825 emitpcode(POC_MOVLW, popGetLit(0xf0));
6826 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6827 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6829 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6830 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6832 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6834 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6835 emitpcode(POC_ANDLW, popGetLit(0x0f));
6836 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6838 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6839 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6840 emitpcode(POC_ANDLW, popGetLit(0xf0));
6841 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6842 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6846 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6847 emitpcode(POC_RRF, popGet(AOP(result),offr));
6851 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6852 emitpcode(POC_BTFSC,
6853 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6854 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6862 emitpcode(POC_RLF, popGet(AOP(result),offr));
6863 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6865 emitpcode(POC_RLF, popGet(AOP(result),offr));
6866 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6867 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6868 emitpcode(POC_ANDLW,popGetLit(0x03));
6870 emitpcode(POC_BTFSC,
6871 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6872 emitpcode(POC_IORLW,popGetLit(0xfc));
6874 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6875 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6876 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6879 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6880 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6881 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6882 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6883 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6884 emitpcode(POC_ANDLW,popGetLit(0x03));
6886 emitpcode(POC_BTFSC,
6887 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6888 emitpcode(POC_IORLW,popGetLit(0xfc));
6890 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6891 emitpcode(POC_RLF, popGet(AOP(result),offr));
6898 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6899 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6900 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6901 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6904 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6906 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6911 /*-----------------------------------------------------------------*/
6912 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6913 /*-----------------------------------------------------------------*/
6914 static void shiftLLeftOrResult (operand *left, int offl,
6915 operand *result, int offr, int shCount)
6917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6918 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6919 /* shift left accumulator */
6921 /* or with result */
6922 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6923 /* back to result */
6924 aopPut(AOP(result),"a",offr);
6927 /*-----------------------------------------------------------------*/
6928 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6929 /*-----------------------------------------------------------------*/
6930 static void shiftRLeftOrResult (operand *left, int offl,
6931 operand *result, int offr, int shCount)
6933 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6934 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6935 /* shift right accumulator */
6937 /* or with result */
6938 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6939 /* back to result */
6940 aopPut(AOP(result),"a",offr);
6943 /*-----------------------------------------------------------------*/
6944 /* genlshOne - left shift a one byte quantity by known count */
6945 /*-----------------------------------------------------------------*/
6946 static void genlshOne (operand *result, operand *left, int shCount)
6948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6949 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6952 /*-----------------------------------------------------------------*/
6953 /* genlshTwo - left shift two bytes by known amount != 0 */
6954 /*-----------------------------------------------------------------*/
6955 static void genlshTwo (operand *result,operand *left, int shCount)
6959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6960 size = pic14_getDataSize(result);
6962 /* if shCount >= 8 */
6968 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6970 movLeft2Result(left, LSB, result, MSB16);
6972 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6975 /* 1 <= shCount <= 7 */
6978 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6980 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6984 /*-----------------------------------------------------------------*/
6985 /* shiftLLong - shift left one long from left to result */
6986 /* offl = LSB or MSB16 */
6987 /*-----------------------------------------------------------------*/
6988 static void shiftLLong (operand *left, operand *result, int offr )
6991 int size = AOP_SIZE(result);
6993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6994 if(size >= LSB+offr){
6995 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6997 pic14_emitcode("add","a,acc");
6998 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6999 size >= MSB16+offr && offr != LSB )
7000 pic14_emitcode("xch","a,%s",
7001 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7003 aopPut(AOP(result),"a",LSB+offr);
7006 if(size >= MSB16+offr){
7007 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7008 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7011 pic14_emitcode("rlc","a");
7012 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7013 size >= MSB24+offr && offr != LSB)
7014 pic14_emitcode("xch","a,%s",
7015 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7017 aopPut(AOP(result),"a",MSB16+offr);
7020 if(size >= MSB24+offr){
7021 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7022 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7025 pic14_emitcode("rlc","a");
7026 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7027 size >= MSB32+offr && offr != LSB )
7028 pic14_emitcode("xch","a,%s",
7029 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7031 aopPut(AOP(result),"a",MSB24+offr);
7034 if(size > MSB32+offr){
7035 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7036 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7039 pic14_emitcode("rlc","a");
7040 aopPut(AOP(result),"a",MSB32+offr);
7043 aopPut(AOP(result),zero,LSB);
7046 /*-----------------------------------------------------------------*/
7047 /* genlshFour - shift four byte by a known amount != 0 */
7048 /*-----------------------------------------------------------------*/
7049 static void genlshFour (operand *result, operand *left, int shCount)
7053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7054 size = AOP_SIZE(result);
7056 /* if shifting more that 3 bytes */
7057 if (shCount >= 24 ) {
7060 /* lowest order of left goes to the highest
7061 order of the destination */
7062 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7064 movLeft2Result(left, LSB, result, MSB32);
7065 aopPut(AOP(result),zero,LSB);
7066 aopPut(AOP(result),zero,MSB16);
7067 aopPut(AOP(result),zero,MSB32);
7071 /* more than two bytes */
7072 else if ( shCount >= 16 ) {
7073 /* lower order two bytes goes to higher order two bytes */
7075 /* if some more remaining */
7077 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7079 movLeft2Result(left, MSB16, result, MSB32);
7080 movLeft2Result(left, LSB, result, MSB24);
7082 aopPut(AOP(result),zero,MSB16);
7083 aopPut(AOP(result),zero,LSB);
7087 /* if more than 1 byte */
7088 else if ( shCount >= 8 ) {
7089 /* lower order three bytes goes to higher order three bytes */
7093 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7095 movLeft2Result(left, LSB, result, MSB16);
7097 else{ /* size = 4 */
7099 movLeft2Result(left, MSB24, result, MSB32);
7100 movLeft2Result(left, MSB16, result, MSB24);
7101 movLeft2Result(left, LSB, result, MSB16);
7102 aopPut(AOP(result),zero,LSB);
7104 else if(shCount == 1)
7105 shiftLLong(left, result, MSB16);
7107 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7108 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7109 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7110 aopPut(AOP(result),zero,LSB);
7115 /* 1 <= shCount <= 7 */
7116 else if(shCount <= 2){
7117 shiftLLong(left, result, LSB);
7119 shiftLLong(result, result, LSB);
7121 /* 3 <= shCount <= 7, optimize */
7123 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7124 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7125 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7129 /*-----------------------------------------------------------------*/
7130 /* genLeftShiftLiteral - left shifting by known count */
7131 /*-----------------------------------------------------------------*/
7132 static void genLeftShiftLiteral (operand *left,
7137 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7141 freeAsmop(right,NULL,ic,TRUE);
7143 aopOp(left,ic,FALSE);
7144 aopOp(result,ic,FALSE);
7146 size = getSize(operandType(result));
7149 pic14_emitcode("; shift left ","result %d, left %d",size,
7153 /* I suppose that the left size >= result size */
7156 movLeft2Result(left, size, result, size);
7160 else if(shCount >= (size * 8))
7162 aopPut(AOP(result),zero,size);
7166 genlshOne (result,left,shCount);
7171 genlshTwo (result,left,shCount);
7175 genlshFour (result,left,shCount);
7179 freeAsmop(left,NULL,ic,TRUE);
7180 freeAsmop(result,NULL,ic,TRUE);
7183 /*-----------------------------------------------------------------*
7184 * genMultiAsm - repeat assembly instruction for size of register.
7185 * if endian == 1, then the high byte (i.e base address + size of
7186 * register) is used first else the low byte is used first;
7187 *-----------------------------------------------------------------*/
7188 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7206 emitpcode(poc, popGet(AOP(reg),offset));
7211 /*-----------------------------------------------------------------*/
7212 /* genLeftShift - generates code for left shifting */
7213 /*-----------------------------------------------------------------*/
7214 static void genLeftShift (iCode *ic)
7216 operand *left,*right, *result;
7219 symbol *tlbl , *tlbl1;
7222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7224 right = IC_RIGHT(ic);
7226 result = IC_RESULT(ic);
7228 aopOp(right,ic,FALSE);
7230 /* if the shift count is known then do it
7231 as efficiently as possible */
7232 if (AOP_TYPE(right) == AOP_LIT) {
7233 genLeftShiftLiteral (left,right,result,ic);
7237 /* shift count is unknown then we have to form
7238 a loop get the loop count in B : Note: we take
7239 only the lower order byte since shifting
7240 more that 32 bits make no sense anyway, ( the
7241 largest size of an object can be only 32 bits ) */
7244 aopOp(left,ic,FALSE);
7245 aopOp(result,ic,FALSE);
7247 /* now move the left to the result if they are not the
7249 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7250 AOP_SIZE(result) > 1) {
7252 size = AOP_SIZE(result);
7255 l = aopGet(AOP(left),offset,FALSE,TRUE);
7256 if (*l == '@' && (IS_AOP_PREG(result))) {
7258 pic14_emitcode("mov","a,%s",l);
7259 aopPut(AOP(result),"a",offset);
7261 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7262 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7263 //aopPut(AOP(result),l,offset);
7269 size = AOP_SIZE(result);
7271 /* if it is only one byte then */
7273 if(optimized_for_speed) {
7274 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7275 emitpcode(POC_ANDLW, popGetLit(0xf0));
7276 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7277 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7278 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7279 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7280 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7281 emitpcode(POC_RLFW, popGet(AOP(result),0));
7282 emitpcode(POC_ANDLW, popGetLit(0xfe));
7283 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7284 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7285 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7288 tlbl = newiTempLabel(NULL);
7289 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7290 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7291 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7294 emitpcode(POC_COMFW, popGet(AOP(right),0));
7295 emitpcode(POC_RRF, popGet(AOP(result),0));
7296 emitpLabel(tlbl->key);
7297 emitpcode(POC_RLF, popGet(AOP(result),0));
7298 emitpcode(POC_ADDLW, popGetLit(1));
7300 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7305 if (pic14_sameRegs(AOP(left),AOP(result))) {
7307 tlbl = newiTempLabel(NULL);
7308 emitpcode(POC_COMFW, popGet(AOP(right),0));
7309 genMultiAsm(POC_RRF, result, size,1);
7310 emitpLabel(tlbl->key);
7311 genMultiAsm(POC_RLF, result, size,0);
7312 emitpcode(POC_ADDLW, popGetLit(1));
7314 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7318 //tlbl = newiTempLabel(NULL);
7320 //tlbl1 = newiTempLabel(NULL);
7322 //reAdjustPreg(AOP(result));
7324 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7325 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7326 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7328 //pic14_emitcode("add","a,acc");
7329 //aopPut(AOP(result),"a",offset++);
7331 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7333 // pic14_emitcode("rlc","a");
7334 // aopPut(AOP(result),"a",offset++);
7336 //reAdjustPreg(AOP(result));
7338 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7339 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7342 tlbl = newiTempLabel(NULL);
7343 tlbl1= newiTempLabel(NULL);
7345 size = AOP_SIZE(result);
7348 pctemp = popGetTempReg(); /* grab a temporary working register. */
7350 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7352 /* offset should be 0, 1 or 3 */
7353 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7355 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7357 emitpcode(POC_MOVWF, pctemp);
7360 emitpLabel(tlbl->key);
7363 emitpcode(POC_RLF, popGet(AOP(result),0));
7365 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7367 emitpcode(POC_DECFSZ, pctemp);
7368 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7369 emitpLabel(tlbl1->key);
7371 popReleaseTempReg(pctemp);
7375 freeAsmop (right,NULL,ic,TRUE);
7376 freeAsmop(left,NULL,ic,TRUE);
7377 freeAsmop(result,NULL,ic,TRUE);
7380 /*-----------------------------------------------------------------*/
7381 /* genrshOne - right shift a one byte quantity by known count */
7382 /*-----------------------------------------------------------------*/
7383 static void genrshOne (operand *result, operand *left,
7384 int shCount, int sign)
7386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7387 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7390 /*-----------------------------------------------------------------*/
7391 /* genrshTwo - right shift two bytes by known amount != 0 */
7392 /*-----------------------------------------------------------------*/
7393 static void genrshTwo (operand *result,operand *left,
7394 int shCount, int sign)
7396 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7397 /* if shCount >= 8 */
7401 shiftR1Left2Result(left, MSB16, result, LSB,
7404 movLeft2Result(left, MSB16, result, LSB);
7406 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7409 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7410 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7414 /* 1 <= shCount <= 7 */
7416 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7419 /*-----------------------------------------------------------------*/
7420 /* shiftRLong - shift right one long from left to result */
7421 /* offl = LSB or MSB16 */
7422 /*-----------------------------------------------------------------*/
7423 static void shiftRLong (operand *left, int offl,
7424 operand *result, int sign)
7426 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7428 pic14_emitcode("clr","c");
7429 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7431 pic14_emitcode("mov","c,acc.7");
7432 pic14_emitcode("rrc","a");
7433 aopPut(AOP(result),"a",MSB32-offl);
7435 /* add sign of "a" */
7436 addSign(result, MSB32, sign);
7438 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7439 pic14_emitcode("rrc","a");
7440 aopPut(AOP(result),"a",MSB24-offl);
7442 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7443 pic14_emitcode("rrc","a");
7444 aopPut(AOP(result),"a",MSB16-offl);
7447 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7448 pic14_emitcode("rrc","a");
7449 aopPut(AOP(result),"a",LSB);
7453 /*-----------------------------------------------------------------*/
7454 /* genrshFour - shift four byte by a known amount != 0 */
7455 /*-----------------------------------------------------------------*/
7456 static void genrshFour (operand *result, operand *left,
7457 int shCount, int sign)
7459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7460 /* if shifting more that 3 bytes */
7461 if(shCount >= 24 ) {
7464 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7466 movLeft2Result(left, MSB32, result, LSB);
7468 addSign(result, MSB16, sign);
7470 else if(shCount >= 16){
7473 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7475 movLeft2Result(left, MSB24, result, LSB);
7476 movLeft2Result(left, MSB32, result, MSB16);
7478 addSign(result, MSB24, sign);
7480 else if(shCount >= 8){
7483 shiftRLong(left, MSB16, result, sign);
7484 else if(shCount == 0){
7485 movLeft2Result(left, MSB16, result, LSB);
7486 movLeft2Result(left, MSB24, result, MSB16);
7487 movLeft2Result(left, MSB32, result, MSB24);
7488 addSign(result, MSB32, sign);
7491 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7492 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7493 /* the last shift is signed */
7494 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7495 addSign(result, MSB32, sign);
7498 else{ /* 1 <= shCount <= 7 */
7500 shiftRLong(left, LSB, result, sign);
7502 shiftRLong(result, LSB, result, sign);
7505 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7506 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7507 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7512 /*-----------------------------------------------------------------*/
7513 /* genRightShiftLiteral - right shifting by known count */
7514 /*-----------------------------------------------------------------*/
7515 static void genRightShiftLiteral (operand *left,
7521 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7524 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7525 freeAsmop(right,NULL,ic,TRUE);
7527 aopOp(left,ic,FALSE);
7528 aopOp(result,ic,FALSE);
7531 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7535 lsize = pic14_getDataSize(left);
7536 res_size = pic14_getDataSize(result);
7537 /* test the LEFT size !!! */
7539 /* I suppose that the left size >= result size */
7542 movLeft2Result(left, lsize, result, res_size);
7545 else if(shCount >= (lsize * 8)){
7548 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7550 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7551 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7556 emitpcode(POC_MOVLW, popGetLit(0));
7557 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7558 emitpcode(POC_MOVLW, popGetLit(0xff));
7560 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7565 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7572 genrshOne (result,left,shCount,sign);
7576 genrshTwo (result,left,shCount,sign);
7580 genrshFour (result,left,shCount,sign);
7588 freeAsmop(left,NULL,ic,TRUE);
7589 freeAsmop(result,NULL,ic,TRUE);
7592 /*-----------------------------------------------------------------*/
7593 /* genSignedRightShift - right shift of signed number */
7594 /*-----------------------------------------------------------------*/
7595 static void genSignedRightShift (iCode *ic)
7597 operand *right, *left, *result;
7600 symbol *tlbl, *tlbl1 ;
7603 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7605 /* we do it the hard way put the shift count in b
7606 and loop thru preserving the sign */
7607 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7609 right = IC_RIGHT(ic);
7611 result = IC_RESULT(ic);
7613 aopOp(right,ic,FALSE);
7614 aopOp(left,ic,FALSE);
7615 aopOp(result,ic,FALSE);
7618 if ( AOP_TYPE(right) == AOP_LIT) {
7619 genRightShiftLiteral (left,right,result,ic,1);
7622 /* shift count is unknown then we have to form
7623 a loop get the loop count in B : Note: we take
7624 only the lower order byte since shifting
7625 more that 32 bits make no sense anyway, ( the
7626 largest size of an object can be only 32 bits ) */
7628 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7629 //pic14_emitcode("inc","b");
7630 //freeAsmop (right,NULL,ic,TRUE);
7631 //aopOp(left,ic,FALSE);
7632 //aopOp(result,ic,FALSE);
7634 /* now move the left to the result if they are not the
7636 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7637 AOP_SIZE(result) > 1) {
7639 size = AOP_SIZE(result);
7643 l = aopGet(AOP(left),offset,FALSE,TRUE);
7644 if (*l == '@' && IS_AOP_PREG(result)) {
7646 pic14_emitcode("mov","a,%s",l);
7647 aopPut(AOP(result),"a",offset);
7649 aopPut(AOP(result),l,offset);
7651 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7652 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7658 /* mov the highest order bit to OVR */
7659 tlbl = newiTempLabel(NULL);
7660 tlbl1= newiTempLabel(NULL);
7662 size = AOP_SIZE(result);
7665 pctemp = popGetTempReg(); /* grab a temporary working register. */
7667 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7669 /* offset should be 0, 1 or 3 */
7670 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7672 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7674 emitpcode(POC_MOVWF, pctemp);
7677 emitpLabel(tlbl->key);
7679 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7680 emitpcode(POC_RRF, popGet(AOP(result),offset));
7683 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7686 emitpcode(POC_DECFSZ, pctemp);
7687 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7688 emitpLabel(tlbl1->key);
7690 popReleaseTempReg(pctemp);
7692 size = AOP_SIZE(result);
7694 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7695 pic14_emitcode("rlc","a");
7696 pic14_emitcode("mov","ov,c");
7697 /* if it is only one byte then */
7699 l = aopGet(AOP(left),0,FALSE,FALSE);
7701 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7702 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7703 pic14_emitcode("mov","c,ov");
7704 pic14_emitcode("rrc","a");
7705 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7706 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7707 aopPut(AOP(result),"a",0);
7711 reAdjustPreg(AOP(result));
7712 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7713 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7714 pic14_emitcode("mov","c,ov");
7716 l = aopGet(AOP(result),offset,FALSE,FALSE);
7718 pic14_emitcode("rrc","a");
7719 aopPut(AOP(result),"a",offset--);
7721 reAdjustPreg(AOP(result));
7722 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7723 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7728 freeAsmop(left,NULL,ic,TRUE);
7729 freeAsmop(result,NULL,ic,TRUE);
7730 freeAsmop(right,NULL,ic,TRUE);
7733 /*-----------------------------------------------------------------*/
7734 /* genRightShift - generate code for right shifting */
7735 /*-----------------------------------------------------------------*/
7736 static void genRightShift (iCode *ic)
7738 operand *right, *left, *result;
7742 symbol *tlbl, *tlbl1 ;
7744 /* if signed then we do it the hard way preserve the
7745 sign bit moving it inwards */
7746 retype = getSpec(operandType(IC_RESULT(ic)));
7747 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7749 if (!SPEC_USIGN(retype)) {
7750 genSignedRightShift (ic);
7754 /* signed & unsigned types are treated the same : i.e. the
7755 signed is NOT propagated inwards : quoting from the
7756 ANSI - standard : "for E1 >> E2, is equivalent to division
7757 by 2**E2 if unsigned or if it has a non-negative value,
7758 otherwise the result is implementation defined ", MY definition
7759 is that the sign does not get propagated */
7761 right = IC_RIGHT(ic);
7763 result = IC_RESULT(ic);
7765 aopOp(right,ic,FALSE);
7767 /* if the shift count is known then do it
7768 as efficiently as possible */
7769 if (AOP_TYPE(right) == AOP_LIT) {
7770 genRightShiftLiteral (left,right,result,ic, 0);
7774 /* shift count is unknown then we have to form
7775 a loop get the loop count in B : Note: we take
7776 only the lower order byte since shifting
7777 more that 32 bits make no sense anyway, ( the
7778 largest size of an object can be only 32 bits ) */
7780 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7781 pic14_emitcode("inc","b");
7782 aopOp(left,ic,FALSE);
7783 aopOp(result,ic,FALSE);
7785 /* now move the left to the result if they are not the
7787 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7788 AOP_SIZE(result) > 1) {
7790 size = AOP_SIZE(result);
7793 l = aopGet(AOP(left),offset,FALSE,TRUE);
7794 if (*l == '@' && IS_AOP_PREG(result)) {
7796 pic14_emitcode("mov","a,%s",l);
7797 aopPut(AOP(result),"a",offset);
7799 aopPut(AOP(result),l,offset);
7804 tlbl = newiTempLabel(NULL);
7805 tlbl1= newiTempLabel(NULL);
7806 size = AOP_SIZE(result);
7809 /* if it is only one byte then */
7812 tlbl = newiTempLabel(NULL);
7813 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7814 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7815 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7818 emitpcode(POC_COMFW, popGet(AOP(right),0));
7819 emitpcode(POC_RLF, popGet(AOP(result),0));
7820 emitpLabel(tlbl->key);
7821 emitpcode(POC_RRF, popGet(AOP(result),0));
7822 emitpcode(POC_ADDLW, popGetLit(1));
7824 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7829 reAdjustPreg(AOP(result));
7830 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7831 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7834 l = aopGet(AOP(result),offset,FALSE,FALSE);
7836 pic14_emitcode("rrc","a");
7837 aopPut(AOP(result),"a",offset--);
7839 reAdjustPreg(AOP(result));
7841 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7842 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7845 freeAsmop(left,NULL,ic,TRUE);
7846 freeAsmop (right,NULL,ic,TRUE);
7847 freeAsmop(result,NULL,ic,TRUE);
7850 /*-----------------------------------------------------------------*/
7851 /* genUnpackBits - generates code for unpacking bits */
7852 /*-----------------------------------------------------------------*/
7853 static void genUnpackBits (operand *result, char *rname, int ptype)
7860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7861 etype = getSpec(operandType(result));
7863 /* read the first byte */
7868 pic14_emitcode("mov","a,@%s",rname);
7872 pic14_emitcode("movx","a,@%s",rname);
7876 pic14_emitcode("movx","a,@dptr");
7880 pic14_emitcode("clr","a");
7881 pic14_emitcode("movc","a","@a+dptr");
7885 pic14_emitcode("lcall","__gptrget");
7889 /* if we have bitdisplacement then it fits */
7890 /* into this byte completely or if length is */
7891 /* less than a byte */
7892 if ((shCnt = SPEC_BSTR(etype)) ||
7893 (SPEC_BLEN(etype) <= 8)) {
7895 /* shift right acc */
7898 pic14_emitcode("anl","a,#0x%02x",
7899 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7900 aopPut(AOP(result),"a",offset);
7904 /* bit field did not fit in a byte */
7905 rlen = SPEC_BLEN(etype) - 8;
7906 aopPut(AOP(result),"a",offset++);
7913 pic14_emitcode("inc","%s",rname);
7914 pic14_emitcode("mov","a,@%s",rname);
7918 pic14_emitcode("inc","%s",rname);
7919 pic14_emitcode("movx","a,@%s",rname);
7923 pic14_emitcode("inc","dptr");
7924 pic14_emitcode("movx","a,@dptr");
7928 pic14_emitcode("clr","a");
7929 pic14_emitcode("inc","dptr");
7930 pic14_emitcode("movc","a","@a+dptr");
7934 pic14_emitcode("inc","dptr");
7935 pic14_emitcode("lcall","__gptrget");
7940 /* if we are done */
7944 aopPut(AOP(result),"a",offset++);
7949 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7950 aopPut(AOP(result),"a",offset);
7957 /*-----------------------------------------------------------------*/
7958 /* genDataPointerGet - generates code when ptr offset is known */
7959 /*-----------------------------------------------------------------*/
7960 static void genDataPointerGet (operand *left,
7964 int size , offset = 0;
7967 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7970 /* optimization - most of the time, left and result are the same
7971 * address, but different types. for the pic code, we could omit
7975 aopOp(result,ic,TRUE);
7977 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7979 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7981 size = AOP_SIZE(result);
7984 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7988 freeAsmop(left,NULL,ic,TRUE);
7989 freeAsmop(result,NULL,ic,TRUE);
7992 /*-----------------------------------------------------------------*/
7993 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7994 /*-----------------------------------------------------------------*/
7995 static void genNearPointerGet (operand *left,
8000 //regs *preg = NULL ;
8002 sym_link *rtype, *retype;
8003 sym_link *ltype = operandType(left);
8006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8008 rtype = operandType(result);
8009 retype= getSpec(rtype);
8011 aopOp(left,ic,FALSE);
8013 /* if left is rematerialisable and
8014 result is not bit variable type and
8015 the left is pointer to data space i.e
8016 lower 128 bytes of space */
8017 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8018 !IS_BITVAR(retype) &&
8019 DCL_TYPE(ltype) == POINTER) {
8020 //genDataPointerGet (left,result,ic);
8024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8026 /* if the value is already in a pointer register
8027 then don't need anything more */
8028 if (!AOP_INPREG(AOP(left))) {
8029 /* otherwise get a free pointer register */
8030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8033 preg = getFreePtr(ic,&aop,FALSE);
8034 pic14_emitcode("mov","%s,%s",
8036 aopGet(AOP(left),0,FALSE,TRUE));
8037 rname = preg->name ;
8041 rname = aopGet(AOP(left),0,FALSE,FALSE);
8043 aopOp (result,ic,FALSE);
8045 /* if bitfield then unpack the bits */
8046 if (IS_BITVAR(retype))
8047 genUnpackBits (result,rname,POINTER);
8049 /* we have can just get the values */
8050 int size = AOP_SIZE(result);
8053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8055 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8056 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8058 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8059 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8061 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8065 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8067 pic14_emitcode("mov","a,@%s",rname);
8068 aopPut(AOP(result),"a",offset);
8070 sprintf(buffer,"@%s",rname);
8071 aopPut(AOP(result),buffer,offset);
8075 pic14_emitcode("inc","%s",rname);
8080 /* now some housekeeping stuff */
8082 /* we had to allocate for this iCode */
8083 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8084 freeAsmop(NULL,aop,ic,TRUE);
8086 /* we did not allocate which means left
8087 already in a pointer register, then
8088 if size > 0 && this could be used again
8089 we have to point it back to where it
8091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8092 if (AOP_SIZE(result) > 1 &&
8093 !OP_SYMBOL(left)->remat &&
8094 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8096 int size = AOP_SIZE(result) - 1;
8098 pic14_emitcode("dec","%s",rname);
8103 freeAsmop(left,NULL,ic,TRUE);
8104 freeAsmop(result,NULL,ic,TRUE);
8108 /*-----------------------------------------------------------------*/
8109 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8110 /*-----------------------------------------------------------------*/
8111 static void genPagedPointerGet (operand *left,
8118 sym_link *rtype, *retype;
8120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8122 rtype = operandType(result);
8123 retype= getSpec(rtype);
8125 aopOp(left,ic,FALSE);
8127 /* if the value is already in a pointer register
8128 then don't need anything more */
8129 if (!AOP_INPREG(AOP(left))) {
8130 /* otherwise get a free pointer register */
8132 preg = getFreePtr(ic,&aop,FALSE);
8133 pic14_emitcode("mov","%s,%s",
8135 aopGet(AOP(left),0,FALSE,TRUE));
8136 rname = preg->name ;
8138 rname = aopGet(AOP(left),0,FALSE,FALSE);
8140 freeAsmop(left,NULL,ic,TRUE);
8141 aopOp (result,ic,FALSE);
8143 /* if bitfield then unpack the bits */
8144 if (IS_BITVAR(retype))
8145 genUnpackBits (result,rname,PPOINTER);
8147 /* we have can just get the values */
8148 int size = AOP_SIZE(result);
8153 pic14_emitcode("movx","a,@%s",rname);
8154 aopPut(AOP(result),"a",offset);
8159 pic14_emitcode("inc","%s",rname);
8163 /* now some housekeeping stuff */
8165 /* we had to allocate for this iCode */
8166 freeAsmop(NULL,aop,ic,TRUE);
8168 /* we did not allocate which means left
8169 already in a pointer register, then
8170 if size > 0 && this could be used again
8171 we have to point it back to where it
8173 if (AOP_SIZE(result) > 1 &&
8174 !OP_SYMBOL(left)->remat &&
8175 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8177 int size = AOP_SIZE(result) - 1;
8179 pic14_emitcode("dec","%s",rname);
8184 freeAsmop(result,NULL,ic,TRUE);
8189 /*-----------------------------------------------------------------*/
8190 /* genFarPointerGet - gget value from far space */
8191 /*-----------------------------------------------------------------*/
8192 static void genFarPointerGet (operand *left,
8193 operand *result, iCode *ic)
8196 sym_link *retype = getSpec(operandType(result));
8198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8200 aopOp(left,ic,FALSE);
8202 /* if the operand is already in dptr
8203 then we do nothing else we move the value to dptr */
8204 if (AOP_TYPE(left) != AOP_STR) {
8205 /* if this is remateriazable */
8206 if (AOP_TYPE(left) == AOP_IMMD)
8207 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8208 else { /* we need to get it byte by byte */
8209 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8210 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8211 if (options.model == MODEL_FLAT24)
8213 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8217 /* so dptr know contains the address */
8218 freeAsmop(left,NULL,ic,TRUE);
8219 aopOp(result,ic,FALSE);
8221 /* if bit then unpack */
8222 if (IS_BITVAR(retype))
8223 genUnpackBits(result,"dptr",FPOINTER);
8225 size = AOP_SIZE(result);
8229 pic14_emitcode("movx","a,@dptr");
8230 aopPut(AOP(result),"a",offset++);
8232 pic14_emitcode("inc","dptr");
8236 freeAsmop(result,NULL,ic,TRUE);
8239 /*-----------------------------------------------------------------*/
8240 /* genCodePointerGet - get value from code space */
8241 /*-----------------------------------------------------------------*/
8242 static void genCodePointerGet (operand *left,
8243 operand *result, iCode *ic)
8246 sym_link *retype = getSpec(operandType(result));
8248 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8250 aopOp(left,ic,FALSE);
8252 /* if the operand is already in dptr
8253 then we do nothing else we move the value to dptr */
8254 if (AOP_TYPE(left) != AOP_STR) {
8255 /* if this is remateriazable */
8256 if (AOP_TYPE(left) == AOP_IMMD)
8257 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8258 else { /* we need to get it byte by byte */
8259 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8260 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8261 if (options.model == MODEL_FLAT24)
8263 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8267 /* so dptr know contains the address */
8268 freeAsmop(left,NULL,ic,TRUE);
8269 aopOp(result,ic,FALSE);
8271 /* if bit then unpack */
8272 if (IS_BITVAR(retype))
8273 genUnpackBits(result,"dptr",CPOINTER);
8275 size = AOP_SIZE(result);
8279 pic14_emitcode("clr","a");
8280 pic14_emitcode("movc","a,@a+dptr");
8281 aopPut(AOP(result),"a",offset++);
8283 pic14_emitcode("inc","dptr");
8287 freeAsmop(result,NULL,ic,TRUE);
8290 /*-----------------------------------------------------------------*/
8291 /* genGenPointerGet - gget value from generic pointer space */
8292 /*-----------------------------------------------------------------*/
8293 static void genGenPointerGet (operand *left,
8294 operand *result, iCode *ic)
8297 sym_link *retype = getSpec(operandType(result));
8299 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8300 aopOp(left,ic,FALSE);
8301 aopOp(result,ic,FALSE);
8304 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8306 /* if the operand is already in dptr
8307 then we do nothing else we move the value to dptr */
8308 // if (AOP_TYPE(left) != AOP_STR) {
8309 /* if this is remateriazable */
8310 if (AOP_TYPE(left) == AOP_IMMD) {
8311 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8312 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8314 else { /* we need to get it byte by byte */
8316 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8317 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8319 size = AOP_SIZE(result);
8323 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8324 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8326 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8331 /* so dptr know contains the address */
8333 /* if bit then unpack */
8334 //if (IS_BITVAR(retype))
8335 // genUnpackBits(result,"dptr",GPOINTER);
8338 freeAsmop(left,NULL,ic,TRUE);
8339 freeAsmop(result,NULL,ic,TRUE);
8343 /*-----------------------------------------------------------------*/
8344 /* genConstPointerGet - get value from const generic pointer space */
8345 /*-----------------------------------------------------------------*/
8346 static void genConstPointerGet (operand *left,
8347 operand *result, iCode *ic)
8349 //sym_link *retype = getSpec(operandType(result));
8350 symbol *albl = newiTempLabel(NULL);
8351 symbol *blbl = newiTempLabel(NULL);
8354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8355 aopOp(left,ic,FALSE);
8356 aopOp(result,ic,FALSE);
8359 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8361 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8363 emitpcode(POC_CALL,popGetLabel(albl->key));
8364 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8365 emitpLabel(albl->key);
8367 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8369 emitpcode(poc,popGet(AOP(left),1));
8370 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8371 emitpcode(poc,popGet(AOP(left),0));
8372 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8374 emitpLabel(blbl->key);
8376 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8379 freeAsmop(left,NULL,ic,TRUE);
8380 freeAsmop(result,NULL,ic,TRUE);
8383 /*-----------------------------------------------------------------*/
8384 /* genPointerGet - generate code for pointer get */
8385 /*-----------------------------------------------------------------*/
8386 static void genPointerGet (iCode *ic)
8388 operand *left, *result ;
8389 sym_link *type, *etype;
8392 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8395 result = IC_RESULT(ic) ;
8397 /* depending on the type of pointer we need to
8398 move it to the correct pointer register */
8399 type = operandType(left);
8400 etype = getSpec(type);
8402 if (IS_PTR_CONST(type))
8403 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8405 /* if left is of type of pointer then it is simple */
8406 if (IS_PTR(type) && !IS_FUNC(type->next))
8407 p_type = DCL_TYPE(type);
8409 /* we have to go by the storage class */
8410 p_type = PTR_TYPE(SPEC_OCLS(etype));
8412 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8414 if (SPEC_OCLS(etype)->codesp ) {
8415 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8416 //p_type = CPOINTER ;
8419 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8420 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8421 /*p_type = FPOINTER ;*/
8423 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8424 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8425 /* p_type = PPOINTER; */
8427 if (SPEC_OCLS(etype) == idata )
8428 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8429 /* p_type = IPOINTER; */
8431 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8432 /* p_type = POINTER ; */
8435 /* now that we have the pointer type we assign
8436 the pointer values */
8441 genNearPointerGet (left,result,ic);
8445 genPagedPointerGet(left,result,ic);
8449 genFarPointerGet (left,result,ic);
8453 genConstPointerGet (left,result,ic);
8454 //pic14_emitcodePointerGet (left,result,ic);
8458 if (IS_PTR_CONST(type))
8459 genConstPointerGet (left,result,ic);
8461 genGenPointerGet (left,result,ic);
8467 /*-----------------------------------------------------------------*/
8468 /* genPackBits - generates code for packed bit storage */
8469 /*-----------------------------------------------------------------*/
8470 static void genPackBits (sym_link *etype ,
8472 char *rname, int p_type)
8480 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8481 blen = SPEC_BLEN(etype);
8482 bstr = SPEC_BSTR(etype);
8484 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8487 /* if the bit lenth is less than or */
8488 /* it exactly fits a byte then */
8489 if (SPEC_BLEN(etype) <= 8 ) {
8490 shCount = SPEC_BSTR(etype) ;
8492 /* shift left acc */
8495 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8500 pic14_emitcode ("mov","b,a");
8501 pic14_emitcode("mov","a,@%s",rname);
8505 pic14_emitcode ("mov","b,a");
8506 pic14_emitcode("movx","a,@dptr");
8510 pic14_emitcode ("push","b");
8511 pic14_emitcode ("push","acc");
8512 pic14_emitcode ("lcall","__gptrget");
8513 pic14_emitcode ("pop","b");
8517 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8518 ((unsigned char)(0xFF << (blen+bstr)) |
8519 (unsigned char)(0xFF >> (8-bstr)) ) );
8520 pic14_emitcode ("orl","a,b");
8521 if (p_type == GPOINTER)
8522 pic14_emitcode("pop","b");
8528 pic14_emitcode("mov","@%s,a",rname);
8532 pic14_emitcode("movx","@dptr,a");
8536 DEBUGpic14_emitcode(";lcall","__gptrput");
8541 if ( SPEC_BLEN(etype) <= 8 )
8544 pic14_emitcode("inc","%s",rname);
8545 rLen = SPEC_BLEN(etype) ;
8547 /* now generate for lengths greater than one byte */
8550 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8560 pic14_emitcode("mov","@%s,a",rname);
8562 pic14_emitcode("mov","@%s,%s",rname,l);
8567 pic14_emitcode("movx","@dptr,a");
8572 DEBUGpic14_emitcode(";lcall","__gptrput");
8575 pic14_emitcode ("inc","%s",rname);
8580 /* last last was not complete */
8582 /* save the byte & read byte */
8585 pic14_emitcode ("mov","b,a");
8586 pic14_emitcode("mov","a,@%s",rname);
8590 pic14_emitcode ("mov","b,a");
8591 pic14_emitcode("movx","a,@dptr");
8595 pic14_emitcode ("push","b");
8596 pic14_emitcode ("push","acc");
8597 pic14_emitcode ("lcall","__gptrget");
8598 pic14_emitcode ("pop","b");
8602 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8603 pic14_emitcode ("orl","a,b");
8606 if (p_type == GPOINTER)
8607 pic14_emitcode("pop","b");
8612 pic14_emitcode("mov","@%s,a",rname);
8616 pic14_emitcode("movx","@dptr,a");
8620 DEBUGpic14_emitcode(";lcall","__gptrput");
8624 /*-----------------------------------------------------------------*/
8625 /* genDataPointerSet - remat pointer to data space */
8626 /*-----------------------------------------------------------------*/
8627 static void genDataPointerSet(operand *right,
8631 int size, offset = 0 ;
8632 char *l, buffer[256];
8634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8635 aopOp(right,ic,FALSE);
8637 l = aopGet(AOP(result),0,FALSE,TRUE);
8638 size = AOP_SIZE(right);
8640 if ( AOP_TYPE(result) == AOP_PCODE) {
8641 fprintf(stderr,"genDataPointerSet %s, %d\n",
8642 AOP(result)->aopu.pcop->name,
8643 PCOI(AOP(result)->aopu.pcop)->offset);
8647 // tsd, was l+1 - the underline `_' prefix was being stripped
8650 sprintf(buffer,"(%s + %d)",l,offset);
8651 fprintf(stderr,"oops %s\n",buffer);
8653 sprintf(buffer,"%s",l);
8655 if (AOP_TYPE(right) == AOP_LIT) {
8656 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8657 lit = lit >> (8*offset);
8659 pic14_emitcode("movlw","%d",lit);
8660 pic14_emitcode("movwf","%s",buffer);
8662 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8663 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8664 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8667 pic14_emitcode("clrf","%s",buffer);
8668 //emitpcode(POC_CLRF, popRegFromString(buffer));
8669 emitpcode(POC_CLRF, popGet(AOP(result),0));
8672 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8673 pic14_emitcode("movwf","%s",buffer);
8675 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8676 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8677 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8684 freeAsmop(right,NULL,ic,TRUE);
8685 freeAsmop(result,NULL,ic,TRUE);
8688 /*-----------------------------------------------------------------*/
8689 /* genNearPointerSet - pic14_emitcode for near pointer put */
8690 /*-----------------------------------------------------------------*/
8691 static void genNearPointerSet (operand *right,
8698 sym_link *ptype = operandType(result);
8701 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8702 retype= getSpec(operandType(right));
8704 aopOp(result,ic,FALSE);
8707 /* if the result is rematerializable &
8708 in data space & not a bit variable */
8709 //if (AOP_TYPE(result) == AOP_IMMD &&
8710 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8711 DCL_TYPE(ptype) == POINTER &&
8712 !IS_BITVAR(retype)) {
8713 genDataPointerSet (right,result,ic);
8714 freeAsmop(result,NULL,ic,TRUE);
8718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8719 aopOp(right,ic,FALSE);
8720 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8722 /* if the value is already in a pointer register
8723 then don't need anything more */
8724 if (!AOP_INPREG(AOP(result))) {
8725 /* otherwise get a free pointer register */
8726 //aop = newAsmop(0);
8727 //preg = getFreePtr(ic,&aop,FALSE);
8728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8729 //pic14_emitcode("mov","%s,%s",
8731 // aopGet(AOP(result),0,FALSE,TRUE));
8732 //rname = preg->name ;
8733 //pic14_emitcode("movwf","fsr");
8734 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8735 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8736 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8737 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8741 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8744 /* if bitfield then unpack the bits */
8745 if (IS_BITVAR(retype)) {
8746 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8747 "The programmer is obviously confused");
8748 //genPackBits (retype,right,rname,POINTER);
8752 /* we have can just get the values */
8753 int size = AOP_SIZE(right);
8756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8758 l = aopGet(AOP(right),offset,FALSE,TRUE);
8761 //pic14_emitcode("mov","@%s,a",rname);
8762 pic14_emitcode("movf","indf,w ;1");
8765 if (AOP_TYPE(right) == AOP_LIT) {
8766 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8768 pic14_emitcode("movlw","%s",l);
8769 pic14_emitcode("movwf","indf ;2");
8771 pic14_emitcode("clrf","indf");
8773 pic14_emitcode("movf","%s,w",l);
8774 pic14_emitcode("movwf","indf ;2");
8776 //pic14_emitcode("mov","@%s,%s",rname,l);
8779 pic14_emitcode("incf","fsr,f ;3");
8780 //pic14_emitcode("inc","%s",rname);
8785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8786 /* now some housekeeping stuff */
8788 /* we had to allocate for this iCode */
8789 freeAsmop(NULL,aop,ic,TRUE);
8791 /* we did not allocate which means left
8792 already in a pointer register, then
8793 if size > 0 && this could be used again
8794 we have to point it back to where it
8796 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8797 if (AOP_SIZE(right) > 1 &&
8798 !OP_SYMBOL(result)->remat &&
8799 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8801 int size = AOP_SIZE(right) - 1;
8803 pic14_emitcode("decf","fsr,f");
8804 //pic14_emitcode("dec","%s",rname);
8808 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8811 freeAsmop(right,NULL,ic,TRUE);
8812 freeAsmop(result,NULL,ic,TRUE);
8815 /*-----------------------------------------------------------------*/
8816 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8817 /*-----------------------------------------------------------------*/
8818 static void genPagedPointerSet (operand *right,
8827 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8829 retype= getSpec(operandType(right));
8831 aopOp(result,ic,FALSE);
8833 /* if the value is already in a pointer register
8834 then don't need anything more */
8835 if (!AOP_INPREG(AOP(result))) {
8836 /* otherwise get a free pointer register */
8838 preg = getFreePtr(ic,&aop,FALSE);
8839 pic14_emitcode("mov","%s,%s",
8841 aopGet(AOP(result),0,FALSE,TRUE));
8842 rname = preg->name ;
8844 rname = aopGet(AOP(result),0,FALSE,FALSE);
8846 freeAsmop(result,NULL,ic,TRUE);
8847 aopOp (right,ic,FALSE);
8849 /* if bitfield then unpack the bits */
8850 if (IS_BITVAR(retype))
8851 genPackBits (retype,right,rname,PPOINTER);
8853 /* we have can just get the values */
8854 int size = AOP_SIZE(right);
8858 l = aopGet(AOP(right),offset,FALSE,TRUE);
8861 pic14_emitcode("movx","@%s,a",rname);
8864 pic14_emitcode("inc","%s",rname);
8870 /* now some housekeeping stuff */
8872 /* we had to allocate for this iCode */
8873 freeAsmop(NULL,aop,ic,TRUE);
8875 /* we did not allocate which means left
8876 already in a pointer register, then
8877 if size > 0 && this could be used again
8878 we have to point it back to where it
8880 if (AOP_SIZE(right) > 1 &&
8881 !OP_SYMBOL(result)->remat &&
8882 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8884 int size = AOP_SIZE(right) - 1;
8886 pic14_emitcode("dec","%s",rname);
8891 freeAsmop(right,NULL,ic,TRUE);
8896 /*-----------------------------------------------------------------*/
8897 /* genFarPointerSet - set value from far space */
8898 /*-----------------------------------------------------------------*/
8899 static void genFarPointerSet (operand *right,
8900 operand *result, iCode *ic)
8903 sym_link *retype = getSpec(operandType(right));
8905 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8906 aopOp(result,ic,FALSE);
8908 /* if the operand is already in dptr
8909 then we do nothing else we move the value to dptr */
8910 if (AOP_TYPE(result) != AOP_STR) {
8911 /* if this is remateriazable */
8912 if (AOP_TYPE(result) == AOP_IMMD)
8913 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8914 else { /* we need to get it byte by byte */
8915 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8916 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8917 if (options.model == MODEL_FLAT24)
8919 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8923 /* so dptr know contains the address */
8924 freeAsmop(result,NULL,ic,TRUE);
8925 aopOp(right,ic,FALSE);
8927 /* if bit then unpack */
8928 if (IS_BITVAR(retype))
8929 genPackBits(retype,right,"dptr",FPOINTER);
8931 size = AOP_SIZE(right);
8935 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8937 pic14_emitcode("movx","@dptr,a");
8939 pic14_emitcode("inc","dptr");
8943 freeAsmop(right,NULL,ic,TRUE);
8946 /*-----------------------------------------------------------------*/
8947 /* genGenPointerSet - set value from generic pointer space */
8948 /*-----------------------------------------------------------------*/
8949 static void genGenPointerSet (operand *right,
8950 operand *result, iCode *ic)
8953 sym_link *retype = getSpec(operandType(right));
8955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8957 aopOp(result,ic,FALSE);
8958 aopOp(right,ic,FALSE);
8959 size = AOP_SIZE(right);
8961 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8963 /* if the operand is already in dptr
8964 then we do nothing else we move the value to dptr */
8965 if (AOP_TYPE(result) != AOP_STR) {
8966 /* if this is remateriazable */
8967 if (AOP_TYPE(result) == AOP_IMMD) {
8968 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8969 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8971 else { /* we need to get it byte by byte */
8972 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8973 size = AOP_SIZE(right);
8976 /* hack hack! see if this the FSR. If so don't load W */
8977 if(AOP_TYPE(right) != AOP_ACC) {
8980 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8981 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8983 if(AOP_SIZE(result) > 1) {
8984 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8985 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8986 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8991 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8993 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8994 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8998 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8999 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9002 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9009 if(aopIdx(AOP(result),0) != 4) {
9011 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9015 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9020 /* so dptr know contains the address */
9023 /* if bit then unpack */
9024 if (IS_BITVAR(retype))
9025 genPackBits(retype,right,"dptr",GPOINTER);
9027 size = AOP_SIZE(right);
9030 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9034 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9035 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9037 if (AOP_TYPE(right) == AOP_LIT)
9038 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9040 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9042 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9049 freeAsmop(right,NULL,ic,TRUE);
9050 freeAsmop(result,NULL,ic,TRUE);
9053 /*-----------------------------------------------------------------*/
9054 /* genPointerSet - stores the value into a pointer location */
9055 /*-----------------------------------------------------------------*/
9056 static void genPointerSet (iCode *ic)
9058 operand *right, *result ;
9059 sym_link *type, *etype;
9062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9064 right = IC_RIGHT(ic);
9065 result = IC_RESULT(ic) ;
9067 /* depending on the type of pointer we need to
9068 move it to the correct pointer register */
9069 type = operandType(result);
9070 etype = getSpec(type);
9071 /* if left is of type of pointer then it is simple */
9072 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9073 p_type = DCL_TYPE(type);
9076 /* we have to go by the storage class */
9077 p_type = PTR_TYPE(SPEC_OCLS(etype));
9079 /* if (SPEC_OCLS(etype)->codesp ) { */
9080 /* p_type = CPOINTER ; */
9083 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9084 /* p_type = FPOINTER ; */
9086 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9087 /* p_type = PPOINTER ; */
9089 /* if (SPEC_OCLS(etype) == idata ) */
9090 /* p_type = IPOINTER ; */
9092 /* p_type = POINTER ; */
9095 /* now that we have the pointer type we assign
9096 the pointer values */
9101 genNearPointerSet (right,result,ic);
9105 genPagedPointerSet (right,result,ic);
9109 genFarPointerSet (right,result,ic);
9113 genGenPointerSet (right,result,ic);
9117 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9118 "genPointerSet: illegal pointer type");
9122 /*-----------------------------------------------------------------*/
9123 /* genIfx - generate code for Ifx statement */
9124 /*-----------------------------------------------------------------*/
9125 static void genIfx (iCode *ic, iCode *popIc)
9127 operand *cond = IC_COND(ic);
9130 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9132 aopOp(cond,ic,FALSE);
9134 /* get the value into acc */
9135 if (AOP_TYPE(cond) != AOP_CRY)
9136 pic14_toBoolean(cond);
9139 /* the result is now in the accumulator */
9140 freeAsmop(cond,NULL,ic,TRUE);
9142 /* if there was something to be popped then do it */
9146 /* if the condition is a bit variable */
9147 if (isbit && IS_ITEMP(cond) &&
9149 genIfxJump(ic,SPIL_LOC(cond)->rname);
9150 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9153 if (isbit && !IS_ITEMP(cond))
9154 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9162 /*-----------------------------------------------------------------*/
9163 /* genAddrOf - generates code for address of */
9164 /*-----------------------------------------------------------------*/
9165 static void genAddrOf (iCode *ic)
9167 operand *right, *result, *left;
9170 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9173 //aopOp(IC_RESULT(ic),ic,FALSE);
9175 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9176 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9177 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9179 DEBUGpic14_AopType(__LINE__,left,right,result);
9181 size = AOP_SIZE(IC_RESULT(ic));
9185 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9186 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9190 freeAsmop(left,NULL,ic,FALSE);
9191 freeAsmop(result,NULL,ic,TRUE);
9196 /*-----------------------------------------------------------------*/
9197 /* genFarFarAssign - assignment when both are in far space */
9198 /*-----------------------------------------------------------------*/
9199 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9201 int size = AOP_SIZE(right);
9204 /* first push the right side on to the stack */
9206 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9208 pic14_emitcode ("push","acc");
9211 freeAsmop(right,NULL,ic,FALSE);
9212 /* now assign DPTR to result */
9213 aopOp(result,ic,FALSE);
9214 size = AOP_SIZE(result);
9216 pic14_emitcode ("pop","acc");
9217 aopPut(AOP(result),"a",--offset);
9219 freeAsmop(result,NULL,ic,FALSE);
9224 /*-----------------------------------------------------------------*/
9225 /* genAssign - generate code for assignment */
9226 /*-----------------------------------------------------------------*/
9227 static void genAssign (iCode *ic)
9229 operand *result, *right;
9230 int size, offset,know_W;
9231 unsigned long lit = 0L;
9233 result = IC_RESULT(ic);
9234 right = IC_RIGHT(ic) ;
9236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9238 /* if they are the same */
9239 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9242 aopOp(right,ic,FALSE);
9243 aopOp(result,ic,TRUE);
9245 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9247 /* if they are the same registers */
9248 if (pic14_sameRegs(AOP(right),AOP(result)))
9251 /* if the result is a bit */
9252 if (AOP_TYPE(result) == AOP_CRY) {
9254 /* if the right size is a literal then
9255 we know what the value is */
9256 if (AOP_TYPE(right) == AOP_LIT) {
9258 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9259 popGet(AOP(result),0));
9261 if (((int) operandLitValue(right)))
9262 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9263 AOP(result)->aopu.aop_dir,
9264 AOP(result)->aopu.aop_dir);
9266 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9267 AOP(result)->aopu.aop_dir,
9268 AOP(result)->aopu.aop_dir);
9272 /* the right is also a bit variable */
9273 if (AOP_TYPE(right) == AOP_CRY) {
9274 emitpcode(POC_BCF, popGet(AOP(result),0));
9275 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9276 emitpcode(POC_BSF, popGet(AOP(result),0));
9278 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9279 AOP(result)->aopu.aop_dir,
9280 AOP(result)->aopu.aop_dir);
9281 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9282 AOP(right)->aopu.aop_dir,
9283 AOP(right)->aopu.aop_dir);
9284 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9285 AOP(result)->aopu.aop_dir,
9286 AOP(result)->aopu.aop_dir);
9291 emitpcode(POC_BCF, popGet(AOP(result),0));
9292 pic14_toBoolean(right);
9294 emitpcode(POC_BSF, popGet(AOP(result),0));
9295 //aopPut(AOP(result),"a",0);
9299 /* bit variables done */
9301 size = AOP_SIZE(result);
9303 if(AOP_TYPE(right) == AOP_LIT)
9304 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9306 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9307 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9308 if(aopIdx(AOP(result),0) == 4) {
9309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9310 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9311 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9314 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9320 if(AOP_TYPE(right) == AOP_LIT) {
9322 if(know_W != (lit&0xff))
9323 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9325 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9327 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9331 } else if (AOP_TYPE(right) == AOP_CRY) {
9332 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9334 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9335 emitpcode(POC_INCF, popGet(AOP(result),0));
9338 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9339 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9340 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9348 freeAsmop (right,NULL,ic,FALSE);
9349 freeAsmop (result,NULL,ic,TRUE);
9352 /*-----------------------------------------------------------------*/
9353 /* genJumpTab - genrates code for jump table */
9354 /*-----------------------------------------------------------------*/
9355 static void genJumpTab (iCode *ic)
9360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9362 aopOp(IC_JTCOND(ic),ic,FALSE);
9363 /* get the condition into accumulator */
9364 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9366 /* multiply by three */
9367 pic14_emitcode("add","a,acc");
9368 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9370 jtab = newiTempLabel(NULL);
9371 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9372 pic14_emitcode("jmp","@a+dptr");
9373 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9375 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9376 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9378 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9379 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9380 emitpLabel(jtab->key);
9382 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9384 /* now generate the jump labels */
9385 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9386 jtab = setNextItem(IC_JTLABELS(ic))) {
9387 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9388 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9394 /*-----------------------------------------------------------------*/
9395 /* genMixedOperation - gen code for operators between mixed types */
9396 /*-----------------------------------------------------------------*/
9398 TSD - Written for the PIC port - but this unfortunately is buggy.
9399 This routine is good in that it is able to efficiently promote
9400 types to different (larger) sizes. Unfortunately, the temporary
9401 variables that are optimized out by this routine are sometimes
9402 used in other places. So until I know how to really parse the
9403 iCode tree, I'm going to not be using this routine :(.
9405 static int genMixedOperation (iCode *ic)
9408 operand *result = IC_RESULT(ic);
9409 sym_link *ctype = operandType(IC_LEFT(ic));
9410 operand *right = IC_RIGHT(ic);
9416 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9418 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9424 nextright = IC_RIGHT(nextic);
9425 nextleft = IC_LEFT(nextic);
9426 nextresult = IC_RESULT(nextic);
9428 aopOp(right,ic,FALSE);
9429 aopOp(result,ic,FALSE);
9430 aopOp(nextright, nextic, FALSE);
9431 aopOp(nextleft, nextic, FALSE);
9432 aopOp(nextresult, nextic, FALSE);
9434 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9440 pic14_emitcode(";remove right +","");
9442 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9448 pic14_emitcode(";remove left +","");
9452 big = AOP_SIZE(nextleft);
9453 small = AOP_SIZE(nextright);
9455 switch(nextic->op) {
9458 pic14_emitcode(";optimize a +","");
9459 /* if unsigned or not an integral type */
9460 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9461 pic14_emitcode(";add a bit to something","");
9464 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9466 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9467 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9468 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9470 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9478 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9479 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9480 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9483 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9485 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9486 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9487 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9488 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9489 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9492 pic14_emitcode("rlf","known_zero,w");
9499 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9500 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9501 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9503 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9513 freeAsmop(right,NULL,ic,TRUE);
9514 freeAsmop(result,NULL,ic,TRUE);
9515 freeAsmop(nextright,NULL,ic,TRUE);
9516 freeAsmop(nextleft,NULL,ic,TRUE);
9518 nextic->generated = 1;
9525 /*-----------------------------------------------------------------*/
9526 /* genCast - gen code for casting */
9527 /*-----------------------------------------------------------------*/
9528 static void genCast (iCode *ic)
9530 operand *result = IC_RESULT(ic);
9531 sym_link *ctype = operandType(IC_LEFT(ic));
9532 sym_link *rtype = operandType(IC_RIGHT(ic));
9533 operand *right = IC_RIGHT(ic);
9536 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9537 /* if they are equivalent then do nothing */
9538 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9541 aopOp(right,ic,FALSE) ;
9542 aopOp(result,ic,FALSE);
9544 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9546 /* if the result is a bit */
9547 if (AOP_TYPE(result) == AOP_CRY) {
9548 /* if the right size is a literal then
9549 we know what the value is */
9550 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9551 if (AOP_TYPE(right) == AOP_LIT) {
9553 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9554 popGet(AOP(result),0));
9556 if (((int) operandLitValue(right)))
9557 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9558 AOP(result)->aopu.aop_dir,
9559 AOP(result)->aopu.aop_dir);
9561 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9562 AOP(result)->aopu.aop_dir,
9563 AOP(result)->aopu.aop_dir);
9568 /* the right is also a bit variable */
9569 if (AOP_TYPE(right) == AOP_CRY) {
9572 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9574 pic14_emitcode("clrc","");
9575 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9576 AOP(right)->aopu.aop_dir,
9577 AOP(right)->aopu.aop_dir);
9578 aopPut(AOP(result),"c",0);
9583 if (AOP_TYPE(right) == AOP_REG) {
9584 emitpcode(POC_BCF, popGet(AOP(result),0));
9585 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9586 emitpcode(POC_BSF, popGet(AOP(result),0));
9588 pic14_toBoolean(right);
9589 aopPut(AOP(result),"a",0);
9593 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9595 size = AOP_SIZE(result);
9597 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9599 emitpcode(POC_CLRF, popGet(AOP(result),0));
9600 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9601 emitpcode(POC_INCF, popGet(AOP(result),0));
9604 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9609 /* if they are the same size : or less */
9610 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9612 /* if they are in the same place */
9613 if (pic14_sameRegs(AOP(right),AOP(result)))
9616 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9617 if (IS_PTR_CONST(rtype))
9618 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9619 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9620 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9622 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9623 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9624 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9625 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9626 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9627 if(AOP_SIZE(result) <2)
9628 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9632 /* if they in different places then copy */
9633 size = AOP_SIZE(result);
9636 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9637 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9639 //aopPut(AOP(result),
9640 // aopGet(AOP(right),offset,FALSE,FALSE),
9650 /* if the result is of type pointer */
9651 if (IS_PTR(ctype)) {
9654 sym_link *type = operandType(right);
9655 sym_link *etype = getSpec(type);
9656 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9658 /* pointer to generic pointer */
9659 if (IS_GENPTR(ctype)) {
9663 p_type = DCL_TYPE(type);
9665 /* we have to go by the storage class */
9666 p_type = PTR_TYPE(SPEC_OCLS(etype));
9668 /* if (SPEC_OCLS(etype)->codesp ) */
9669 /* p_type = CPOINTER ; */
9671 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9672 /* p_type = FPOINTER ; */
9674 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9675 /* p_type = PPOINTER; */
9677 /* if (SPEC_OCLS(etype) == idata ) */
9678 /* p_type = IPOINTER ; */
9680 /* p_type = POINTER ; */
9683 /* the first two bytes are known */
9684 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9685 size = GPTRSIZE - 1;
9688 if(offset < AOP_SIZE(right)) {
9689 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9690 if ((AOP_TYPE(right) == AOP_PCODE) &&
9691 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9692 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9693 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9696 aopGet(AOP(right),offset,FALSE,FALSE),
9700 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9703 /* the last byte depending on type */
9707 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9710 pic14_emitcode(";BUG!? ","%d",__LINE__);
9714 pic14_emitcode(";BUG!? ","%d",__LINE__);
9718 pic14_emitcode(";BUG!? ","%d",__LINE__);
9723 /* this should never happen */
9724 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9725 "got unknown pointer type");
9728 //aopPut(AOP(result),l, GPTRSIZE - 1);
9732 /* just copy the pointers */
9733 size = AOP_SIZE(result);
9737 aopGet(AOP(right),offset,FALSE,FALSE),
9746 /* so we now know that the size of destination is greater
9747 than the size of the source.
9748 Now, if the next iCode is an operator then we might be
9749 able to optimize the operation without performing a cast.
9751 if(genMixedOperation(ic))
9754 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9756 /* we move to result for the size of source */
9757 size = AOP_SIZE(right);
9760 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9761 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9765 /* now depending on the sign of the destination */
9766 size = AOP_SIZE(result) - AOP_SIZE(right);
9767 /* if unsigned or not an integral type */
9768 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9770 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9772 /* we need to extend the sign :{ */
9775 /* Save one instruction of casting char to int */
9776 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9777 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9778 emitpcode(POC_DECF, popGet(AOP(result),offset));
9780 emitpcodeNULLop(POC_CLRW);
9783 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9785 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9787 emitpcode(POC_MOVLW, popGetLit(0xff));
9790 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9795 freeAsmop(right,NULL,ic,TRUE);
9796 freeAsmop(result,NULL,ic,TRUE);
9800 /*-----------------------------------------------------------------*/
9801 /* genDjnz - generate decrement & jump if not zero instrucion */
9802 /*-----------------------------------------------------------------*/
9803 static int genDjnz (iCode *ic, iCode *ifx)
9806 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9811 /* if the if condition has a false label
9812 then we cannot save */
9816 /* if the minus is not of the form
9818 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9819 !IS_OP_LITERAL(IC_RIGHT(ic)))
9822 if (operandLitValue(IC_RIGHT(ic)) != 1)
9825 /* if the size of this greater than one then no
9827 if (getSize(operandType(IC_RESULT(ic))) > 1)
9830 /* otherwise we can save BIG */
9831 lbl = newiTempLabel(NULL);
9832 lbl1= newiTempLabel(NULL);
9834 aopOp(IC_RESULT(ic),ic,FALSE);
9836 if (IS_AOP_PREG(IC_RESULT(ic))) {
9837 pic14_emitcode("dec","%s",
9838 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9839 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9840 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9844 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9845 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9847 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9848 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9851 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9852 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9853 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9854 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9857 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9862 /*-----------------------------------------------------------------*/
9863 /* genReceive - generate code for a receive iCode */
9864 /*-----------------------------------------------------------------*/
9865 static void genReceive (iCode *ic)
9867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9869 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9870 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9871 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9873 int size = getSize(operandType(IC_RESULT(ic)));
9874 int offset = fReturnSizePic - size;
9876 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9877 fReturn[fReturnSizePic - offset - 1] : "acc"));
9880 aopOp(IC_RESULT(ic),ic,FALSE);
9881 size = AOP_SIZE(IC_RESULT(ic));
9884 pic14_emitcode ("pop","acc");
9885 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9890 aopOp(IC_RESULT(ic),ic,FALSE);
9892 assignResultValue(IC_RESULT(ic));
9895 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9898 /*-----------------------------------------------------------------*/
9899 /* genpic14Code - generate code for pic14 based controllers */
9900 /*-----------------------------------------------------------------*/
9902 * At this point, ralloc.c has gone through the iCode and attempted
9903 * to optimize in a way suitable for a PIC. Now we've got to generate
9904 * PIC instructions that correspond to the iCode.
9906 * Once the instructions are generated, we'll pass through both the
9907 * peep hole optimizer and the pCode optimizer.
9908 *-----------------------------------------------------------------*/
9910 void genpic14Code (iCode *lic)
9915 lineHead = lineCurr = NULL;
9917 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9920 /* if debug information required */
9921 if (options.debug && currFunc) {
9923 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9925 if (IS_STATIC(currFunc->etype)) {
9926 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9927 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9929 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9930 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9937 for (ic = lic ; ic ; ic = ic->next ) {
9939 DEBUGpic14_emitcode(";ic","");
9940 if ( cln != ic->lineno ) {
9941 if ( options.debug ) {
9943 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9944 FileBaseName(ic->filename),ic->lineno,
9945 ic->level,ic->block);
9949 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9950 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9951 printCLine(ic->filename, ic->lineno));
9954 newpCodeCSource(ic->lineno,
9956 printCLine(ic->filename, ic->lineno)));
9960 /* if the result is marked as
9961 spilt and rematerializable or code for
9962 this has already been generated then
9964 if (resultRemat(ic) || ic->generated )
9967 /* depending on the operation */
9986 /* IPOP happens only when trying to restore a
9987 spilt live range, if there is an ifx statement
9988 following this pop then the if statement might
9989 be using some of the registers being popped which
9990 would destory the contents of the register so
9991 we need to check for this condition and handle it */
9993 ic->next->op == IFX &&
9994 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9995 genIfx (ic->next,ic);
10013 genEndFunction (ic);
10033 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10050 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10054 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10061 /* note these two are xlated by algebraic equivalence
10062 during parsing SDCC.y */
10063 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10064 "got '>=' or '<=' shouldn't have come here");
10068 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10080 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10084 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10088 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10112 genRightShift (ic);
10115 case GET_VALUE_AT_ADDRESS:
10120 if (POINTER_SET(ic))
10147 addSet(&_G.sendSet,ic);
10156 /* now we are ready to call the
10157 peep hole optimizer */
10158 if (!options.nopeep) {
10159 peepHole (&lineHead);
10161 /* now do the actual printing */
10162 printLine (lineHead,codeOutFile);
10165 DFPRINTF((stderr,"printing pBlock\n\n"));
10166 printpBlock(stdout,pb);