1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
66 pCode *AssembleLine(char *line);
67 extern void printpBlock(FILE *of, pBlock *pb);
69 static int labelOffset=0;
70 extern int debug_verbose;
71 static int optimized_for_speed = 0;
73 /* max_key keeps track of the largest label number used in
74 a function. This is then used to adjust the label offset
75 for the next function.
78 static int GpsuedoStkPtr=0;
80 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
81 unsigned int pic14aopLiteral (value *val, int offset);
82 const char *AopType(short type);
83 static iCode *ifxForOp ( operand *op, iCode *ic );
85 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
87 /* this is the down and dirty file with all kinds of
88 kludgy & hacky stuff. This is what it is all about
89 CODE GENERATION for a specific MCU . some of the
90 routines may be reusable, will have to see */
92 static char *zero = "#0x00";
93 static char *one = "#0x01";
94 static char *spname = "sp";
96 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
97 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
98 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
99 static char **fReturn = fReturnpic14;
101 static char *accUse[] = {"a","b"};
103 //static short rbank = -1;
115 /* Resolved ifx structure. This structure stores information
116 about an iCode ifx that makes it easier to generate code.
118 typedef struct resolvedIfx {
119 symbol *lbl; /* pointer to a label */
120 int condition; /* true or false ifx */
121 int generated; /* set true when the code associated with the ifx
125 extern int pic14_ptrRegReq ;
126 extern int pic14_nRegs;
127 extern FILE *codeOutFile;
128 static void saverbank (int, iCode *,bool);
130 static lineNode *lineHead = NULL;
131 static lineNode *lineCurr = NULL;
133 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
134 0xE0, 0xC0, 0x80, 0x00};
135 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
136 0x07, 0x03, 0x01, 0x00};
140 /*-----------------------------------------------------------------*/
141 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
142 /* exponent of 2 is returned, otherwise -1 is */
144 /* note that this is similar to the function `powof2' in SDCCsymt */
148 /*-----------------------------------------------------------------*/
149 static int my_powof2 (unsigned long num)
152 if( (num & (num-1)) == 0) {
165 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
168 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
170 ((result) ? AopType(AOP_TYPE(result)) : "-"),
171 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
172 ((left) ? AopType(AOP_TYPE(left)) : "-"),
173 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
174 ((right) ? AopType(AOP_TYPE(right)) : "-"),
175 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
176 ((result) ? AOP_SIZE(result) : 0));
180 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
183 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
185 ((result) ? AopType(AOP_TYPE(result)) : "-"),
186 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
187 ((left) ? AopType(AOP_TYPE(left)) : "-"),
188 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
189 ((right) ? AopType(AOP_TYPE(right)) : "-"),
190 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
194 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
197 char lb[INITIAL_INLINEASM];
207 sprintf(lb,"%s\t",inst);
209 sprintf(lb,"%s",inst);
210 vsprintf(lb+(strlen(lb)),fmt,ap);
214 while (isspace(*lbp)) lbp++;
217 lineCurr = (lineCurr ?
218 connectLine(lineCurr,newLineNode(lb)) :
219 (lineHead = newLineNode(lb)));
220 lineCurr->isInline = _G.inLine;
221 lineCurr->isDebug = _G.debugLine;
223 addpCode2pBlock(pb,newpCodeCharP(lb));
229 void emitpLabel(int key)
231 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
234 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
238 addpCode2pBlock(pb,newpCode(poc,pcop));
240 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
243 void emitpcodeNULLop(PIC_OPCODE poc)
246 addpCode2pBlock(pb,newpCode(poc,NULL));
250 /*-----------------------------------------------------------------*/
251 /* pic14_emitcode - writes the code into a file : for now it is simple */
252 /*-----------------------------------------------------------------*/
253 void pic14_emitcode (char *inst,char *fmt, ...)
256 char lb[INITIAL_INLINEASM];
263 sprintf(lb,"%s\t",inst);
265 sprintf(lb,"%s",inst);
266 vsprintf(lb+(strlen(lb)),fmt,ap);
270 while (isspace(*lbp)) lbp++;
273 lineCurr = (lineCurr ?
274 connectLine(lineCurr,newLineNode(lb)) :
275 (lineHead = newLineNode(lb)));
276 lineCurr->isInline = _G.inLine;
277 lineCurr->isDebug = _G.debugLine;
280 addpCode2pBlock(pb,newpCodeCharP(lb));
286 /*-----------------------------------------------------------------*/
287 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
288 /*-----------------------------------------------------------------*/
289 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
291 bool r0iu = FALSE , r1iu = FALSE;
292 bool r0ou = FALSE , r1ou = FALSE;
294 /* the logic: if r0 & r1 used in the instruction
295 then we are in trouble otherwise */
297 /* first check if r0 & r1 are used by this
298 instruction, in which case we are in trouble */
299 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
305 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
308 /* if no usage of r0 then return it */
309 if (!r0iu && !r0ou) {
310 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311 (*aopp)->type = AOP_R0;
313 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
316 /* if no usage of r1 then return it */
317 if (!r1iu && !r1ou) {
318 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319 (*aopp)->type = AOP_R1;
321 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
324 /* now we know they both have usage */
325 /* if r0 not used in this instruction */
327 /* push it if not already pushed */
329 //pic14_emitcode ("push","%s",
330 // pic14_regWithIdx(R0_IDX)->dname);
334 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335 (*aopp)->type = AOP_R0;
337 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
340 /* if r1 not used then */
343 /* push it if not already pushed */
345 //pic14_emitcode ("push","%s",
346 // pic14_regWithIdx(R1_IDX)->dname);
350 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351 (*aopp)->type = AOP_R1;
352 return pic14_regWithIdx(R1_IDX);
356 /* I said end of world but not quite end of world yet */
357 /* if this is a result then we can push it on the stack*/
359 (*aopp)->type = AOP_STK;
363 /* other wise this is true end of the world */
364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365 "getFreePtr should never reach here");
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp */
371 /*-----------------------------------------------------------------*/
372 asmop *newAsmop (short type)
376 aop = Safe_calloc(1,sizeof(asmop));
381 static void genSetDPTR(int n)
385 pic14_emitcode(";", "Select standard DPTR");
386 pic14_emitcode("mov", "dps, #0x00");
390 pic14_emitcode(";", "Select alternate DPTR");
391 pic14_emitcode("mov", "dps, #0x01");
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for */
397 /* generating code */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
404 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
406 resIfx->condition = 1; /* assume that the ifx is true */
407 resIfx->generated = 0; /* indicate that the ifx has not been used */
410 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
412 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
413 __FUNCTION__,__LINE__,resIfx->lbl->key);
417 resIfx->lbl = IC_TRUE(ifx);
419 resIfx->lbl = IC_FALSE(ifx);
420 resIfx->condition = 0;
424 DEBUGpic14_emitcode("; ***","ifx true is non-null");
426 DEBUGpic14_emitcode("; ***","ifx false is non-null");
430 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
439 return PTR_TYPE(SPEC_OCLS(etype));
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
449 memmap *space= SPEC_OCLS(sym->etype);
451 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452 /* if already has one */
456 /* assign depending on the storage class */
457 /* if it is on the stack or indirectly addressable */
458 /* space we need to assign either r0 or r1 to it */
459 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
460 sym->aop = aop = newAsmop(0);
461 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
462 aop->size = getSize(sym->type);
464 /* now assign the address of the variable to
465 the pointer register */
466 if (aop->type != AOP_STK) {
470 pic14_emitcode("push","acc");
472 pic14_emitcode("mov","a,_bp");
473 pic14_emitcode("add","a,#0x%02x",
475 ((char)(sym->stack - _G.nRegsSaved )) :
476 ((char)sym->stack)) & 0xff);
477 pic14_emitcode("mov","%s,a",
478 aop->aopu.aop_ptr->name);
481 pic14_emitcode("pop","acc");
483 pic14_emitcode("mov","%s,#%s",
484 aop->aopu.aop_ptr->name,
486 aop->paged = space->paged;
488 aop->aopu.aop_stk = sym->stack;
492 if (sym->onStack && options.stack10bit)
494 /* It's on the 10 bit stack, which is located in
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
501 pic14_emitcode("push","acc");
503 pic14_emitcode("mov","a,_bp");
504 pic14_emitcode("add","a,#0x%02x",
506 ((char)(sym->stack - _G.nRegsSaved )) :
507 ((char)sym->stack)) & 0xff);
510 pic14_emitcode ("mov","dpx1,#0x40");
511 pic14_emitcode ("mov","dph1,#0x00");
512 pic14_emitcode ("mov","dpl1, a");
516 pic14_emitcode("pop","acc");
518 sym->aop = aop = newAsmop(AOP_DPTR2);
519 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d",__LINE__);
524 /* if in bit space */
525 if (IN_BITSPACE(space)) {
526 sym->aop = aop = newAsmop (AOP_CRY);
527 aop->aopu.aop_dir = sym->rname ;
528 aop->size = getSize(sym->type);
529 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
532 /* if it is in direct space */
533 if (IN_DIRSPACE(space)) {
534 sym->aop = aop = newAsmop (AOP_DIR);
535 aop->aopu.aop_dir = sym->rname ;
536 aop->size = getSize(sym->type);
537 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
541 /* special case for a function */
542 if (IS_FUNC(sym->type)) {
543 sym->aop = aop = newAsmop(AOP_IMMD);
544 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
545 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
546 strcpy(aop->aopu.aop_immd,sym->rname);
547 aop->size = FPTRSIZE;
548 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
553 /* only remaining is far space */
554 /* in which case DPTR gets the address */
555 sym->aop = aop = newAsmop(AOP_PCODE);
557 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
558 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
559 PCOI(aop->aopu.pcop)->index = 0;
561 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
562 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
564 allocDirReg (IC_LEFT(ic));
566 aop->size = FPTRSIZE;
568 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
569 sym->aop = aop = newAsmop(AOP_DPTR);
570 pic14_emitcode ("mov","dptr,#%s", sym->rname);
571 aop->size = getSize(sym->type);
573 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
576 /* if it is in code space */
577 if (IN_CODESPACE(space))
583 /*-----------------------------------------------------------------*/
584 /* aopForRemat - rematerialzes an object */
585 /*-----------------------------------------------------------------*/
586 static asmop *aopForRemat (operand *op) // x symbol *sym)
588 symbol *sym = OP_SYMBOL(op);
590 asmop *aop = newAsmop(AOP_PCODE);
594 ic = sym->rematiCode;
596 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
597 if(IS_OP_POINTER(op)) {
598 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
602 val += (int) operandLitValue(IC_RIGHT(ic));
603 } else if (ic->op == '-') {
604 val -= (int) operandLitValue(IC_RIGHT(ic));
608 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
611 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
612 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
613 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
614 PCOI(aop->aopu.pcop)->index = val;
616 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
617 OP_SYMBOL(IC_LEFT(ic))->rname,
618 val, IS_PTR_CONST(operandType(op)));
620 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
622 allocDirReg (IC_LEFT(ic));
627 int aopIdx (asmop *aop, int offset)
632 if(aop->type != AOP_REG)
635 return aop->aopu.aop_reg[offset]->rIdx;
638 /*-----------------------------------------------------------------*/
639 /* regsInCommon - two operands have some registers in common */
640 /*-----------------------------------------------------------------*/
641 static bool regsInCommon (operand *op1, operand *op2)
646 /* if they have registers in common */
647 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
650 sym1 = OP_SYMBOL(op1);
651 sym2 = OP_SYMBOL(op2);
653 if (sym1->nRegs == 0 || sym2->nRegs == 0)
656 for (i = 0 ; i < sym1->nRegs ; i++) {
661 for (j = 0 ; j < sym2->nRegs ;j++ ) {
665 if (sym2->regs[j] == sym1->regs[i])
673 /*-----------------------------------------------------------------*/
674 /* operandsEqu - equivalent */
675 /*-----------------------------------------------------------------*/
676 static bool operandsEqu ( operand *op1, operand *op2)
680 /* if they not symbols */
681 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
684 sym1 = OP_SYMBOL(op1);
685 sym2 = OP_SYMBOL(op2);
687 /* if both are itemps & one is spilt
688 and the other is not then false */
689 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
690 sym1->isspilt != sym2->isspilt )
693 /* if they are the same */
697 if (strcmp(sym1->rname,sym2->rname) == 0)
701 /* if left is a tmp & right is not */
705 (sym1->usl.spillLoc == sym2))
712 (sym2->usl.spillLoc == sym1))
718 /*-----------------------------------------------------------------*/
719 /* pic14_sameRegs - two asmops have the same registers */
720 /*-----------------------------------------------------------------*/
721 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
728 if (aop1->type != AOP_REG ||
729 aop2->type != AOP_REG )
732 if (aop1->size != aop2->size )
735 for (i = 0 ; i < aop1->size ; i++ )
736 if (aop1->aopu.aop_reg[i] !=
737 aop2->aopu.aop_reg[i] )
743 /*-----------------------------------------------------------------*/
744 /* aopOp - allocates an asmop for an operand : */
745 /*-----------------------------------------------------------------*/
746 void aopOp (operand *op, iCode *ic, bool result)
755 // DEBUGpic14_emitcode(";","%d",__LINE__);
756 /* if this a literal */
757 if (IS_OP_LITERAL(op)) {
758 op->aop = aop = newAsmop(AOP_LIT);
759 aop->aopu.aop_lit = op->operand.valOperand;
760 aop->size = getSize(operandType(op));
765 sym_link *type = operandType(op);
766 if(IS_PTR_CONST(type))
767 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
770 /* if already has a asmop then continue */
774 /* if the underlying symbol has a aop */
775 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
776 DEBUGpic14_emitcode(";","%d",__LINE__);
777 op->aop = OP_SYMBOL(op)->aop;
781 /* if this is a true symbol */
782 if (IS_TRUE_SYMOP(op)) {
783 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
784 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
788 /* this is a temporary : this has
794 e) can be a return use only */
799 /* if the type is a conditional */
800 if (sym->regType == REG_CND) {
801 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
806 /* if it is spilt then two situations
808 b) has a spill location */
809 if (sym->isspilt || sym->nRegs == 0) {
811 DEBUGpic14_emitcode(";","%d",__LINE__);
812 /* rematerialize it NOW */
815 sym->aop = op->aop = aop =
817 aop->size = getSize(sym->type);
818 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
824 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825 aop->size = getSize(sym->type);
826 for ( i = 0 ; i < 2 ; i++ )
827 aop->aopu.aop_str[i] = accUse[i];
828 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
834 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
835 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
836 //allocDirReg (IC_LEFT(ic));
837 aop->size = getSize(sym->type);
842 aop = op->aop = sym->aop = newAsmop(AOP_STR);
843 aop->size = getSize(sym->type);
844 for ( i = 0 ; i < fReturnSizePic ; i++ )
845 aop->aopu.aop_str[i] = fReturn[i];
847 DEBUGpic14_emitcode(";","%d",__LINE__);
851 /* else spill location */
852 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
853 /* force a new aop if sizes differ */
854 sym->usl.spillLoc->aop = NULL;
856 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
857 __FUNCTION__,__LINE__,
858 sym->usl.spillLoc->rname,
859 sym->rname, sym->usl.spillLoc->offset);
861 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
862 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
863 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
865 sym->usl.spillLoc->offset);
866 aop->size = getSize(sym->type);
872 sym_link *type = operandType(op);
873 if(IS_PTR_CONST(type))
874 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
877 /* must be in a register */
878 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
879 sym->aop = op->aop = aop = newAsmop(AOP_REG);
880 aop->size = sym->nRegs;
881 for ( i = 0 ; i < sym->nRegs ;i++)
882 aop->aopu.aop_reg[i] = sym->regs[i];
885 /*-----------------------------------------------------------------*/
886 /* freeAsmop - free up the asmop given to an operand */
887 /*----------------------------------------------------------------*/
888 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
905 /* depending on the asmop type only three cases need work AOP_RO
906 , AOP_R1 && AOP_STK */
912 pic14_emitcode ("pop","ar0");
916 bitVectUnSetBit(ic->rUsed,R0_IDX);
922 pic14_emitcode ("pop","ar1");
926 bitVectUnSetBit(ic->rUsed,R1_IDX);
932 int stk = aop->aopu.aop_stk + aop->size;
933 bitVectUnSetBit(ic->rUsed,R0_IDX);
934 bitVectUnSetBit(ic->rUsed,R1_IDX);
936 getFreePtr(ic,&aop,FALSE);
938 if (options.stack10bit)
940 /* I'm not sure what to do here yet... */
943 "*** Warning: probably generating bad code for "
944 "10 bit stack mode.\n");
948 pic14_emitcode ("mov","a,_bp");
949 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
950 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
952 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
956 pic14_emitcode("pop","acc");
957 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
959 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
962 freeAsmop(op,NULL,ic,TRUE);
964 pic14_emitcode("pop","ar0");
969 pic14_emitcode("pop","ar1");
977 /* all other cases just dealloc */
981 OP_SYMBOL(op)->aop = NULL;
982 /* if the symbol has a spill */
984 SPIL_LOC(op)->aop = NULL;
989 /*-----------------------------------------------------------------*/
990 /* aopGet - for fetching value of the aop */
991 /*-----------------------------------------------------------------*/
992 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
997 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
998 /* offset is greater than
1000 if (offset > (aop->size - 1) &&
1001 aop->type != AOP_LIT)
1004 /* depending on type */
1005 switch (aop->type) {
1009 DEBUGpic14_emitcode(";","%d",__LINE__);
1010 /* if we need to increment it */
1011 while (offset > aop->coff) {
1012 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1016 while (offset < aop->coff) {
1017 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1021 aop->coff = offset ;
1023 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1024 return (dname ? "acc" : "a");
1026 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1027 rs = Safe_calloc(1,strlen(s)+1);
1033 DEBUGpic14_emitcode(";","%d",__LINE__);
1034 if (aop->type == AOP_DPTR2)
1039 while (offset > aop->coff) {
1040 pic14_emitcode ("inc","dptr");
1044 while (offset < aop->coff) {
1045 pic14_emitcode("lcall","__decdptr");
1051 pic14_emitcode("clr","a");
1052 pic14_emitcode("movc","a,@a+dptr");
1055 pic14_emitcode("movx","a,@dptr");
1058 if (aop->type == AOP_DPTR2)
1063 return (dname ? "acc" : "a");
1068 sprintf (s,"%s",aop->aopu.aop_immd);
1071 sprintf(s,"(%s >> %d)",
1076 aop->aopu.aop_immd);
1077 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1078 rs = Safe_calloc(1,strlen(s)+1);
1084 sprintf(s,"(%s + %d)",
1087 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1089 sprintf(s,"%s",aop->aopu.aop_dir);
1090 rs = Safe_calloc(1,strlen(s)+1);
1096 // return aop->aopu.aop_reg[offset]->dname;
1098 return aop->aopu.aop_reg[offset]->name;
1101 //pic14_emitcode(";","%d",__LINE__);
1102 return aop->aopu.aop_dir;
1105 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1106 return "AOP_accumulator_bug";
1109 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1110 rs = Safe_calloc(1,strlen(s)+1);
1115 DEBUGpic14_emitcode(";","%d",__LINE__);
1116 aop->coff = offset ;
1117 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1121 return aop->aopu.aop_str[offset];
1125 pCodeOp *pcop = aop->aopu.pcop;
1126 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1128 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1129 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1130 sprintf(s,"%s", pcop->name);
1132 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1135 rs = Safe_calloc(1,strlen(s)+1);
1141 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1142 "aopget got unsupported aop->type");
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp */
1149 /*-----------------------------------------------------------------*/
1150 pCodeOp *popGetTempReg(void)
1155 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1156 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1157 PCOR(pcop)->r->wasUsed=1;
1158 PCOR(pcop)->r->isFree=0;
1164 /*-----------------------------------------------------------------*/
1165 /* popGetTempReg - create a new temporary pCodeOp */
1166 /*-----------------------------------------------------------------*/
1167 void popReleaseTempReg(pCodeOp *pcop)
1170 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1171 PCOR(pcop)->r->isFree = 1;
1174 /*-----------------------------------------------------------------*/
1175 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1176 /*-----------------------------------------------------------------*/
1177 pCodeOp *popGetLabel(unsigned int key)
1180 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1185 return newpCodeOpLabel(NULL,key+100+labelOffset);
1188 /*-----------------------------------------------------------------*/
1189 /* popCopyReg - copy a pcode operator */
1190 /*-----------------------------------------------------------------*/
1191 pCodeOp *popCopyReg(pCodeOpReg *pc)
1195 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1196 pcor->pcop.type = pc->pcop.type;
1198 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1199 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1201 pcor->pcop.name = NULL;
1204 pcor->rIdx = pc->rIdx;
1207 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetLit(unsigned int lit)
1217 return newpCodeOpLit(lit);
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1227 return newpCodeOpImmd(name, offset,index, 0);
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str)
1240 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1244 pcop = newpCodeOp(str,PO_STR);
1249 /*-----------------------------------------------------------------*/
1250 /* popRegFromString - */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popRegFromString(char *str, int size, int offset)
1255 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1256 pcop->type = PO_DIR;
1258 DEBUGpic14_emitcode(";","%d",__LINE__);
1263 pcop->name = Safe_calloc(1,strlen(str)+1);
1264 strcpy(pcop->name,str);
1266 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1268 PCOR(pcop)->r = dirregWithName(pcop->name);
1269 if(PCOR(pcop)->r == NULL) {
1270 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1271 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1272 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1274 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1276 PCOR(pcop)->instance = offset;
1281 pCodeOp *popRegFromIdx(int rIdx)
1285 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1286 __FUNCTION__,__LINE__,rIdx);
1288 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1290 PCOR(pcop)->rIdx = rIdx;
1291 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1292 PCOR(pcop)->r->isFree = 0;
1293 PCOR(pcop)->r->wasUsed = 1;
1295 pcop->type = PCOR(pcop)->r->pc_type;
1300 /*-----------------------------------------------------------------*/
1301 /* popGet - asm operator to pcode operator conversion */
1302 /*-----------------------------------------------------------------*/
1303 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1305 //char *s = buffer ;
1310 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1311 /* offset is greater than
1314 if (offset > (aop->size - 1) &&
1315 aop->type != AOP_LIT)
1316 return NULL; //zero;
1318 /* depending on type */
1319 switch (aop->type) {
1326 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1330 DEBUGpic14_emitcode(";","%d",__LINE__);
1331 return popGetImmd(aop->aopu.aop_immd,offset,0);
1334 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1336 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1337 pcop->type = PO_DIR;
1341 sprintf(s,"(%s + %d)",
1345 sprintf(s,"%s",aop->aopu.aop_dir);
1346 pcop->name = Safe_calloc(1,strlen(s)+1);
1347 strcpy(pcop->name,s);
1349 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1350 strcpy(pcop->name,aop->aopu.aop_dir);
1351 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1352 if(PCOR(pcop)->r == NULL) {
1353 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1354 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1355 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1357 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1359 PCOR(pcop)->instance = offset;
1366 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1368 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1369 PCOR(pcop)->rIdx = rIdx;
1370 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1371 PCOR(pcop)->r->wasUsed=1;
1372 PCOR(pcop)->r->isFree=0;
1374 PCOR(pcop)->instance = offset;
1375 pcop->type = PCOR(pcop)->r->pc_type;
1376 //rs = aop->aopu.aop_reg[offset]->name;
1377 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1382 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1383 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1384 //if(PCOR(pcop)->r == NULL)
1385 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1389 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1392 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1393 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1395 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1396 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1397 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1398 pcop->type = PCOR(pcop)->r->pc_type;
1399 pcop->name = PCOR(pcop)->r->name;
1405 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1407 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1408 pcop = pCodeOpCopy(aop->aopu.pcop);
1409 PCOI(pcop)->offset = offset;
1413 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1414 "popGet got unsupported aop->type");
1417 /*-----------------------------------------------------------------*/
1418 /* aopPut - puts a string for a aop */
1419 /*-----------------------------------------------------------------*/
1420 void aopPut (asmop *aop, char *s, int offset)
1425 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1427 if (aop->size && offset > ( aop->size - 1)) {
1428 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1429 "aopPut got offset > aop->size");
1433 /* will assign value to value */
1434 /* depending on where it is ofcourse */
1435 switch (aop->type) {
1438 sprintf(d,"(%s + %d)",
1439 aop->aopu.aop_dir,offset);
1440 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1443 sprintf(d,"%s",aop->aopu.aop_dir);
1446 DEBUGpic14_emitcode(";","%d",__LINE__);
1448 pic14_emitcode("movf","%s,w",s);
1449 pic14_emitcode("movwf","%s",d);
1452 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1453 if(offset >= aop->size) {
1454 emitpcode(POC_CLRF,popGet(aop,offset));
1457 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1460 emitpcode(POC_MOVWF,popGet(aop,offset));
1467 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1468 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1471 strcmp(s,"r0") == 0 ||
1472 strcmp(s,"r1") == 0 ||
1473 strcmp(s,"r2") == 0 ||
1474 strcmp(s,"r3") == 0 ||
1475 strcmp(s,"r4") == 0 ||
1476 strcmp(s,"r5") == 0 ||
1477 strcmp(s,"r6") == 0 ||
1478 strcmp(s,"r7") == 0 )
1479 pic14_emitcode("mov","%s,%s ; %d",
1480 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1484 if(strcmp(s,"W")==0 )
1485 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1487 pic14_emitcode("movwf","%s",
1488 aop->aopu.aop_reg[offset]->name);
1490 if(strcmp(s,zero)==0) {
1491 emitpcode(POC_CLRF,popGet(aop,offset));
1493 } else if(strcmp(s,"W")==0) {
1494 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1495 pcop->type = PO_GPR_REGISTER;
1497 PCOR(pcop)->rIdx = -1;
1498 PCOR(pcop)->r = NULL;
1500 DEBUGpic14_emitcode(";","%d",__LINE__);
1501 pcop->name = Safe_strdup(s);
1502 emitpcode(POC_MOVFW,pcop);
1503 emitpcode(POC_MOVWF,popGet(aop,offset));
1504 } else if(strcmp(s,one)==0) {
1505 emitpcode(POC_CLRF,popGet(aop,offset));
1506 emitpcode(POC_INCF,popGet(aop,offset));
1508 emitpcode(POC_MOVWF,popGet(aop,offset));
1516 if (aop->type == AOP_DPTR2)
1522 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1523 "aopPut writting to code space");
1527 while (offset > aop->coff) {
1529 pic14_emitcode ("inc","dptr");
1532 while (offset < aop->coff) {
1534 pic14_emitcode("lcall","__decdptr");
1539 /* if not in accumulater */
1542 pic14_emitcode ("movx","@dptr,a");
1544 if (aop->type == AOP_DPTR2)
1552 while (offset > aop->coff) {
1554 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1556 while (offset < aop->coff) {
1558 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1564 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1569 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1571 if (strcmp(s,"r0") == 0 ||
1572 strcmp(s,"r1") == 0 ||
1573 strcmp(s,"r2") == 0 ||
1574 strcmp(s,"r3") == 0 ||
1575 strcmp(s,"r4") == 0 ||
1576 strcmp(s,"r5") == 0 ||
1577 strcmp(s,"r6") == 0 ||
1578 strcmp(s,"r7") == 0 ) {
1580 sprintf(buffer,"a%s",s);
1581 pic14_emitcode("mov","@%s,%s",
1582 aop->aopu.aop_ptr->name,buffer);
1584 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1589 if (strcmp(s,"a") == 0)
1590 pic14_emitcode("push","acc");
1592 pic14_emitcode("push","%s",s);
1597 /* if bit variable */
1598 if (!aop->aopu.aop_dir) {
1599 pic14_emitcode("clr","a");
1600 pic14_emitcode("rlc","a");
1603 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1606 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1609 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1611 lbl = newiTempLabel(NULL);
1613 if (strcmp(s,"a")) {
1616 pic14_emitcode("clr","c");
1617 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1618 pic14_emitcode("cpl","c");
1619 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1620 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1627 if (strcmp(aop->aopu.aop_str[offset],s))
1628 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1633 if (!offset && (strcmp(s,"acc") == 0))
1636 if (strcmp(aop->aopu.aop_str[offset],s))
1637 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1641 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1642 "aopPut got unsupported aop->type");
1648 /*-----------------------------------------------------------------*/
1649 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1650 /*-----------------------------------------------------------------*/
1651 void mov2w (asmop *aop, int offset)
1657 if ( aop->type == AOP_PCODE ||
1658 aop->type == AOP_LIT )
1659 emitpcode(POC_MOVLW,popGet(aop,offset));
1661 emitpcode(POC_MOVFW,popGet(aop,offset));
1665 /*-----------------------------------------------------------------*/
1666 /* reAdjustPreg - points a register back to where it should */
1667 /*-----------------------------------------------------------------*/
1668 static void reAdjustPreg (asmop *aop)
1672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1674 if ((size = aop->size) <= 1)
1677 switch (aop->type) {
1681 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1685 if (aop->type == AOP_DPTR2)
1691 pic14_emitcode("lcall","__decdptr");
1694 if (aop->type == AOP_DPTR2)
1704 /*-----------------------------------------------------------------*/
1705 /* genNotFloat - generates not for float operations */
1706 /*-----------------------------------------------------------------*/
1707 static void genNotFloat (operand *op, operand *res)
1713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1714 /* we will put 127 in the first byte of
1716 aopPut(AOP(res),"#127",0);
1717 size = AOP_SIZE(op) - 1;
1720 l = aopGet(op->aop,offset++,FALSE,FALSE);
1724 pic14_emitcode("orl","a,%s",
1726 offset++,FALSE,FALSE));
1728 tlbl = newiTempLabel(NULL);
1730 tlbl = newiTempLabel(NULL);
1731 aopPut(res->aop,one,1);
1732 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1733 aopPut(res->aop,zero,1);
1734 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1736 size = res->aop->size - 2;
1738 /* put zeros in the rest */
1740 aopPut(res->aop,zero,offset++);
1744 /*-----------------------------------------------------------------*/
1745 /* opIsGptr: returns non-zero if the passed operand is */
1746 /* a generic pointer type. */
1747 /*-----------------------------------------------------------------*/
1748 static int opIsGptr(operand *op)
1750 sym_link *type = operandType(op);
1752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1753 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1761 /*-----------------------------------------------------------------*/
1762 /* pic14_getDataSize - get the operand data size */
1763 /*-----------------------------------------------------------------*/
1764 int pic14_getDataSize(operand *op)
1766 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1769 return AOP_SIZE(op);
1771 // tsd- in the pic port, the genptr size is 1, so this code here
1772 // fails. ( in the 8051 port, the size was 4).
1775 size = AOP_SIZE(op);
1776 if (size == GPTRSIZE)
1778 sym_link *type = operandType(op);
1779 if (IS_GENPTR(type))
1781 /* generic pointer; arithmetic operations
1782 * should ignore the high byte (pointer type).
1785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_outAcc - output Acc */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_outAcc(operand *result)
1798 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1799 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1802 size = pic14_getDataSize(result);
1804 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1807 /* unsigned or positive */
1809 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1814 /*-----------------------------------------------------------------*/
1815 /* pic14_outBitC - output a bit C */
1816 /*-----------------------------------------------------------------*/
1817 void pic14_outBitC(operand *result)
1820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1821 /* if the result is bit */
1822 if (AOP_TYPE(result) == AOP_CRY)
1823 aopPut(AOP(result),"c",0);
1825 pic14_emitcode("clr","a ; %d", __LINE__);
1826 pic14_emitcode("rlc","a");
1827 pic14_outAcc(result);
1831 /*-----------------------------------------------------------------*/
1832 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1833 /*-----------------------------------------------------------------*/
1834 void pic14_toBoolean(operand *oper)
1836 int size = AOP_SIZE(oper) - 1;
1839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1841 if ( AOP_TYPE(oper) != AOP_ACC) {
1842 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1845 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1850 /*-----------------------------------------------------------------*/
1851 /* genNot - generate code for ! operation */
1852 /*-----------------------------------------------------------------*/
1853 static void genNot (iCode *ic)
1856 sym_link *optype = operandType(IC_LEFT(ic));
1859 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1860 /* assign asmOps to operand & result */
1861 aopOp (IC_LEFT(ic),ic,FALSE);
1862 aopOp (IC_RESULT(ic),ic,TRUE);
1864 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1865 /* if in bit space then a special case */
1866 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1867 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1868 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1869 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1871 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1872 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1873 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1878 /* if type float then do float */
1879 if (IS_FLOAT(optype)) {
1880 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1884 size = AOP_SIZE(IC_RESULT(ic));
1886 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1887 emitpcode(POC_ANDLW,popGetLit(1));
1888 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1891 pic14_toBoolean(IC_LEFT(ic));
1893 tlbl = newiTempLabel(NULL);
1894 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1895 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1896 pic14_outBitC(IC_RESULT(ic));
1899 /* release the aops */
1900 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1901 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1905 /*-----------------------------------------------------------------*/
1906 /* genCpl - generate code for complement */
1907 /*-----------------------------------------------------------------*/
1908 static void genCpl (iCode *ic)
1914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1915 /* assign asmOps to operand & result */
1916 aopOp (IC_LEFT(ic),ic,FALSE);
1917 aopOp (IC_RESULT(ic),ic,TRUE);
1919 /* if both are in bit space then
1921 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1922 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1924 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1925 pic14_emitcode("cpl","c");
1926 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1930 size = AOP_SIZE(IC_RESULT(ic));
1932 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1934 pic14_emitcode("cpl","a");
1935 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1940 /* release the aops */
1941 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1942 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1945 /*-----------------------------------------------------------------*/
1946 /* genUminusFloat - unary minus for floating points */
1947 /*-----------------------------------------------------------------*/
1948 static void genUminusFloat(operand *op,operand *result)
1950 int size ,offset =0 ;
1953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1954 /* for this we just need to flip the
1955 first it then copy the rest in place */
1956 size = AOP_SIZE(op) - 1;
1957 l = aopGet(AOP(op),3,FALSE,FALSE);
1961 pic14_emitcode("cpl","acc.7");
1962 aopPut(AOP(result),"a",3);
1966 aopGet(AOP(op),offset,FALSE,FALSE),
1972 /*-----------------------------------------------------------------*/
1973 /* genUminus - unary minus code generation */
1974 /*-----------------------------------------------------------------*/
1975 static void genUminus (iCode *ic)
1978 sym_link *optype, *rtype;
1981 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1983 aopOp(IC_LEFT(ic),ic,FALSE);
1984 aopOp(IC_RESULT(ic),ic,TRUE);
1986 /* if both in bit space then special
1988 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1989 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1991 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1992 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1993 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1998 optype = operandType(IC_LEFT(ic));
1999 rtype = operandType(IC_RESULT(ic));
2001 /* if float then do float stuff */
2002 if (IS_FLOAT(optype)) {
2003 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2007 /* otherwise subtract from zero by taking the 2's complement */
2008 size = AOP_SIZE(IC_LEFT(ic));
2010 for(i=0; i<size; i++) {
2011 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2012 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2014 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2015 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2019 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2020 for(i=1; i<size; i++) {
2022 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2026 /* release the aops */
2027 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2028 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2031 /*-----------------------------------------------------------------*/
2032 /* saveRegisters - will look for a call and save the registers */
2033 /*-----------------------------------------------------------------*/
2034 static void saveRegisters(iCode *lic)
2041 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2043 for (ic = lic ; ic ; ic = ic->next)
2044 if (ic->op == CALL || ic->op == PCALL)
2048 fprintf(stderr,"found parameter push with no function call\n");
2052 /* if the registers have been saved already then
2054 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2057 /* find the registers in use at this time
2058 and push them away to safety */
2059 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2063 if (options.useXstack) {
2064 if (bitVectBitValue(rsave,R0_IDX))
2065 pic14_emitcode("mov","b,r0");
2066 pic14_emitcode("mov","r0,%s",spname);
2067 for (i = 0 ; i < pic14_nRegs ; i++) {
2068 if (bitVectBitValue(rsave,i)) {
2070 pic14_emitcode("mov","a,b");
2072 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2073 pic14_emitcode("movx","@r0,a");
2074 pic14_emitcode("inc","r0");
2077 pic14_emitcode("mov","%s,r0",spname);
2078 if (bitVectBitValue(rsave,R0_IDX))
2079 pic14_emitcode("mov","r0,b");
2081 //for (i = 0 ; i < pic14_nRegs ; i++) {
2082 // if (bitVectBitValue(rsave,i))
2083 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2086 dtype = operandType(IC_LEFT(ic));
2087 if (currFunc && dtype &&
2088 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2089 IFFUNC_ISISR(currFunc->type) &&
2092 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2095 /*-----------------------------------------------------------------*/
2096 /* unsaveRegisters - pop the pushed registers */
2097 /*-----------------------------------------------------------------*/
2098 static void unsaveRegisters (iCode *ic)
2103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2104 /* find the registers in use at this time
2105 and push them away to safety */
2106 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2109 if (options.useXstack) {
2110 pic14_emitcode("mov","r0,%s",spname);
2111 for (i = pic14_nRegs ; i >= 0 ; i--) {
2112 if (bitVectBitValue(rsave,i)) {
2113 pic14_emitcode("dec","r0");
2114 pic14_emitcode("movx","a,@r0");
2116 pic14_emitcode("mov","b,a");
2118 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2122 pic14_emitcode("mov","%s,r0",spname);
2123 if (bitVectBitValue(rsave,R0_IDX))
2124 pic14_emitcode("mov","r0,b");
2126 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2127 // if (bitVectBitValue(rsave,i))
2128 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2134 /*-----------------------------------------------------------------*/
2136 /*-----------------------------------------------------------------*/
2137 static void pushSide(operand * oper, int size)
2141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2143 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2144 if (AOP_TYPE(oper) != AOP_REG &&
2145 AOP_TYPE(oper) != AOP_DIR &&
2147 pic14_emitcode("mov","a,%s",l);
2148 pic14_emitcode("push","acc");
2150 pic14_emitcode("push","%s",l);
2155 /*-----------------------------------------------------------------*/
2156 /* assignResultValue - */
2157 /*-----------------------------------------------------------------*/
2158 static void assignResultValue(operand * oper)
2160 int size = AOP_SIZE(oper);
2162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2164 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2166 if(!GpsuedoStkPtr) {
2167 /* The last byte in the assignment is in W */
2169 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2174 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2176 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2181 /*-----------------------------------------------------------------*/
2182 /* genIpush - genrate code for pushing this gets a little complex */
2183 /*-----------------------------------------------------------------*/
2184 static void genIpush (iCode *ic)
2187 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2189 int size, offset = 0 ;
2193 /* if this is not a parm push : ie. it is spill push
2194 and spill push is always done on the local stack */
2195 if (!ic->parmPush) {
2197 /* and the item is spilt then do nothing */
2198 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2201 aopOp(IC_LEFT(ic),ic,FALSE);
2202 size = AOP_SIZE(IC_LEFT(ic));
2203 /* push it on the stack */
2205 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2210 pic14_emitcode("push","%s",l);
2215 /* this is a paramter push: in this case we call
2216 the routine to find the call and save those
2217 registers that need to be saved */
2220 /* then do the push */
2221 aopOp(IC_LEFT(ic),ic,FALSE);
2224 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2225 size = AOP_SIZE(IC_LEFT(ic));
2228 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2229 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2230 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2232 pic14_emitcode("mov","a,%s",l);
2233 pic14_emitcode("push","acc");
2235 pic14_emitcode("push","%s",l);
2238 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2242 /*-----------------------------------------------------------------*/
2243 /* genIpop - recover the registers: can happen only for spilling */
2244 /*-----------------------------------------------------------------*/
2245 static void genIpop (iCode *ic)
2247 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2252 /* if the temp was not pushed then */
2253 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2256 aopOp(IC_LEFT(ic),ic,FALSE);
2257 size = AOP_SIZE(IC_LEFT(ic));
2260 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2263 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2267 /*-----------------------------------------------------------------*/
2268 /* unsaverbank - restores the resgister bank from stack */
2269 /*-----------------------------------------------------------------*/
2270 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2272 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2280 if (options.useXstack) {
2282 r = getFreePtr(ic,&aop,FALSE);
2285 pic14_emitcode("mov","%s,_spx",r->name);
2286 pic14_emitcode("movx","a,@%s",r->name);
2287 pic14_emitcode("mov","psw,a");
2288 pic14_emitcode("dec","%s",r->name);
2291 pic14_emitcode ("pop","psw");
2294 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2295 if (options.useXstack) {
2296 pic14_emitcode("movx","a,@%s",r->name);
2297 //pic14_emitcode("mov","(%s+%d),a",
2298 // regspic14[i].base,8*bank+regspic14[i].offset);
2299 pic14_emitcode("dec","%s",r->name);
2302 pic14_emitcode("pop",""); //"(%s+%d)",
2303 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2306 if (options.useXstack) {
2308 pic14_emitcode("mov","_spx,%s",r->name);
2309 freeAsmop(NULL,aop,ic,TRUE);
2315 /*-----------------------------------------------------------------*/
2316 /* saverbank - saves an entire register bank on the stack */
2317 /*-----------------------------------------------------------------*/
2318 static void saverbank (int bank, iCode *ic, bool pushPsw)
2320 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2326 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2327 if (options.useXstack) {
2330 r = getFreePtr(ic,&aop,FALSE);
2331 pic14_emitcode("mov","%s,_spx",r->name);
2335 for (i = 0 ; i < pic14_nRegs ;i++) {
2336 if (options.useXstack) {
2337 pic14_emitcode("inc","%s",r->name);
2338 //pic14_emitcode("mov","a,(%s+%d)",
2339 // regspic14[i].base,8*bank+regspic14[i].offset);
2340 pic14_emitcode("movx","@%s,a",r->name);
2342 pic14_emitcode("push","");// "(%s+%d)",
2343 //regspic14[i].base,8*bank+regspic14[i].offset);
2347 if (options.useXstack) {
2348 pic14_emitcode("mov","a,psw");
2349 pic14_emitcode("movx","@%s,a",r->name);
2350 pic14_emitcode("inc","%s",r->name);
2351 pic14_emitcode("mov","_spx,%s",r->name);
2352 freeAsmop (NULL,aop,ic,TRUE);
2355 pic14_emitcode("push","psw");
2357 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2363 /*-----------------------------------------------------------------*/
2364 /* genCall - generates a call statement */
2365 /*-----------------------------------------------------------------*/
2366 static void genCall (iCode *ic)
2370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2372 /* if caller saves & we have not saved then */
2376 /* if we are calling a function that is not using
2377 the same register bank then we need to save the
2378 destination registers on the stack */
2379 dtype = operandType(IC_LEFT(ic));
2380 if (currFunc && dtype &&
2381 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2382 IFFUNC_ISISR(currFunc->type) &&
2385 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2387 /* if send set is not empty the assign */
2390 /* For the Pic port, there is no data stack.
2391 * So parameters passed to functions are stored
2392 * in registers. (The pCode optimizer will get
2393 * rid of most of these :).
2395 int psuedoStkPtr=-1;
2396 int firstTimeThruLoop = 1;
2398 _G.sendSet = reverseSet(_G.sendSet);
2400 /* First figure how many parameters are getting passed */
2401 for (sic = setFirstItem(_G.sendSet) ; sic ;
2402 sic = setNextItem(_G.sendSet)) {
2404 aopOp(IC_LEFT(sic),sic,FALSE);
2405 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2406 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2409 for (sic = setFirstItem(_G.sendSet) ; sic ;
2410 sic = setNextItem(_G.sendSet)) {
2411 int size, offset = 0;
2413 aopOp(IC_LEFT(sic),sic,FALSE);
2414 size = AOP_SIZE(IC_LEFT(sic));
2417 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2418 AopType(AOP_TYPE(IC_LEFT(sic))));
2420 if(!firstTimeThruLoop) {
2421 /* If this is not the first time we've been through the loop
2422 * then we need to save the parameter in a temporary
2423 * register. The last byte of the last parameter is
2425 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2428 firstTimeThruLoop=0;
2430 //if (strcmp(l,fReturn[offset])) {
2431 mov2w (AOP(IC_LEFT(sic)), offset);
2433 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2434 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2435 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2437 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2442 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2447 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2448 OP_SYMBOL(IC_LEFT(ic))->rname :
2449 OP_SYMBOL(IC_LEFT(ic))->name));
2452 /* if we need assign a result value */
2453 if ((IS_ITEMP(IC_RESULT(ic)) &&
2454 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2455 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2456 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2459 aopOp(IC_RESULT(ic),ic,FALSE);
2462 assignResultValue(IC_RESULT(ic));
2464 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2465 AopType(AOP_TYPE(IC_RESULT(ic))));
2467 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2470 /* adjust the stack for parameters if
2472 if (ic->parmBytes) {
2474 if (ic->parmBytes > 3) {
2475 pic14_emitcode("mov","a,%s",spname);
2476 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2477 pic14_emitcode("mov","%s,a",spname);
2479 for ( i = 0 ; i < ic->parmBytes ;i++)
2480 pic14_emitcode("dec","%s",spname);
2484 /* if register bank was saved then pop them */
2486 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2488 /* if we hade saved some registers then unsave them */
2489 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2490 unsaveRegisters (ic);
2495 /*-----------------------------------------------------------------*/
2496 /* genPcall - generates a call by pointer statement */
2497 /*-----------------------------------------------------------------*/
2498 static void genPcall (iCode *ic)
2501 symbol *rlbl = newiTempLabel(NULL);
2504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2505 /* if caller saves & we have not saved then */
2509 /* if we are calling a function that is not using
2510 the same register bank then we need to save the
2511 destination registers on the stack */
2512 dtype = operandType(IC_LEFT(ic));
2513 if (currFunc && dtype &&
2514 IFFUNC_ISISR(currFunc->type) &&
2515 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2516 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2519 /* push the return address on to the stack */
2520 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2521 pic14_emitcode("push","acc");
2522 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2523 pic14_emitcode("push","acc");
2525 if (options.model == MODEL_FLAT24)
2527 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2528 pic14_emitcode("push","acc");
2531 /* now push the calling address */
2532 aopOp(IC_LEFT(ic),ic,FALSE);
2534 pushSide(IC_LEFT(ic), FPTRSIZE);
2536 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2538 /* if send set is not empty the assign */
2542 for (sic = setFirstItem(_G.sendSet) ; sic ;
2543 sic = setNextItem(_G.sendSet)) {
2544 int size, offset = 0;
2545 aopOp(IC_LEFT(sic),sic,FALSE);
2546 size = AOP_SIZE(IC_LEFT(sic));
2548 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2550 if (strcmp(l,fReturn[offset]))
2551 pic14_emitcode("mov","%s,%s",
2556 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2561 pic14_emitcode("ret","");
2562 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2565 /* if we need assign a result value */
2566 if ((IS_ITEMP(IC_RESULT(ic)) &&
2567 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2568 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2569 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2572 aopOp(IC_RESULT(ic),ic,FALSE);
2575 assignResultValue(IC_RESULT(ic));
2577 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2580 /* adjust the stack for parameters if
2582 if (ic->parmBytes) {
2584 if (ic->parmBytes > 3) {
2585 pic14_emitcode("mov","a,%s",spname);
2586 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2587 pic14_emitcode("mov","%s,a",spname);
2589 for ( i = 0 ; i < ic->parmBytes ;i++)
2590 pic14_emitcode("dec","%s",spname);
2594 /* if register bank was saved then unsave them */
2595 if (currFunc && dtype &&
2596 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2597 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2599 /* if we hade saved some registers then
2602 unsaveRegisters (ic);
2606 /*-----------------------------------------------------------------*/
2607 /* resultRemat - result is rematerializable */
2608 /*-----------------------------------------------------------------*/
2609 static int resultRemat (iCode *ic)
2611 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2612 if (SKIP_IC(ic) || ic->op == IFX)
2615 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2616 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2617 if (sym->remat && !POINTER_SET(ic))
2624 #if defined(__BORLANDC__) || defined(_MSC_VER)
2625 #define STRCASECMP stricmp
2627 #define STRCASECMP strcasecmp
2631 /*-----------------------------------------------------------------*/
2632 /* inExcludeList - return 1 if the string is in exclude Reg list */
2633 /*-----------------------------------------------------------------*/
2634 static bool inExcludeList(char *s)
2636 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2640 if (options.excludeRegs[i] &&
2641 STRCASECMP(options.excludeRegs[i],"none") == 0)
2644 for ( i = 0 ; options.excludeRegs[i]; i++) {
2645 if (options.excludeRegs[i] &&
2646 STRCASECMP(s,options.excludeRegs[i]) == 0)
2653 /*-----------------------------------------------------------------*/
2654 /* genFunction - generated code for function entry */
2655 /*-----------------------------------------------------------------*/
2656 static void genFunction (iCode *ic)
2661 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2663 labelOffset += (max_key+4);
2667 /* create the function header */
2668 pic14_emitcode(";","-----------------------------------------");
2669 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2670 pic14_emitcode(";","-----------------------------------------");
2672 pic14_emitcode("","%s:",sym->rname);
2673 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2675 ftype = operandType(IC_LEFT(ic));
2677 /* if critical function then turn interrupts off */
2678 if (IFFUNC_ISCRITICAL(ftype))
2679 pic14_emitcode("clr","ea");
2681 /* here we need to generate the equates for the
2682 register bank if required */
2684 if (FUNC_REGBANK(ftype) != rbank) {
2687 rbank = FUNC_REGBANK(ftype);
2688 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2689 if (strcmp(regspic14[i].base,"0") == 0)
2690 pic14_emitcode("","%s = 0x%02x",
2692 8*rbank+regspic14[i].offset);
2694 pic14_emitcode ("","%s = %s + 0x%02x",
2697 8*rbank+regspic14[i].offset);
2702 /* if this is an interrupt service routine then
2703 save acc, b, dpl, dph */
2704 if (IFFUNC_ISISR(sym->type)) {
2705 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2706 emitpcodeNULLop(POC_NOP);
2707 emitpcodeNULLop(POC_NOP);
2708 emitpcodeNULLop(POC_NOP);
2709 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2710 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2711 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2712 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2714 pBlockConvert2ISR(pb);
2716 if (!inExcludeList("acc"))
2717 pic14_emitcode ("push","acc");
2718 if (!inExcludeList("b"))
2719 pic14_emitcode ("push","b");
2720 if (!inExcludeList("dpl"))
2721 pic14_emitcode ("push","dpl");
2722 if (!inExcludeList("dph"))
2723 pic14_emitcode ("push","dph");
2724 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2726 pic14_emitcode ("push", "dpx");
2727 /* Make sure we're using standard DPTR */
2728 pic14_emitcode ("push", "dps");
2729 pic14_emitcode ("mov", "dps, #0x00");
2730 if (options.stack10bit)
2732 /* This ISR could conceivably use DPTR2. Better save it. */
2733 pic14_emitcode ("push", "dpl1");
2734 pic14_emitcode ("push", "dph1");
2735 pic14_emitcode ("push", "dpx1");
2738 /* if this isr has no bank i.e. is going to
2739 run with bank 0 , then we need to save more
2741 if (!FUNC_REGBANK(sym->type)) {
2743 /* if this function does not call any other
2744 function then we can be economical and
2745 save only those registers that are used */
2746 if (! IFFUNC_HASFCALL(sym->type)) {
2749 /* if any registers used */
2750 if (sym->regsUsed) {
2751 /* save the registers used */
2752 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2753 if (bitVectBitValue(sym->regsUsed,i) ||
2754 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2755 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2760 /* this function has a function call cannot
2761 determines register usage so we will have the
2763 saverbank(0,ic,FALSE);
2768 /* if callee-save to be used for this function
2769 then save the registers being used in this function */
2770 if (IFFUNC_CALLEESAVES(sym->type)) {
2773 /* if any registers used */
2774 if (sym->regsUsed) {
2775 /* save the registers used */
2776 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2777 if (bitVectBitValue(sym->regsUsed,i) ||
2778 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2779 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2787 /* set the register bank to the desired value */
2788 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2789 pic14_emitcode("push","psw");
2790 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2793 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2795 if (options.useXstack) {
2796 pic14_emitcode("mov","r0,%s",spname);
2797 pic14_emitcode("mov","a,_bp");
2798 pic14_emitcode("movx","@r0,a");
2799 pic14_emitcode("inc","%s",spname);
2803 /* set up the stack */
2804 pic14_emitcode ("push","_bp"); /* save the callers stack */
2806 pic14_emitcode ("mov","_bp,%s",spname);
2809 /* adjust the stack for the function */
2814 werror(W_STACK_OVERFLOW,sym->name);
2816 if (i > 3 && sym->recvSize < 4) {
2818 pic14_emitcode ("mov","a,sp");
2819 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2820 pic14_emitcode ("mov","sp,a");
2825 pic14_emitcode("inc","sp");
2830 pic14_emitcode ("mov","a,_spx");
2831 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2832 pic14_emitcode ("mov","_spx,a");
2837 /*-----------------------------------------------------------------*/
2838 /* genEndFunction - generates epilogue for functions */
2839 /*-----------------------------------------------------------------*/
2840 static void genEndFunction (iCode *ic)
2842 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2846 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2848 pic14_emitcode ("mov","%s,_bp",spname);
2851 /* if use external stack but some variables were
2852 added to the local stack then decrement the
2854 if (options.useXstack && sym->stack) {
2855 pic14_emitcode("mov","a,sp");
2856 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2857 pic14_emitcode("mov","sp,a");
2861 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2862 if (options.useXstack) {
2863 pic14_emitcode("mov","r0,%s",spname);
2864 pic14_emitcode("movx","a,@r0");
2865 pic14_emitcode("mov","_bp,a");
2866 pic14_emitcode("dec","%s",spname);
2870 pic14_emitcode ("pop","_bp");
2874 /* restore the register bank */
2875 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2876 pic14_emitcode ("pop","psw");
2878 if (IFFUNC_ISISR(sym->type)) {
2880 /* now we need to restore the registers */
2881 /* if this isr has no bank i.e. is going to
2882 run with bank 0 , then we need to save more
2884 if (!FUNC_REGBANK(sym->type)) {
2886 /* if this function does not call any other
2887 function then we can be economical and
2888 save only those registers that are used */
2889 if (! IFFUNC_HASFCALL(sym->type)) {
2892 /* if any registers used */
2893 if (sym->regsUsed) {
2894 /* save the registers used */
2895 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2896 if (bitVectBitValue(sym->regsUsed,i) ||
2897 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2898 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2903 /* this function has a function call cannot
2904 determines register usage so we will have the
2906 unsaverbank(0,ic,FALSE);
2910 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2912 if (options.stack10bit)
2914 pic14_emitcode ("pop", "dpx1");
2915 pic14_emitcode ("pop", "dph1");
2916 pic14_emitcode ("pop", "dpl1");
2918 pic14_emitcode ("pop", "dps");
2919 pic14_emitcode ("pop", "dpx");
2921 if (!inExcludeList("dph"))
2922 pic14_emitcode ("pop","dph");
2923 if (!inExcludeList("dpl"))
2924 pic14_emitcode ("pop","dpl");
2925 if (!inExcludeList("b"))
2926 pic14_emitcode ("pop","b");
2927 if (!inExcludeList("acc"))
2928 pic14_emitcode ("pop","acc");
2930 if (IFFUNC_ISCRITICAL(sym->type))
2931 pic14_emitcode("setb","ea");
2934 /* if debug then send end of function */
2935 /* if (options.debug && currFunc) { */
2938 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2939 FileBaseName(ic->filename),currFunc->lastLine,
2940 ic->level,ic->block);
2941 if (IS_STATIC(currFunc->etype))
2942 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2944 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2948 pic14_emitcode ("reti","");
2950 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2951 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2952 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2953 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2954 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2955 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2957 emitpcodeNULLop(POC_RETFIE);
2961 if (IFFUNC_ISCRITICAL(sym->type))
2962 pic14_emitcode("setb","ea");
2964 if (IFFUNC_CALLEESAVES(sym->type)) {
2967 /* if any registers used */
2968 if (sym->regsUsed) {
2969 /* save the registers used */
2970 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2971 if (bitVectBitValue(sym->regsUsed,i) ||
2972 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2973 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2979 /* if debug then send end of function */
2982 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2983 FileBaseName(ic->filename),currFunc->lastLine,
2984 ic->level,ic->block);
2985 if (IS_STATIC(currFunc->etype))
2986 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2988 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2992 pic14_emitcode ("return","");
2993 emitpcodeNULLop(POC_RETURN);
2995 /* Mark the end of a function */
2996 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
3001 /*-----------------------------------------------------------------*/
3002 /* genRet - generate code for return statement */
3003 /*-----------------------------------------------------------------*/
3004 static void genRet (iCode *ic)
3006 int size,offset = 0 , pushed = 0;
3008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3009 /* if we have no return value then
3010 just generate the "ret" */
3014 /* we have something to return then
3015 move the return value into place */
3016 aopOp(IC_LEFT(ic),ic,FALSE);
3017 size = AOP_SIZE(IC_LEFT(ic));
3021 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3023 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3025 pic14_emitcode("push","%s",l);
3028 l = aopGet(AOP(IC_LEFT(ic)),offset,
3030 if (strcmp(fReturn[offset],l)) {
3031 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3032 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3033 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3035 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3038 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3048 if (strcmp(fReturn[pushed],"a"))
3049 pic14_emitcode("pop",fReturn[pushed]);
3051 pic14_emitcode("pop","acc");
3054 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3057 /* generate a jump to the return label
3058 if the next is not the return statement */
3059 if (!(ic->next && ic->next->op == LABEL &&
3060 IC_LABEL(ic->next) == returnLabel)) {
3062 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3063 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3068 /*-----------------------------------------------------------------*/
3069 /* genLabel - generates a label */
3070 /*-----------------------------------------------------------------*/
3071 static void genLabel (iCode *ic)
3073 /* special case never generate */
3074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3075 if (IC_LABEL(ic) == entryLabel)
3078 emitpLabel(IC_LABEL(ic)->key);
3079 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3082 /*-----------------------------------------------------------------*/
3083 /* genGoto - generates a goto */
3084 /*-----------------------------------------------------------------*/
3086 static void genGoto (iCode *ic)
3088 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3089 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3093 /*-----------------------------------------------------------------*/
3094 /* genMultbits :- multiplication of bits */
3095 /*-----------------------------------------------------------------*/
3096 static void genMultbits (operand *left,
3100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3102 if(!pic14_sameRegs(AOP(result),AOP(right)))
3103 emitpcode(POC_BSF, popGet(AOP(result),0));
3105 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3106 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3107 emitpcode(POC_BCF, popGet(AOP(result),0));
3112 /*-----------------------------------------------------------------*/
3113 /* genMultOneByte : 8 bit multiplication & division */
3114 /*-----------------------------------------------------------------*/
3115 static void genMultOneByte (operand *left,
3119 sym_link *opetype = operandType(result);
3124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3125 DEBUGpic14_AopType(__LINE__,left,right,result);
3126 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3128 /* (if two literals, the value is computed before) */
3129 /* if one literal, literal on the right */
3130 if (AOP_TYPE(left) == AOP_LIT){
3136 size = AOP_SIZE(result);
3139 if (AOP_TYPE(right) == AOP_LIT){
3140 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3141 aopGet(AOP(right),0,FALSE,FALSE),
3142 aopGet(AOP(left),0,FALSE,FALSE),
3143 aopGet(AOP(result),0,FALSE,FALSE));
3144 pic14_emitcode("call","genMultLit");
3146 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3147 aopGet(AOP(right),0,FALSE,FALSE),
3148 aopGet(AOP(left),0,FALSE,FALSE),
3149 aopGet(AOP(result),0,FALSE,FALSE));
3150 pic14_emitcode("call","genMult8X8_8");
3153 genMult8X8_8 (left, right,result);
3156 /* signed or unsigned */
3157 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3158 //l = aopGet(AOP(left),0,FALSE,FALSE);
3160 //pic14_emitcode("mul","ab");
3161 /* if result size = 1, mul signed = mul unsigned */
3162 //aopPut(AOP(result),"a",0);
3164 } else { // (size > 1)
3166 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3167 aopGet(AOP(right),0,FALSE,FALSE),
3168 aopGet(AOP(left),0,FALSE,FALSE),
3169 aopGet(AOP(result),0,FALSE,FALSE));
3171 if (SPEC_USIGN(opetype)){
3172 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3173 genUMult8X8_16 (left, right, result, NULL);
3176 /* for filling the MSBs */
3177 emitpcode(POC_CLRF, popGet(AOP(result),2));
3178 emitpcode(POC_CLRF, popGet(AOP(result),3));
3182 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3184 pic14_emitcode("mov","a,b");
3186 /* adjust the MSB if left or right neg */
3188 /* if one literal */
3189 if (AOP_TYPE(right) == AOP_LIT){
3190 pic14_emitcode("multiply ","right is a lit");
3191 /* AND literal negative */
3192 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3193 /* adjust MSB (c==0 after mul) */
3194 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3198 genSMult8X8_16 (left, right, result, NULL);
3202 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3204 pic14_emitcode("rlc","a");
3205 pic14_emitcode("subb","a,acc");
3213 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3214 //aopPut(AOP(result),"a",offset++);
3218 /*-----------------------------------------------------------------*/
3219 /* genMult - generates code for multiplication */
3220 /*-----------------------------------------------------------------*/
3221 static void genMult (iCode *ic)
3223 operand *left = IC_LEFT(ic);
3224 operand *right = IC_RIGHT(ic);
3225 operand *result= IC_RESULT(ic);
3227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3228 /* assign the amsops */
3229 aopOp (left,ic,FALSE);
3230 aopOp (right,ic,FALSE);
3231 aopOp (result,ic,TRUE);
3233 DEBUGpic14_AopType(__LINE__,left,right,result);
3235 /* special cases first */
3237 if (AOP_TYPE(left) == AOP_CRY &&
3238 AOP_TYPE(right)== AOP_CRY) {
3239 genMultbits(left,right,result);
3243 /* if both are of size == 1 */
3244 if (AOP_SIZE(left) == 1 &&
3245 AOP_SIZE(right) == 1 ) {
3246 genMultOneByte(left,right,result);
3250 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3252 /* should have been converted to function call */
3256 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3257 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3258 freeAsmop(result,NULL,ic,TRUE);
3261 /*-----------------------------------------------------------------*/
3262 /* genDivbits :- division of bits */
3263 /*-----------------------------------------------------------------*/
3264 static void genDivbits (operand *left,
3271 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3272 /* the result must be bit */
3273 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3274 l = aopGet(AOP(left),0,FALSE,FALSE);
3278 pic14_emitcode("div","ab");
3279 pic14_emitcode("rrc","a");
3280 aopPut(AOP(result),"c",0);
3283 /*-----------------------------------------------------------------*/
3284 /* genDivOneByte : 8 bit division */
3285 /*-----------------------------------------------------------------*/
3286 static void genDivOneByte (operand *left,
3290 sym_link *opetype = operandType(result);
3295 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3296 size = AOP_SIZE(result) - 1;
3298 /* signed or unsigned */
3299 if (SPEC_USIGN(opetype)) {
3300 /* unsigned is easy */
3301 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3302 l = aopGet(AOP(left),0,FALSE,FALSE);
3304 pic14_emitcode("div","ab");
3305 aopPut(AOP(result),"a",0);
3307 aopPut(AOP(result),zero,offset++);
3311 /* signed is a little bit more difficult */
3313 /* save the signs of the operands */
3314 l = aopGet(AOP(left),0,FALSE,FALSE);
3316 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3317 pic14_emitcode("push","acc"); /* save it on the stack */
3319 /* now sign adjust for both left & right */
3320 l = aopGet(AOP(right),0,FALSE,FALSE);
3322 lbl = newiTempLabel(NULL);
3323 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3324 pic14_emitcode("cpl","a");
3325 pic14_emitcode("inc","a");
3326 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3327 pic14_emitcode("mov","b,a");
3329 /* sign adjust left side */
3330 l = aopGet(AOP(left),0,FALSE,FALSE);
3333 lbl = newiTempLabel(NULL);
3334 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3335 pic14_emitcode("cpl","a");
3336 pic14_emitcode("inc","a");
3337 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3339 /* now the division */
3340 pic14_emitcode("div","ab");
3341 /* we are interested in the lower order
3343 pic14_emitcode("mov","b,a");
3344 lbl = newiTempLabel(NULL);
3345 pic14_emitcode("pop","acc");
3346 /* if there was an over flow we don't
3347 adjust the sign of the result */
3348 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3349 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3351 pic14_emitcode("clr","a");
3352 pic14_emitcode("subb","a,b");
3353 pic14_emitcode("mov","b,a");
3354 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3356 /* now we are done */
3357 aopPut(AOP(result),"b",0);
3359 pic14_emitcode("mov","c,b.7");
3360 pic14_emitcode("subb","a,acc");
3363 aopPut(AOP(result),"a",offset++);
3367 /*-----------------------------------------------------------------*/
3368 /* genDiv - generates code for division */
3369 /*-----------------------------------------------------------------*/
3370 static void genDiv (iCode *ic)
3372 operand *left = IC_LEFT(ic);
3373 operand *right = IC_RIGHT(ic);
3374 operand *result= IC_RESULT(ic);
3376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3377 /* assign the amsops */
3378 aopOp (left,ic,FALSE);
3379 aopOp (right,ic,FALSE);
3380 aopOp (result,ic,TRUE);
3382 /* special cases first */
3384 if (AOP_TYPE(left) == AOP_CRY &&
3385 AOP_TYPE(right)== AOP_CRY) {
3386 genDivbits(left,right,result);
3390 /* if both are of size == 1 */
3391 if (AOP_SIZE(left) == 1 &&
3392 AOP_SIZE(right) == 1 ) {
3393 genDivOneByte(left,right,result);
3397 /* should have been converted to function call */
3400 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3401 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3402 freeAsmop(result,NULL,ic,TRUE);
3405 /*-----------------------------------------------------------------*/
3406 /* genModbits :- modulus of bits */
3407 /*-----------------------------------------------------------------*/
3408 static void genModbits (operand *left,
3415 /* the result must be bit */
3416 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3417 l = aopGet(AOP(left),0,FALSE,FALSE);
3421 pic14_emitcode("div","ab");
3422 pic14_emitcode("mov","a,b");
3423 pic14_emitcode("rrc","a");
3424 aopPut(AOP(result),"c",0);
3427 /*-----------------------------------------------------------------*/
3428 /* genModOneByte : 8 bit modulus */
3429 /*-----------------------------------------------------------------*/
3430 static void genModOneByte (operand *left,
3434 sym_link *opetype = operandType(result);
3438 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3439 /* signed or unsigned */
3440 if (SPEC_USIGN(opetype)) {
3441 /* unsigned is easy */
3442 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3443 l = aopGet(AOP(left),0,FALSE,FALSE);
3445 pic14_emitcode("div","ab");
3446 aopPut(AOP(result),"b",0);
3450 /* signed is a little bit more difficult */
3452 /* save the signs of the operands */
3453 l = aopGet(AOP(left),0,FALSE,FALSE);
3456 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3457 pic14_emitcode("push","acc"); /* save it on the stack */
3459 /* now sign adjust for both left & right */
3460 l = aopGet(AOP(right),0,FALSE,FALSE);
3463 lbl = newiTempLabel(NULL);
3464 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3465 pic14_emitcode("cpl","a");
3466 pic14_emitcode("inc","a");
3467 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3468 pic14_emitcode("mov","b,a");
3470 /* sign adjust left side */
3471 l = aopGet(AOP(left),0,FALSE,FALSE);
3474 lbl = newiTempLabel(NULL);
3475 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3476 pic14_emitcode("cpl","a");
3477 pic14_emitcode("inc","a");
3478 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3480 /* now the multiplication */
3481 pic14_emitcode("div","ab");
3482 /* we are interested in the lower order
3484 lbl = newiTempLabel(NULL);
3485 pic14_emitcode("pop","acc");
3486 /* if there was an over flow we don't
3487 adjust the sign of the result */
3488 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3489 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3491 pic14_emitcode("clr","a");
3492 pic14_emitcode("subb","a,b");
3493 pic14_emitcode("mov","b,a");
3494 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3496 /* now we are done */
3497 aopPut(AOP(result),"b",0);
3501 /*-----------------------------------------------------------------*/
3502 /* genMod - generates code for division */
3503 /*-----------------------------------------------------------------*/
3504 static void genMod (iCode *ic)
3506 operand *left = IC_LEFT(ic);
3507 operand *right = IC_RIGHT(ic);
3508 operand *result= IC_RESULT(ic);
3510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3511 /* assign the amsops */
3512 aopOp (left,ic,FALSE);
3513 aopOp (right,ic,FALSE);
3514 aopOp (result,ic,TRUE);
3516 /* special cases first */
3518 if (AOP_TYPE(left) == AOP_CRY &&
3519 AOP_TYPE(right)== AOP_CRY) {
3520 genModbits(left,right,result);
3524 /* if both are of size == 1 */
3525 if (AOP_SIZE(left) == 1 &&
3526 AOP_SIZE(right) == 1 ) {
3527 genModOneByte(left,right,result);
3531 /* should have been converted to function call */
3535 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3536 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3537 freeAsmop(result,NULL,ic,TRUE);
3540 /*-----------------------------------------------------------------*/
3541 /* genIfxJump :- will create a jump depending on the ifx */
3542 /*-----------------------------------------------------------------*/
3544 note: May need to add parameter to indicate when a variable is in bit space.
3546 static void genIfxJump (iCode *ic, char *jval)
3549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3550 /* if true label then we jump if condition
3552 if ( IC_TRUE(ic) ) {
3554 if(strcmp(jval,"a") == 0)
3556 else if (strcmp(jval,"c") == 0)
3559 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3560 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3563 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3564 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3568 /* false label is present */
3569 if(strcmp(jval,"a") == 0)
3571 else if (strcmp(jval,"c") == 0)
3574 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3575 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3578 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3579 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3584 /* mark the icode as generated */
3588 /*-----------------------------------------------------------------*/
3590 /*-----------------------------------------------------------------*/
3591 static void genSkip(iCode *ifx,int status_bit)
3596 if ( IC_TRUE(ifx) ) {
3597 switch(status_bit) {
3612 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3613 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3617 switch(status_bit) {
3631 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3632 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3638 /*-----------------------------------------------------------------*/
3640 /*-----------------------------------------------------------------*/
3641 static void genSkipc(resolvedIfx *rifx)
3651 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3652 rifx->generated = 1;
3655 /*-----------------------------------------------------------------*/
3657 /*-----------------------------------------------------------------*/
3658 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3663 if( (rifx->condition ^ invert_condition) & 1)
3668 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3669 rifx->generated = 1;
3672 /*-----------------------------------------------------------------*/
3674 /*-----------------------------------------------------------------*/
3675 static void genSkipz(iCode *ifx, int condition)
3686 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3688 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3691 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3693 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3696 /*-----------------------------------------------------------------*/
3698 /*-----------------------------------------------------------------*/
3699 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3705 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3707 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3710 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3711 rifx->generated = 1;
3715 /*-----------------------------------------------------------------*/
3716 /* genChkZeroes :- greater or less than comparison */
3717 /* For each byte in a literal that is zero, inclusive or the */
3718 /* the corresponding byte in the operand with W */
3719 /* returns true if any of the bytes are zero */
3720 /*-----------------------------------------------------------------*/
3721 static int genChkZeroes(operand *op, int lit, int size)
3728 i = (lit >> (size*8)) & 0xff;
3732 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3734 emitpcode(POC_IORFW, popGet(AOP(op),size));
3743 /*-----------------------------------------------------------------*/
3744 /* genCmp :- greater or less than comparison */
3745 /*-----------------------------------------------------------------*/
3746 static void genCmp (operand *left,operand *right,
3747 operand *result, iCode *ifx, int sign)
3749 int size; //, offset = 0 ;
3750 unsigned long lit = 0L,i = 0;
3751 resolvedIfx rFalseIfx;
3752 // resolvedIfx rTrueIfx;
3754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3757 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3758 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3762 resolveIfx(&rFalseIfx,ifx);
3763 truelbl = newiTempLabel(NULL);
3764 size = max(AOP_SIZE(left),AOP_SIZE(right));
3766 DEBUGpic14_AopType(__LINE__,left,right,result);
3770 /* if literal is on the right then swap with left */
3771 if ((AOP_TYPE(right) == AOP_LIT)) {
3772 operand *tmp = right ;
3773 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3774 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3777 lit = (lit - 1) & mask;
3780 rFalseIfx.condition ^= 1;
3783 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3784 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3788 //if(IC_TRUE(ifx) == NULL)
3789 /* if left & right are bit variables */
3790 if (AOP_TYPE(left) == AOP_CRY &&
3791 AOP_TYPE(right) == AOP_CRY ) {
3792 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3793 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3795 /* subtract right from left if at the
3796 end the carry flag is set then we know that
3797 left is greater than right */
3801 symbol *lbl = newiTempLabel(NULL);
3804 if(AOP_TYPE(right) == AOP_LIT) {
3806 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3808 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3815 genSkipCond(&rFalseIfx,left,size-1,7);
3817 /* no need to compare to 0...*/
3818 /* NOTE: this is a de-generate compare that most certainly
3819 * creates some dead code. */
3820 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3822 if(ifx) ifx->generated = 1;
3829 //i = (lit >> (size*8)) & 0xff;
3830 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3832 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3834 i = ((0-lit) & 0xff);
3837 /* lit is 0x7f, all signed chars are less than
3838 * this except for 0x7f itself */
3839 emitpcode(POC_XORLW, popGetLit(0x7f));
3840 genSkipz2(&rFalseIfx,0);
3842 emitpcode(POC_ADDLW, popGetLit(0x80));
3843 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3844 genSkipc(&rFalseIfx);
3849 genSkipz2(&rFalseIfx,1);
3851 emitpcode(POC_ADDLW, popGetLit(i));
3852 genSkipc(&rFalseIfx);
3856 if(ifx) ifx->generated = 1;
3860 /* chars are out of the way. now do ints and longs */
3863 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3870 genSkipCond(&rFalseIfx,left,size,7);
3871 if(ifx) ifx->generated = 1;
3876 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3878 //rFalseIfx.condition ^= 1;
3879 //genSkipCond(&rFalseIfx,left,size,7);
3880 //rFalseIfx.condition ^= 1;
3882 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3883 if(rFalseIfx.condition)
3884 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3886 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3888 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3889 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3890 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3893 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3895 if(rFalseIfx.condition) {
3897 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3903 genSkipc(&rFalseIfx);
3904 emitpLabel(truelbl->key);
3905 if(ifx) ifx->generated = 1;
3912 if( (lit & 0xff) == 0) {
3913 /* lower byte is zero */
3914 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3915 i = ((lit >> 8) & 0xff) ^0x80;
3916 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3917 emitpcode(POC_ADDLW, popGetLit( 0x80));
3918 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3919 genSkipc(&rFalseIfx);
3922 if(ifx) ifx->generated = 1;
3927 /* Special cases for signed longs */
3928 if( (lit & 0xffffff) == 0) {
3929 /* lower byte is zero */
3930 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3931 i = ((lit >> 8*3) & 0xff) ^0x80;
3932 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3933 emitpcode(POC_ADDLW, popGetLit( 0x80));
3934 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3935 genSkipc(&rFalseIfx);
3938 if(ifx) ifx->generated = 1;
3946 if(lit & (0x80 << (size*8))) {
3947 /* lit is negative */
3948 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3950 //genSkipCond(&rFalseIfx,left,size,7);
3952 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3954 if(rFalseIfx.condition)
3955 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3957 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3961 /* lit is positive */
3962 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3963 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3964 if(rFalseIfx.condition)
3965 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3967 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3972 This works, but is only good for ints.
3973 It also requires a "known zero" register.
3974 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3975 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3976 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3977 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3978 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3979 genSkipc(&rFalseIfx);
3981 emitpLabel(truelbl->key);
3982 if(ifx) ifx->generated = 1;
3986 /* There are no more special cases, so perform a general compare */
3988 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3989 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3993 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3995 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3997 //rFalseIfx.condition ^= 1;
3998 genSkipc(&rFalseIfx);
4000 emitpLabel(truelbl->key);
4002 if(ifx) ifx->generated = 1;
4009 /* sign is out of the way. So now do an unsigned compare */
4010 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4013 /* General case - compare to an unsigned literal on the right.*/
4015 i = (lit >> (size*8)) & 0xff;
4016 emitpcode(POC_MOVLW, popGetLit(i));
4017 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4019 i = (lit >> (size*8)) & 0xff;
4022 emitpcode(POC_MOVLW, popGetLit(i));
4024 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4026 /* this byte of the lit is zero,
4027 *if it's not the last then OR in the variable */
4029 emitpcode(POC_IORFW, popGet(AOP(left),size));
4034 emitpLabel(lbl->key);
4035 //if(emitFinalCheck)
4036 genSkipc(&rFalseIfx);
4038 emitpLabel(truelbl->key);
4040 if(ifx) ifx->generated = 1;
4047 if(AOP_TYPE(left) == AOP_LIT) {
4048 //symbol *lbl = newiTempLabel(NULL);
4050 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4053 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4056 if((lit == 0) && (sign == 0)){
4059 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4061 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4063 genSkipz2(&rFalseIfx,0);
4064 if(ifx) ifx->generated = 1;
4071 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4072 /* degenerate compare can never be true */
4073 if(rFalseIfx.condition == 0)
4074 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4076 if(ifx) ifx->generated = 1;
4081 /* signed comparisons to a literal byte */
4083 int lp1 = (lit+1) & 0xff;
4085 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4088 rFalseIfx.condition ^= 1;
4089 genSkipCond(&rFalseIfx,right,0,7);
4092 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4093 emitpcode(POC_XORLW, popGetLit(0x7f));
4094 genSkipz2(&rFalseIfx,1);
4097 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4098 emitpcode(POC_ADDLW, popGetLit(0x80));
4099 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4100 rFalseIfx.condition ^= 1;
4101 genSkipc(&rFalseIfx);
4105 /* unsigned comparisons to a literal byte */
4107 switch(lit & 0xff ) {
4109 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4110 genSkipz2(&rFalseIfx,0);
4113 rFalseIfx.condition ^= 1;
4114 genSkipCond(&rFalseIfx,right,0,7);
4118 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4119 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4121 rFalseIfx.condition ^= 1;
4122 if (AOP_TYPE(result) == AOP_CRY)
4123 genSkipc(&rFalseIfx);
4125 emitpcode(POC_CLRF, popGet(AOP(result),0));
4126 emitpcode(POC_RLF, popGet(AOP(result),0));
4132 if(ifx) ifx->generated = 1;
4138 /* Size is greater than 1 */
4146 /* this means lit = 0xffffffff, or -1 */
4149 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4150 rFalseIfx.condition ^= 1;
4151 genSkipCond(&rFalseIfx,right,size,7);
4152 if(ifx) ifx->generated = 1;
4159 if(rFalseIfx.condition) {
4160 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4161 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4164 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4166 emitpcode(POC_IORFW, popGet(AOP(right),size));
4170 if(rFalseIfx.condition) {
4171 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4172 emitpLabel(truelbl->key);
4174 rFalseIfx.condition ^= 1;
4175 genSkipCond(&rFalseIfx,right,s,7);
4178 if(ifx) ifx->generated = 1;
4182 if((size == 1) && (0 == (lp1&0xff))) {
4183 /* lower byte of signed word is zero */
4184 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4185 i = ((lp1 >> 8) & 0xff) ^0x80;
4186 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4187 emitpcode(POC_ADDLW, popGetLit( 0x80));
4188 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4189 rFalseIfx.condition ^= 1;
4190 genSkipc(&rFalseIfx);
4193 if(ifx) ifx->generated = 1;
4197 if(lit & (0x80 << (size*8))) {
4198 /* Lit is less than zero */
4199 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4200 //rFalseIfx.condition ^= 1;
4201 //genSkipCond(&rFalseIfx,left,size,7);
4202 //rFalseIfx.condition ^= 1;
4203 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4206 if(rFalseIfx.condition)
4207 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4209 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4213 /* Lit is greater than or equal to zero */
4214 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4215 //rFalseIfx.condition ^= 1;
4216 //genSkipCond(&rFalseIfx,right,size,7);
4217 //rFalseIfx.condition ^= 1;
4219 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4220 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4222 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4223 if(rFalseIfx.condition)
4224 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4226 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4231 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4232 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4236 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4238 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4240 rFalseIfx.condition ^= 1;
4241 //rFalseIfx.condition = 1;
4242 genSkipc(&rFalseIfx);
4244 emitpLabel(truelbl->key);
4246 if(ifx) ifx->generated = 1;
4251 /* compare word or long to an unsigned literal on the right.*/
4256 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4259 break; /* handled above */
4262 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4264 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265 genSkipz2(&rFalseIfx,0);
4269 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4271 emitpcode(POC_IORFW, popGet(AOP(right),size));
4274 if(rFalseIfx.condition)
4275 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4277 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4280 emitpcode(POC_MOVLW, popGetLit(lit+1));
4281 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4283 rFalseIfx.condition ^= 1;
4284 genSkipc(&rFalseIfx);
4287 emitpLabel(truelbl->key);
4289 if(ifx) ifx->generated = 1;
4295 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4296 i = (lit >> (size*8)) & 0xff;
4298 emitpcode(POC_MOVLW, popGetLit(i));
4299 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4302 i = (lit >> (size*8)) & 0xff;
4305 emitpcode(POC_MOVLW, popGetLit(i));
4307 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4309 /* this byte of the lit is zero,
4310 *if it's not the last then OR in the variable */
4312 emitpcode(POC_IORFW, popGet(AOP(right),size));
4317 emitpLabel(lbl->key);
4319 rFalseIfx.condition ^= 1;
4320 genSkipc(&rFalseIfx);
4324 emitpLabel(truelbl->key);
4325 if(ifx) ifx->generated = 1;
4329 /* Compare two variables */
4331 DEBUGpic14_emitcode(";sign","%d",sign);
4335 /* Sigh. thus sucks... */
4337 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4338 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4339 emitpcode(POC_MOVLW, popGetLit(0x80));
4340 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4341 emitpcode(POC_XORFW, popGet(AOP(right),size));
4342 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4344 /* Signed char comparison */
4345 /* Special thanks to Nikolai Golovchenko for this snippet */
4346 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4347 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4348 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4349 emitpcode(POC_XORFW, popGet(AOP(left),0));
4350 emitpcode(POC_XORFW, popGet(AOP(right),0));
4351 emitpcode(POC_ADDLW, popGetLit(0x80));
4353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4354 genSkipc(&rFalseIfx);
4356 if(ifx) ifx->generated = 1;
4362 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4363 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4367 /* The rest of the bytes of a multi-byte compare */
4371 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4374 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4375 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4380 emitpLabel(lbl->key);
4382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4383 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4384 (AOP_TYPE(result) == AOP_REG)) {
4385 emitpcode(POC_CLRF, popGet(AOP(result),0));
4386 emitpcode(POC_RLF, popGet(AOP(result),0));
4388 genSkipc(&rFalseIfx);
4390 //genSkipc(&rFalseIfx);
4391 if(ifx) ifx->generated = 1;
4398 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4400 pic14_outBitC(result);
4402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4403 /* if the result is used in the next
4404 ifx conditional branch then generate
4405 code a little differently */
4407 genIfxJump (ifx,"c");
4409 pic14_outBitC(result);
4410 /* leave the result in acc */
4415 /*-----------------------------------------------------------------*/
4416 /* genCmpGt :- greater than comparison */
4417 /*-----------------------------------------------------------------*/
4418 static void genCmpGt (iCode *ic, iCode *ifx)
4420 operand *left, *right, *result;
4421 sym_link *letype , *retype;
4424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4426 right= IC_RIGHT(ic);
4427 result = IC_RESULT(ic);
4429 letype = getSpec(operandType(left));
4430 retype =getSpec(operandType(right));
4431 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4432 /* assign the amsops */
4433 aopOp (left,ic,FALSE);
4434 aopOp (right,ic,FALSE);
4435 aopOp (result,ic,TRUE);
4437 genCmp(right, left, result, ifx, sign);
4439 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 freeAsmop(result,NULL,ic,TRUE);
4444 /*-----------------------------------------------------------------*/
4445 /* genCmpLt - less than comparisons */
4446 /*-----------------------------------------------------------------*/
4447 static void genCmpLt (iCode *ic, iCode *ifx)
4449 operand *left, *right, *result;
4450 sym_link *letype , *retype;
4453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4455 right= IC_RIGHT(ic);
4456 result = IC_RESULT(ic);
4458 letype = getSpec(operandType(left));
4459 retype =getSpec(operandType(right));
4460 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4462 /* assign the amsops */
4463 aopOp (left,ic,FALSE);
4464 aopOp (right,ic,FALSE);
4465 aopOp (result,ic,TRUE);
4467 genCmp(left, right, result, ifx, sign);
4469 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4470 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471 freeAsmop(result,NULL,ic,TRUE);
4474 /*-----------------------------------------------------------------*/
4475 /* genc16bit2lit - compare a 16 bit value to a literal */
4476 /*-----------------------------------------------------------------*/
4477 static void genc16bit2lit(operand *op, int lit, int offset)
4481 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4482 if( (lit&0xff) == 0)
4487 switch( BYTEofLONG(lit,i)) {
4489 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4492 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4495 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4498 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4499 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4504 switch( BYTEofLONG(lit,i)) {
4506 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4510 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4514 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4517 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4519 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4525 /*-----------------------------------------------------------------*/
4526 /* gencjneshort - compare and jump if not equal */
4527 /*-----------------------------------------------------------------*/
4528 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4530 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4535 unsigned long lit = 0L;
4536 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4537 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4539 resolveIfx(&rIfx,ifx);
4540 lbl = newiTempLabel(NULL);
4543 /* if the left side is a literal or
4544 if the right is in a pointer register and left
4546 if ((AOP_TYPE(left) == AOP_LIT) ||
4547 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4552 if(AOP_TYPE(right) == AOP_LIT)
4553 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4555 /* if the right side is a literal then anything goes */
4556 if (AOP_TYPE(right) == AOP_LIT &&
4557 AOP_TYPE(left) != AOP_DIR ) {
4560 genc16bit2lit(left, lit, 0);
4562 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4567 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4568 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4570 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4574 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4582 /* if the right side is in a register or in direct space or
4583 if the left is a pointer register & right is not */
4584 else if (AOP_TYPE(right) == AOP_REG ||
4585 AOP_TYPE(right) == AOP_DIR ||
4586 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4587 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4590 genc16bit2lit(left, lit, 0);
4592 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4597 if((AOP_TYPE(left) == AOP_DIR) &&
4598 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4600 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4601 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4603 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4605 switch (lit & 0xff) {
4607 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4610 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4611 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4615 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4616 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4620 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4621 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4626 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4629 if(AOP_TYPE(result) == AOP_CRY) {
4630 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4635 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4637 /* fix me. probably need to check result size too */
4638 emitpcode(POC_CLRF,popGet(AOP(result),0));
4643 emitpcode(POC_INCF,popGet(AOP(result),0));
4653 } else if(AOP_TYPE(right) == AOP_REG &&
4654 AOP_TYPE(left) != AOP_DIR){
4657 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4658 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4659 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4664 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4669 /* right is a pointer reg need both a & b */
4671 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4673 pic14_emitcode("mov","b,%s",l);
4674 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4675 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4679 emitpLabel(lbl->key);
4686 /*-----------------------------------------------------------------*/
4687 /* gencjne - compare and jump if not equal */
4688 /*-----------------------------------------------------------------*/
4689 static void gencjne(operand *left, operand *right, iCode *ifx)
4691 symbol *tlbl = newiTempLabel(NULL);
4693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4694 gencjneshort(left, right, lbl);
4696 pic14_emitcode("mov","a,%s",one);
4697 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4698 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4699 pic14_emitcode("clr","a");
4700 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4702 emitpLabel(lbl->key);
4703 emitpLabel(tlbl->key);
4708 /*-----------------------------------------------------------------*/
4709 /* genCmpEq - generates code for equal to */
4710 /*-----------------------------------------------------------------*/
4711 static void genCmpEq (iCode *ic, iCode *ifx)
4713 operand *left, *right, *result;
4714 unsigned long lit = 0L;
4717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4720 DEBUGpic14_emitcode ("; ifx is non-null","");
4722 DEBUGpic14_emitcode ("; ifx is null","");
4724 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4725 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4726 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4728 size = max(AOP_SIZE(left),AOP_SIZE(right));
4730 DEBUGpic14_AopType(__LINE__,left,right,result);
4732 /* if literal, literal on the right or
4733 if the right is in a pointer register and left
4735 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4736 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4737 operand *tmp = right ;
4743 if(ifx && !AOP_SIZE(result)){
4745 /* if they are both bit variables */
4746 if (AOP_TYPE(left) == AOP_CRY &&
4747 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4748 if(AOP_TYPE(right) == AOP_LIT){
4749 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4751 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4752 pic14_emitcode("cpl","c");
4753 } else if(lit == 1L) {
4754 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4756 pic14_emitcode("clr","c");
4758 /* AOP_TYPE(right) == AOP_CRY */
4760 symbol *lbl = newiTempLabel(NULL);
4761 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4762 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4763 pic14_emitcode("cpl","c");
4764 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4766 /* if true label then we jump if condition
4768 tlbl = newiTempLabel(NULL);
4769 if ( IC_TRUE(ifx) ) {
4770 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4771 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4773 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4774 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4776 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4779 /* left and right are both bit variables, result is carry */
4782 resolveIfx(&rIfx,ifx);
4784 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4785 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4786 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4787 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4792 /* They're not both bit variables. Is the right a literal? */
4793 if(AOP_TYPE(right) == AOP_LIT) {
4794 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4799 switch(lit & 0xff) {
4801 if ( IC_TRUE(ifx) ) {
4802 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4804 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4806 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4807 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4811 if ( IC_TRUE(ifx) ) {
4812 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4814 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4816 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4817 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4821 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4823 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4828 /* end of size == 1 */
4832 genc16bit2lit(left,lit,offset);
4835 /* end of size == 2 */
4840 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4841 emitpcode(POC_IORFW,popGet(AOP(left),1));
4842 emitpcode(POC_IORFW,popGet(AOP(left),2));
4843 emitpcode(POC_IORFW,popGet(AOP(left),3));
4847 /* search for patterns that can be optimized */
4849 genc16bit2lit(left,lit,0);
4852 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4854 genc16bit2lit(left,lit,2);
4856 emitpcode(POC_IORFW,popGet(AOP(left),2));
4857 emitpcode(POC_IORFW,popGet(AOP(left),3));
4870 } else if(AOP_TYPE(right) == AOP_CRY ) {
4871 /* we know the left is not a bit, but that the right is */
4872 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4873 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4874 popGet(AOP(right),offset));
4875 emitpcode(POC_XORLW,popGetLit(1));
4877 /* if the two are equal, then W will be 0 and the Z bit is set
4878 * we could test Z now, or go ahead and check the high order bytes if
4879 * the variable we're comparing is larger than a byte. */
4882 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4884 if ( IC_TRUE(ifx) ) {
4886 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4887 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4890 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4891 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4895 /* They're both variables that are larger than bits */
4898 tlbl = newiTempLabel(NULL);
4901 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4902 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4904 if ( IC_TRUE(ifx) ) {
4907 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4908 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4911 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4912 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4916 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4917 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4921 if(s>1 && IC_TRUE(ifx)) {
4922 emitpLabel(tlbl->key);
4923 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4927 /* mark the icode as generated */
4932 /* if they are both bit variables */
4933 if (AOP_TYPE(left) == AOP_CRY &&
4934 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4935 if(AOP_TYPE(right) == AOP_LIT){
4936 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4938 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4939 pic14_emitcode("cpl","c");
4940 } else if(lit == 1L) {
4941 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4943 pic14_emitcode("clr","c");
4945 /* AOP_TYPE(right) == AOP_CRY */
4947 symbol *lbl = newiTempLabel(NULL);
4948 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4949 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4950 pic14_emitcode("cpl","c");
4951 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4954 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4955 pic14_outBitC(result);
4959 genIfxJump (ifx,"c");
4962 /* if the result is used in an arithmetic operation
4963 then put the result in place */
4964 pic14_outBitC(result);
4967 gencjne(left,right,result,ifx);
4970 gencjne(left,right,newiTempLabel(NULL));
4972 if(IC_TRUE(ifx)->key)
4973 gencjne(left,right,IC_TRUE(ifx)->key);
4975 gencjne(left,right,IC_FALSE(ifx)->key);
4979 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4980 aopPut(AOP(result),"a",0);
4985 genIfxJump (ifx,"a");
4989 /* if the result is used in an arithmetic operation
4990 then put the result in place */
4992 if (AOP_TYPE(result) != AOP_CRY)
4993 pic14_outAcc(result);
4995 /* leave the result in acc */
4999 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5000 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5001 freeAsmop(result,NULL,ic,TRUE);
5004 /*-----------------------------------------------------------------*/
5005 /* ifxForOp - returns the icode containing the ifx for operand */
5006 /*-----------------------------------------------------------------*/
5007 static iCode *ifxForOp ( operand *op, iCode *ic )
5009 /* if true symbol then needs to be assigned */
5010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5011 if (IS_TRUE_SYMOP(op))
5014 /* if this has register type condition and
5015 the next instruction is ifx with the same operand
5016 and live to of the operand is upto the ifx only then */
5018 ic->next->op == IFX &&
5019 IC_COND(ic->next)->key == op->key &&
5020 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5024 ic->next->op == IFX &&
5025 IC_COND(ic->next)->key == op->key) {
5026 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5030 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5032 ic->next->op == IFX)
5033 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5036 ic->next->op == IFX &&
5037 IC_COND(ic->next)->key == op->key) {
5038 DEBUGpic14_emitcode ("; "," key is okay");
5039 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5040 OP_SYMBOL(op)->liveTo,
5047 /*-----------------------------------------------------------------*/
5048 /* genAndOp - for && operation */
5049 /*-----------------------------------------------------------------*/
5050 static void genAndOp (iCode *ic)
5052 operand *left,*right, *result;
5055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5056 /* note here that && operations that are in an
5057 if statement are taken away by backPatchLabels
5058 only those used in arthmetic operations remain */
5059 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5060 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5061 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5063 /* if both are bit variables */
5064 if (AOP_TYPE(left) == AOP_CRY &&
5065 AOP_TYPE(right) == AOP_CRY ) {
5066 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5067 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5068 pic14_outBitC(result);
5070 tlbl = newiTempLabel(NULL);
5071 pic14_toBoolean(left);
5072 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5073 pic14_toBoolean(right);
5074 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5075 pic14_outBitAcc(result);
5078 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5079 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5080 freeAsmop(result,NULL,ic,TRUE);
5084 /*-----------------------------------------------------------------*/
5085 /* genOrOp - for || operation */
5086 /*-----------------------------------------------------------------*/
5089 modified this code, but it doesn't appear to ever get called
5092 static void genOrOp (iCode *ic)
5094 operand *left,*right, *result;
5097 /* note here that || operations that are in an
5098 if statement are taken away by backPatchLabels
5099 only those used in arthmetic operations remain */
5100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5101 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5102 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5103 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5105 DEBUGpic14_AopType(__LINE__,left,right,result);
5107 /* if both are bit variables */
5108 if (AOP_TYPE(left) == AOP_CRY &&
5109 AOP_TYPE(right) == AOP_CRY ) {
5110 pic14_emitcode("clrc","");
5111 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5112 AOP(left)->aopu.aop_dir,
5113 AOP(left)->aopu.aop_dir);
5114 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5115 AOP(right)->aopu.aop_dir,
5116 AOP(right)->aopu.aop_dir);
5117 pic14_emitcode("setc","");
5120 tlbl = newiTempLabel(NULL);
5121 pic14_toBoolean(left);
5123 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5124 pic14_toBoolean(right);
5125 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5127 pic14_outBitAcc(result);
5130 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5131 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5132 freeAsmop(result,NULL,ic,TRUE);
5135 /*-----------------------------------------------------------------*/
5136 /* isLiteralBit - test if lit == 2^n */
5137 /*-----------------------------------------------------------------*/
5138 static int isLiteralBit(unsigned long lit)
5140 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5141 0x100L,0x200L,0x400L,0x800L,
5142 0x1000L,0x2000L,0x4000L,0x8000L,
5143 0x10000L,0x20000L,0x40000L,0x80000L,
5144 0x100000L,0x200000L,0x400000L,0x800000L,
5145 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5146 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5150 for(idx = 0; idx < 32; idx++)
5156 /*-----------------------------------------------------------------*/
5157 /* continueIfTrue - */
5158 /*-----------------------------------------------------------------*/
5159 static void continueIfTrue (iCode *ic)
5161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5163 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5167 /*-----------------------------------------------------------------*/
5169 /*-----------------------------------------------------------------*/
5170 static void jumpIfTrue (iCode *ic)
5172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5174 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5178 /*-----------------------------------------------------------------*/
5179 /* jmpTrueOrFalse - */
5180 /*-----------------------------------------------------------------*/
5181 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5183 // ugly but optimized by peephole
5184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5186 symbol *nlbl = newiTempLabel(NULL);
5187 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5188 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5189 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5190 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5193 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5194 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5199 /*-----------------------------------------------------------------*/
5200 /* genAnd - code for and */
5201 /*-----------------------------------------------------------------*/
5202 static void genAnd (iCode *ic, iCode *ifx)
5204 operand *left, *right, *result;
5206 unsigned long lit = 0L;
5211 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5212 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5213 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5214 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5216 resolveIfx(&rIfx,ifx);
5218 /* if left is a literal & right is not then exchange them */
5219 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5220 AOP_NEEDSACC(left)) {
5221 operand *tmp = right ;
5226 /* if result = right then exchange them */
5227 if(pic14_sameRegs(AOP(result),AOP(right))){
5228 operand *tmp = right ;
5233 /* if right is bit then exchange them */
5234 if (AOP_TYPE(right) == AOP_CRY &&
5235 AOP_TYPE(left) != AOP_CRY){
5236 operand *tmp = right ;
5240 if(AOP_TYPE(right) == AOP_LIT)
5241 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5243 size = AOP_SIZE(result);
5245 DEBUGpic14_AopType(__LINE__,left,right,result);
5248 // result = bit & yy;
5249 if (AOP_TYPE(left) == AOP_CRY){
5250 // c = bit & literal;
5251 if(AOP_TYPE(right) == AOP_LIT){
5253 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5256 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5259 if(size && (AOP_TYPE(result) == AOP_CRY)){
5260 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5263 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5267 pic14_emitcode("clr","c");
5270 if (AOP_TYPE(right) == AOP_CRY){
5272 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5273 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5276 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5278 pic14_emitcode("rrc","a");
5279 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5285 pic14_outBitC(result);
5287 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5288 genIfxJump(ifx, "c");
5292 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5293 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5294 if((AOP_TYPE(right) == AOP_LIT) &&
5295 (AOP_TYPE(result) == AOP_CRY) &&
5296 (AOP_TYPE(left) != AOP_CRY)){
5297 int posbit = isLiteralBit(lit);
5301 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5304 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5310 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5311 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5313 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5314 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5317 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5318 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5319 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5326 symbol *tlbl = newiTempLabel(NULL);
5327 int sizel = AOP_SIZE(left);
5329 pic14_emitcode("setb","c");
5331 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5332 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5334 if((posbit = isLiteralBit(bytelit)) != 0)
5335 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5337 if(bytelit != 0x0FFL)
5338 pic14_emitcode("anl","a,%s",
5339 aopGet(AOP(right),offset,FALSE,TRUE));
5340 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5345 // bit = left & literal
5347 pic14_emitcode("clr","c");
5348 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5350 // if(left & literal)
5353 jmpTrueOrFalse(ifx, tlbl);
5357 pic14_outBitC(result);
5361 /* if left is same as result */
5362 if(pic14_sameRegs(AOP(result),AOP(left))){
5364 for(;size--; offset++,lit>>=8) {
5365 if(AOP_TYPE(right) == AOP_LIT){
5366 switch(lit & 0xff) {
5368 /* and'ing with 0 has clears the result */
5369 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5370 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5373 /* and'ing with 0xff is a nop when the result and left are the same */
5378 int p = my_powof2( (~lit) & 0xff );
5380 /* only one bit is set in the literal, so use a bcf instruction */
5381 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5382 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5385 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5386 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5387 if(know_W != (lit&0xff))
5388 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5390 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5395 if (AOP_TYPE(left) == AOP_ACC) {
5396 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5398 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5399 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5406 // left & result in different registers
5407 if(AOP_TYPE(result) == AOP_CRY){
5409 // if(size), result in bit
5410 // if(!size && ifx), conditional oper: if(left & right)
5411 symbol *tlbl = newiTempLabel(NULL);
5412 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5414 pic14_emitcode("setb","c");
5416 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5417 pic14_emitcode("anl","a,%s",
5418 aopGet(AOP(left),offset,FALSE,FALSE));
5419 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5424 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5425 pic14_outBitC(result);
5427 jmpTrueOrFalse(ifx, tlbl);
5429 for(;(size--);offset++) {
5431 // result = left & right
5432 if(AOP_TYPE(right) == AOP_LIT){
5433 int t = (lit >> (offset*8)) & 0x0FFL;
5436 pic14_emitcode("clrf","%s",
5437 aopGet(AOP(result),offset,FALSE,FALSE));
5438 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5441 pic14_emitcode("movf","%s,w",
5442 aopGet(AOP(left),offset,FALSE,FALSE));
5443 pic14_emitcode("movwf","%s",
5444 aopGet(AOP(result),offset,FALSE,FALSE));
5445 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5446 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5449 pic14_emitcode("movlw","0x%x",t);
5450 pic14_emitcode("andwf","%s,w",
5451 aopGet(AOP(left),offset,FALSE,FALSE));
5452 pic14_emitcode("movwf","%s",
5453 aopGet(AOP(result),offset,FALSE,FALSE));
5455 emitpcode(POC_MOVLW, popGetLit(t));
5456 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5457 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5462 if (AOP_TYPE(left) == AOP_ACC) {
5463 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5464 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5466 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5467 pic14_emitcode("andwf","%s,w",
5468 aopGet(AOP(left),offset,FALSE,FALSE));
5469 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5470 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5472 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5473 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5479 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5480 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5481 freeAsmop(result,NULL,ic,TRUE);
5484 /*-----------------------------------------------------------------*/
5485 /* genOr - code for or */
5486 /*-----------------------------------------------------------------*/
5487 static void genOr (iCode *ic, iCode *ifx)
5489 operand *left, *right, *result;
5491 unsigned long lit = 0L;
5493 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5495 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5496 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5497 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5499 DEBUGpic14_AopType(__LINE__,left,right,result);
5501 /* if left is a literal & right is not then exchange them */
5502 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5503 AOP_NEEDSACC(left)) {
5504 operand *tmp = right ;
5509 /* if result = right then exchange them */
5510 if(pic14_sameRegs(AOP(result),AOP(right))){
5511 operand *tmp = right ;
5516 /* if right is bit then exchange them */
5517 if (AOP_TYPE(right) == AOP_CRY &&
5518 AOP_TYPE(left) != AOP_CRY){
5519 operand *tmp = right ;
5524 DEBUGpic14_AopType(__LINE__,left,right,result);
5526 if(AOP_TYPE(right) == AOP_LIT)
5527 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5529 size = AOP_SIZE(result);
5533 if (AOP_TYPE(left) == AOP_CRY){
5534 if(AOP_TYPE(right) == AOP_LIT){
5535 // c = bit & literal;
5537 // lit != 0 => result = 1
5538 if(AOP_TYPE(result) == AOP_CRY){
5540 emitpcode(POC_BSF, popGet(AOP(result),0));
5541 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5542 // AOP(result)->aopu.aop_dir,
5543 // AOP(result)->aopu.aop_dir);
5545 continueIfTrue(ifx);
5549 // lit == 0 => result = left
5550 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5552 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5555 if (AOP_TYPE(right) == AOP_CRY){
5556 if(pic14_sameRegs(AOP(result),AOP(left))){
5558 emitpcode(POC_BCF, popGet(AOP(result),0));
5559 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5560 emitpcode(POC_BSF, popGet(AOP(result),0));
5562 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5563 AOP(result)->aopu.aop_dir,
5564 AOP(result)->aopu.aop_dir);
5565 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5566 AOP(right)->aopu.aop_dir,
5567 AOP(right)->aopu.aop_dir);
5568 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5569 AOP(result)->aopu.aop_dir,
5570 AOP(result)->aopu.aop_dir);
5572 if( AOP_TYPE(result) == AOP_ACC) {
5573 emitpcode(POC_MOVLW, popGetLit(0));
5574 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5575 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5576 emitpcode(POC_MOVLW, popGetLit(1));
5580 emitpcode(POC_BCF, popGet(AOP(result),0));
5581 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5582 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5583 emitpcode(POC_BSF, popGet(AOP(result),0));
5585 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5586 AOP(result)->aopu.aop_dir,
5587 AOP(result)->aopu.aop_dir);
5588 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5589 AOP(right)->aopu.aop_dir,
5590 AOP(right)->aopu.aop_dir);
5591 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5592 AOP(left)->aopu.aop_dir,
5593 AOP(left)->aopu.aop_dir);
5594 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5595 AOP(result)->aopu.aop_dir,
5596 AOP(result)->aopu.aop_dir);
5601 symbol *tlbl = newiTempLabel(NULL);
5602 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5605 emitpcode(POC_BCF, popGet(AOP(result),0));
5606 if( AOP_TYPE(right) == AOP_ACC) {
5607 emitpcode(POC_IORLW, popGetLit(0));
5609 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5610 emitpcode(POC_BSF, popGet(AOP(result),0));
5615 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5616 pic14_emitcode(";XXX setb","c");
5617 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5618 AOP(left)->aopu.aop_dir,tlbl->key+100);
5619 pic14_toBoolean(right);
5620 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5621 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5622 jmpTrueOrFalse(ifx, tlbl);
5626 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5633 pic14_outBitC(result);
5635 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5636 genIfxJump(ifx, "c");
5640 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5641 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5642 if((AOP_TYPE(right) == AOP_LIT) &&
5643 (AOP_TYPE(result) == AOP_CRY) &&
5644 (AOP_TYPE(left) != AOP_CRY)){
5646 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5649 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5651 continueIfTrue(ifx);
5654 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5655 // lit = 0, result = boolean(left)
5657 pic14_emitcode(";XXX setb","c");
5658 pic14_toBoolean(right);
5660 symbol *tlbl = newiTempLabel(NULL);
5661 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5663 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5665 genIfxJump (ifx,"a");
5669 pic14_outBitC(result);
5673 /* if left is same as result */
5674 if(pic14_sameRegs(AOP(result),AOP(left))){
5676 for(;size--; offset++,lit>>=8) {
5677 if(AOP_TYPE(right) == AOP_LIT){
5678 if((lit & 0xff) == 0)
5679 /* or'ing with 0 has no effect */
5682 int p = my_powof2(lit & 0xff);
5684 /* only one bit is set in the literal, so use a bsf instruction */
5686 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5688 if(know_W != (lit & 0xff))
5689 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5690 know_W = lit & 0xff;
5691 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5696 if (AOP_TYPE(left) == AOP_ACC) {
5697 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5698 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5700 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5701 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5703 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5704 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5710 // left & result in different registers
5711 if(AOP_TYPE(result) == AOP_CRY){
5713 // if(size), result in bit
5714 // if(!size && ifx), conditional oper: if(left | right)
5715 symbol *tlbl = newiTempLabel(NULL);
5716 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5717 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5721 pic14_emitcode(";XXX setb","c");
5723 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5724 pic14_emitcode(";XXX orl","a,%s",
5725 aopGet(AOP(left),offset,FALSE,FALSE));
5726 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5731 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5732 pic14_outBitC(result);
5734 jmpTrueOrFalse(ifx, tlbl);
5735 } else for(;(size--);offset++){
5737 // result = left & right
5738 if(AOP_TYPE(right) == AOP_LIT){
5739 int t = (lit >> (offset*8)) & 0x0FFL;
5742 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5743 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5745 pic14_emitcode("movf","%s,w",
5746 aopGet(AOP(left),offset,FALSE,FALSE));
5747 pic14_emitcode("movwf","%s",
5748 aopGet(AOP(result),offset,FALSE,FALSE));
5751 emitpcode(POC_MOVLW, popGetLit(t));
5752 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5753 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5755 pic14_emitcode("movlw","0x%x",t);
5756 pic14_emitcode("iorwf","%s,w",
5757 aopGet(AOP(left),offset,FALSE,FALSE));
5758 pic14_emitcode("movwf","%s",
5759 aopGet(AOP(result),offset,FALSE,FALSE));
5765 // faster than result <- left, anl result,right
5766 // and better if result is SFR
5767 if (AOP_TYPE(left) == AOP_ACC) {
5768 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5769 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5771 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5772 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5774 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5775 pic14_emitcode("iorwf","%s,w",
5776 aopGet(AOP(left),offset,FALSE,FALSE));
5778 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5779 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5784 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5785 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5786 freeAsmop(result,NULL,ic,TRUE);
5789 /*-----------------------------------------------------------------*/
5790 /* genXor - code for xclusive or */
5791 /*-----------------------------------------------------------------*/
5792 static void genXor (iCode *ic, iCode *ifx)
5794 operand *left, *right, *result;
5796 unsigned long lit = 0L;
5798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5800 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5801 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5802 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5804 /* if left is a literal & right is not ||
5805 if left needs acc & right does not */
5806 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5807 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5808 operand *tmp = right ;
5813 /* if result = right then exchange them */
5814 if(pic14_sameRegs(AOP(result),AOP(right))){
5815 operand *tmp = right ;
5820 /* if right is bit then exchange them */
5821 if (AOP_TYPE(right) == AOP_CRY &&
5822 AOP_TYPE(left) != AOP_CRY){
5823 operand *tmp = right ;
5827 if(AOP_TYPE(right) == AOP_LIT)
5828 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5830 size = AOP_SIZE(result);
5834 if (AOP_TYPE(left) == AOP_CRY){
5835 if(AOP_TYPE(right) == AOP_LIT){
5836 // c = bit & literal;
5838 // lit>>1 != 0 => result = 1
5839 if(AOP_TYPE(result) == AOP_CRY){
5841 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5842 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5844 continueIfTrue(ifx);
5847 pic14_emitcode("setb","c");
5851 // lit == 0, result = left
5852 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5854 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5856 // lit == 1, result = not(left)
5857 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5858 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5859 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5860 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5863 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5864 pic14_emitcode("cpl","c");
5871 symbol *tlbl = newiTempLabel(NULL);
5872 if (AOP_TYPE(right) == AOP_CRY){
5874 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5877 int sizer = AOP_SIZE(right);
5879 // if val>>1 != 0, result = 1
5880 pic14_emitcode("setb","c");
5882 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5884 // test the msb of the lsb
5885 pic14_emitcode("anl","a,#0xfe");
5886 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5890 pic14_emitcode("rrc","a");
5892 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5893 pic14_emitcode("cpl","c");
5894 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5899 pic14_outBitC(result);
5901 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5902 genIfxJump(ifx, "c");
5906 if(pic14_sameRegs(AOP(result),AOP(left))){
5907 /* if left is same as result */
5908 for(;size--; offset++) {
5909 if(AOP_TYPE(right) == AOP_LIT){
5910 int t = (lit >> (offset*8)) & 0x0FFL;
5914 if (IS_AOP_PREG(left)) {
5915 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5916 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5917 aopPut(AOP(result),"a",offset);
5919 emitpcode(POC_MOVLW, popGetLit(t));
5920 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5921 pic14_emitcode("xrl","%s,%s",
5922 aopGet(AOP(left),offset,FALSE,TRUE),
5923 aopGet(AOP(right),offset,FALSE,FALSE));
5926 if (AOP_TYPE(left) == AOP_ACC)
5927 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5929 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5930 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5932 if (IS_AOP_PREG(left)) {
5933 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5934 aopPut(AOP(result),"a",offset);
5936 pic14_emitcode("xrl","%s,a",
5937 aopGet(AOP(left),offset,FALSE,TRUE));
5943 // left & result in different registers
5944 if(AOP_TYPE(result) == AOP_CRY){
5946 // if(size), result in bit
5947 // if(!size && ifx), conditional oper: if(left ^ right)
5948 symbol *tlbl = newiTempLabel(NULL);
5949 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5951 pic14_emitcode("setb","c");
5953 if((AOP_TYPE(right) == AOP_LIT) &&
5954 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5955 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5957 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5958 pic14_emitcode("xrl","a,%s",
5959 aopGet(AOP(left),offset,FALSE,FALSE));
5961 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5966 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5967 pic14_outBitC(result);
5969 jmpTrueOrFalse(ifx, tlbl);
5970 } else for(;(size--);offset++){
5972 // result = left & right
5973 if(AOP_TYPE(right) == AOP_LIT){
5974 int t = (lit >> (offset*8)) & 0x0FFL;
5977 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5978 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5979 pic14_emitcode("movf","%s,w",
5980 aopGet(AOP(left),offset,FALSE,FALSE));
5981 pic14_emitcode("movwf","%s",
5982 aopGet(AOP(result),offset,FALSE,FALSE));
5985 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5986 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5987 pic14_emitcode("comf","%s,w",
5988 aopGet(AOP(left),offset,FALSE,FALSE));
5989 pic14_emitcode("movwf","%s",
5990 aopGet(AOP(result),offset,FALSE,FALSE));
5993 emitpcode(POC_MOVLW, popGetLit(t));
5994 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5995 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5996 pic14_emitcode("movlw","0x%x",t);
5997 pic14_emitcode("xorwf","%s,w",
5998 aopGet(AOP(left),offset,FALSE,FALSE));
5999 pic14_emitcode("movwf","%s",
6000 aopGet(AOP(result),offset,FALSE,FALSE));
6006 // faster than result <- left, anl result,right
6007 // and better if result is SFR
6008 if (AOP_TYPE(left) == AOP_ACC) {
6009 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6010 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6012 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6013 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6014 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6015 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6017 if ( AOP_TYPE(result) != AOP_ACC){
6018 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6019 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6025 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6026 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6027 freeAsmop(result,NULL,ic,TRUE);
6030 /*-----------------------------------------------------------------*/
6031 /* genInline - write the inline code out */
6032 /*-----------------------------------------------------------------*/
6033 static void genInline (iCode *ic)
6035 char *buffer, *bp, *bp1;
6037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6039 _G.inLine += (!options.asmpeep);
6041 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6042 strcpy(buffer,IC_INLINE(ic));
6044 /* emit each line as a code */
6050 addpCode2pBlock(pb,AssembleLine(bp1));
6057 pic14_emitcode(bp1,"");
6063 if ((bp1 != bp) && *bp1)
6064 addpCode2pBlock(pb,AssembleLine(bp1));
6068 _G.inLine -= (!options.asmpeep);
6071 /*-----------------------------------------------------------------*/
6072 /* genRRC - rotate right with carry */
6073 /*-----------------------------------------------------------------*/
6074 static void genRRC (iCode *ic)
6076 operand *left , *result ;
6077 int size, offset = 0, same;
6079 /* rotate right with carry */
6081 result=IC_RESULT(ic);
6082 aopOp (left,ic,FALSE);
6083 aopOp (result,ic,FALSE);
6085 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6087 same = pic14_sameRegs(AOP(result),AOP(left));
6089 size = AOP_SIZE(result);
6091 /* get the lsb and put it into the carry */
6092 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6099 emitpcode(POC_RRF, popGet(AOP(left),offset));
6101 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6102 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6108 freeAsmop(left,NULL,ic,TRUE);
6109 freeAsmop(result,NULL,ic,TRUE);
6112 /*-----------------------------------------------------------------*/
6113 /* genRLC - generate code for rotate left with carry */
6114 /*-----------------------------------------------------------------*/
6115 static void genRLC (iCode *ic)
6117 operand *left , *result ;
6118 int size, offset = 0;
6121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6122 /* rotate right with carry */
6124 result=IC_RESULT(ic);
6125 aopOp (left,ic,FALSE);
6126 aopOp (result,ic,FALSE);
6128 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6130 same = pic14_sameRegs(AOP(result),AOP(left));
6132 /* move it to the result */
6133 size = AOP_SIZE(result);
6135 /* get the msb and put it into the carry */
6136 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6143 emitpcode(POC_RLF, popGet(AOP(left),offset));
6145 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6146 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6153 freeAsmop(left,NULL,ic,TRUE);
6154 freeAsmop(result,NULL,ic,TRUE);
6157 /*-----------------------------------------------------------------*/
6158 /* genGetHbit - generates code get highest order bit */
6159 /*-----------------------------------------------------------------*/
6160 static void genGetHbit (iCode *ic)
6162 operand *left, *result;
6164 result=IC_RESULT(ic);
6165 aopOp (left,ic,FALSE);
6166 aopOp (result,ic,FALSE);
6168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6169 /* get the highest order byte into a */
6170 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6171 if(AOP_TYPE(result) == AOP_CRY){
6172 pic14_emitcode("rlc","a");
6173 pic14_outBitC(result);
6176 pic14_emitcode("rl","a");
6177 pic14_emitcode("anl","a,#0x01");
6178 pic14_outAcc(result);
6182 freeAsmop(left,NULL,ic,TRUE);
6183 freeAsmop(result,NULL,ic,TRUE);
6186 /*-----------------------------------------------------------------*/
6187 /* AccRol - rotate left accumulator by known count */
6188 /*-----------------------------------------------------------------*/
6189 static void AccRol (int shCount)
6191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6192 shCount &= 0x0007; // shCount : 0..7
6197 pic14_emitcode("rl","a");
6200 pic14_emitcode("rl","a");
6201 pic14_emitcode("rl","a");
6204 pic14_emitcode("swap","a");
6205 pic14_emitcode("rr","a");
6208 pic14_emitcode("swap","a");
6211 pic14_emitcode("swap","a");
6212 pic14_emitcode("rl","a");
6215 pic14_emitcode("rr","a");
6216 pic14_emitcode("rr","a");
6219 pic14_emitcode("rr","a");
6224 /*-----------------------------------------------------------------*/
6225 /* AccLsh - left shift accumulator by known count */
6226 /*-----------------------------------------------------------------*/
6227 static void AccLsh (int shCount)
6229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6232 pic14_emitcode("add","a,acc");
6235 pic14_emitcode("add","a,acc");
6236 pic14_emitcode("add","a,acc");
6238 /* rotate left accumulator */
6240 /* and kill the lower order bits */
6241 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6246 /*-----------------------------------------------------------------*/
6247 /* AccRsh - right shift accumulator by known count */
6248 /*-----------------------------------------------------------------*/
6249 static void AccRsh (int shCount)
6251 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6255 pic14_emitcode("rrc","a");
6257 /* rotate right accumulator */
6258 AccRol(8 - shCount);
6259 /* and kill the higher order bits */
6260 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6266 /*-----------------------------------------------------------------*/
6267 /* AccSRsh - signed right shift accumulator by known count */
6268 /*-----------------------------------------------------------------*/
6269 static void AccSRsh (int shCount)
6272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6275 pic14_emitcode("mov","c,acc.7");
6276 pic14_emitcode("rrc","a");
6277 } else if(shCount == 2){
6278 pic14_emitcode("mov","c,acc.7");
6279 pic14_emitcode("rrc","a");
6280 pic14_emitcode("mov","c,acc.7");
6281 pic14_emitcode("rrc","a");
6283 tlbl = newiTempLabel(NULL);
6284 /* rotate right accumulator */
6285 AccRol(8 - shCount);
6286 /* and kill the higher order bits */
6287 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6288 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6289 pic14_emitcode("orl","a,#0x%02x",
6290 (unsigned char)~SRMask[shCount]);
6291 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6296 /*-----------------------------------------------------------------*/
6297 /* shiftR1Left2Result - shift right one byte from left to result */
6298 /*-----------------------------------------------------------------*/
6299 static void shiftR1Left2ResultSigned (operand *left, int offl,
6300 operand *result, int offr,
6305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6307 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6311 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6313 emitpcode(POC_RRF, popGet(AOP(result),offr));
6315 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6316 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6322 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6324 emitpcode(POC_RRF, popGet(AOP(result),offr));
6326 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6327 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6329 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6330 emitpcode(POC_RRF, popGet(AOP(result),offr));
6336 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6338 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6339 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6342 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6343 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6344 emitpcode(POC_ANDLW, popGetLit(0x1f));
6346 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6347 emitpcode(POC_IORLW, popGetLit(0xe0));
6349 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6353 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6354 emitpcode(POC_ANDLW, popGetLit(0x0f));
6355 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6356 emitpcode(POC_IORLW, popGetLit(0xf0));
6357 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6361 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6363 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6364 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6366 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6367 emitpcode(POC_ANDLW, popGetLit(0x07));
6368 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6369 emitpcode(POC_IORLW, popGetLit(0xf8));
6370 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6375 emitpcode(POC_MOVLW, popGetLit(0x00));
6376 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6377 emitpcode(POC_MOVLW, popGetLit(0xfe));
6378 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6379 emitpcode(POC_IORLW, popGetLit(0x01));
6380 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6382 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6383 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6384 emitpcode(POC_DECF, popGet(AOP(result),offr));
6385 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6386 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6392 emitpcode(POC_MOVLW, popGetLit(0x00));
6393 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6394 emitpcode(POC_MOVLW, popGetLit(0xff));
6395 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6397 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6398 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6399 emitpcode(POC_DECF, popGet(AOP(result),offr));
6407 /*-----------------------------------------------------------------*/
6408 /* shiftR1Left2Result - shift right one byte from left to result */
6409 /*-----------------------------------------------------------------*/
6410 static void shiftR1Left2Result (operand *left, int offl,
6411 operand *result, int offr,
6412 int shCount, int sign)
6416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6418 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6420 /* Copy the msb into the carry if signed. */
6422 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6432 emitpcode(POC_RRF, popGet(AOP(result),offr));
6434 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6435 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6441 emitpcode(POC_RRF, popGet(AOP(result),offr));
6443 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6444 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6447 emitpcode(POC_RRF, popGet(AOP(result),offr));
6452 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6454 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6455 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6458 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6459 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6460 emitpcode(POC_ANDLW, popGetLit(0x1f));
6461 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6465 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6466 emitpcode(POC_ANDLW, popGetLit(0x0f));
6467 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6471 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6472 emitpcode(POC_ANDLW, popGetLit(0x0f));
6473 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6475 emitpcode(POC_RRF, popGet(AOP(result),offr));
6480 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6481 emitpcode(POC_ANDLW, popGetLit(0x80));
6482 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483 emitpcode(POC_RLF, popGet(AOP(result),offr));
6484 emitpcode(POC_RLF, popGet(AOP(result),offr));
6489 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6490 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6491 emitpcode(POC_RLF, popGet(AOP(result),offr));
6500 /*-----------------------------------------------------------------*/
6501 /* shiftL1Left2Result - shift left one byte from left to result */
6502 /*-----------------------------------------------------------------*/
6503 static void shiftL1Left2Result (operand *left, int offl,
6504 operand *result, int offr, int shCount)
6509 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6511 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6512 DEBUGpic14_emitcode ("; ***","same = %d",same);
6513 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6515 /* shift left accumulator */
6516 //AccLsh(shCount); // don't comment out just yet...
6517 // aopPut(AOP(result),"a",offr);
6521 /* Shift left 1 bit position */
6522 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6524 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6526 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6527 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6531 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6532 emitpcode(POC_ANDLW,popGetLit(0x7e));
6533 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6534 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6537 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6538 emitpcode(POC_ANDLW,popGetLit(0x3e));
6539 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6540 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6541 emitpcode(POC_RLF, popGet(AOP(result),offr));
6544 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6545 emitpcode(POC_ANDLW, popGetLit(0xf0));
6546 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6549 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6550 emitpcode(POC_ANDLW, popGetLit(0xf0));
6551 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6552 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6555 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6556 emitpcode(POC_ANDLW, popGetLit(0x30));
6557 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6558 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6559 emitpcode(POC_RLF, popGet(AOP(result),offr));
6562 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6563 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6564 emitpcode(POC_RRF, popGet(AOP(result),offr));
6568 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6573 /*-----------------------------------------------------------------*/
6574 /* movLeft2Result - move byte from left to result */
6575 /*-----------------------------------------------------------------*/
6576 static void movLeft2Result (operand *left, int offl,
6577 operand *result, int offr)
6580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6581 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6582 l = aopGet(AOP(left),offl,FALSE,FALSE);
6584 if (*l == '@' && (IS_AOP_PREG(result))) {
6585 pic14_emitcode("mov","a,%s",l);
6586 aopPut(AOP(result),"a",offr);
6588 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6589 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6594 /*-----------------------------------------------------------------*/
6595 /* shiftL2Left2Result - shift left two bytes from left to result */
6596 /*-----------------------------------------------------------------*/
6597 static void shiftL2Left2Result (operand *left, int offl,
6598 operand *result, int offr, int shCount)
6602 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6604 if(pic14_sameRegs(AOP(result), AOP(left))) {
6612 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6613 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6614 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_RLF, popGet(AOP(result),offr));
6619 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6625 emitpcode(POC_MOVLW, popGetLit(0x0f));
6626 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6627 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6628 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6629 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6630 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6631 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6633 emitpcode(POC_RLF, popGet(AOP(result),offr));
6634 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6638 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6639 emitpcode(POC_RRF, popGet(AOP(result),offr));
6640 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6641 emitpcode(POC_RRF, popGet(AOP(result),offr));
6642 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6643 emitpcode(POC_ANDLW,popGetLit(0xc0));
6644 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6645 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6646 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6647 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6650 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6651 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6652 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6653 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6654 emitpcode(POC_RRF, popGet(AOP(result),offr));
6664 /* note, use a mov/add for the shift since the mov has a
6665 chance of getting optimized out */
6666 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6667 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6668 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6669 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6670 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_RLF, popGet(AOP(result),offr));
6675 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6682 emitpcode(POC_ANDLW, popGetLit(0xF0));
6683 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6685 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6686 emitpcode(POC_ANDLW, popGetLit(0xF0));
6687 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6688 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_RLF, popGet(AOP(result),offr));
6693 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6697 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6698 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6699 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6700 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6702 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6703 emitpcode(POC_RRF, popGet(AOP(result),offr));
6704 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6705 emitpcode(POC_ANDLW,popGetLit(0xc0));
6706 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6707 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6708 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6709 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6712 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6713 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6714 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6716 emitpcode(POC_RRF, popGet(AOP(result),offr));
6721 /*-----------------------------------------------------------------*/
6722 /* shiftR2Left2Result - shift right two bytes from left to result */
6723 /*-----------------------------------------------------------------*/
6724 static void shiftR2Left2Result (operand *left, int offl,
6725 operand *result, int offr,
6726 int shCount, int sign)
6730 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6731 same = pic14_sameRegs(AOP(result), AOP(left));
6733 if(same && ((offl + MSB16) == offr)){
6735 /* don't crash result[offr] */
6736 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6737 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6739 movLeft2Result(left,offl, result, offr);
6740 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6742 /* a:x >> shCount (x = lsb(result))*/
6745 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6747 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6756 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6761 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6762 emitpcode(POC_RRF,popGet(AOP(result),offr));
6764 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6765 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6766 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6767 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6772 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6776 emitpcode(POC_RRF,popGet(AOP(result),offr));
6783 emitpcode(POC_MOVLW, popGetLit(0xf0));
6784 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6785 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6787 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6788 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6789 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6790 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6792 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6793 emitpcode(POC_ANDLW, popGetLit(0x0f));
6794 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6796 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6797 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6798 emitpcode(POC_ANDLW, popGetLit(0xf0));
6799 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6804 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6805 emitpcode(POC_RRF, popGet(AOP(result),offr));
6809 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6810 emitpcode(POC_BTFSC,
6811 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6812 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6820 emitpcode(POC_RLF, popGet(AOP(result),offr));
6821 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6823 emitpcode(POC_RLF, popGet(AOP(result),offr));
6824 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6825 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6826 emitpcode(POC_ANDLW,popGetLit(0x03));
6828 emitpcode(POC_BTFSC,
6829 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6830 emitpcode(POC_IORLW,popGetLit(0xfc));
6832 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6834 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6835 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6837 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6838 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6840 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6841 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6842 emitpcode(POC_ANDLW,popGetLit(0x03));
6844 emitpcode(POC_BTFSC,
6845 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6846 emitpcode(POC_IORLW,popGetLit(0xfc));
6848 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6849 emitpcode(POC_RLF, popGet(AOP(result),offr));
6856 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6857 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6858 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6859 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6862 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6864 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6869 /*-----------------------------------------------------------------*/
6870 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6871 /*-----------------------------------------------------------------*/
6872 static void shiftLLeftOrResult (operand *left, int offl,
6873 operand *result, int offr, int shCount)
6875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6876 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6877 /* shift left accumulator */
6879 /* or with result */
6880 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6881 /* back to result */
6882 aopPut(AOP(result),"a",offr);
6885 /*-----------------------------------------------------------------*/
6886 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6887 /*-----------------------------------------------------------------*/
6888 static void shiftRLeftOrResult (operand *left, int offl,
6889 operand *result, int offr, int shCount)
6891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6892 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6893 /* shift right accumulator */
6895 /* or with result */
6896 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6897 /* back to result */
6898 aopPut(AOP(result),"a",offr);
6901 /*-----------------------------------------------------------------*/
6902 /* genlshOne - left shift a one byte quantity by known count */
6903 /*-----------------------------------------------------------------*/
6904 static void genlshOne (operand *result, operand *left, int shCount)
6906 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6907 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6910 /*-----------------------------------------------------------------*/
6911 /* genlshTwo - left shift two bytes by known amount != 0 */
6912 /*-----------------------------------------------------------------*/
6913 static void genlshTwo (operand *result,operand *left, int shCount)
6917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6918 size = pic14_getDataSize(result);
6920 /* if shCount >= 8 */
6926 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6928 movLeft2Result(left, LSB, result, MSB16);
6930 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6933 /* 1 <= shCount <= 7 */
6936 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6938 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6942 /*-----------------------------------------------------------------*/
6943 /* shiftLLong - shift left one long from left to result */
6944 /* offl = LSB or MSB16 */
6945 /*-----------------------------------------------------------------*/
6946 static void shiftLLong (operand *left, operand *result, int offr )
6949 int size = AOP_SIZE(result);
6951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6952 if(size >= LSB+offr){
6953 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6955 pic14_emitcode("add","a,acc");
6956 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6957 size >= MSB16+offr && offr != LSB )
6958 pic14_emitcode("xch","a,%s",
6959 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6961 aopPut(AOP(result),"a",LSB+offr);
6964 if(size >= MSB16+offr){
6965 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6966 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6969 pic14_emitcode("rlc","a");
6970 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6971 size >= MSB24+offr && offr != LSB)
6972 pic14_emitcode("xch","a,%s",
6973 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6975 aopPut(AOP(result),"a",MSB16+offr);
6978 if(size >= MSB24+offr){
6979 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6980 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6983 pic14_emitcode("rlc","a");
6984 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6985 size >= MSB32+offr && offr != LSB )
6986 pic14_emitcode("xch","a,%s",
6987 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6989 aopPut(AOP(result),"a",MSB24+offr);
6992 if(size > MSB32+offr){
6993 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6994 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6997 pic14_emitcode("rlc","a");
6998 aopPut(AOP(result),"a",MSB32+offr);
7001 aopPut(AOP(result),zero,LSB);
7004 /*-----------------------------------------------------------------*/
7005 /* genlshFour - shift four byte by a known amount != 0 */
7006 /*-----------------------------------------------------------------*/
7007 static void genlshFour (operand *result, operand *left, int shCount)
7011 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7012 size = AOP_SIZE(result);
7014 /* if shifting more that 3 bytes */
7015 if (shCount >= 24 ) {
7018 /* lowest order of left goes to the highest
7019 order of the destination */
7020 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7022 movLeft2Result(left, LSB, result, MSB32);
7023 aopPut(AOP(result),zero,LSB);
7024 aopPut(AOP(result),zero,MSB16);
7025 aopPut(AOP(result),zero,MSB32);
7029 /* more than two bytes */
7030 else if ( shCount >= 16 ) {
7031 /* lower order two bytes goes to higher order two bytes */
7033 /* if some more remaining */
7035 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7037 movLeft2Result(left, MSB16, result, MSB32);
7038 movLeft2Result(left, LSB, result, MSB24);
7040 aopPut(AOP(result),zero,MSB16);
7041 aopPut(AOP(result),zero,LSB);
7045 /* if more than 1 byte */
7046 else if ( shCount >= 8 ) {
7047 /* lower order three bytes goes to higher order three bytes */
7051 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7053 movLeft2Result(left, LSB, result, MSB16);
7055 else{ /* size = 4 */
7057 movLeft2Result(left, MSB24, result, MSB32);
7058 movLeft2Result(left, MSB16, result, MSB24);
7059 movLeft2Result(left, LSB, result, MSB16);
7060 aopPut(AOP(result),zero,LSB);
7062 else if(shCount == 1)
7063 shiftLLong(left, result, MSB16);
7065 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7066 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7067 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7068 aopPut(AOP(result),zero,LSB);
7073 /* 1 <= shCount <= 7 */
7074 else if(shCount <= 2){
7075 shiftLLong(left, result, LSB);
7077 shiftLLong(result, result, LSB);
7079 /* 3 <= shCount <= 7, optimize */
7081 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7082 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7083 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7087 /*-----------------------------------------------------------------*/
7088 /* genLeftShiftLiteral - left shifting by known count */
7089 /*-----------------------------------------------------------------*/
7090 static void genLeftShiftLiteral (operand *left,
7095 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7099 freeAsmop(right,NULL,ic,TRUE);
7101 aopOp(left,ic,FALSE);
7102 aopOp(result,ic,FALSE);
7104 size = getSize(operandType(result));
7107 pic14_emitcode("; shift left ","result %d, left %d",size,
7111 /* I suppose that the left size >= result size */
7114 movLeft2Result(left, size, result, size);
7118 else if(shCount >= (size * 8))
7120 aopPut(AOP(result),zero,size);
7124 genlshOne (result,left,shCount);
7129 genlshTwo (result,left,shCount);
7133 genlshFour (result,left,shCount);
7137 freeAsmop(left,NULL,ic,TRUE);
7138 freeAsmop(result,NULL,ic,TRUE);
7141 /*-----------------------------------------------------------------*
7142 * genMultiAsm - repeat assembly instruction for size of register.
7143 * if endian == 1, then the high byte (i.e base address + size of
7144 * register) is used first else the low byte is used first;
7145 *-----------------------------------------------------------------*/
7146 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7151 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7164 emitpcode(poc, popGet(AOP(reg),offset));
7169 /*-----------------------------------------------------------------*/
7170 /* genLeftShift - generates code for left shifting */
7171 /*-----------------------------------------------------------------*/
7172 static void genLeftShift (iCode *ic)
7174 operand *left,*right, *result;
7177 symbol *tlbl , *tlbl1;
7180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7182 right = IC_RIGHT(ic);
7184 result = IC_RESULT(ic);
7186 aopOp(right,ic,FALSE);
7188 /* if the shift count is known then do it
7189 as efficiently as possible */
7190 if (AOP_TYPE(right) == AOP_LIT) {
7191 genLeftShiftLiteral (left,right,result,ic);
7195 /* shift count is unknown then we have to form
7196 a loop get the loop count in B : Note: we take
7197 only the lower order byte since shifting
7198 more that 32 bits make no sense anyway, ( the
7199 largest size of an object can be only 32 bits ) */
7202 aopOp(left,ic,FALSE);
7203 aopOp(result,ic,FALSE);
7205 /* now move the left to the result if they are not the
7207 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7208 AOP_SIZE(result) > 1) {
7210 size = AOP_SIZE(result);
7213 l = aopGet(AOP(left),offset,FALSE,TRUE);
7214 if (*l == '@' && (IS_AOP_PREG(result))) {
7216 pic14_emitcode("mov","a,%s",l);
7217 aopPut(AOP(result),"a",offset);
7219 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7220 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7221 //aopPut(AOP(result),l,offset);
7227 size = AOP_SIZE(result);
7229 /* if it is only one byte then */
7231 if(optimized_for_speed) {
7232 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7233 emitpcode(POC_ANDLW, popGetLit(0xf0));
7234 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7235 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7236 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7237 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7238 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7239 emitpcode(POC_RLFW, popGet(AOP(result),0));
7240 emitpcode(POC_ANDLW, popGetLit(0xfe));
7241 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7242 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7243 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7246 tlbl = newiTempLabel(NULL);
7247 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7248 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7249 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7252 emitpcode(POC_COMFW, popGet(AOP(right),0));
7253 emitpcode(POC_RRF, popGet(AOP(result),0));
7254 emitpLabel(tlbl->key);
7255 emitpcode(POC_RLF, popGet(AOP(result),0));
7256 emitpcode(POC_ADDLW, popGetLit(1));
7258 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7263 if (pic14_sameRegs(AOP(left),AOP(result))) {
7265 tlbl = newiTempLabel(NULL);
7266 emitpcode(POC_COMFW, popGet(AOP(right),0));
7267 genMultiAsm(POC_RRF, result, size,1);
7268 emitpLabel(tlbl->key);
7269 genMultiAsm(POC_RLF, result, size,0);
7270 emitpcode(POC_ADDLW, popGetLit(1));
7272 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7276 //tlbl = newiTempLabel(NULL);
7278 //tlbl1 = newiTempLabel(NULL);
7280 //reAdjustPreg(AOP(result));
7282 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7283 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7284 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7286 //pic14_emitcode("add","a,acc");
7287 //aopPut(AOP(result),"a",offset++);
7289 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7291 // pic14_emitcode("rlc","a");
7292 // aopPut(AOP(result),"a",offset++);
7294 //reAdjustPreg(AOP(result));
7296 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7297 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7300 tlbl = newiTempLabel(NULL);
7301 tlbl1= newiTempLabel(NULL);
7303 size = AOP_SIZE(result);
7306 pctemp = popGetTempReg(); /* grab a temporary working register. */
7308 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7310 /* offset should be 0, 1 or 3 */
7311 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7313 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7315 emitpcode(POC_MOVWF, pctemp);
7318 emitpLabel(tlbl->key);
7321 emitpcode(POC_RLF, popGet(AOP(result),0));
7323 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7325 emitpcode(POC_DECFSZ, pctemp);
7326 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7327 emitpLabel(tlbl1->key);
7329 popReleaseTempReg(pctemp);
7333 freeAsmop (right,NULL,ic,TRUE);
7334 freeAsmop(left,NULL,ic,TRUE);
7335 freeAsmop(result,NULL,ic,TRUE);
7338 /*-----------------------------------------------------------------*/
7339 /* genrshOne - right shift a one byte quantity by known count */
7340 /*-----------------------------------------------------------------*/
7341 static void genrshOne (operand *result, operand *left,
7342 int shCount, int sign)
7344 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7345 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7348 /*-----------------------------------------------------------------*/
7349 /* genrshTwo - right shift two bytes by known amount != 0 */
7350 /*-----------------------------------------------------------------*/
7351 static void genrshTwo (operand *result,operand *left,
7352 int shCount, int sign)
7354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7355 /* if shCount >= 8 */
7359 shiftR1Left2Result(left, MSB16, result, LSB,
7362 movLeft2Result(left, MSB16, result, LSB);
7364 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7367 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7368 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7372 /* 1 <= shCount <= 7 */
7374 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7377 /*-----------------------------------------------------------------*/
7378 /* shiftRLong - shift right one long from left to result */
7379 /* offl = LSB or MSB16 */
7380 /*-----------------------------------------------------------------*/
7381 static void shiftRLong (operand *left, int offl,
7382 operand *result, int sign)
7384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7386 pic14_emitcode("clr","c");
7387 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7389 pic14_emitcode("mov","c,acc.7");
7390 pic14_emitcode("rrc","a");
7391 aopPut(AOP(result),"a",MSB32-offl);
7393 /* add sign of "a" */
7394 addSign(result, MSB32, sign);
7396 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7397 pic14_emitcode("rrc","a");
7398 aopPut(AOP(result),"a",MSB24-offl);
7400 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7401 pic14_emitcode("rrc","a");
7402 aopPut(AOP(result),"a",MSB16-offl);
7405 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7406 pic14_emitcode("rrc","a");
7407 aopPut(AOP(result),"a",LSB);
7411 /*-----------------------------------------------------------------*/
7412 /* genrshFour - shift four byte by a known amount != 0 */
7413 /*-----------------------------------------------------------------*/
7414 static void genrshFour (operand *result, operand *left,
7415 int shCount, int sign)
7417 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7418 /* if shifting more that 3 bytes */
7419 if(shCount >= 24 ) {
7422 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7424 movLeft2Result(left, MSB32, result, LSB);
7426 addSign(result, MSB16, sign);
7428 else if(shCount >= 16){
7431 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7433 movLeft2Result(left, MSB24, result, LSB);
7434 movLeft2Result(left, MSB32, result, MSB16);
7436 addSign(result, MSB24, sign);
7438 else if(shCount >= 8){
7441 shiftRLong(left, MSB16, result, sign);
7442 else if(shCount == 0){
7443 movLeft2Result(left, MSB16, result, LSB);
7444 movLeft2Result(left, MSB24, result, MSB16);
7445 movLeft2Result(left, MSB32, result, MSB24);
7446 addSign(result, MSB32, sign);
7449 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7450 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7451 /* the last shift is signed */
7452 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7453 addSign(result, MSB32, sign);
7456 else{ /* 1 <= shCount <= 7 */
7458 shiftRLong(left, LSB, result, sign);
7460 shiftRLong(result, LSB, result, sign);
7463 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7464 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7465 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7470 /*-----------------------------------------------------------------*/
7471 /* genRightShiftLiteral - right shifting by known count */
7472 /*-----------------------------------------------------------------*/
7473 static void genRightShiftLiteral (operand *left,
7479 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7482 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7483 freeAsmop(right,NULL,ic,TRUE);
7485 aopOp(left,ic,FALSE);
7486 aopOp(result,ic,FALSE);
7489 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7493 lsize = pic14_getDataSize(left);
7494 res_size = pic14_getDataSize(result);
7495 /* test the LEFT size !!! */
7497 /* I suppose that the left size >= result size */
7500 movLeft2Result(left, lsize, result, res_size);
7503 else if(shCount >= (lsize * 8)){
7506 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7508 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7509 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7514 emitpcode(POC_MOVLW, popGetLit(0));
7515 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7516 emitpcode(POC_MOVLW, popGetLit(0xff));
7518 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7523 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7530 genrshOne (result,left,shCount,sign);
7534 genrshTwo (result,left,shCount,sign);
7538 genrshFour (result,left,shCount,sign);
7546 freeAsmop(left,NULL,ic,TRUE);
7547 freeAsmop(result,NULL,ic,TRUE);
7550 /*-----------------------------------------------------------------*/
7551 /* genSignedRightShift - right shift of signed number */
7552 /*-----------------------------------------------------------------*/
7553 static void genSignedRightShift (iCode *ic)
7555 operand *right, *left, *result;
7558 symbol *tlbl, *tlbl1 ;
7561 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7563 /* we do it the hard way put the shift count in b
7564 and loop thru preserving the sign */
7565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7567 right = IC_RIGHT(ic);
7569 result = IC_RESULT(ic);
7571 aopOp(right,ic,FALSE);
7572 aopOp(left,ic,FALSE);
7573 aopOp(result,ic,FALSE);
7576 if ( AOP_TYPE(right) == AOP_LIT) {
7577 genRightShiftLiteral (left,right,result,ic,1);
7580 /* shift count is unknown then we have to form
7581 a loop get the loop count in B : Note: we take
7582 only the lower order byte since shifting
7583 more that 32 bits make no sense anyway, ( the
7584 largest size of an object can be only 32 bits ) */
7586 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7587 //pic14_emitcode("inc","b");
7588 //freeAsmop (right,NULL,ic,TRUE);
7589 //aopOp(left,ic,FALSE);
7590 //aopOp(result,ic,FALSE);
7592 /* now move the left to the result if they are not the
7594 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7595 AOP_SIZE(result) > 1) {
7597 size = AOP_SIZE(result);
7601 l = aopGet(AOP(left),offset,FALSE,TRUE);
7602 if (*l == '@' && IS_AOP_PREG(result)) {
7604 pic14_emitcode("mov","a,%s",l);
7605 aopPut(AOP(result),"a",offset);
7607 aopPut(AOP(result),l,offset);
7609 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7610 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7616 /* mov the highest order bit to OVR */
7617 tlbl = newiTempLabel(NULL);
7618 tlbl1= newiTempLabel(NULL);
7620 size = AOP_SIZE(result);
7623 pctemp = popGetTempReg(); /* grab a temporary working register. */
7625 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7627 /* offset should be 0, 1 or 3 */
7628 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7630 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7632 emitpcode(POC_MOVWF, pctemp);
7635 emitpLabel(tlbl->key);
7637 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7638 emitpcode(POC_RRF, popGet(AOP(result),offset));
7641 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7644 emitpcode(POC_DECFSZ, pctemp);
7645 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7646 emitpLabel(tlbl1->key);
7648 popReleaseTempReg(pctemp);
7650 size = AOP_SIZE(result);
7652 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7653 pic14_emitcode("rlc","a");
7654 pic14_emitcode("mov","ov,c");
7655 /* if it is only one byte then */
7657 l = aopGet(AOP(left),0,FALSE,FALSE);
7659 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7660 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7661 pic14_emitcode("mov","c,ov");
7662 pic14_emitcode("rrc","a");
7663 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7664 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7665 aopPut(AOP(result),"a",0);
7669 reAdjustPreg(AOP(result));
7670 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7671 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7672 pic14_emitcode("mov","c,ov");
7674 l = aopGet(AOP(result),offset,FALSE,FALSE);
7676 pic14_emitcode("rrc","a");
7677 aopPut(AOP(result),"a",offset--);
7679 reAdjustPreg(AOP(result));
7680 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7681 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7686 freeAsmop(left,NULL,ic,TRUE);
7687 freeAsmop(result,NULL,ic,TRUE);
7688 freeAsmop(right,NULL,ic,TRUE);
7691 /*-----------------------------------------------------------------*/
7692 /* genRightShift - generate code for right shifting */
7693 /*-----------------------------------------------------------------*/
7694 static void genRightShift (iCode *ic)
7696 operand *right, *left, *result;
7700 symbol *tlbl, *tlbl1 ;
7702 /* if signed then we do it the hard way preserve the
7703 sign bit moving it inwards */
7704 retype = getSpec(operandType(IC_RESULT(ic)));
7705 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7707 if (!SPEC_USIGN(retype)) {
7708 genSignedRightShift (ic);
7712 /* signed & unsigned types are treated the same : i.e. the
7713 signed is NOT propagated inwards : quoting from the
7714 ANSI - standard : "for E1 >> E2, is equivalent to division
7715 by 2**E2 if unsigned or if it has a non-negative value,
7716 otherwise the result is implementation defined ", MY definition
7717 is that the sign does not get propagated */
7719 right = IC_RIGHT(ic);
7721 result = IC_RESULT(ic);
7723 aopOp(right,ic,FALSE);
7725 /* if the shift count is known then do it
7726 as efficiently as possible */
7727 if (AOP_TYPE(right) == AOP_LIT) {
7728 genRightShiftLiteral (left,right,result,ic, 0);
7732 /* shift count is unknown then we have to form
7733 a loop get the loop count in B : Note: we take
7734 only the lower order byte since shifting
7735 more that 32 bits make no sense anyway, ( the
7736 largest size of an object can be only 32 bits ) */
7738 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7739 pic14_emitcode("inc","b");
7740 aopOp(left,ic,FALSE);
7741 aopOp(result,ic,FALSE);
7743 /* now move the left to the result if they are not the
7745 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7746 AOP_SIZE(result) > 1) {
7748 size = AOP_SIZE(result);
7751 l = aopGet(AOP(left),offset,FALSE,TRUE);
7752 if (*l == '@' && IS_AOP_PREG(result)) {
7754 pic14_emitcode("mov","a,%s",l);
7755 aopPut(AOP(result),"a",offset);
7757 aopPut(AOP(result),l,offset);
7762 tlbl = newiTempLabel(NULL);
7763 tlbl1= newiTempLabel(NULL);
7764 size = AOP_SIZE(result);
7767 /* if it is only one byte then */
7770 tlbl = newiTempLabel(NULL);
7771 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7772 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7773 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7776 emitpcode(POC_COMFW, popGet(AOP(right),0));
7777 emitpcode(POC_RLF, popGet(AOP(result),0));
7778 emitpLabel(tlbl->key);
7779 emitpcode(POC_RRF, popGet(AOP(result),0));
7780 emitpcode(POC_ADDLW, popGetLit(1));
7782 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7787 reAdjustPreg(AOP(result));
7788 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7789 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7792 l = aopGet(AOP(result),offset,FALSE,FALSE);
7794 pic14_emitcode("rrc","a");
7795 aopPut(AOP(result),"a",offset--);
7797 reAdjustPreg(AOP(result));
7799 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7800 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7803 freeAsmop(left,NULL,ic,TRUE);
7804 freeAsmop (right,NULL,ic,TRUE);
7805 freeAsmop(result,NULL,ic,TRUE);
7808 /*-----------------------------------------------------------------*/
7809 /* genUnpackBits - generates code for unpacking bits */
7810 /*-----------------------------------------------------------------*/
7811 static void genUnpackBits (operand *result, char *rname, int ptype)
7818 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7819 etype = getSpec(operandType(result));
7821 /* read the first byte */
7826 pic14_emitcode("mov","a,@%s",rname);
7830 pic14_emitcode("movx","a,@%s",rname);
7834 pic14_emitcode("movx","a,@dptr");
7838 pic14_emitcode("clr","a");
7839 pic14_emitcode("movc","a","@a+dptr");
7843 pic14_emitcode("lcall","__gptrget");
7847 /* if we have bitdisplacement then it fits */
7848 /* into this byte completely or if length is */
7849 /* less than a byte */
7850 if ((shCnt = SPEC_BSTR(etype)) ||
7851 (SPEC_BLEN(etype) <= 8)) {
7853 /* shift right acc */
7856 pic14_emitcode("anl","a,#0x%02x",
7857 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7858 aopPut(AOP(result),"a",offset);
7862 /* bit field did not fit in a byte */
7863 rlen = SPEC_BLEN(etype) - 8;
7864 aopPut(AOP(result),"a",offset++);
7871 pic14_emitcode("inc","%s",rname);
7872 pic14_emitcode("mov","a,@%s",rname);
7876 pic14_emitcode("inc","%s",rname);
7877 pic14_emitcode("movx","a,@%s",rname);
7881 pic14_emitcode("inc","dptr");
7882 pic14_emitcode("movx","a,@dptr");
7886 pic14_emitcode("clr","a");
7887 pic14_emitcode("inc","dptr");
7888 pic14_emitcode("movc","a","@a+dptr");
7892 pic14_emitcode("inc","dptr");
7893 pic14_emitcode("lcall","__gptrget");
7898 /* if we are done */
7902 aopPut(AOP(result),"a",offset++);
7907 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7908 aopPut(AOP(result),"a",offset);
7915 /*-----------------------------------------------------------------*/
7916 /* genDataPointerGet - generates code when ptr offset is known */
7917 /*-----------------------------------------------------------------*/
7918 static void genDataPointerGet (operand *left,
7922 int size , offset = 0;
7925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7928 /* optimization - most of the time, left and result are the same
7929 * address, but different types. for the pic code, we could omit
7933 aopOp(result,ic,TRUE);
7935 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7937 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7939 size = AOP_SIZE(result);
7942 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7946 freeAsmop(left,NULL,ic,TRUE);
7947 freeAsmop(result,NULL,ic,TRUE);
7950 /*-----------------------------------------------------------------*/
7951 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7952 /*-----------------------------------------------------------------*/
7953 static void genNearPointerGet (operand *left,
7958 //regs *preg = NULL ;
7960 sym_link *rtype, *retype;
7961 sym_link *ltype = operandType(left);
7964 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 rtype = operandType(result);
7967 retype= getSpec(rtype);
7969 aopOp(left,ic,FALSE);
7971 /* if left is rematerialisable and
7972 result is not bit variable type and
7973 the left is pointer to data space i.e
7974 lower 128 bytes of space */
7975 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7976 !IS_BITVAR(retype) &&
7977 DCL_TYPE(ltype) == POINTER) {
7978 //genDataPointerGet (left,result,ic);
7982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7984 /* if the value is already in a pointer register
7985 then don't need anything more */
7986 if (!AOP_INPREG(AOP(left))) {
7987 /* otherwise get a free pointer register */
7988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7991 preg = getFreePtr(ic,&aop,FALSE);
7992 pic14_emitcode("mov","%s,%s",
7994 aopGet(AOP(left),0,FALSE,TRUE));
7995 rname = preg->name ;
7999 rname = aopGet(AOP(left),0,FALSE,FALSE);
8001 aopOp (result,ic,FALSE);
8003 /* if bitfield then unpack the bits */
8004 if (IS_BITVAR(retype))
8005 genUnpackBits (result,rname,POINTER);
8007 /* we have can just get the values */
8008 int size = AOP_SIZE(result);
8011 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8013 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8014 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8016 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8017 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8019 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8023 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8025 pic14_emitcode("mov","a,@%s",rname);
8026 aopPut(AOP(result),"a",offset);
8028 sprintf(buffer,"@%s",rname);
8029 aopPut(AOP(result),buffer,offset);
8033 pic14_emitcode("inc","%s",rname);
8038 /* now some housekeeping stuff */
8040 /* we had to allocate for this iCode */
8041 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8042 freeAsmop(NULL,aop,ic,TRUE);
8044 /* we did not allocate which means left
8045 already in a pointer register, then
8046 if size > 0 && this could be used again
8047 we have to point it back to where it
8049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8050 if (AOP_SIZE(result) > 1 &&
8051 !OP_SYMBOL(left)->remat &&
8052 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8054 int size = AOP_SIZE(result) - 1;
8056 pic14_emitcode("dec","%s",rname);
8061 freeAsmop(left,NULL,ic,TRUE);
8062 freeAsmop(result,NULL,ic,TRUE);
8066 /*-----------------------------------------------------------------*/
8067 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8068 /*-----------------------------------------------------------------*/
8069 static void genPagedPointerGet (operand *left,
8076 sym_link *rtype, *retype;
8078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8080 rtype = operandType(result);
8081 retype= getSpec(rtype);
8083 aopOp(left,ic,FALSE);
8085 /* if the value is already in a pointer register
8086 then don't need anything more */
8087 if (!AOP_INPREG(AOP(left))) {
8088 /* otherwise get a free pointer register */
8090 preg = getFreePtr(ic,&aop,FALSE);
8091 pic14_emitcode("mov","%s,%s",
8093 aopGet(AOP(left),0,FALSE,TRUE));
8094 rname = preg->name ;
8096 rname = aopGet(AOP(left),0,FALSE,FALSE);
8098 freeAsmop(left,NULL,ic,TRUE);
8099 aopOp (result,ic,FALSE);
8101 /* if bitfield then unpack the bits */
8102 if (IS_BITVAR(retype))
8103 genUnpackBits (result,rname,PPOINTER);
8105 /* we have can just get the values */
8106 int size = AOP_SIZE(result);
8111 pic14_emitcode("movx","a,@%s",rname);
8112 aopPut(AOP(result),"a",offset);
8117 pic14_emitcode("inc","%s",rname);
8121 /* now some housekeeping stuff */
8123 /* we had to allocate for this iCode */
8124 freeAsmop(NULL,aop,ic,TRUE);
8126 /* we did not allocate which means left
8127 already in a pointer register, then
8128 if size > 0 && this could be used again
8129 we have to point it back to where it
8131 if (AOP_SIZE(result) > 1 &&
8132 !OP_SYMBOL(left)->remat &&
8133 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8135 int size = AOP_SIZE(result) - 1;
8137 pic14_emitcode("dec","%s",rname);
8142 freeAsmop(result,NULL,ic,TRUE);
8147 /*-----------------------------------------------------------------*/
8148 /* genFarPointerGet - gget value from far space */
8149 /*-----------------------------------------------------------------*/
8150 static void genFarPointerGet (operand *left,
8151 operand *result, iCode *ic)
8154 sym_link *retype = getSpec(operandType(result));
8156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8158 aopOp(left,ic,FALSE);
8160 /* if the operand is already in dptr
8161 then we do nothing else we move the value to dptr */
8162 if (AOP_TYPE(left) != AOP_STR) {
8163 /* if this is remateriazable */
8164 if (AOP_TYPE(left) == AOP_IMMD)
8165 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8166 else { /* we need to get it byte by byte */
8167 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8168 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8169 if (options.model == MODEL_FLAT24)
8171 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8175 /* so dptr know contains the address */
8176 freeAsmop(left,NULL,ic,TRUE);
8177 aopOp(result,ic,FALSE);
8179 /* if bit then unpack */
8180 if (IS_BITVAR(retype))
8181 genUnpackBits(result,"dptr",FPOINTER);
8183 size = AOP_SIZE(result);
8187 pic14_emitcode("movx","a,@dptr");
8188 aopPut(AOP(result),"a",offset++);
8190 pic14_emitcode("inc","dptr");
8194 freeAsmop(result,NULL,ic,TRUE);
8197 /*-----------------------------------------------------------------*/
8198 /* genCodePointerGet - get value from code space */
8199 /*-----------------------------------------------------------------*/
8200 static void genCodePointerGet (operand *left,
8201 operand *result, iCode *ic)
8204 sym_link *retype = getSpec(operandType(result));
8206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8208 aopOp(left,ic,FALSE);
8210 /* if the operand is already in dptr
8211 then we do nothing else we move the value to dptr */
8212 if (AOP_TYPE(left) != AOP_STR) {
8213 /* if this is remateriazable */
8214 if (AOP_TYPE(left) == AOP_IMMD)
8215 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8216 else { /* we need to get it byte by byte */
8217 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8218 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8219 if (options.model == MODEL_FLAT24)
8221 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8225 /* so dptr know contains the address */
8226 freeAsmop(left,NULL,ic,TRUE);
8227 aopOp(result,ic,FALSE);
8229 /* if bit then unpack */
8230 if (IS_BITVAR(retype))
8231 genUnpackBits(result,"dptr",CPOINTER);
8233 size = AOP_SIZE(result);
8237 pic14_emitcode("clr","a");
8238 pic14_emitcode("movc","a,@a+dptr");
8239 aopPut(AOP(result),"a",offset++);
8241 pic14_emitcode("inc","dptr");
8245 freeAsmop(result,NULL,ic,TRUE);
8248 /*-----------------------------------------------------------------*/
8249 /* genGenPointerGet - gget value from generic pointer space */
8250 /*-----------------------------------------------------------------*/
8251 static void genGenPointerGet (operand *left,
8252 operand *result, iCode *ic)
8255 sym_link *retype = getSpec(operandType(result));
8257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8258 aopOp(left,ic,FALSE);
8259 aopOp(result,ic,FALSE);
8262 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8264 /* if the operand is already in dptr
8265 then we do nothing else we move the value to dptr */
8266 // if (AOP_TYPE(left) != AOP_STR) {
8267 /* if this is remateriazable */
8268 if (AOP_TYPE(left) == AOP_IMMD) {
8269 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8270 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8272 else { /* we need to get it byte by byte */
8274 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8275 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8277 size = AOP_SIZE(result);
8281 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8282 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8284 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8289 /* so dptr know contains the address */
8291 /* if bit then unpack */
8292 //if (IS_BITVAR(retype))
8293 // genUnpackBits(result,"dptr",GPOINTER);
8296 freeAsmop(left,NULL,ic,TRUE);
8297 freeAsmop(result,NULL,ic,TRUE);
8301 /*-----------------------------------------------------------------*/
8302 /* genConstPointerGet - get value from const generic pointer space */
8303 /*-----------------------------------------------------------------*/
8304 static void genConstPointerGet (operand *left,
8305 operand *result, iCode *ic)
8307 //sym_link *retype = getSpec(operandType(result));
8308 symbol *albl = newiTempLabel(NULL);
8309 symbol *blbl = newiTempLabel(NULL);
8312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8313 aopOp(left,ic,FALSE);
8314 aopOp(result,ic,FALSE);
8317 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8319 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8321 emitpcode(POC_CALL,popGetLabel(albl->key));
8322 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8323 emitpLabel(albl->key);
8325 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8327 emitpcode(poc,popGet(AOP(left),1));
8328 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8329 emitpcode(poc,popGet(AOP(left),0));
8330 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8332 emitpLabel(blbl->key);
8334 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8337 freeAsmop(left,NULL,ic,TRUE);
8338 freeAsmop(result,NULL,ic,TRUE);
8341 /*-----------------------------------------------------------------*/
8342 /* genPointerGet - generate code for pointer get */
8343 /*-----------------------------------------------------------------*/
8344 static void genPointerGet (iCode *ic)
8346 operand *left, *result ;
8347 sym_link *type, *etype;
8350 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8353 result = IC_RESULT(ic) ;
8355 /* depending on the type of pointer we need to
8356 move it to the correct pointer register */
8357 type = operandType(left);
8358 etype = getSpec(type);
8360 if (IS_PTR_CONST(type))
8361 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8363 /* if left is of type of pointer then it is simple */
8364 if (IS_PTR(type) && !IS_FUNC(type->next))
8365 p_type = DCL_TYPE(type);
8367 /* we have to go by the storage class */
8368 p_type = PTR_TYPE(SPEC_OCLS(etype));
8370 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8372 if (SPEC_OCLS(etype)->codesp ) {
8373 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8374 //p_type = CPOINTER ;
8377 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8378 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8379 /*p_type = FPOINTER ;*/
8381 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8382 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8383 /* p_type = PPOINTER; */
8385 if (SPEC_OCLS(etype) == idata )
8386 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8387 /* p_type = IPOINTER; */
8389 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8390 /* p_type = POINTER ; */
8393 /* now that we have the pointer type we assign
8394 the pointer values */
8399 genNearPointerGet (left,result,ic);
8403 genPagedPointerGet(left,result,ic);
8407 genFarPointerGet (left,result,ic);
8411 genConstPointerGet (left,result,ic);
8412 //pic14_emitcodePointerGet (left,result,ic);
8416 if (IS_PTR_CONST(type))
8417 genConstPointerGet (left,result,ic);
8419 genGenPointerGet (left,result,ic);
8425 /*-----------------------------------------------------------------*/
8426 /* genPackBits - generates code for packed bit storage */
8427 /*-----------------------------------------------------------------*/
8428 static void genPackBits (sym_link *etype ,
8430 char *rname, int p_type)
8438 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8439 blen = SPEC_BLEN(etype);
8440 bstr = SPEC_BSTR(etype);
8442 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8445 /* if the bit lenth is less than or */
8446 /* it exactly fits a byte then */
8447 if (SPEC_BLEN(etype) <= 8 ) {
8448 shCount = SPEC_BSTR(etype) ;
8450 /* shift left acc */
8453 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8458 pic14_emitcode ("mov","b,a");
8459 pic14_emitcode("mov","a,@%s",rname);
8463 pic14_emitcode ("mov","b,a");
8464 pic14_emitcode("movx","a,@dptr");
8468 pic14_emitcode ("push","b");
8469 pic14_emitcode ("push","acc");
8470 pic14_emitcode ("lcall","__gptrget");
8471 pic14_emitcode ("pop","b");
8475 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8476 ((unsigned char)(0xFF << (blen+bstr)) |
8477 (unsigned char)(0xFF >> (8-bstr)) ) );
8478 pic14_emitcode ("orl","a,b");
8479 if (p_type == GPOINTER)
8480 pic14_emitcode("pop","b");
8486 pic14_emitcode("mov","@%s,a",rname);
8490 pic14_emitcode("movx","@dptr,a");
8494 DEBUGpic14_emitcode(";lcall","__gptrput");
8499 if ( SPEC_BLEN(etype) <= 8 )
8502 pic14_emitcode("inc","%s",rname);
8503 rLen = SPEC_BLEN(etype) ;
8505 /* now generate for lengths greater than one byte */
8508 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8518 pic14_emitcode("mov","@%s,a",rname);
8520 pic14_emitcode("mov","@%s,%s",rname,l);
8525 pic14_emitcode("movx","@dptr,a");
8530 DEBUGpic14_emitcode(";lcall","__gptrput");
8533 pic14_emitcode ("inc","%s",rname);
8538 /* last last was not complete */
8540 /* save the byte & read byte */
8543 pic14_emitcode ("mov","b,a");
8544 pic14_emitcode("mov","a,@%s",rname);
8548 pic14_emitcode ("mov","b,a");
8549 pic14_emitcode("movx","a,@dptr");
8553 pic14_emitcode ("push","b");
8554 pic14_emitcode ("push","acc");
8555 pic14_emitcode ("lcall","__gptrget");
8556 pic14_emitcode ("pop","b");
8560 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8561 pic14_emitcode ("orl","a,b");
8564 if (p_type == GPOINTER)
8565 pic14_emitcode("pop","b");
8570 pic14_emitcode("mov","@%s,a",rname);
8574 pic14_emitcode("movx","@dptr,a");
8578 DEBUGpic14_emitcode(";lcall","__gptrput");
8582 /*-----------------------------------------------------------------*/
8583 /* genDataPointerSet - remat pointer to data space */
8584 /*-----------------------------------------------------------------*/
8585 static void genDataPointerSet(operand *right,
8589 int size, offset = 0 ;
8590 char *l, buffer[256];
8592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8593 aopOp(right,ic,FALSE);
8595 l = aopGet(AOP(result),0,FALSE,TRUE);
8596 size = AOP_SIZE(right);
8598 if ( AOP_TYPE(result) == AOP_PCODE) {
8599 fprintf(stderr,"genDataPointerSet %s, %d\n",
8600 AOP(result)->aopu.pcop->name,
8601 PCOI(AOP(result)->aopu.pcop)->offset);
8605 // tsd, was l+1 - the underline `_' prefix was being stripped
8608 sprintf(buffer,"(%s + %d)",l,offset);
8609 fprintf(stderr,"oops %s\n",buffer);
8611 sprintf(buffer,"%s",l);
8613 if (AOP_TYPE(right) == AOP_LIT) {
8614 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8615 lit = lit >> (8*offset);
8617 pic14_emitcode("movlw","%d",lit);
8618 pic14_emitcode("movwf","%s",buffer);
8620 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8621 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8622 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8625 pic14_emitcode("clrf","%s",buffer);
8626 //emitpcode(POC_CLRF, popRegFromString(buffer));
8627 emitpcode(POC_CLRF, popGet(AOP(result),0));
8630 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8631 pic14_emitcode("movwf","%s",buffer);
8633 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8634 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8635 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8642 freeAsmop(right,NULL,ic,TRUE);
8643 freeAsmop(result,NULL,ic,TRUE);
8646 /*-----------------------------------------------------------------*/
8647 /* genNearPointerSet - pic14_emitcode for near pointer put */
8648 /*-----------------------------------------------------------------*/
8649 static void genNearPointerSet (operand *right,
8656 sym_link *ptype = operandType(result);
8659 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8660 retype= getSpec(operandType(right));
8662 aopOp(result,ic,FALSE);
8665 /* if the result is rematerializable &
8666 in data space & not a bit variable */
8667 //if (AOP_TYPE(result) == AOP_IMMD &&
8668 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8669 DCL_TYPE(ptype) == POINTER &&
8670 !IS_BITVAR(retype)) {
8671 genDataPointerSet (right,result,ic);
8672 freeAsmop(result,NULL,ic,TRUE);
8676 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8677 aopOp(right,ic,FALSE);
8678 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8680 /* if the value is already in a pointer register
8681 then don't need anything more */
8682 if (!AOP_INPREG(AOP(result))) {
8683 /* otherwise get a free pointer register */
8684 //aop = newAsmop(0);
8685 //preg = getFreePtr(ic,&aop,FALSE);
8686 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8687 //pic14_emitcode("mov","%s,%s",
8689 // aopGet(AOP(result),0,FALSE,TRUE));
8690 //rname = preg->name ;
8691 //pic14_emitcode("movwf","fsr");
8692 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8693 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8694 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8695 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8699 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8702 /* if bitfield then unpack the bits */
8703 if (IS_BITVAR(retype)) {
8704 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8705 "The programmer is obviously confused");
8706 //genPackBits (retype,right,rname,POINTER);
8710 /* we have can just get the values */
8711 int size = AOP_SIZE(right);
8714 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8716 l = aopGet(AOP(right),offset,FALSE,TRUE);
8719 //pic14_emitcode("mov","@%s,a",rname);
8720 pic14_emitcode("movf","indf,w ;1");
8723 if (AOP_TYPE(right) == AOP_LIT) {
8724 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8726 pic14_emitcode("movlw","%s",l);
8727 pic14_emitcode("movwf","indf ;2");
8729 pic14_emitcode("clrf","indf");
8731 pic14_emitcode("movf","%s,w",l);
8732 pic14_emitcode("movwf","indf ;2");
8734 //pic14_emitcode("mov","@%s,%s",rname,l);
8737 pic14_emitcode("incf","fsr,f ;3");
8738 //pic14_emitcode("inc","%s",rname);
8743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8744 /* now some housekeeping stuff */
8746 /* we had to allocate for this iCode */
8747 freeAsmop(NULL,aop,ic,TRUE);
8749 /* we did not allocate which means left
8750 already in a pointer register, then
8751 if size > 0 && this could be used again
8752 we have to point it back to where it
8754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8755 if (AOP_SIZE(right) > 1 &&
8756 !OP_SYMBOL(result)->remat &&
8757 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8759 int size = AOP_SIZE(right) - 1;
8761 pic14_emitcode("decf","fsr,f");
8762 //pic14_emitcode("dec","%s",rname);
8766 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8769 freeAsmop(right,NULL,ic,TRUE);
8770 freeAsmop(result,NULL,ic,TRUE);
8773 /*-----------------------------------------------------------------*/
8774 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8775 /*-----------------------------------------------------------------*/
8776 static void genPagedPointerSet (operand *right,
8785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8787 retype= getSpec(operandType(right));
8789 aopOp(result,ic,FALSE);
8791 /* if the value is already in a pointer register
8792 then don't need anything more */
8793 if (!AOP_INPREG(AOP(result))) {
8794 /* otherwise get a free pointer register */
8796 preg = getFreePtr(ic,&aop,FALSE);
8797 pic14_emitcode("mov","%s,%s",
8799 aopGet(AOP(result),0,FALSE,TRUE));
8800 rname = preg->name ;
8802 rname = aopGet(AOP(result),0,FALSE,FALSE);
8804 freeAsmop(result,NULL,ic,TRUE);
8805 aopOp (right,ic,FALSE);
8807 /* if bitfield then unpack the bits */
8808 if (IS_BITVAR(retype))
8809 genPackBits (retype,right,rname,PPOINTER);
8811 /* we have can just get the values */
8812 int size = AOP_SIZE(right);
8816 l = aopGet(AOP(right),offset,FALSE,TRUE);
8819 pic14_emitcode("movx","@%s,a",rname);
8822 pic14_emitcode("inc","%s",rname);
8828 /* now some housekeeping stuff */
8830 /* we had to allocate for this iCode */
8831 freeAsmop(NULL,aop,ic,TRUE);
8833 /* we did not allocate which means left
8834 already in a pointer register, then
8835 if size > 0 && this could be used again
8836 we have to point it back to where it
8838 if (AOP_SIZE(right) > 1 &&
8839 !OP_SYMBOL(result)->remat &&
8840 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8842 int size = AOP_SIZE(right) - 1;
8844 pic14_emitcode("dec","%s",rname);
8849 freeAsmop(right,NULL,ic,TRUE);
8854 /*-----------------------------------------------------------------*/
8855 /* genFarPointerSet - set value from far space */
8856 /*-----------------------------------------------------------------*/
8857 static void genFarPointerSet (operand *right,
8858 operand *result, iCode *ic)
8861 sym_link *retype = getSpec(operandType(right));
8863 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8864 aopOp(result,ic,FALSE);
8866 /* if the operand is already in dptr
8867 then we do nothing else we move the value to dptr */
8868 if (AOP_TYPE(result) != AOP_STR) {
8869 /* if this is remateriazable */
8870 if (AOP_TYPE(result) == AOP_IMMD)
8871 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8872 else { /* we need to get it byte by byte */
8873 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8874 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8875 if (options.model == MODEL_FLAT24)
8877 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8881 /* so dptr know contains the address */
8882 freeAsmop(result,NULL,ic,TRUE);
8883 aopOp(right,ic,FALSE);
8885 /* if bit then unpack */
8886 if (IS_BITVAR(retype))
8887 genPackBits(retype,right,"dptr",FPOINTER);
8889 size = AOP_SIZE(right);
8893 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8895 pic14_emitcode("movx","@dptr,a");
8897 pic14_emitcode("inc","dptr");
8901 freeAsmop(right,NULL,ic,TRUE);
8904 /*-----------------------------------------------------------------*/
8905 /* genGenPointerSet - set value from generic pointer space */
8906 /*-----------------------------------------------------------------*/
8907 static void genGenPointerSet (operand *right,
8908 operand *result, iCode *ic)
8911 sym_link *retype = getSpec(operandType(right));
8913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8915 aopOp(result,ic,FALSE);
8916 aopOp(right,ic,FALSE);
8917 size = AOP_SIZE(right);
8919 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8921 /* if the operand is already in dptr
8922 then we do nothing else we move the value to dptr */
8923 if (AOP_TYPE(result) != AOP_STR) {
8924 /* if this is remateriazable */
8925 if (AOP_TYPE(result) == AOP_IMMD) {
8926 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8927 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8929 else { /* we need to get it byte by byte */
8930 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8931 size = AOP_SIZE(right);
8934 /* hack hack! see if this the FSR. If so don't load W */
8935 if(AOP_TYPE(right) != AOP_ACC) {
8937 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8938 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8941 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8943 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8944 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8948 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8949 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8952 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8959 if(aopIdx(AOP(result),0) != 4) {
8961 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8965 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8970 /* so dptr know contains the address */
8973 /* if bit then unpack */
8974 if (IS_BITVAR(retype))
8975 genPackBits(retype,right,"dptr",GPOINTER);
8977 size = AOP_SIZE(right);
8980 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8984 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8985 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8987 if (AOP_TYPE(right) == AOP_LIT)
8988 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8990 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8992 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8999 freeAsmop(right,NULL,ic,TRUE);
9000 freeAsmop(result,NULL,ic,TRUE);
9003 /*-----------------------------------------------------------------*/
9004 /* genPointerSet - stores the value into a pointer location */
9005 /*-----------------------------------------------------------------*/
9006 static void genPointerSet (iCode *ic)
9008 operand *right, *result ;
9009 sym_link *type, *etype;
9012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9014 right = IC_RIGHT(ic);
9015 result = IC_RESULT(ic) ;
9017 /* depending on the type of pointer we need to
9018 move it to the correct pointer register */
9019 type = operandType(result);
9020 etype = getSpec(type);
9021 /* if left is of type of pointer then it is simple */
9022 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9023 p_type = DCL_TYPE(type);
9026 /* we have to go by the storage class */
9027 p_type = PTR_TYPE(SPEC_OCLS(etype));
9029 /* if (SPEC_OCLS(etype)->codesp ) { */
9030 /* p_type = CPOINTER ; */
9033 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9034 /* p_type = FPOINTER ; */
9036 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9037 /* p_type = PPOINTER ; */
9039 /* if (SPEC_OCLS(etype) == idata ) */
9040 /* p_type = IPOINTER ; */
9042 /* p_type = POINTER ; */
9045 /* now that we have the pointer type we assign
9046 the pointer values */
9051 genNearPointerSet (right,result,ic);
9055 genPagedPointerSet (right,result,ic);
9059 genFarPointerSet (right,result,ic);
9063 genGenPointerSet (right,result,ic);
9067 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9068 "genPointerSet: illegal pointer type");
9072 /*-----------------------------------------------------------------*/
9073 /* genIfx - generate code for Ifx statement */
9074 /*-----------------------------------------------------------------*/
9075 static void genIfx (iCode *ic, iCode *popIc)
9077 operand *cond = IC_COND(ic);
9080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9082 aopOp(cond,ic,FALSE);
9084 /* get the value into acc */
9085 if (AOP_TYPE(cond) != AOP_CRY)
9086 pic14_toBoolean(cond);
9089 /* the result is now in the accumulator */
9090 freeAsmop(cond,NULL,ic,TRUE);
9092 /* if there was something to be popped then do it */
9096 /* if the condition is a bit variable */
9097 if (isbit && IS_ITEMP(cond) &&
9099 genIfxJump(ic,SPIL_LOC(cond)->rname);
9100 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9103 if (isbit && !IS_ITEMP(cond))
9104 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9112 /*-----------------------------------------------------------------*/
9113 /* genAddrOf - generates code for address of */
9114 /*-----------------------------------------------------------------*/
9115 static void genAddrOf (iCode *ic)
9117 operand *right, *result, *left;
9120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9123 //aopOp(IC_RESULT(ic),ic,FALSE);
9125 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9126 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9127 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9129 DEBUGpic14_AopType(__LINE__,left,right,result);
9131 size = AOP_SIZE(IC_RESULT(ic));
9135 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9136 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9140 freeAsmop(left,NULL,ic,FALSE);
9141 freeAsmop(result,NULL,ic,TRUE);
9146 /*-----------------------------------------------------------------*/
9147 /* genFarFarAssign - assignment when both are in far space */
9148 /*-----------------------------------------------------------------*/
9149 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9151 int size = AOP_SIZE(right);
9154 /* first push the right side on to the stack */
9156 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9158 pic14_emitcode ("push","acc");
9161 freeAsmop(right,NULL,ic,FALSE);
9162 /* now assign DPTR to result */
9163 aopOp(result,ic,FALSE);
9164 size = AOP_SIZE(result);
9166 pic14_emitcode ("pop","acc");
9167 aopPut(AOP(result),"a",--offset);
9169 freeAsmop(result,NULL,ic,FALSE);
9174 /*-----------------------------------------------------------------*/
9175 /* genAssign - generate code for assignment */
9176 /*-----------------------------------------------------------------*/
9177 static void genAssign (iCode *ic)
9179 operand *result, *right;
9180 int size, offset,know_W;
9181 unsigned long lit = 0L;
9183 result = IC_RESULT(ic);
9184 right = IC_RIGHT(ic) ;
9186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9188 /* if they are the same */
9189 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9192 aopOp(right,ic,FALSE);
9193 aopOp(result,ic,TRUE);
9195 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9197 /* if they are the same registers */
9198 if (pic14_sameRegs(AOP(right),AOP(result)))
9201 /* if the result is a bit */
9202 if (AOP_TYPE(result) == AOP_CRY) {
9204 /* if the right size is a literal then
9205 we know what the value is */
9206 if (AOP_TYPE(right) == AOP_LIT) {
9208 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9209 popGet(AOP(result),0));
9211 if (((int) operandLitValue(right)))
9212 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9213 AOP(result)->aopu.aop_dir,
9214 AOP(result)->aopu.aop_dir);
9216 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9217 AOP(result)->aopu.aop_dir,
9218 AOP(result)->aopu.aop_dir);
9222 /* the right is also a bit variable */
9223 if (AOP_TYPE(right) == AOP_CRY) {
9224 emitpcode(POC_BCF, popGet(AOP(result),0));
9225 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9226 emitpcode(POC_BSF, popGet(AOP(result),0));
9228 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9229 AOP(result)->aopu.aop_dir,
9230 AOP(result)->aopu.aop_dir);
9231 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9232 AOP(right)->aopu.aop_dir,
9233 AOP(right)->aopu.aop_dir);
9234 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9235 AOP(result)->aopu.aop_dir,
9236 AOP(result)->aopu.aop_dir);
9241 emitpcode(POC_BCF, popGet(AOP(result),0));
9242 pic14_toBoolean(right);
9244 emitpcode(POC_BSF, popGet(AOP(result),0));
9245 //aopPut(AOP(result),"a",0);
9249 /* bit variables done */
9251 size = AOP_SIZE(result);
9253 if(AOP_TYPE(right) == AOP_LIT)
9254 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9256 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9258 if(aopIdx(AOP(result),0) == 4) {
9259 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9260 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9261 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9264 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9270 if(AOP_TYPE(right) == AOP_LIT) {
9272 if(know_W != (lit&0xff))
9273 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9275 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9277 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9281 } else if (AOP_TYPE(right) == AOP_CRY) {
9282 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9284 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9285 emitpcode(POC_INCF, popGet(AOP(result),0));
9288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9289 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9290 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9298 freeAsmop (right,NULL,ic,FALSE);
9299 freeAsmop (result,NULL,ic,TRUE);
9302 /*-----------------------------------------------------------------*/
9303 /* genJumpTab - genrates code for jump table */
9304 /*-----------------------------------------------------------------*/
9305 static void genJumpTab (iCode *ic)
9310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9312 aopOp(IC_JTCOND(ic),ic,FALSE);
9313 /* get the condition into accumulator */
9314 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9316 /* multiply by three */
9317 pic14_emitcode("add","a,acc");
9318 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9320 jtab = newiTempLabel(NULL);
9321 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9322 pic14_emitcode("jmp","@a+dptr");
9323 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9325 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9326 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9328 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9329 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9330 emitpLabel(jtab->key);
9332 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9334 /* now generate the jump labels */
9335 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9336 jtab = setNextItem(IC_JTLABELS(ic))) {
9337 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9338 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9344 /*-----------------------------------------------------------------*/
9345 /* genMixedOperation - gen code for operators between mixed types */
9346 /*-----------------------------------------------------------------*/
9348 TSD - Written for the PIC port - but this unfortunately is buggy.
9349 This routine is good in that it is able to efficiently promote
9350 types to different (larger) sizes. Unfortunately, the temporary
9351 variables that are optimized out by this routine are sometimes
9352 used in other places. So until I know how to really parse the
9353 iCode tree, I'm going to not be using this routine :(.
9355 static int genMixedOperation (iCode *ic)
9358 operand *result = IC_RESULT(ic);
9359 sym_link *ctype = operandType(IC_LEFT(ic));
9360 operand *right = IC_RIGHT(ic);
9366 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9368 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9374 nextright = IC_RIGHT(nextic);
9375 nextleft = IC_LEFT(nextic);
9376 nextresult = IC_RESULT(nextic);
9378 aopOp(right,ic,FALSE);
9379 aopOp(result,ic,FALSE);
9380 aopOp(nextright, nextic, FALSE);
9381 aopOp(nextleft, nextic, FALSE);
9382 aopOp(nextresult, nextic, FALSE);
9384 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9390 pic14_emitcode(";remove right +","");
9392 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9398 pic14_emitcode(";remove left +","");
9402 big = AOP_SIZE(nextleft);
9403 small = AOP_SIZE(nextright);
9405 switch(nextic->op) {
9408 pic14_emitcode(";optimize a +","");
9409 /* if unsigned or not an integral type */
9410 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9411 pic14_emitcode(";add a bit to something","");
9414 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9416 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9417 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9418 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9420 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9428 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9429 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9430 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9433 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9435 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9436 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9437 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9438 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9439 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9442 pic14_emitcode("rlf","known_zero,w");
9449 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9450 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9451 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9453 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9463 freeAsmop(right,NULL,ic,TRUE);
9464 freeAsmop(result,NULL,ic,TRUE);
9465 freeAsmop(nextright,NULL,ic,TRUE);
9466 freeAsmop(nextleft,NULL,ic,TRUE);
9468 nextic->generated = 1;
9475 /*-----------------------------------------------------------------*/
9476 /* genCast - gen code for casting */
9477 /*-----------------------------------------------------------------*/
9478 static void genCast (iCode *ic)
9480 operand *result = IC_RESULT(ic);
9481 sym_link *ctype = operandType(IC_LEFT(ic));
9482 sym_link *rtype = operandType(IC_RIGHT(ic));
9483 operand *right = IC_RIGHT(ic);
9486 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9487 /* if they are equivalent then do nothing */
9488 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9491 aopOp(right,ic,FALSE) ;
9492 aopOp(result,ic,FALSE);
9494 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9496 /* if the result is a bit */
9497 if (AOP_TYPE(result) == AOP_CRY) {
9498 /* if the right size is a literal then
9499 we know what the value is */
9500 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9501 if (AOP_TYPE(right) == AOP_LIT) {
9503 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9504 popGet(AOP(result),0));
9506 if (((int) operandLitValue(right)))
9507 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9508 AOP(result)->aopu.aop_dir,
9509 AOP(result)->aopu.aop_dir);
9511 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9512 AOP(result)->aopu.aop_dir,
9513 AOP(result)->aopu.aop_dir);
9518 /* the right is also a bit variable */
9519 if (AOP_TYPE(right) == AOP_CRY) {
9522 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9524 pic14_emitcode("clrc","");
9525 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9526 AOP(right)->aopu.aop_dir,
9527 AOP(right)->aopu.aop_dir);
9528 aopPut(AOP(result),"c",0);
9533 if (AOP_TYPE(right) == AOP_REG) {
9534 emitpcode(POC_BCF, popGet(AOP(result),0));
9535 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9536 emitpcode(POC_BSF, popGet(AOP(result),0));
9538 pic14_toBoolean(right);
9539 aopPut(AOP(result),"a",0);
9543 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9545 size = AOP_SIZE(result);
9547 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9549 emitpcode(POC_CLRF, popGet(AOP(result),0));
9550 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9551 emitpcode(POC_INCF, popGet(AOP(result),0));
9554 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9559 /* if they are the same size : or less */
9560 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9562 /* if they are in the same place */
9563 if (pic14_sameRegs(AOP(right),AOP(result)))
9566 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9567 if (IS_PTR_CONST(rtype))
9568 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9569 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9570 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9572 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9573 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9574 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9575 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9576 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9577 if(AOP_SIZE(result) <2)
9578 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9582 /* if they in different places then copy */
9583 size = AOP_SIZE(result);
9586 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9587 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9589 //aopPut(AOP(result),
9590 // aopGet(AOP(right),offset,FALSE,FALSE),
9600 /* if the result is of type pointer */
9601 if (IS_PTR(ctype)) {
9604 sym_link *type = operandType(right);
9605 sym_link *etype = getSpec(type);
9606 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9608 /* pointer to generic pointer */
9609 if (IS_GENPTR(ctype)) {
9613 p_type = DCL_TYPE(type);
9615 /* we have to go by the storage class */
9616 p_type = PTR_TYPE(SPEC_OCLS(etype));
9618 /* if (SPEC_OCLS(etype)->codesp ) */
9619 /* p_type = CPOINTER ; */
9621 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9622 /* p_type = FPOINTER ; */
9624 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9625 /* p_type = PPOINTER; */
9627 /* if (SPEC_OCLS(etype) == idata ) */
9628 /* p_type = IPOINTER ; */
9630 /* p_type = POINTER ; */
9633 /* the first two bytes are known */
9634 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9635 size = GPTRSIZE - 1;
9638 if(offset < AOP_SIZE(right)) {
9639 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9640 if ((AOP_TYPE(right) == AOP_PCODE) &&
9641 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9642 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9643 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9646 aopGet(AOP(right),offset,FALSE,FALSE),
9650 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9653 /* the last byte depending on type */
9657 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9660 pic14_emitcode(";BUG!? ","%d",__LINE__);
9664 pic14_emitcode(";BUG!? ","%d",__LINE__);
9668 pic14_emitcode(";BUG!? ","%d",__LINE__);
9673 /* this should never happen */
9674 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9675 "got unknown pointer type");
9678 //aopPut(AOP(result),l, GPTRSIZE - 1);
9682 /* just copy the pointers */
9683 size = AOP_SIZE(result);
9687 aopGet(AOP(right),offset,FALSE,FALSE),
9696 /* so we now know that the size of destination is greater
9697 than the size of the source.
9698 Now, if the next iCode is an operator then we might be
9699 able to optimize the operation without performing a cast.
9701 if(genMixedOperation(ic))
9704 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9706 /* we move to result for the size of source */
9707 size = AOP_SIZE(right);
9710 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9711 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9715 /* now depending on the sign of the destination */
9716 size = AOP_SIZE(result) - AOP_SIZE(right);
9717 /* if unsigned or not an integral type */
9718 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9720 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9722 /* we need to extend the sign :{ */
9725 /* Save one instruction of casting char to int */
9726 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9727 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9728 emitpcode(POC_DECF, popGet(AOP(result),offset));
9730 emitpcodeNULLop(POC_CLRW);
9733 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9735 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9737 emitpcode(POC_MOVLW, popGetLit(0xff));
9740 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9745 freeAsmop(right,NULL,ic,TRUE);
9746 freeAsmop(result,NULL,ic,TRUE);
9750 /*-----------------------------------------------------------------*/
9751 /* genDjnz - generate decrement & jump if not zero instrucion */
9752 /*-----------------------------------------------------------------*/
9753 static int genDjnz (iCode *ic, iCode *ifx)
9756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9761 /* if the if condition has a false label
9762 then we cannot save */
9766 /* if the minus is not of the form
9768 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9769 !IS_OP_LITERAL(IC_RIGHT(ic)))
9772 if (operandLitValue(IC_RIGHT(ic)) != 1)
9775 /* if the size of this greater than one then no
9777 if (getSize(operandType(IC_RESULT(ic))) > 1)
9780 /* otherwise we can save BIG */
9781 lbl = newiTempLabel(NULL);
9782 lbl1= newiTempLabel(NULL);
9784 aopOp(IC_RESULT(ic),ic,FALSE);
9786 if (IS_AOP_PREG(IC_RESULT(ic))) {
9787 pic14_emitcode("dec","%s",
9788 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9789 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9790 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9794 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9795 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9797 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9798 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9801 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9802 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9803 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9804 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9807 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9812 /*-----------------------------------------------------------------*/
9813 /* genReceive - generate code for a receive iCode */
9814 /*-----------------------------------------------------------------*/
9815 static void genReceive (iCode *ic)
9817 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9819 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9820 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9821 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9823 int size = getSize(operandType(IC_RESULT(ic)));
9824 int offset = fReturnSizePic - size;
9826 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9827 fReturn[fReturnSizePic - offset - 1] : "acc"));
9830 aopOp(IC_RESULT(ic),ic,FALSE);
9831 size = AOP_SIZE(IC_RESULT(ic));
9834 pic14_emitcode ("pop","acc");
9835 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9840 aopOp(IC_RESULT(ic),ic,FALSE);
9842 assignResultValue(IC_RESULT(ic));
9845 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9848 /*-----------------------------------------------------------------*/
9849 /* genpic14Code - generate code for pic14 based controllers */
9850 /*-----------------------------------------------------------------*/
9852 * At this point, ralloc.c has gone through the iCode and attempted
9853 * to optimize in a way suitable for a PIC. Now we've got to generate
9854 * PIC instructions that correspond to the iCode.
9856 * Once the instructions are generated, we'll pass through both the
9857 * peep hole optimizer and the pCode optimizer.
9858 *-----------------------------------------------------------------*/
9860 void genpic14Code (iCode *lic)
9865 lineHead = lineCurr = NULL;
9867 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9870 /* if debug information required */
9871 if (options.debug && currFunc) {
9873 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9875 if (IS_STATIC(currFunc->etype)) {
9876 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9877 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9879 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9880 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9887 for (ic = lic ; ic ; ic = ic->next ) {
9889 DEBUGpic14_emitcode(";ic","");
9890 if ( cln != ic->lineno ) {
9891 if ( options.debug ) {
9893 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9894 FileBaseName(ic->filename),ic->lineno,
9895 ic->level,ic->block);
9899 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9900 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9901 printCLine(ic->filename, ic->lineno));
9904 newpCodeCSource(ic->lineno,
9906 printCLine(ic->filename, ic->lineno)));
9910 /* if the result is marked as
9911 spilt and rematerializable or code for
9912 this has already been generated then
9914 if (resultRemat(ic) || ic->generated )
9917 /* depending on the operation */
9936 /* IPOP happens only when trying to restore a
9937 spilt live range, if there is an ifx statement
9938 following this pop then the if statement might
9939 be using some of the registers being popped which
9940 would destory the contents of the register so
9941 we need to check for this condition and handle it */
9943 ic->next->op == IFX &&
9944 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9945 genIfx (ic->next,ic);
9963 genEndFunction (ic);
9983 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10000 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10004 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10011 /* note these two are xlated by algebraic equivalence
10012 during parsing SDCC.y */
10013 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10014 "got '>=' or '<=' shouldn't have come here");
10018 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10030 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10034 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10038 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10062 genRightShift (ic);
10065 case GET_VALUE_AT_ADDRESS:
10070 if (POINTER_SET(ic))
10097 addSet(&_G.sendSet,ic);
10106 /* now we are ready to call the
10107 peep hole optimizer */
10108 if (!options.nopeep) {
10109 peepHole (&lineHead);
10111 /* now do the actual printing */
10112 printLine (lineHead,codeOutFile);
10115 DFPRINTF((stderr,"printing pBlock\n\n"));
10116 printpBlock(stdout,pb);