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));
3768 /* if literal is on the right then swap with left */
3769 if ((AOP_TYPE(right) == AOP_LIT)) {
3770 operand *tmp = right ;
3771 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3772 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3775 lit = (lit - 1) & mask;
3778 rFalseIfx.condition ^= 1;
3781 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3782 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3786 //if(IC_TRUE(ifx) == NULL)
3787 /* if left & right are bit variables */
3788 if (AOP_TYPE(left) == AOP_CRY &&
3789 AOP_TYPE(right) == AOP_CRY ) {
3790 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3791 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3793 /* subtract right from left if at the
3794 end the carry flag is set then we know that
3795 left is greater than right */
3799 symbol *lbl = newiTempLabel(NULL);
3802 if(AOP_TYPE(right) == AOP_LIT) {
3804 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3806 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3813 genSkipCond(&rFalseIfx,left,size-1,7);
3815 /* no need to compare to 0...*/
3816 /* NOTE: this is a de-generate compare that most certainly
3817 * creates some dead code. */
3818 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3820 if(ifx) ifx->generated = 1;
3827 //i = (lit >> (size*8)) & 0xff;
3828 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3830 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3832 i = ((0-lit) & 0xff);
3835 /* lit is 0x7f, all signed chars are less than
3836 * this except for 0x7f itself */
3837 emitpcode(POC_XORLW, popGetLit(0x7f));
3838 genSkipz2(&rFalseIfx,0);
3840 emitpcode(POC_ADDLW, popGetLit(0x80));
3841 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3842 genSkipc(&rFalseIfx);
3847 genSkipz2(&rFalseIfx,1);
3849 emitpcode(POC_ADDLW, popGetLit(i));
3850 genSkipc(&rFalseIfx);
3854 if(ifx) ifx->generated = 1;
3858 /* chars are out of the way. now do ints and longs */
3861 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3868 genSkipCond(&rFalseIfx,left,size,7);
3869 if(ifx) ifx->generated = 1;
3874 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3876 //rFalseIfx.condition ^= 1;
3877 //genSkipCond(&rFalseIfx,left,size,7);
3878 //rFalseIfx.condition ^= 1;
3880 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3881 if(rFalseIfx.condition)
3882 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3884 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3886 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3887 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3888 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3891 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3893 if(rFalseIfx.condition) {
3895 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3901 genSkipc(&rFalseIfx);
3902 emitpLabel(truelbl->key);
3903 if(ifx) ifx->generated = 1;
3910 if( (lit & 0xff) == 0) {
3911 /* lower byte is zero */
3912 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3913 i = ((lit >> 8) & 0xff) ^0x80;
3914 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3915 emitpcode(POC_ADDLW, popGetLit( 0x80));
3916 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3917 genSkipc(&rFalseIfx);
3920 if(ifx) ifx->generated = 1;
3925 /* Special cases for signed longs */
3926 if( (lit & 0xffffff) == 0) {
3927 /* lower byte is zero */
3928 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3929 i = ((lit >> 8*3) & 0xff) ^0x80;
3930 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3931 emitpcode(POC_ADDLW, popGetLit( 0x80));
3932 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3933 genSkipc(&rFalseIfx);
3936 if(ifx) ifx->generated = 1;
3944 if(lit & (0x80 << (size*8))) {
3945 /* lit is negative */
3946 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3948 //genSkipCond(&rFalseIfx,left,size,7);
3950 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3952 if(rFalseIfx.condition)
3953 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3955 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3959 /* lit is positive */
3960 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3961 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3962 if(rFalseIfx.condition)
3963 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3965 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3970 This works, but is only good for ints.
3971 It also requires a "known zero" register.
3972 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3973 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3974 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3975 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3976 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3977 genSkipc(&rFalseIfx);
3979 emitpLabel(truelbl->key);
3980 if(ifx) ifx->generated = 1;
3984 /* There are no more special cases, so perform a general compare */
3986 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3987 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3991 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3993 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3995 //rFalseIfx.condition ^= 1;
3996 genSkipc(&rFalseIfx);
3998 emitpLabel(truelbl->key);
4000 if(ifx) ifx->generated = 1;
4007 /* sign is out of the way. So now do an unsigned compare */
4008 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4011 /* General case - compare to an unsigned literal on the right.*/
4013 i = (lit >> (size*8)) & 0xff;
4014 emitpcode(POC_MOVLW, popGetLit(i));
4015 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4017 i = (lit >> (size*8)) & 0xff;
4020 emitpcode(POC_MOVLW, popGetLit(i));
4022 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4024 /* this byte of the lit is zero,
4025 *if it's not the last then OR in the variable */
4027 emitpcode(POC_IORFW, popGet(AOP(left),size));
4032 emitpLabel(lbl->key);
4033 //if(emitFinalCheck)
4034 genSkipc(&rFalseIfx);
4036 emitpLabel(truelbl->key);
4038 if(ifx) ifx->generated = 1;
4044 if(AOP_TYPE(left) == AOP_LIT) {
4045 //symbol *lbl = newiTempLabel(NULL);
4047 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4050 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4053 if((lit == 0) && (sign == 0)){
4056 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4058 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4060 genSkipz2(&rFalseIfx,0);
4061 if(ifx) ifx->generated = 1;
4068 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4069 /* degenerate compare can never be true */
4070 if(rFalseIfx.condition == 0)
4071 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4073 if(ifx) ifx->generated = 1;
4078 /* signed comparisons to a literal byte */
4080 int lp1 = (lit+1) & 0xff;
4082 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4085 rFalseIfx.condition ^= 1;
4086 genSkipCond(&rFalseIfx,right,0,7);
4089 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4090 emitpcode(POC_XORLW, popGetLit(0x7f));
4091 genSkipz2(&rFalseIfx,1);
4094 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4095 emitpcode(POC_ADDLW, popGetLit(0x80));
4096 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4097 rFalseIfx.condition ^= 1;
4098 genSkipc(&rFalseIfx);
4102 /* unsigned comparisons to a literal byte */
4104 switch(lit & 0xff ) {
4106 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4107 genSkipz2(&rFalseIfx,0);
4110 rFalseIfx.condition ^= 1;
4111 genSkipCond(&rFalseIfx,right,0,7);
4115 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4116 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4118 rFalseIfx.condition ^= 1;
4119 genSkipc(&rFalseIfx);
4124 if(ifx) ifx->generated = 1;
4129 /* Size is greater than 1 */
4137 /* this means lit = 0xffffffff, or -1 */
4140 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4141 rFalseIfx.condition ^= 1;
4142 genSkipCond(&rFalseIfx,right,size,7);
4143 if(ifx) ifx->generated = 1;
4150 if(rFalseIfx.condition) {
4151 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4155 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4157 emitpcode(POC_IORFW, popGet(AOP(right),size));
4161 if(rFalseIfx.condition) {
4162 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4163 emitpLabel(truelbl->key);
4165 rFalseIfx.condition ^= 1;
4166 genSkipCond(&rFalseIfx,right,s,7);
4169 if(ifx) ifx->generated = 1;
4173 if((size == 1) && (0 == (lp1&0xff))) {
4174 /* lower byte of signed word is zero */
4175 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4176 i = ((lp1 >> 8) & 0xff) ^0x80;
4177 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4178 emitpcode(POC_ADDLW, popGetLit( 0x80));
4179 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4180 rFalseIfx.condition ^= 1;
4181 genSkipc(&rFalseIfx);
4184 if(ifx) ifx->generated = 1;
4188 if(lit & (0x80 << (size*8))) {
4189 /* Lit is less than zero */
4190 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4191 //rFalseIfx.condition ^= 1;
4192 //genSkipCond(&rFalseIfx,left,size,7);
4193 //rFalseIfx.condition ^= 1;
4194 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4195 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4197 if(rFalseIfx.condition)
4198 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4200 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4204 /* Lit is greater than or equal to zero */
4205 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4206 //rFalseIfx.condition ^= 1;
4207 //genSkipCond(&rFalseIfx,right,size,7);
4208 //rFalseIfx.condition ^= 1;
4210 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4211 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4213 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214 if(rFalseIfx.condition)
4215 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4217 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4222 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4223 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4227 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4229 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4231 rFalseIfx.condition ^= 1;
4232 //rFalseIfx.condition = 1;
4233 genSkipc(&rFalseIfx);
4235 emitpLabel(truelbl->key);
4237 if(ifx) ifx->generated = 1;
4242 /* compare word or long to an unsigned literal on the right.*/
4247 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4250 break; /* handled above */
4253 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4255 emitpcode(POC_IORFW, popGet(AOP(right),size));
4256 genSkipz2(&rFalseIfx,0);
4260 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4262 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265 if(rFalseIfx.condition)
4266 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4268 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4271 emitpcode(POC_MOVLW, popGetLit(lit+1));
4272 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4274 rFalseIfx.condition ^= 1;
4275 genSkipc(&rFalseIfx);
4278 emitpLabel(truelbl->key);
4280 if(ifx) ifx->generated = 1;
4286 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4287 i = (lit >> (size*8)) & 0xff;
4289 emitpcode(POC_MOVLW, popGetLit(i));
4290 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4293 i = (lit >> (size*8)) & 0xff;
4296 emitpcode(POC_MOVLW, popGetLit(i));
4298 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4300 /* this byte of the lit is zero,
4301 *if it's not the last then OR in the variable */
4303 emitpcode(POC_IORFW, popGet(AOP(right),size));
4308 emitpLabel(lbl->key);
4310 rFalseIfx.condition ^= 1;
4311 genSkipc(&rFalseIfx);
4315 emitpLabel(truelbl->key);
4316 if(ifx) ifx->generated = 1;
4320 /* Compare two variables */
4322 DEBUGpic14_emitcode(";sign","%d",sign);
4326 /* Sigh. thus sucks... */
4328 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4329 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4330 emitpcode(POC_MOVLW, popGetLit(0x80));
4331 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4332 emitpcode(POC_XORFW, popGet(AOP(right),size));
4333 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4335 /* Signed char comparison */
4336 /* Special thanks to Nikolai Golovchenko for this snippet */
4337 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4338 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4339 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4340 emitpcode(POC_XORFW, popGet(AOP(left),0));
4341 emitpcode(POC_XORFW, popGet(AOP(right),0));
4342 emitpcode(POC_ADDLW, popGetLit(0x80));
4344 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4345 genSkipc(&rFalseIfx);
4347 if(ifx) ifx->generated = 1;
4353 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4354 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4358 /* The rest of the bytes of a multi-byte compare */
4362 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4365 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4366 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4371 emitpLabel(lbl->key);
4373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4374 genSkipc(&rFalseIfx);
4375 if(ifx) ifx->generated = 1;
4380 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4381 pic14_outBitC(result);
4383 /* if the result is used in the next
4384 ifx conditional branch then generate
4385 code a little differently */
4387 genIfxJump (ifx,"c");
4389 pic14_outBitC(result);
4390 /* leave the result in acc */
4395 /*-----------------------------------------------------------------*/
4396 /* genCmpGt :- greater than comparison */
4397 /*-----------------------------------------------------------------*/
4398 static void genCmpGt (iCode *ic, iCode *ifx)
4400 operand *left, *right, *result;
4401 sym_link *letype , *retype;
4404 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4406 right= IC_RIGHT(ic);
4407 result = IC_RESULT(ic);
4409 letype = getSpec(operandType(left));
4410 retype =getSpec(operandType(right));
4411 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4412 /* assign the amsops */
4413 aopOp (left,ic,FALSE);
4414 aopOp (right,ic,FALSE);
4415 aopOp (result,ic,TRUE);
4417 genCmp(right, left, result, ifx, sign);
4419 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4420 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4421 freeAsmop(result,NULL,ic,TRUE);
4424 /*-----------------------------------------------------------------*/
4425 /* genCmpLt - less than comparisons */
4426 /*-----------------------------------------------------------------*/
4427 static void genCmpLt (iCode *ic, iCode *ifx)
4429 operand *left, *right, *result;
4430 sym_link *letype , *retype;
4433 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4435 right= IC_RIGHT(ic);
4436 result = IC_RESULT(ic);
4438 letype = getSpec(operandType(left));
4439 retype =getSpec(operandType(right));
4440 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4442 /* assign the amsops */
4443 aopOp (left,ic,FALSE);
4444 aopOp (right,ic,FALSE);
4445 aopOp (result,ic,TRUE);
4447 genCmp(left, right, result, ifx, sign);
4449 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4450 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4451 freeAsmop(result,NULL,ic,TRUE);
4454 /*-----------------------------------------------------------------*/
4455 /* genc16bit2lit - compare a 16 bit value to a literal */
4456 /*-----------------------------------------------------------------*/
4457 static void genc16bit2lit(operand *op, int lit, int offset)
4461 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4462 if( (lit&0xff) == 0)
4467 switch( BYTEofLONG(lit,i)) {
4469 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4472 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4475 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4478 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4479 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4484 switch( BYTEofLONG(lit,i)) {
4486 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4490 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4494 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4497 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4499 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4505 /*-----------------------------------------------------------------*/
4506 /* gencjneshort - compare and jump if not equal */
4507 /*-----------------------------------------------------------------*/
4508 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4510 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4515 unsigned long lit = 0L;
4516 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4517 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4519 resolveIfx(&rIfx,ifx);
4520 lbl = newiTempLabel(NULL);
4523 /* if the left side is a literal or
4524 if the right is in a pointer register and left
4526 if ((AOP_TYPE(left) == AOP_LIT) ||
4527 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4532 if(AOP_TYPE(right) == AOP_LIT)
4533 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4535 /* if the right side is a literal then anything goes */
4536 if (AOP_TYPE(right) == AOP_LIT &&
4537 AOP_TYPE(left) != AOP_DIR ) {
4540 genc16bit2lit(left, lit, 0);
4542 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4547 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4548 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4550 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4554 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4562 /* if the right side is in a register or in direct space or
4563 if the left is a pointer register & right is not */
4564 else if (AOP_TYPE(right) == AOP_REG ||
4565 AOP_TYPE(right) == AOP_DIR ||
4566 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4567 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4570 genc16bit2lit(left, lit, 0);
4572 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4577 if((AOP_TYPE(left) == AOP_DIR) &&
4578 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4580 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4581 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4583 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4585 switch (lit & 0xff) {
4587 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4590 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4591 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4595 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4596 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4600 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4601 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4606 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4609 if(AOP_TYPE(result) == AOP_CRY) {
4610 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4615 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4617 /* fix me. probably need to check result size too */
4618 emitpcode(POC_CLRF,popGet(AOP(result),0));
4623 emitpcode(POC_INCF,popGet(AOP(result),0));
4633 } else if(AOP_TYPE(right) == AOP_REG &&
4634 AOP_TYPE(left) != AOP_DIR){
4637 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4638 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4639 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4644 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4649 /* right is a pointer reg need both a & b */
4651 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4653 pic14_emitcode("mov","b,%s",l);
4654 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4655 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4659 emitpLabel(lbl->key);
4666 /*-----------------------------------------------------------------*/
4667 /* gencjne - compare and jump if not equal */
4668 /*-----------------------------------------------------------------*/
4669 static void gencjne(operand *left, operand *right, iCode *ifx)
4671 symbol *tlbl = newiTempLabel(NULL);
4673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4674 gencjneshort(left, right, lbl);
4676 pic14_emitcode("mov","a,%s",one);
4677 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4678 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4679 pic14_emitcode("clr","a");
4680 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4682 emitpLabel(lbl->key);
4683 emitpLabel(tlbl->key);
4688 /*-----------------------------------------------------------------*/
4689 /* genCmpEq - generates code for equal to */
4690 /*-----------------------------------------------------------------*/
4691 static void genCmpEq (iCode *ic, iCode *ifx)
4693 operand *left, *right, *result;
4694 unsigned long lit = 0L;
4697 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4700 DEBUGpic14_emitcode ("; ifx is non-null","");
4702 DEBUGpic14_emitcode ("; ifx is null","");
4704 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4705 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4706 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4708 size = max(AOP_SIZE(left),AOP_SIZE(right));
4710 DEBUGpic14_AopType(__LINE__,left,right,result);
4712 /* if literal, literal on the right or
4713 if the right is in a pointer register and left
4715 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4716 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4717 operand *tmp = right ;
4723 if(ifx && !AOP_SIZE(result)){
4725 /* if they are both bit variables */
4726 if (AOP_TYPE(left) == AOP_CRY &&
4727 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4728 if(AOP_TYPE(right) == AOP_LIT){
4729 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4731 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4732 pic14_emitcode("cpl","c");
4733 } else if(lit == 1L) {
4734 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4736 pic14_emitcode("clr","c");
4738 /* AOP_TYPE(right) == AOP_CRY */
4740 symbol *lbl = newiTempLabel(NULL);
4741 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4742 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4743 pic14_emitcode("cpl","c");
4744 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4746 /* if true label then we jump if condition
4748 tlbl = newiTempLabel(NULL);
4749 if ( IC_TRUE(ifx) ) {
4750 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4751 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4753 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4754 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4756 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4759 /* left and right are both bit variables, result is carry */
4762 resolveIfx(&rIfx,ifx);
4764 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4765 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4766 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4767 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4772 /* They're not both bit variables. Is the right a literal? */
4773 if(AOP_TYPE(right) == AOP_LIT) {
4774 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4779 switch(lit & 0xff) {
4781 if ( IC_TRUE(ifx) ) {
4782 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4784 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4786 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4787 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4791 if ( IC_TRUE(ifx) ) {
4792 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4794 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4796 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4797 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4801 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4803 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4808 /* end of size == 1 */
4812 genc16bit2lit(left,lit,offset);
4815 /* end of size == 2 */
4820 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4821 emitpcode(POC_IORFW,popGet(AOP(left),1));
4822 emitpcode(POC_IORFW,popGet(AOP(left),2));
4823 emitpcode(POC_IORFW,popGet(AOP(left),3));
4827 /* search for patterns that can be optimized */
4829 genc16bit2lit(left,lit,0);
4832 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4834 genc16bit2lit(left,lit,2);
4836 emitpcode(POC_IORFW,popGet(AOP(left),2));
4837 emitpcode(POC_IORFW,popGet(AOP(left),3));
4850 } else if(AOP_TYPE(right) == AOP_CRY ) {
4851 /* we know the left is not a bit, but that the right is */
4852 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4853 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4854 popGet(AOP(right),offset));
4855 emitpcode(POC_XORLW,popGetLit(1));
4857 /* if the two are equal, then W will be 0 and the Z bit is set
4858 * we could test Z now, or go ahead and check the high order bytes if
4859 * the variable we're comparing is larger than a byte. */
4862 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4864 if ( IC_TRUE(ifx) ) {
4866 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4867 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4870 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4871 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4875 /* They're both variables that are larger than bits */
4878 tlbl = newiTempLabel(NULL);
4881 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4882 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4884 if ( IC_TRUE(ifx) ) {
4887 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4888 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4891 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4892 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4896 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4897 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4901 if(s>1 && IC_TRUE(ifx)) {
4902 emitpLabel(tlbl->key);
4903 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4907 /* mark the icode as generated */
4912 /* if they are both bit variables */
4913 if (AOP_TYPE(left) == AOP_CRY &&
4914 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4915 if(AOP_TYPE(right) == AOP_LIT){
4916 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4918 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4919 pic14_emitcode("cpl","c");
4920 } else if(lit == 1L) {
4921 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4923 pic14_emitcode("clr","c");
4925 /* AOP_TYPE(right) == AOP_CRY */
4927 symbol *lbl = newiTempLabel(NULL);
4928 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4929 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4930 pic14_emitcode("cpl","c");
4931 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4934 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4935 pic14_outBitC(result);
4939 genIfxJump (ifx,"c");
4942 /* if the result is used in an arithmetic operation
4943 then put the result in place */
4944 pic14_outBitC(result);
4947 gencjne(left,right,result,ifx);
4950 gencjne(left,right,newiTempLabel(NULL));
4952 if(IC_TRUE(ifx)->key)
4953 gencjne(left,right,IC_TRUE(ifx)->key);
4955 gencjne(left,right,IC_FALSE(ifx)->key);
4959 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4960 aopPut(AOP(result),"a",0);
4965 genIfxJump (ifx,"a");
4969 /* if the result is used in an arithmetic operation
4970 then put the result in place */
4972 if (AOP_TYPE(result) != AOP_CRY)
4973 pic14_outAcc(result);
4975 /* leave the result in acc */
4979 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4980 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4981 freeAsmop(result,NULL,ic,TRUE);
4984 /*-----------------------------------------------------------------*/
4985 /* ifxForOp - returns the icode containing the ifx for operand */
4986 /*-----------------------------------------------------------------*/
4987 static iCode *ifxForOp ( operand *op, iCode *ic )
4989 /* if true symbol then needs to be assigned */
4990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4991 if (IS_TRUE_SYMOP(op))
4994 /* if this has register type condition and
4995 the next instruction is ifx with the same operand
4996 and live to of the operand is upto the ifx only then */
4998 ic->next->op == IFX &&
4999 IC_COND(ic->next)->key == op->key &&
5000 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5004 ic->next->op == IFX &&
5005 IC_COND(ic->next)->key == op->key) {
5006 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5010 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5012 ic->next->op == IFX)
5013 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5016 ic->next->op == IFX &&
5017 IC_COND(ic->next)->key == op->key) {
5018 DEBUGpic14_emitcode ("; "," key is okay");
5019 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5020 OP_SYMBOL(op)->liveTo,
5027 /*-----------------------------------------------------------------*/
5028 /* genAndOp - for && operation */
5029 /*-----------------------------------------------------------------*/
5030 static void genAndOp (iCode *ic)
5032 operand *left,*right, *result;
5035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5036 /* note here that && operations that are in an
5037 if statement are taken away by backPatchLabels
5038 only those used in arthmetic operations remain */
5039 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5040 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5041 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5043 /* if both are bit variables */
5044 if (AOP_TYPE(left) == AOP_CRY &&
5045 AOP_TYPE(right) == AOP_CRY ) {
5046 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5047 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5048 pic14_outBitC(result);
5050 tlbl = newiTempLabel(NULL);
5051 pic14_toBoolean(left);
5052 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5053 pic14_toBoolean(right);
5054 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5055 pic14_outBitAcc(result);
5058 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5059 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5060 freeAsmop(result,NULL,ic,TRUE);
5064 /*-----------------------------------------------------------------*/
5065 /* genOrOp - for || operation */
5066 /*-----------------------------------------------------------------*/
5069 modified this code, but it doesn't appear to ever get called
5072 static void genOrOp (iCode *ic)
5074 operand *left,*right, *result;
5077 /* note here that || operations that are in an
5078 if statement are taken away by backPatchLabels
5079 only those used in arthmetic operations remain */
5080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5081 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5082 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5083 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5085 DEBUGpic14_AopType(__LINE__,left,right,result);
5087 /* if both are bit variables */
5088 if (AOP_TYPE(left) == AOP_CRY &&
5089 AOP_TYPE(right) == AOP_CRY ) {
5090 pic14_emitcode("clrc","");
5091 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5092 AOP(left)->aopu.aop_dir,
5093 AOP(left)->aopu.aop_dir);
5094 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5095 AOP(right)->aopu.aop_dir,
5096 AOP(right)->aopu.aop_dir);
5097 pic14_emitcode("setc","");
5100 tlbl = newiTempLabel(NULL);
5101 pic14_toBoolean(left);
5103 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5104 pic14_toBoolean(right);
5105 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5107 pic14_outBitAcc(result);
5110 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5111 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5112 freeAsmop(result,NULL,ic,TRUE);
5115 /*-----------------------------------------------------------------*/
5116 /* isLiteralBit - test if lit == 2^n */
5117 /*-----------------------------------------------------------------*/
5118 static int isLiteralBit(unsigned long lit)
5120 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5121 0x100L,0x200L,0x400L,0x800L,
5122 0x1000L,0x2000L,0x4000L,0x8000L,
5123 0x10000L,0x20000L,0x40000L,0x80000L,
5124 0x100000L,0x200000L,0x400000L,0x800000L,
5125 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5126 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5130 for(idx = 0; idx < 32; idx++)
5136 /*-----------------------------------------------------------------*/
5137 /* continueIfTrue - */
5138 /*-----------------------------------------------------------------*/
5139 static void continueIfTrue (iCode *ic)
5141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5143 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5147 /*-----------------------------------------------------------------*/
5149 /*-----------------------------------------------------------------*/
5150 static void jumpIfTrue (iCode *ic)
5152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5154 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5158 /*-----------------------------------------------------------------*/
5159 /* jmpTrueOrFalse - */
5160 /*-----------------------------------------------------------------*/
5161 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5163 // ugly but optimized by peephole
5164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5166 symbol *nlbl = newiTempLabel(NULL);
5167 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5168 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5169 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5170 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5173 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5174 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5179 /*-----------------------------------------------------------------*/
5180 /* genAnd - code for and */
5181 /*-----------------------------------------------------------------*/
5182 static void genAnd (iCode *ic, iCode *ifx)
5184 operand *left, *right, *result;
5186 unsigned long lit = 0L;
5191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5192 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5193 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5194 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5196 resolveIfx(&rIfx,ifx);
5198 /* if left is a literal & right is not then exchange them */
5199 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5200 AOP_NEEDSACC(left)) {
5201 operand *tmp = right ;
5206 /* if result = right then exchange them */
5207 if(pic14_sameRegs(AOP(result),AOP(right))){
5208 operand *tmp = right ;
5213 /* if right is bit then exchange them */
5214 if (AOP_TYPE(right) == AOP_CRY &&
5215 AOP_TYPE(left) != AOP_CRY){
5216 operand *tmp = right ;
5220 if(AOP_TYPE(right) == AOP_LIT)
5221 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5223 size = AOP_SIZE(result);
5225 DEBUGpic14_AopType(__LINE__,left,right,result);
5228 // result = bit & yy;
5229 if (AOP_TYPE(left) == AOP_CRY){
5230 // c = bit & literal;
5231 if(AOP_TYPE(right) == AOP_LIT){
5233 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5236 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5239 if(size && (AOP_TYPE(result) == AOP_CRY)){
5240 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5243 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5247 pic14_emitcode("clr","c");
5250 if (AOP_TYPE(right) == AOP_CRY){
5252 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5253 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5256 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5258 pic14_emitcode("rrc","a");
5259 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5265 pic14_outBitC(result);
5267 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5268 genIfxJump(ifx, "c");
5272 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5273 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5274 if((AOP_TYPE(right) == AOP_LIT) &&
5275 (AOP_TYPE(result) == AOP_CRY) &&
5276 (AOP_TYPE(left) != AOP_CRY)){
5277 int posbit = isLiteralBit(lit);
5281 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5284 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5290 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5291 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5293 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5294 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5297 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5298 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5299 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5306 symbol *tlbl = newiTempLabel(NULL);
5307 int sizel = AOP_SIZE(left);
5309 pic14_emitcode("setb","c");
5311 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5312 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5314 if((posbit = isLiteralBit(bytelit)) != 0)
5315 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5317 if(bytelit != 0x0FFL)
5318 pic14_emitcode("anl","a,%s",
5319 aopGet(AOP(right),offset,FALSE,TRUE));
5320 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5325 // bit = left & literal
5327 pic14_emitcode("clr","c");
5328 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5330 // if(left & literal)
5333 jmpTrueOrFalse(ifx, tlbl);
5337 pic14_outBitC(result);
5341 /* if left is same as result */
5342 if(pic14_sameRegs(AOP(result),AOP(left))){
5344 for(;size--; offset++,lit>>=8) {
5345 if(AOP_TYPE(right) == AOP_LIT){
5346 switch(lit & 0xff) {
5348 /* and'ing with 0 has clears the result */
5349 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5350 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5353 /* and'ing with 0xff is a nop when the result and left are the same */
5358 int p = my_powof2( (~lit) & 0xff );
5360 /* only one bit is set in the literal, so use a bcf instruction */
5361 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5362 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5365 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5366 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5367 if(know_W != (lit&0xff))
5368 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5370 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5375 if (AOP_TYPE(left) == AOP_ACC) {
5376 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5378 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5379 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5386 // left & result in different registers
5387 if(AOP_TYPE(result) == AOP_CRY){
5389 // if(size), result in bit
5390 // if(!size && ifx), conditional oper: if(left & right)
5391 symbol *tlbl = newiTempLabel(NULL);
5392 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5394 pic14_emitcode("setb","c");
5396 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5397 pic14_emitcode("anl","a,%s",
5398 aopGet(AOP(left),offset,FALSE,FALSE));
5399 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5404 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5405 pic14_outBitC(result);
5407 jmpTrueOrFalse(ifx, tlbl);
5409 for(;(size--);offset++) {
5411 // result = left & right
5412 if(AOP_TYPE(right) == AOP_LIT){
5413 int t = (lit >> (offset*8)) & 0x0FFL;
5416 pic14_emitcode("clrf","%s",
5417 aopGet(AOP(result),offset,FALSE,FALSE));
5418 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5421 pic14_emitcode("movf","%s,w",
5422 aopGet(AOP(left),offset,FALSE,FALSE));
5423 pic14_emitcode("movwf","%s",
5424 aopGet(AOP(result),offset,FALSE,FALSE));
5425 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5426 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5429 pic14_emitcode("movlw","0x%x",t);
5430 pic14_emitcode("andwf","%s,w",
5431 aopGet(AOP(left),offset,FALSE,FALSE));
5432 pic14_emitcode("movwf","%s",
5433 aopGet(AOP(result),offset,FALSE,FALSE));
5435 emitpcode(POC_MOVLW, popGetLit(t));
5436 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5437 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5442 if (AOP_TYPE(left) == AOP_ACC) {
5443 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5444 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5446 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5447 pic14_emitcode("andwf","%s,w",
5448 aopGet(AOP(left),offset,FALSE,FALSE));
5449 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5450 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5452 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5453 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5459 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5460 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5461 freeAsmop(result,NULL,ic,TRUE);
5464 /*-----------------------------------------------------------------*/
5465 /* genOr - code for or */
5466 /*-----------------------------------------------------------------*/
5467 static void genOr (iCode *ic, iCode *ifx)
5469 operand *left, *right, *result;
5471 unsigned long lit = 0L;
5473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5475 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5476 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5477 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5479 DEBUGpic14_AopType(__LINE__,left,right,result);
5481 /* if left is a literal & right is not then exchange them */
5482 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5483 AOP_NEEDSACC(left)) {
5484 operand *tmp = right ;
5489 /* if result = right then exchange them */
5490 if(pic14_sameRegs(AOP(result),AOP(right))){
5491 operand *tmp = right ;
5496 /* if right is bit then exchange them */
5497 if (AOP_TYPE(right) == AOP_CRY &&
5498 AOP_TYPE(left) != AOP_CRY){
5499 operand *tmp = right ;
5504 DEBUGpic14_AopType(__LINE__,left,right,result);
5506 if(AOP_TYPE(right) == AOP_LIT)
5507 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5509 size = AOP_SIZE(result);
5513 if (AOP_TYPE(left) == AOP_CRY){
5514 if(AOP_TYPE(right) == AOP_LIT){
5515 // c = bit & literal;
5517 // lit != 0 => result = 1
5518 if(AOP_TYPE(result) == AOP_CRY){
5520 emitpcode(POC_BSF, popGet(AOP(result),0));
5521 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5522 // AOP(result)->aopu.aop_dir,
5523 // AOP(result)->aopu.aop_dir);
5525 continueIfTrue(ifx);
5529 // lit == 0 => result = left
5530 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5532 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5535 if (AOP_TYPE(right) == AOP_CRY){
5536 if(pic14_sameRegs(AOP(result),AOP(left))){
5538 emitpcode(POC_BCF, popGet(AOP(result),0));
5539 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5540 emitpcode(POC_BSF, popGet(AOP(result),0));
5542 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5543 AOP(result)->aopu.aop_dir,
5544 AOP(result)->aopu.aop_dir);
5545 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5546 AOP(right)->aopu.aop_dir,
5547 AOP(right)->aopu.aop_dir);
5548 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5549 AOP(result)->aopu.aop_dir,
5550 AOP(result)->aopu.aop_dir);
5552 if( AOP_TYPE(result) == AOP_ACC) {
5553 emitpcode(POC_MOVLW, popGetLit(0));
5554 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5555 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5556 emitpcode(POC_MOVLW, popGetLit(1));
5560 emitpcode(POC_BCF, popGet(AOP(result),0));
5561 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5562 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5563 emitpcode(POC_BSF, popGet(AOP(result),0));
5565 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5566 AOP(result)->aopu.aop_dir,
5567 AOP(result)->aopu.aop_dir);
5568 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5569 AOP(right)->aopu.aop_dir,
5570 AOP(right)->aopu.aop_dir);
5571 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5572 AOP(left)->aopu.aop_dir,
5573 AOP(left)->aopu.aop_dir);
5574 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5575 AOP(result)->aopu.aop_dir,
5576 AOP(result)->aopu.aop_dir);
5581 symbol *tlbl = newiTempLabel(NULL);
5582 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5585 emitpcode(POC_BCF, popGet(AOP(result),0));
5586 if( AOP_TYPE(right) == AOP_ACC) {
5587 emitpcode(POC_IORLW, popGetLit(0));
5589 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5590 emitpcode(POC_BSF, popGet(AOP(result),0));
5595 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5596 pic14_emitcode(";XXX setb","c");
5597 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5598 AOP(left)->aopu.aop_dir,tlbl->key+100);
5599 pic14_toBoolean(right);
5600 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5601 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5602 jmpTrueOrFalse(ifx, tlbl);
5606 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5613 pic14_outBitC(result);
5615 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5616 genIfxJump(ifx, "c");
5620 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5621 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5622 if((AOP_TYPE(right) == AOP_LIT) &&
5623 (AOP_TYPE(result) == AOP_CRY) &&
5624 (AOP_TYPE(left) != AOP_CRY)){
5626 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5629 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5631 continueIfTrue(ifx);
5634 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5635 // lit = 0, result = boolean(left)
5637 pic14_emitcode(";XXX setb","c");
5638 pic14_toBoolean(right);
5640 symbol *tlbl = newiTempLabel(NULL);
5641 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5643 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5645 genIfxJump (ifx,"a");
5649 pic14_outBitC(result);
5653 /* if left is same as result */
5654 if(pic14_sameRegs(AOP(result),AOP(left))){
5656 for(;size--; offset++,lit>>=8) {
5657 if(AOP_TYPE(right) == AOP_LIT){
5658 if((lit & 0xff) == 0)
5659 /* or'ing with 0 has no effect */
5662 int p = my_powof2(lit & 0xff);
5664 /* only one bit is set in the literal, so use a bsf instruction */
5666 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5668 if(know_W != (lit & 0xff))
5669 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5670 know_W = lit & 0xff;
5671 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5676 if (AOP_TYPE(left) == AOP_ACC) {
5677 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5678 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5680 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5681 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5683 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5684 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5690 // left & result in different registers
5691 if(AOP_TYPE(result) == AOP_CRY){
5693 // if(size), result in bit
5694 // if(!size && ifx), conditional oper: if(left | right)
5695 symbol *tlbl = newiTempLabel(NULL);
5696 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5697 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5701 pic14_emitcode(";XXX setb","c");
5703 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5704 pic14_emitcode(";XXX orl","a,%s",
5705 aopGet(AOP(left),offset,FALSE,FALSE));
5706 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5711 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5712 pic14_outBitC(result);
5714 jmpTrueOrFalse(ifx, tlbl);
5715 } else for(;(size--);offset++){
5717 // result = left & right
5718 if(AOP_TYPE(right) == AOP_LIT){
5719 int t = (lit >> (offset*8)) & 0x0FFL;
5722 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5723 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5725 pic14_emitcode("movf","%s,w",
5726 aopGet(AOP(left),offset,FALSE,FALSE));
5727 pic14_emitcode("movwf","%s",
5728 aopGet(AOP(result),offset,FALSE,FALSE));
5731 emitpcode(POC_MOVLW, popGetLit(t));
5732 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5733 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5735 pic14_emitcode("movlw","0x%x",t);
5736 pic14_emitcode("iorwf","%s,w",
5737 aopGet(AOP(left),offset,FALSE,FALSE));
5738 pic14_emitcode("movwf","%s",
5739 aopGet(AOP(result),offset,FALSE,FALSE));
5745 // faster than result <- left, anl result,right
5746 // and better if result is SFR
5747 if (AOP_TYPE(left) == AOP_ACC) {
5748 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5749 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5751 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5752 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5754 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5755 pic14_emitcode("iorwf","%s,w",
5756 aopGet(AOP(left),offset,FALSE,FALSE));
5758 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5759 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5764 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5765 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5766 freeAsmop(result,NULL,ic,TRUE);
5769 /*-----------------------------------------------------------------*/
5770 /* genXor - code for xclusive or */
5771 /*-----------------------------------------------------------------*/
5772 static void genXor (iCode *ic, iCode *ifx)
5774 operand *left, *right, *result;
5776 unsigned long lit = 0L;
5778 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5780 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5781 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5782 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5784 /* if left is a literal & right is not ||
5785 if left needs acc & right does not */
5786 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5787 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5788 operand *tmp = right ;
5793 /* if result = right then exchange them */
5794 if(pic14_sameRegs(AOP(result),AOP(right))){
5795 operand *tmp = right ;
5800 /* if right is bit then exchange them */
5801 if (AOP_TYPE(right) == AOP_CRY &&
5802 AOP_TYPE(left) != AOP_CRY){
5803 operand *tmp = right ;
5807 if(AOP_TYPE(right) == AOP_LIT)
5808 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5810 size = AOP_SIZE(result);
5814 if (AOP_TYPE(left) == AOP_CRY){
5815 if(AOP_TYPE(right) == AOP_LIT){
5816 // c = bit & literal;
5818 // lit>>1 != 0 => result = 1
5819 if(AOP_TYPE(result) == AOP_CRY){
5821 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5822 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5824 continueIfTrue(ifx);
5827 pic14_emitcode("setb","c");
5831 // lit == 0, result = left
5832 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5834 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5836 // lit == 1, result = not(left)
5837 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5838 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5839 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5840 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5843 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5844 pic14_emitcode("cpl","c");
5851 symbol *tlbl = newiTempLabel(NULL);
5852 if (AOP_TYPE(right) == AOP_CRY){
5854 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5857 int sizer = AOP_SIZE(right);
5859 // if val>>1 != 0, result = 1
5860 pic14_emitcode("setb","c");
5862 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5864 // test the msb of the lsb
5865 pic14_emitcode("anl","a,#0xfe");
5866 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5870 pic14_emitcode("rrc","a");
5872 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5873 pic14_emitcode("cpl","c");
5874 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5879 pic14_outBitC(result);
5881 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5882 genIfxJump(ifx, "c");
5886 if(pic14_sameRegs(AOP(result),AOP(left))){
5887 /* if left is same as result */
5888 for(;size--; offset++) {
5889 if(AOP_TYPE(right) == AOP_LIT){
5890 int t = (lit >> (offset*8)) & 0x0FFL;
5894 if (IS_AOP_PREG(left)) {
5895 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5896 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5897 aopPut(AOP(result),"a",offset);
5899 emitpcode(POC_MOVLW, popGetLit(t));
5900 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5901 pic14_emitcode("xrl","%s,%s",
5902 aopGet(AOP(left),offset,FALSE,TRUE),
5903 aopGet(AOP(right),offset,FALSE,FALSE));
5906 if (AOP_TYPE(left) == AOP_ACC)
5907 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5909 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5910 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5912 if (IS_AOP_PREG(left)) {
5913 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5914 aopPut(AOP(result),"a",offset);
5916 pic14_emitcode("xrl","%s,a",
5917 aopGet(AOP(left),offset,FALSE,TRUE));
5923 // left & result in different registers
5924 if(AOP_TYPE(result) == AOP_CRY){
5926 // if(size), result in bit
5927 // if(!size && ifx), conditional oper: if(left ^ right)
5928 symbol *tlbl = newiTempLabel(NULL);
5929 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5931 pic14_emitcode("setb","c");
5933 if((AOP_TYPE(right) == AOP_LIT) &&
5934 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5935 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5937 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5938 pic14_emitcode("xrl","a,%s",
5939 aopGet(AOP(left),offset,FALSE,FALSE));
5941 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5946 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5947 pic14_outBitC(result);
5949 jmpTrueOrFalse(ifx, tlbl);
5950 } else for(;(size--);offset++){
5952 // result = left & right
5953 if(AOP_TYPE(right) == AOP_LIT){
5954 int t = (lit >> (offset*8)) & 0x0FFL;
5957 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5958 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5959 pic14_emitcode("movf","%s,w",
5960 aopGet(AOP(left),offset,FALSE,FALSE));
5961 pic14_emitcode("movwf","%s",
5962 aopGet(AOP(result),offset,FALSE,FALSE));
5965 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5966 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5967 pic14_emitcode("comf","%s,w",
5968 aopGet(AOP(left),offset,FALSE,FALSE));
5969 pic14_emitcode("movwf","%s",
5970 aopGet(AOP(result),offset,FALSE,FALSE));
5973 emitpcode(POC_MOVLW, popGetLit(t));
5974 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5975 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5976 pic14_emitcode("movlw","0x%x",t);
5977 pic14_emitcode("xorwf","%s,w",
5978 aopGet(AOP(left),offset,FALSE,FALSE));
5979 pic14_emitcode("movwf","%s",
5980 aopGet(AOP(result),offset,FALSE,FALSE));
5986 // faster than result <- left, anl result,right
5987 // and better if result is SFR
5988 if (AOP_TYPE(left) == AOP_ACC) {
5989 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5990 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5992 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5993 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5994 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5995 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5997 if ( AOP_TYPE(result) != AOP_ACC){
5998 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5999 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6005 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6006 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6007 freeAsmop(result,NULL,ic,TRUE);
6010 /*-----------------------------------------------------------------*/
6011 /* genInline - write the inline code out */
6012 /*-----------------------------------------------------------------*/
6013 static void genInline (iCode *ic)
6015 char *buffer, *bp, *bp1;
6017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6019 _G.inLine += (!options.asmpeep);
6021 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6022 strcpy(buffer,IC_INLINE(ic));
6024 /* emit each line as a code */
6030 addpCode2pBlock(pb,AssembleLine(bp1));
6037 pic14_emitcode(bp1,"");
6043 if ((bp1 != bp) && *bp1)
6044 addpCode2pBlock(pb,AssembleLine(bp1));
6048 _G.inLine -= (!options.asmpeep);
6051 /*-----------------------------------------------------------------*/
6052 /* genRRC - rotate right with carry */
6053 /*-----------------------------------------------------------------*/
6054 static void genRRC (iCode *ic)
6056 operand *left , *result ;
6057 int size, offset = 0, same;
6059 /* rotate right with carry */
6061 result=IC_RESULT(ic);
6062 aopOp (left,ic,FALSE);
6063 aopOp (result,ic,FALSE);
6065 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6067 same = pic14_sameRegs(AOP(result),AOP(left));
6069 size = AOP_SIZE(result);
6071 /* get the lsb and put it into the carry */
6072 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6079 emitpcode(POC_RRF, popGet(AOP(left),offset));
6081 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6082 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6088 freeAsmop(left,NULL,ic,TRUE);
6089 freeAsmop(result,NULL,ic,TRUE);
6092 /*-----------------------------------------------------------------*/
6093 /* genRLC - generate code for rotate left with carry */
6094 /*-----------------------------------------------------------------*/
6095 static void genRLC (iCode *ic)
6097 operand *left , *result ;
6098 int size, offset = 0;
6101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6102 /* rotate right with carry */
6104 result=IC_RESULT(ic);
6105 aopOp (left,ic,FALSE);
6106 aopOp (result,ic,FALSE);
6108 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6110 same = pic14_sameRegs(AOP(result),AOP(left));
6112 /* move it to the result */
6113 size = AOP_SIZE(result);
6115 /* get the msb and put it into the carry */
6116 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6123 emitpcode(POC_RLF, popGet(AOP(left),offset));
6125 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6126 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6133 freeAsmop(left,NULL,ic,TRUE);
6134 freeAsmop(result,NULL,ic,TRUE);
6137 /*-----------------------------------------------------------------*/
6138 /* genGetHbit - generates code get highest order bit */
6139 /*-----------------------------------------------------------------*/
6140 static void genGetHbit (iCode *ic)
6142 operand *left, *result;
6144 result=IC_RESULT(ic);
6145 aopOp (left,ic,FALSE);
6146 aopOp (result,ic,FALSE);
6148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6149 /* get the highest order byte into a */
6150 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6151 if(AOP_TYPE(result) == AOP_CRY){
6152 pic14_emitcode("rlc","a");
6153 pic14_outBitC(result);
6156 pic14_emitcode("rl","a");
6157 pic14_emitcode("anl","a,#0x01");
6158 pic14_outAcc(result);
6162 freeAsmop(left,NULL,ic,TRUE);
6163 freeAsmop(result,NULL,ic,TRUE);
6166 /*-----------------------------------------------------------------*/
6167 /* AccRol - rotate left accumulator by known count */
6168 /*-----------------------------------------------------------------*/
6169 static void AccRol (int shCount)
6171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6172 shCount &= 0x0007; // shCount : 0..7
6177 pic14_emitcode("rl","a");
6180 pic14_emitcode("rl","a");
6181 pic14_emitcode("rl","a");
6184 pic14_emitcode("swap","a");
6185 pic14_emitcode("rr","a");
6188 pic14_emitcode("swap","a");
6191 pic14_emitcode("swap","a");
6192 pic14_emitcode("rl","a");
6195 pic14_emitcode("rr","a");
6196 pic14_emitcode("rr","a");
6199 pic14_emitcode("rr","a");
6204 /*-----------------------------------------------------------------*/
6205 /* AccLsh - left shift accumulator by known count */
6206 /*-----------------------------------------------------------------*/
6207 static void AccLsh (int shCount)
6209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6212 pic14_emitcode("add","a,acc");
6215 pic14_emitcode("add","a,acc");
6216 pic14_emitcode("add","a,acc");
6218 /* rotate left accumulator */
6220 /* and kill the lower order bits */
6221 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6226 /*-----------------------------------------------------------------*/
6227 /* AccRsh - right shift accumulator by known count */
6228 /*-----------------------------------------------------------------*/
6229 static void AccRsh (int shCount)
6231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6235 pic14_emitcode("rrc","a");
6237 /* rotate right accumulator */
6238 AccRol(8 - shCount);
6239 /* and kill the higher order bits */
6240 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6246 /*-----------------------------------------------------------------*/
6247 /* AccSRsh - signed right shift accumulator by known count */
6248 /*-----------------------------------------------------------------*/
6249 static void AccSRsh (int shCount)
6252 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6255 pic14_emitcode("mov","c,acc.7");
6256 pic14_emitcode("rrc","a");
6257 } else if(shCount == 2){
6258 pic14_emitcode("mov","c,acc.7");
6259 pic14_emitcode("rrc","a");
6260 pic14_emitcode("mov","c,acc.7");
6261 pic14_emitcode("rrc","a");
6263 tlbl = newiTempLabel(NULL);
6264 /* rotate right accumulator */
6265 AccRol(8 - shCount);
6266 /* and kill the higher order bits */
6267 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6268 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6269 pic14_emitcode("orl","a,#0x%02x",
6270 (unsigned char)~SRMask[shCount]);
6271 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6276 /*-----------------------------------------------------------------*/
6277 /* shiftR1Left2Result - shift right one byte from left to result */
6278 /*-----------------------------------------------------------------*/
6279 static void shiftR1Left2ResultSigned (operand *left, int offl,
6280 operand *result, int offr,
6285 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6287 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6291 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6293 emitpcode(POC_RRF, popGet(AOP(result),offr));
6295 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6296 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6302 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6304 emitpcode(POC_RRF, popGet(AOP(result),offr));
6306 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6307 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6309 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6310 emitpcode(POC_RRF, popGet(AOP(result),offr));
6316 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6318 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6319 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6322 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6323 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6324 emitpcode(POC_ANDLW, popGetLit(0x1f));
6326 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6327 emitpcode(POC_IORLW, popGetLit(0xe0));
6329 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6333 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6334 emitpcode(POC_ANDLW, popGetLit(0x0f));
6335 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6336 emitpcode(POC_IORLW, popGetLit(0xf0));
6337 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6341 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6343 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6344 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6346 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6347 emitpcode(POC_ANDLW, popGetLit(0x07));
6348 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6349 emitpcode(POC_IORLW, popGetLit(0xf8));
6350 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6355 emitpcode(POC_MOVLW, popGetLit(0x00));
6356 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6357 emitpcode(POC_MOVLW, popGetLit(0xfe));
6358 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6359 emitpcode(POC_IORLW, popGetLit(0x01));
6360 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6362 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6363 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6364 emitpcode(POC_DECF, popGet(AOP(result),offr));
6365 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6366 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6372 emitpcode(POC_MOVLW, popGetLit(0x00));
6373 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6374 emitpcode(POC_MOVLW, popGetLit(0xff));
6375 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6377 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6378 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6379 emitpcode(POC_DECF, popGet(AOP(result),offr));
6387 /*-----------------------------------------------------------------*/
6388 /* shiftR1Left2Result - shift right one byte from left to result */
6389 /*-----------------------------------------------------------------*/
6390 static void shiftR1Left2Result (operand *left, int offl,
6391 operand *result, int offr,
6392 int shCount, int sign)
6396 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6398 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6400 /* Copy the msb into the carry if signed. */
6402 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6412 emitpcode(POC_RRF, popGet(AOP(result),offr));
6414 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6415 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6421 emitpcode(POC_RRF, popGet(AOP(result),offr));
6423 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6424 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427 emitpcode(POC_RRF, popGet(AOP(result),offr));
6432 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6434 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6435 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6439 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6440 emitpcode(POC_ANDLW, popGetLit(0x1f));
6441 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6446 emitpcode(POC_ANDLW, popGetLit(0x0f));
6447 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6451 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6452 emitpcode(POC_ANDLW, popGetLit(0x0f));
6453 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6455 emitpcode(POC_RRF, popGet(AOP(result),offr));
6460 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6461 emitpcode(POC_ANDLW, popGetLit(0x80));
6462 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6463 emitpcode(POC_RLF, popGet(AOP(result),offr));
6464 emitpcode(POC_RLF, popGet(AOP(result),offr));
6469 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6470 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6471 emitpcode(POC_RLF, popGet(AOP(result),offr));
6480 /*-----------------------------------------------------------------*/
6481 /* shiftL1Left2Result - shift left one byte from left to result */
6482 /*-----------------------------------------------------------------*/
6483 static void shiftL1Left2Result (operand *left, int offl,
6484 operand *result, int offr, int shCount)
6489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6491 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6492 DEBUGpic14_emitcode ("; ***","same = %d",same);
6493 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6495 /* shift left accumulator */
6496 //AccLsh(shCount); // don't comment out just yet...
6497 // aopPut(AOP(result),"a",offr);
6501 /* Shift left 1 bit position */
6502 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6504 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6506 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6507 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6511 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW,popGetLit(0x7e));
6513 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6514 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6517 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6518 emitpcode(POC_ANDLW,popGetLit(0x3e));
6519 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6520 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6521 emitpcode(POC_RLF, popGet(AOP(result),offr));
6524 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6525 emitpcode(POC_ANDLW, popGetLit(0xf0));
6526 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6529 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6530 emitpcode(POC_ANDLW, popGetLit(0xf0));
6531 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6532 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6535 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6536 emitpcode(POC_ANDLW, popGetLit(0x30));
6537 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6538 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6539 emitpcode(POC_RLF, popGet(AOP(result),offr));
6542 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6543 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6544 emitpcode(POC_RRF, popGet(AOP(result),offr));
6548 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6553 /*-----------------------------------------------------------------*/
6554 /* movLeft2Result - move byte from left to result */
6555 /*-----------------------------------------------------------------*/
6556 static void movLeft2Result (operand *left, int offl,
6557 operand *result, int offr)
6560 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6561 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6562 l = aopGet(AOP(left),offl,FALSE,FALSE);
6564 if (*l == '@' && (IS_AOP_PREG(result))) {
6565 pic14_emitcode("mov","a,%s",l);
6566 aopPut(AOP(result),"a",offr);
6568 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6569 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6574 /*-----------------------------------------------------------------*/
6575 /* shiftL2Left2Result - shift left two bytes from left to result */
6576 /*-----------------------------------------------------------------*/
6577 static void shiftL2Left2Result (operand *left, int offl,
6578 operand *result, int offr, int shCount)
6582 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6584 if(pic14_sameRegs(AOP(result), AOP(left))) {
6592 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6593 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6594 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6598 emitpcode(POC_RLF, popGet(AOP(result),offr));
6599 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_MOVLW, popGetLit(0x0f));
6606 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6607 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6609 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6610 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6611 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_RLF, popGet(AOP(result),offr));
6614 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6619 emitpcode(POC_RRF, popGet(AOP(result),offr));
6620 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6621 emitpcode(POC_RRF, popGet(AOP(result),offr));
6622 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6623 emitpcode(POC_ANDLW,popGetLit(0xc0));
6624 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6625 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6626 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6627 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6630 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6631 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6632 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6633 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6634 emitpcode(POC_RRF, popGet(AOP(result),offr));
6644 /* note, use a mov/add for the shift since the mov has a
6645 chance of getting optimized out */
6646 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6647 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6648 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6649 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6650 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6654 emitpcode(POC_RLF, popGet(AOP(result),offr));
6655 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6661 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6662 emitpcode(POC_ANDLW, popGetLit(0xF0));
6663 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6665 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6666 emitpcode(POC_ANDLW, popGetLit(0xF0));
6667 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6668 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_RLF, popGet(AOP(result),offr));
6673 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6677 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6678 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6679 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6680 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6682 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_RRF, popGet(AOP(result),offr));
6684 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6685 emitpcode(POC_ANDLW,popGetLit(0xc0));
6686 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6688 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6689 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6693 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6694 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6695 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6696 emitpcode(POC_RRF, popGet(AOP(result),offr));
6701 /*-----------------------------------------------------------------*/
6702 /* shiftR2Left2Result - shift right two bytes from left to result */
6703 /*-----------------------------------------------------------------*/
6704 static void shiftR2Left2Result (operand *left, int offl,
6705 operand *result, int offr,
6706 int shCount, int sign)
6710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6711 same = pic14_sameRegs(AOP(result), AOP(left));
6713 if(same && ((offl + MSB16) == offr)){
6715 /* don't crash result[offr] */
6716 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6717 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6719 movLeft2Result(left,offl, result, offr);
6720 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6722 /* a:x >> shCount (x = lsb(result))*/
6725 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6727 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6736 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_RRF,popGet(AOP(result),offr));
6744 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6745 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6747 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6752 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6756 emitpcode(POC_RRF,popGet(AOP(result),offr));
6763 emitpcode(POC_MOVLW, popGetLit(0xf0));
6764 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6765 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6767 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6768 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6769 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6770 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6772 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6773 emitpcode(POC_ANDLW, popGetLit(0x0f));
6774 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6776 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6777 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6778 emitpcode(POC_ANDLW, popGetLit(0xf0));
6779 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6780 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6784 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6785 emitpcode(POC_RRF, popGet(AOP(result),offr));
6789 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6790 emitpcode(POC_BTFSC,
6791 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6792 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_RLF, popGet(AOP(result),offr));
6801 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_RLF, popGet(AOP(result),offr));
6804 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6805 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6806 emitpcode(POC_ANDLW,popGetLit(0x03));
6808 emitpcode(POC_BTFSC,
6809 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6810 emitpcode(POC_IORLW,popGetLit(0xfc));
6812 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6813 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6814 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6815 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6817 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6818 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6819 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6820 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6821 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6822 emitpcode(POC_ANDLW,popGetLit(0x03));
6824 emitpcode(POC_BTFSC,
6825 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6826 emitpcode(POC_IORLW,popGetLit(0xfc));
6828 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6829 emitpcode(POC_RLF, popGet(AOP(result),offr));
6836 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6837 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6838 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6839 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6842 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6844 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6849 /*-----------------------------------------------------------------*/
6850 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6851 /*-----------------------------------------------------------------*/
6852 static void shiftLLeftOrResult (operand *left, int offl,
6853 operand *result, int offr, int shCount)
6855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6856 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6857 /* shift left accumulator */
6859 /* or with result */
6860 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6861 /* back to result */
6862 aopPut(AOP(result),"a",offr);
6865 /*-----------------------------------------------------------------*/
6866 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6867 /*-----------------------------------------------------------------*/
6868 static void shiftRLeftOrResult (operand *left, int offl,
6869 operand *result, int offr, int shCount)
6871 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6872 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6873 /* shift right accumulator */
6875 /* or with result */
6876 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6877 /* back to result */
6878 aopPut(AOP(result),"a",offr);
6881 /*-----------------------------------------------------------------*/
6882 /* genlshOne - left shift a one byte quantity by known count */
6883 /*-----------------------------------------------------------------*/
6884 static void genlshOne (operand *result, operand *left, int shCount)
6886 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6887 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6890 /*-----------------------------------------------------------------*/
6891 /* genlshTwo - left shift two bytes by known amount != 0 */
6892 /*-----------------------------------------------------------------*/
6893 static void genlshTwo (operand *result,operand *left, int shCount)
6897 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6898 size = pic14_getDataSize(result);
6900 /* if shCount >= 8 */
6906 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6908 movLeft2Result(left, LSB, result, MSB16);
6910 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6913 /* 1 <= shCount <= 7 */
6916 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6918 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6922 /*-----------------------------------------------------------------*/
6923 /* shiftLLong - shift left one long from left to result */
6924 /* offl = LSB or MSB16 */
6925 /*-----------------------------------------------------------------*/
6926 static void shiftLLong (operand *left, operand *result, int offr )
6929 int size = AOP_SIZE(result);
6931 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6932 if(size >= LSB+offr){
6933 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6935 pic14_emitcode("add","a,acc");
6936 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6937 size >= MSB16+offr && offr != LSB )
6938 pic14_emitcode("xch","a,%s",
6939 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6941 aopPut(AOP(result),"a",LSB+offr);
6944 if(size >= MSB16+offr){
6945 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6946 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6949 pic14_emitcode("rlc","a");
6950 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6951 size >= MSB24+offr && offr != LSB)
6952 pic14_emitcode("xch","a,%s",
6953 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6955 aopPut(AOP(result),"a",MSB16+offr);
6958 if(size >= MSB24+offr){
6959 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6960 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6963 pic14_emitcode("rlc","a");
6964 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6965 size >= MSB32+offr && offr != LSB )
6966 pic14_emitcode("xch","a,%s",
6967 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6969 aopPut(AOP(result),"a",MSB24+offr);
6972 if(size > MSB32+offr){
6973 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6974 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6977 pic14_emitcode("rlc","a");
6978 aopPut(AOP(result),"a",MSB32+offr);
6981 aopPut(AOP(result),zero,LSB);
6984 /*-----------------------------------------------------------------*/
6985 /* genlshFour - shift four byte by a known amount != 0 */
6986 /*-----------------------------------------------------------------*/
6987 static void genlshFour (operand *result, operand *left, int shCount)
6991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6992 size = AOP_SIZE(result);
6994 /* if shifting more that 3 bytes */
6995 if (shCount >= 24 ) {
6998 /* lowest order of left goes to the highest
6999 order of the destination */
7000 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7002 movLeft2Result(left, LSB, result, MSB32);
7003 aopPut(AOP(result),zero,LSB);
7004 aopPut(AOP(result),zero,MSB16);
7005 aopPut(AOP(result),zero,MSB32);
7009 /* more than two bytes */
7010 else if ( shCount >= 16 ) {
7011 /* lower order two bytes goes to higher order two bytes */
7013 /* if some more remaining */
7015 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7017 movLeft2Result(left, MSB16, result, MSB32);
7018 movLeft2Result(left, LSB, result, MSB24);
7020 aopPut(AOP(result),zero,MSB16);
7021 aopPut(AOP(result),zero,LSB);
7025 /* if more than 1 byte */
7026 else if ( shCount >= 8 ) {
7027 /* lower order three bytes goes to higher order three bytes */
7031 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7033 movLeft2Result(left, LSB, result, MSB16);
7035 else{ /* size = 4 */
7037 movLeft2Result(left, MSB24, result, MSB32);
7038 movLeft2Result(left, MSB16, result, MSB24);
7039 movLeft2Result(left, LSB, result, MSB16);
7040 aopPut(AOP(result),zero,LSB);
7042 else if(shCount == 1)
7043 shiftLLong(left, result, MSB16);
7045 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7046 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7047 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7048 aopPut(AOP(result),zero,LSB);
7053 /* 1 <= shCount <= 7 */
7054 else if(shCount <= 2){
7055 shiftLLong(left, result, LSB);
7057 shiftLLong(result, result, LSB);
7059 /* 3 <= shCount <= 7, optimize */
7061 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7062 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7063 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7067 /*-----------------------------------------------------------------*/
7068 /* genLeftShiftLiteral - left shifting by known count */
7069 /*-----------------------------------------------------------------*/
7070 static void genLeftShiftLiteral (operand *left,
7075 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7079 freeAsmop(right,NULL,ic,TRUE);
7081 aopOp(left,ic,FALSE);
7082 aopOp(result,ic,FALSE);
7084 size = getSize(operandType(result));
7087 pic14_emitcode("; shift left ","result %d, left %d",size,
7091 /* I suppose that the left size >= result size */
7094 movLeft2Result(left, size, result, size);
7098 else if(shCount >= (size * 8))
7100 aopPut(AOP(result),zero,size);
7104 genlshOne (result,left,shCount);
7109 genlshTwo (result,left,shCount);
7113 genlshFour (result,left,shCount);
7117 freeAsmop(left,NULL,ic,TRUE);
7118 freeAsmop(result,NULL,ic,TRUE);
7121 /*-----------------------------------------------------------------*
7122 * genMultiAsm - repeat assembly instruction for size of register.
7123 * if endian == 1, then the high byte (i.e base address + size of
7124 * register) is used first else the low byte is used first;
7125 *-----------------------------------------------------------------*/
7126 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7144 emitpcode(poc, popGet(AOP(reg),offset));
7149 /*-----------------------------------------------------------------*/
7150 /* genLeftShift - generates code for left shifting */
7151 /*-----------------------------------------------------------------*/
7152 static void genLeftShift (iCode *ic)
7154 operand *left,*right, *result;
7157 symbol *tlbl , *tlbl1;
7160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7162 right = IC_RIGHT(ic);
7164 result = IC_RESULT(ic);
7166 aopOp(right,ic,FALSE);
7168 /* if the shift count is known then do it
7169 as efficiently as possible */
7170 if (AOP_TYPE(right) == AOP_LIT) {
7171 genLeftShiftLiteral (left,right,result,ic);
7175 /* shift count is unknown then we have to form
7176 a loop get the loop count in B : Note: we take
7177 only the lower order byte since shifting
7178 more that 32 bits make no sense anyway, ( the
7179 largest size of an object can be only 32 bits ) */
7182 aopOp(left,ic,FALSE);
7183 aopOp(result,ic,FALSE);
7185 /* now move the left to the result if they are not the
7187 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7188 AOP_SIZE(result) > 1) {
7190 size = AOP_SIZE(result);
7193 l = aopGet(AOP(left),offset,FALSE,TRUE);
7194 if (*l == '@' && (IS_AOP_PREG(result))) {
7196 pic14_emitcode("mov","a,%s",l);
7197 aopPut(AOP(result),"a",offset);
7199 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7200 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7201 //aopPut(AOP(result),l,offset);
7207 size = AOP_SIZE(result);
7209 /* if it is only one byte then */
7211 if(optimized_for_speed) {
7212 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7213 emitpcode(POC_ANDLW, popGetLit(0xf0));
7214 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7215 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7216 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7217 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7218 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7219 emitpcode(POC_RLFW, popGet(AOP(result),0));
7220 emitpcode(POC_ANDLW, popGetLit(0xfe));
7221 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7222 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7223 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7226 tlbl = newiTempLabel(NULL);
7227 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7228 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7229 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7232 emitpcode(POC_COMFW, popGet(AOP(right),0));
7233 emitpcode(POC_RRF, popGet(AOP(result),0));
7234 emitpLabel(tlbl->key);
7235 emitpcode(POC_RLF, popGet(AOP(result),0));
7236 emitpcode(POC_ADDLW, popGetLit(1));
7238 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7243 if (pic14_sameRegs(AOP(left),AOP(result))) {
7245 tlbl = newiTempLabel(NULL);
7246 emitpcode(POC_COMFW, popGet(AOP(right),0));
7247 genMultiAsm(POC_RRF, result, size,1);
7248 emitpLabel(tlbl->key);
7249 genMultiAsm(POC_RLF, result, size,0);
7250 emitpcode(POC_ADDLW, popGetLit(1));
7252 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7256 //tlbl = newiTempLabel(NULL);
7258 //tlbl1 = newiTempLabel(NULL);
7260 //reAdjustPreg(AOP(result));
7262 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7263 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7264 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7266 //pic14_emitcode("add","a,acc");
7267 //aopPut(AOP(result),"a",offset++);
7269 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7271 // pic14_emitcode("rlc","a");
7272 // aopPut(AOP(result),"a",offset++);
7274 //reAdjustPreg(AOP(result));
7276 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7277 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7280 tlbl = newiTempLabel(NULL);
7281 tlbl1= newiTempLabel(NULL);
7283 size = AOP_SIZE(result);
7286 pctemp = popGetTempReg(); /* grab a temporary working register. */
7288 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7290 /* offset should be 0, 1 or 3 */
7291 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7293 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7295 emitpcode(POC_MOVWF, pctemp);
7298 emitpLabel(tlbl->key);
7301 emitpcode(POC_RLF, popGet(AOP(result),0));
7303 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7305 emitpcode(POC_DECFSZ, pctemp);
7306 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7307 emitpLabel(tlbl1->key);
7309 popReleaseTempReg(pctemp);
7313 freeAsmop (right,NULL,ic,TRUE);
7314 freeAsmop(left,NULL,ic,TRUE);
7315 freeAsmop(result,NULL,ic,TRUE);
7318 /*-----------------------------------------------------------------*/
7319 /* genrshOne - right shift a one byte quantity by known count */
7320 /*-----------------------------------------------------------------*/
7321 static void genrshOne (operand *result, operand *left,
7322 int shCount, int sign)
7324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7325 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7328 /*-----------------------------------------------------------------*/
7329 /* genrshTwo - right shift two bytes by known amount != 0 */
7330 /*-----------------------------------------------------------------*/
7331 static void genrshTwo (operand *result,operand *left,
7332 int shCount, int sign)
7334 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7335 /* if shCount >= 8 */
7339 shiftR1Left2Result(left, MSB16, result, LSB,
7342 movLeft2Result(left, MSB16, result, LSB);
7344 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7347 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7348 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7352 /* 1 <= shCount <= 7 */
7354 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7357 /*-----------------------------------------------------------------*/
7358 /* shiftRLong - shift right one long from left to result */
7359 /* offl = LSB or MSB16 */
7360 /*-----------------------------------------------------------------*/
7361 static void shiftRLong (operand *left, int offl,
7362 operand *result, int sign)
7364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7366 pic14_emitcode("clr","c");
7367 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7369 pic14_emitcode("mov","c,acc.7");
7370 pic14_emitcode("rrc","a");
7371 aopPut(AOP(result),"a",MSB32-offl);
7373 /* add sign of "a" */
7374 addSign(result, MSB32, sign);
7376 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7377 pic14_emitcode("rrc","a");
7378 aopPut(AOP(result),"a",MSB24-offl);
7380 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7381 pic14_emitcode("rrc","a");
7382 aopPut(AOP(result),"a",MSB16-offl);
7385 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7386 pic14_emitcode("rrc","a");
7387 aopPut(AOP(result),"a",LSB);
7391 /*-----------------------------------------------------------------*/
7392 /* genrshFour - shift four byte by a known amount != 0 */
7393 /*-----------------------------------------------------------------*/
7394 static void genrshFour (operand *result, operand *left,
7395 int shCount, int sign)
7397 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7398 /* if shifting more that 3 bytes */
7399 if(shCount >= 24 ) {
7402 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7404 movLeft2Result(left, MSB32, result, LSB);
7406 addSign(result, MSB16, sign);
7408 else if(shCount >= 16){
7411 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7413 movLeft2Result(left, MSB24, result, LSB);
7414 movLeft2Result(left, MSB32, result, MSB16);
7416 addSign(result, MSB24, sign);
7418 else if(shCount >= 8){
7421 shiftRLong(left, MSB16, result, sign);
7422 else if(shCount == 0){
7423 movLeft2Result(left, MSB16, result, LSB);
7424 movLeft2Result(left, MSB24, result, MSB16);
7425 movLeft2Result(left, MSB32, result, MSB24);
7426 addSign(result, MSB32, sign);
7429 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7430 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7431 /* the last shift is signed */
7432 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7433 addSign(result, MSB32, sign);
7436 else{ /* 1 <= shCount <= 7 */
7438 shiftRLong(left, LSB, result, sign);
7440 shiftRLong(result, LSB, result, sign);
7443 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7444 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7445 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7450 /*-----------------------------------------------------------------*/
7451 /* genRightShiftLiteral - right shifting by known count */
7452 /*-----------------------------------------------------------------*/
7453 static void genRightShiftLiteral (operand *left,
7459 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7462 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7463 freeAsmop(right,NULL,ic,TRUE);
7465 aopOp(left,ic,FALSE);
7466 aopOp(result,ic,FALSE);
7469 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7473 lsize = pic14_getDataSize(left);
7474 res_size = pic14_getDataSize(result);
7475 /* test the LEFT size !!! */
7477 /* I suppose that the left size >= result size */
7480 movLeft2Result(left, lsize, result, res_size);
7483 else if(shCount >= (lsize * 8)){
7486 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7488 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7489 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7494 emitpcode(POC_MOVLW, popGetLit(0));
7495 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7496 emitpcode(POC_MOVLW, popGetLit(0xff));
7498 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7503 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7510 genrshOne (result,left,shCount,sign);
7514 genrshTwo (result,left,shCount,sign);
7518 genrshFour (result,left,shCount,sign);
7526 freeAsmop(left,NULL,ic,TRUE);
7527 freeAsmop(result,NULL,ic,TRUE);
7530 /*-----------------------------------------------------------------*/
7531 /* genSignedRightShift - right shift of signed number */
7532 /*-----------------------------------------------------------------*/
7533 static void genSignedRightShift (iCode *ic)
7535 operand *right, *left, *result;
7538 symbol *tlbl, *tlbl1 ;
7541 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7543 /* we do it the hard way put the shift count in b
7544 and loop thru preserving the sign */
7545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7547 right = IC_RIGHT(ic);
7549 result = IC_RESULT(ic);
7551 aopOp(right,ic,FALSE);
7552 aopOp(left,ic,FALSE);
7553 aopOp(result,ic,FALSE);
7556 if ( AOP_TYPE(right) == AOP_LIT) {
7557 genRightShiftLiteral (left,right,result,ic,1);
7560 /* shift count is unknown then we have to form
7561 a loop get the loop count in B : Note: we take
7562 only the lower order byte since shifting
7563 more that 32 bits make no sense anyway, ( the
7564 largest size of an object can be only 32 bits ) */
7566 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7567 //pic14_emitcode("inc","b");
7568 //freeAsmop (right,NULL,ic,TRUE);
7569 //aopOp(left,ic,FALSE);
7570 //aopOp(result,ic,FALSE);
7572 /* now move the left to the result if they are not the
7574 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7575 AOP_SIZE(result) > 1) {
7577 size = AOP_SIZE(result);
7581 l = aopGet(AOP(left),offset,FALSE,TRUE);
7582 if (*l == '@' && IS_AOP_PREG(result)) {
7584 pic14_emitcode("mov","a,%s",l);
7585 aopPut(AOP(result),"a",offset);
7587 aopPut(AOP(result),l,offset);
7589 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7590 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7596 /* mov the highest order bit to OVR */
7597 tlbl = newiTempLabel(NULL);
7598 tlbl1= newiTempLabel(NULL);
7600 size = AOP_SIZE(result);
7603 pctemp = popGetTempReg(); /* grab a temporary working register. */
7605 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7607 /* offset should be 0, 1 or 3 */
7608 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7610 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7612 emitpcode(POC_MOVWF, pctemp);
7615 emitpLabel(tlbl->key);
7617 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7618 emitpcode(POC_RRF, popGet(AOP(result),offset));
7621 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7624 emitpcode(POC_DECFSZ, pctemp);
7625 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7626 emitpLabel(tlbl1->key);
7628 popReleaseTempReg(pctemp);
7630 size = AOP_SIZE(result);
7632 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7633 pic14_emitcode("rlc","a");
7634 pic14_emitcode("mov","ov,c");
7635 /* if it is only one byte then */
7637 l = aopGet(AOP(left),0,FALSE,FALSE);
7639 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7640 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7641 pic14_emitcode("mov","c,ov");
7642 pic14_emitcode("rrc","a");
7643 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7644 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7645 aopPut(AOP(result),"a",0);
7649 reAdjustPreg(AOP(result));
7650 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7651 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7652 pic14_emitcode("mov","c,ov");
7654 l = aopGet(AOP(result),offset,FALSE,FALSE);
7656 pic14_emitcode("rrc","a");
7657 aopPut(AOP(result),"a",offset--);
7659 reAdjustPreg(AOP(result));
7660 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7661 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7666 freeAsmop(left,NULL,ic,TRUE);
7667 freeAsmop(result,NULL,ic,TRUE);
7668 freeAsmop(right,NULL,ic,TRUE);
7671 /*-----------------------------------------------------------------*/
7672 /* genRightShift - generate code for right shifting */
7673 /*-----------------------------------------------------------------*/
7674 static void genRightShift (iCode *ic)
7676 operand *right, *left, *result;
7680 symbol *tlbl, *tlbl1 ;
7682 /* if signed then we do it the hard way preserve the
7683 sign bit moving it inwards */
7684 retype = getSpec(operandType(IC_RESULT(ic)));
7685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7687 if (!SPEC_USIGN(retype)) {
7688 genSignedRightShift (ic);
7692 /* signed & unsigned types are treated the same : i.e. the
7693 signed is NOT propagated inwards : quoting from the
7694 ANSI - standard : "for E1 >> E2, is equivalent to division
7695 by 2**E2 if unsigned or if it has a non-negative value,
7696 otherwise the result is implementation defined ", MY definition
7697 is that the sign does not get propagated */
7699 right = IC_RIGHT(ic);
7701 result = IC_RESULT(ic);
7703 aopOp(right,ic,FALSE);
7705 /* if the shift count is known then do it
7706 as efficiently as possible */
7707 if (AOP_TYPE(right) == AOP_LIT) {
7708 genRightShiftLiteral (left,right,result,ic, 0);
7712 /* shift count is unknown then we have to form
7713 a loop get the loop count in B : Note: we take
7714 only the lower order byte since shifting
7715 more that 32 bits make no sense anyway, ( the
7716 largest size of an object can be only 32 bits ) */
7718 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7719 pic14_emitcode("inc","b");
7720 aopOp(left,ic,FALSE);
7721 aopOp(result,ic,FALSE);
7723 /* now move the left to the result if they are not the
7725 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7726 AOP_SIZE(result) > 1) {
7728 size = AOP_SIZE(result);
7731 l = aopGet(AOP(left),offset,FALSE,TRUE);
7732 if (*l == '@' && IS_AOP_PREG(result)) {
7734 pic14_emitcode("mov","a,%s",l);
7735 aopPut(AOP(result),"a",offset);
7737 aopPut(AOP(result),l,offset);
7742 tlbl = newiTempLabel(NULL);
7743 tlbl1= newiTempLabel(NULL);
7744 size = AOP_SIZE(result);
7747 /* if it is only one byte then */
7750 tlbl = newiTempLabel(NULL);
7751 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7752 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7753 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7756 emitpcode(POC_COMFW, popGet(AOP(right),0));
7757 emitpcode(POC_RLF, popGet(AOP(result),0));
7758 emitpLabel(tlbl->key);
7759 emitpcode(POC_RRF, popGet(AOP(result),0));
7760 emitpcode(POC_ADDLW, popGetLit(1));
7762 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7767 reAdjustPreg(AOP(result));
7768 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7769 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7772 l = aopGet(AOP(result),offset,FALSE,FALSE);
7774 pic14_emitcode("rrc","a");
7775 aopPut(AOP(result),"a",offset--);
7777 reAdjustPreg(AOP(result));
7779 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7780 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7783 freeAsmop(left,NULL,ic,TRUE);
7784 freeAsmop (right,NULL,ic,TRUE);
7785 freeAsmop(result,NULL,ic,TRUE);
7788 /*-----------------------------------------------------------------*/
7789 /* genUnpackBits - generates code for unpacking bits */
7790 /*-----------------------------------------------------------------*/
7791 static void genUnpackBits (operand *result, char *rname, int ptype)
7798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7799 etype = getSpec(operandType(result));
7801 /* read the first byte */
7806 pic14_emitcode("mov","a,@%s",rname);
7810 pic14_emitcode("movx","a,@%s",rname);
7814 pic14_emitcode("movx","a,@dptr");
7818 pic14_emitcode("clr","a");
7819 pic14_emitcode("movc","a","@a+dptr");
7823 pic14_emitcode("lcall","__gptrget");
7827 /* if we have bitdisplacement then it fits */
7828 /* into this byte completely or if length is */
7829 /* less than a byte */
7830 if ((shCnt = SPEC_BSTR(etype)) ||
7831 (SPEC_BLEN(etype) <= 8)) {
7833 /* shift right acc */
7836 pic14_emitcode("anl","a,#0x%02x",
7837 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7838 aopPut(AOP(result),"a",offset);
7842 /* bit field did not fit in a byte */
7843 rlen = SPEC_BLEN(etype) - 8;
7844 aopPut(AOP(result),"a",offset++);
7851 pic14_emitcode("inc","%s",rname);
7852 pic14_emitcode("mov","a,@%s",rname);
7856 pic14_emitcode("inc","%s",rname);
7857 pic14_emitcode("movx","a,@%s",rname);
7861 pic14_emitcode("inc","dptr");
7862 pic14_emitcode("movx","a,@dptr");
7866 pic14_emitcode("clr","a");
7867 pic14_emitcode("inc","dptr");
7868 pic14_emitcode("movc","a","@a+dptr");
7872 pic14_emitcode("inc","dptr");
7873 pic14_emitcode("lcall","__gptrget");
7878 /* if we are done */
7882 aopPut(AOP(result),"a",offset++);
7887 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7888 aopPut(AOP(result),"a",offset);
7895 /*-----------------------------------------------------------------*/
7896 /* genDataPointerGet - generates code when ptr offset is known */
7897 /*-----------------------------------------------------------------*/
7898 static void genDataPointerGet (operand *left,
7902 int size , offset = 0;
7905 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7908 /* optimization - most of the time, left and result are the same
7909 * address, but different types. for the pic code, we could omit
7913 aopOp(result,ic,TRUE);
7915 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7917 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7919 size = AOP_SIZE(result);
7922 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7926 freeAsmop(left,NULL,ic,TRUE);
7927 freeAsmop(result,NULL,ic,TRUE);
7930 /*-----------------------------------------------------------------*/
7931 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7932 /*-----------------------------------------------------------------*/
7933 static void genNearPointerGet (operand *left,
7938 //regs *preg = NULL ;
7940 sym_link *rtype, *retype;
7941 sym_link *ltype = operandType(left);
7944 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7946 rtype = operandType(result);
7947 retype= getSpec(rtype);
7949 aopOp(left,ic,FALSE);
7951 /* if left is rematerialisable and
7952 result is not bit variable type and
7953 the left is pointer to data space i.e
7954 lower 128 bytes of space */
7955 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7956 !IS_BITVAR(retype) &&
7957 DCL_TYPE(ltype) == POINTER) {
7958 //genDataPointerGet (left,result,ic);
7962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7964 /* if the value is already in a pointer register
7965 then don't need anything more */
7966 if (!AOP_INPREG(AOP(left))) {
7967 /* otherwise get a free pointer register */
7968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7971 preg = getFreePtr(ic,&aop,FALSE);
7972 pic14_emitcode("mov","%s,%s",
7974 aopGet(AOP(left),0,FALSE,TRUE));
7975 rname = preg->name ;
7979 rname = aopGet(AOP(left),0,FALSE,FALSE);
7981 aopOp (result,ic,FALSE);
7983 /* if bitfield then unpack the bits */
7984 if (IS_BITVAR(retype))
7985 genUnpackBits (result,rname,POINTER);
7987 /* we have can just get the values */
7988 int size = AOP_SIZE(result);
7991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7993 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7994 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7996 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7997 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7999 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8003 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8005 pic14_emitcode("mov","a,@%s",rname);
8006 aopPut(AOP(result),"a",offset);
8008 sprintf(buffer,"@%s",rname);
8009 aopPut(AOP(result),buffer,offset);
8013 pic14_emitcode("inc","%s",rname);
8018 /* now some housekeeping stuff */
8020 /* we had to allocate for this iCode */
8021 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8022 freeAsmop(NULL,aop,ic,TRUE);
8024 /* we did not allocate which means left
8025 already in a pointer register, then
8026 if size > 0 && this could be used again
8027 we have to point it back to where it
8029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8030 if (AOP_SIZE(result) > 1 &&
8031 !OP_SYMBOL(left)->remat &&
8032 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8034 int size = AOP_SIZE(result) - 1;
8036 pic14_emitcode("dec","%s",rname);
8041 freeAsmop(left,NULL,ic,TRUE);
8042 freeAsmop(result,NULL,ic,TRUE);
8046 /*-----------------------------------------------------------------*/
8047 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8048 /*-----------------------------------------------------------------*/
8049 static void genPagedPointerGet (operand *left,
8056 sym_link *rtype, *retype;
8058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8060 rtype = operandType(result);
8061 retype= getSpec(rtype);
8063 aopOp(left,ic,FALSE);
8065 /* if the value is already in a pointer register
8066 then don't need anything more */
8067 if (!AOP_INPREG(AOP(left))) {
8068 /* otherwise get a free pointer register */
8070 preg = getFreePtr(ic,&aop,FALSE);
8071 pic14_emitcode("mov","%s,%s",
8073 aopGet(AOP(left),0,FALSE,TRUE));
8074 rname = preg->name ;
8076 rname = aopGet(AOP(left),0,FALSE,FALSE);
8078 freeAsmop(left,NULL,ic,TRUE);
8079 aopOp (result,ic,FALSE);
8081 /* if bitfield then unpack the bits */
8082 if (IS_BITVAR(retype))
8083 genUnpackBits (result,rname,PPOINTER);
8085 /* we have can just get the values */
8086 int size = AOP_SIZE(result);
8091 pic14_emitcode("movx","a,@%s",rname);
8092 aopPut(AOP(result),"a",offset);
8097 pic14_emitcode("inc","%s",rname);
8101 /* now some housekeeping stuff */
8103 /* we had to allocate for this iCode */
8104 freeAsmop(NULL,aop,ic,TRUE);
8106 /* we did not allocate which means left
8107 already in a pointer register, then
8108 if size > 0 && this could be used again
8109 we have to point it back to where it
8111 if (AOP_SIZE(result) > 1 &&
8112 !OP_SYMBOL(left)->remat &&
8113 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8115 int size = AOP_SIZE(result) - 1;
8117 pic14_emitcode("dec","%s",rname);
8122 freeAsmop(result,NULL,ic,TRUE);
8127 /*-----------------------------------------------------------------*/
8128 /* genFarPointerGet - gget value from far space */
8129 /*-----------------------------------------------------------------*/
8130 static void genFarPointerGet (operand *left,
8131 operand *result, iCode *ic)
8134 sym_link *retype = getSpec(operandType(result));
8136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8138 aopOp(left,ic,FALSE);
8140 /* if the operand is already in dptr
8141 then we do nothing else we move the value to dptr */
8142 if (AOP_TYPE(left) != AOP_STR) {
8143 /* if this is remateriazable */
8144 if (AOP_TYPE(left) == AOP_IMMD)
8145 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8146 else { /* we need to get it byte by byte */
8147 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8148 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8149 if (options.model == MODEL_FLAT24)
8151 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8155 /* so dptr know contains the address */
8156 freeAsmop(left,NULL,ic,TRUE);
8157 aopOp(result,ic,FALSE);
8159 /* if bit then unpack */
8160 if (IS_BITVAR(retype))
8161 genUnpackBits(result,"dptr",FPOINTER);
8163 size = AOP_SIZE(result);
8167 pic14_emitcode("movx","a,@dptr");
8168 aopPut(AOP(result),"a",offset++);
8170 pic14_emitcode("inc","dptr");
8174 freeAsmop(result,NULL,ic,TRUE);
8177 /*-----------------------------------------------------------------*/
8178 /* genCodePointerGet - get value from code space */
8179 /*-----------------------------------------------------------------*/
8180 static void genCodePointerGet (operand *left,
8181 operand *result, iCode *ic)
8184 sym_link *retype = getSpec(operandType(result));
8186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8188 aopOp(left,ic,FALSE);
8190 /* if the operand is already in dptr
8191 then we do nothing else we move the value to dptr */
8192 if (AOP_TYPE(left) != AOP_STR) {
8193 /* if this is remateriazable */
8194 if (AOP_TYPE(left) == AOP_IMMD)
8195 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8196 else { /* we need to get it byte by byte */
8197 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8198 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8199 if (options.model == MODEL_FLAT24)
8201 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8205 /* so dptr know contains the address */
8206 freeAsmop(left,NULL,ic,TRUE);
8207 aopOp(result,ic,FALSE);
8209 /* if bit then unpack */
8210 if (IS_BITVAR(retype))
8211 genUnpackBits(result,"dptr",CPOINTER);
8213 size = AOP_SIZE(result);
8217 pic14_emitcode("clr","a");
8218 pic14_emitcode("movc","a,@a+dptr");
8219 aopPut(AOP(result),"a",offset++);
8221 pic14_emitcode("inc","dptr");
8225 freeAsmop(result,NULL,ic,TRUE);
8228 /*-----------------------------------------------------------------*/
8229 /* genGenPointerGet - gget value from generic pointer space */
8230 /*-----------------------------------------------------------------*/
8231 static void genGenPointerGet (operand *left,
8232 operand *result, iCode *ic)
8235 sym_link *retype = getSpec(operandType(result));
8237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8238 aopOp(left,ic,FALSE);
8239 aopOp(result,ic,FALSE);
8242 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8244 /* if the operand is already in dptr
8245 then we do nothing else we move the value to dptr */
8246 // if (AOP_TYPE(left) != AOP_STR) {
8247 /* if this is remateriazable */
8248 if (AOP_TYPE(left) == AOP_IMMD) {
8249 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8250 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8252 else { /* we need to get it byte by byte */
8254 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8255 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8257 size = AOP_SIZE(result);
8261 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8262 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8264 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8269 /* so dptr know contains the address */
8271 /* if bit then unpack */
8272 //if (IS_BITVAR(retype))
8273 // genUnpackBits(result,"dptr",GPOINTER);
8276 freeAsmop(left,NULL,ic,TRUE);
8277 freeAsmop(result,NULL,ic,TRUE);
8281 /*-----------------------------------------------------------------*/
8282 /* genConstPointerGet - get value from const generic pointer space */
8283 /*-----------------------------------------------------------------*/
8284 static void genConstPointerGet (operand *left,
8285 operand *result, iCode *ic)
8287 //sym_link *retype = getSpec(operandType(result));
8288 symbol *albl = newiTempLabel(NULL);
8289 symbol *blbl = newiTempLabel(NULL);
8292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8293 aopOp(left,ic,FALSE);
8294 aopOp(result,ic,FALSE);
8297 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8299 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8301 emitpcode(POC_CALL,popGetLabel(albl->key));
8302 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8303 emitpLabel(albl->key);
8305 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8307 emitpcode(poc,popGet(AOP(left),1));
8308 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8309 emitpcode(poc,popGet(AOP(left),0));
8310 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8312 emitpLabel(blbl->key);
8314 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8317 freeAsmop(left,NULL,ic,TRUE);
8318 freeAsmop(result,NULL,ic,TRUE);
8321 /*-----------------------------------------------------------------*/
8322 /* genPointerGet - generate code for pointer get */
8323 /*-----------------------------------------------------------------*/
8324 static void genPointerGet (iCode *ic)
8326 operand *left, *result ;
8327 sym_link *type, *etype;
8330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8333 result = IC_RESULT(ic) ;
8335 /* depending on the type of pointer we need to
8336 move it to the correct pointer register */
8337 type = operandType(left);
8338 etype = getSpec(type);
8340 if (IS_PTR_CONST(type))
8341 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8343 /* if left is of type of pointer then it is simple */
8344 if (IS_PTR(type) && !IS_FUNC(type->next))
8345 p_type = DCL_TYPE(type);
8347 /* we have to go by the storage class */
8348 p_type = PTR_TYPE(SPEC_OCLS(etype));
8350 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8352 if (SPEC_OCLS(etype)->codesp ) {
8353 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8354 //p_type = CPOINTER ;
8357 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8358 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8359 /*p_type = FPOINTER ;*/
8361 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8362 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8363 /* p_type = PPOINTER; */
8365 if (SPEC_OCLS(etype) == idata )
8366 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8367 /* p_type = IPOINTER; */
8369 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8370 /* p_type = POINTER ; */
8373 /* now that we have the pointer type we assign
8374 the pointer values */
8379 genNearPointerGet (left,result,ic);
8383 genPagedPointerGet(left,result,ic);
8387 genFarPointerGet (left,result,ic);
8391 genConstPointerGet (left,result,ic);
8392 //pic14_emitcodePointerGet (left,result,ic);
8396 if (IS_PTR_CONST(type))
8397 genConstPointerGet (left,result,ic);
8399 genGenPointerGet (left,result,ic);
8405 /*-----------------------------------------------------------------*/
8406 /* genPackBits - generates code for packed bit storage */
8407 /*-----------------------------------------------------------------*/
8408 static void genPackBits (sym_link *etype ,
8410 char *rname, int p_type)
8418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8419 blen = SPEC_BLEN(etype);
8420 bstr = SPEC_BSTR(etype);
8422 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8425 /* if the bit lenth is less than or */
8426 /* it exactly fits a byte then */
8427 if (SPEC_BLEN(etype) <= 8 ) {
8428 shCount = SPEC_BSTR(etype) ;
8430 /* shift left acc */
8433 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8438 pic14_emitcode ("mov","b,a");
8439 pic14_emitcode("mov","a,@%s",rname);
8443 pic14_emitcode ("mov","b,a");
8444 pic14_emitcode("movx","a,@dptr");
8448 pic14_emitcode ("push","b");
8449 pic14_emitcode ("push","acc");
8450 pic14_emitcode ("lcall","__gptrget");
8451 pic14_emitcode ("pop","b");
8455 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8456 ((unsigned char)(0xFF << (blen+bstr)) |
8457 (unsigned char)(0xFF >> (8-bstr)) ) );
8458 pic14_emitcode ("orl","a,b");
8459 if (p_type == GPOINTER)
8460 pic14_emitcode("pop","b");
8466 pic14_emitcode("mov","@%s,a",rname);
8470 pic14_emitcode("movx","@dptr,a");
8474 DEBUGpic14_emitcode(";lcall","__gptrput");
8479 if ( SPEC_BLEN(etype) <= 8 )
8482 pic14_emitcode("inc","%s",rname);
8483 rLen = SPEC_BLEN(etype) ;
8485 /* now generate for lengths greater than one byte */
8488 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8498 pic14_emitcode("mov","@%s,a",rname);
8500 pic14_emitcode("mov","@%s,%s",rname,l);
8505 pic14_emitcode("movx","@dptr,a");
8510 DEBUGpic14_emitcode(";lcall","__gptrput");
8513 pic14_emitcode ("inc","%s",rname);
8518 /* last last was not complete */
8520 /* save the byte & read byte */
8523 pic14_emitcode ("mov","b,a");
8524 pic14_emitcode("mov","a,@%s",rname);
8528 pic14_emitcode ("mov","b,a");
8529 pic14_emitcode("movx","a,@dptr");
8533 pic14_emitcode ("push","b");
8534 pic14_emitcode ("push","acc");
8535 pic14_emitcode ("lcall","__gptrget");
8536 pic14_emitcode ("pop","b");
8540 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8541 pic14_emitcode ("orl","a,b");
8544 if (p_type == GPOINTER)
8545 pic14_emitcode("pop","b");
8550 pic14_emitcode("mov","@%s,a",rname);
8554 pic14_emitcode("movx","@dptr,a");
8558 DEBUGpic14_emitcode(";lcall","__gptrput");
8562 /*-----------------------------------------------------------------*/
8563 /* genDataPointerSet - remat pointer to data space */
8564 /*-----------------------------------------------------------------*/
8565 static void genDataPointerSet(operand *right,
8569 int size, offset = 0 ;
8570 char *l, buffer[256];
8572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8573 aopOp(right,ic,FALSE);
8575 l = aopGet(AOP(result),0,FALSE,TRUE);
8576 size = AOP_SIZE(right);
8578 if ( AOP_TYPE(result) == AOP_PCODE) {
8579 fprintf(stderr,"genDataPointerSet %s, %d\n",
8580 AOP(result)->aopu.pcop->name,
8581 PCOI(AOP(result)->aopu.pcop)->offset);
8585 // tsd, was l+1 - the underline `_' prefix was being stripped
8588 sprintf(buffer,"(%s + %d)",l,offset);
8589 fprintf(stderr,"oops %s\n",buffer);
8591 sprintf(buffer,"%s",l);
8593 if (AOP_TYPE(right) == AOP_LIT) {
8594 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8595 lit = lit >> (8*offset);
8597 pic14_emitcode("movlw","%d",lit);
8598 pic14_emitcode("movwf","%s",buffer);
8600 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8601 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8602 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8605 pic14_emitcode("clrf","%s",buffer);
8606 //emitpcode(POC_CLRF, popRegFromString(buffer));
8607 emitpcode(POC_CLRF, popGet(AOP(result),0));
8610 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8611 pic14_emitcode("movwf","%s",buffer);
8613 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8614 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8615 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8622 freeAsmop(right,NULL,ic,TRUE);
8623 freeAsmop(result,NULL,ic,TRUE);
8626 /*-----------------------------------------------------------------*/
8627 /* genNearPointerSet - pic14_emitcode for near pointer put */
8628 /*-----------------------------------------------------------------*/
8629 static void genNearPointerSet (operand *right,
8636 sym_link *ptype = operandType(result);
8639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8640 retype= getSpec(operandType(right));
8642 aopOp(result,ic,FALSE);
8645 /* if the result is rematerializable &
8646 in data space & not a bit variable */
8647 //if (AOP_TYPE(result) == AOP_IMMD &&
8648 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8649 DCL_TYPE(ptype) == POINTER &&
8650 !IS_BITVAR(retype)) {
8651 genDataPointerSet (right,result,ic);
8652 freeAsmop(result,NULL,ic,TRUE);
8656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8657 aopOp(right,ic,FALSE);
8658 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8660 /* if the value is already in a pointer register
8661 then don't need anything more */
8662 if (!AOP_INPREG(AOP(result))) {
8663 /* otherwise get a free pointer register */
8664 //aop = newAsmop(0);
8665 //preg = getFreePtr(ic,&aop,FALSE);
8666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8667 //pic14_emitcode("mov","%s,%s",
8669 // aopGet(AOP(result),0,FALSE,TRUE));
8670 //rname = preg->name ;
8671 //pic14_emitcode("movwf","fsr");
8672 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8673 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8674 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8675 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8679 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8682 /* if bitfield then unpack the bits */
8683 if (IS_BITVAR(retype)) {
8684 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8685 "The programmer is obviously confused");
8686 //genPackBits (retype,right,rname,POINTER);
8690 /* we have can just get the values */
8691 int size = AOP_SIZE(right);
8694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8696 l = aopGet(AOP(right),offset,FALSE,TRUE);
8699 //pic14_emitcode("mov","@%s,a",rname);
8700 pic14_emitcode("movf","indf,w ;1");
8703 if (AOP_TYPE(right) == AOP_LIT) {
8704 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8706 pic14_emitcode("movlw","%s",l);
8707 pic14_emitcode("movwf","indf ;2");
8709 pic14_emitcode("clrf","indf");
8711 pic14_emitcode("movf","%s,w",l);
8712 pic14_emitcode("movwf","indf ;2");
8714 //pic14_emitcode("mov","@%s,%s",rname,l);
8717 pic14_emitcode("incf","fsr,f ;3");
8718 //pic14_emitcode("inc","%s",rname);
8723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8724 /* now some housekeeping stuff */
8726 /* we had to allocate for this iCode */
8727 freeAsmop(NULL,aop,ic,TRUE);
8729 /* we did not allocate which means left
8730 already in a pointer register, then
8731 if size > 0 && this could be used again
8732 we have to point it back to where it
8734 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8735 if (AOP_SIZE(right) > 1 &&
8736 !OP_SYMBOL(result)->remat &&
8737 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8739 int size = AOP_SIZE(right) - 1;
8741 pic14_emitcode("decf","fsr,f");
8742 //pic14_emitcode("dec","%s",rname);
8746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8749 freeAsmop(right,NULL,ic,TRUE);
8750 freeAsmop(result,NULL,ic,TRUE);
8753 /*-----------------------------------------------------------------*/
8754 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8755 /*-----------------------------------------------------------------*/
8756 static void genPagedPointerSet (operand *right,
8765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 retype= getSpec(operandType(right));
8769 aopOp(result,ic,FALSE);
8771 /* if the value is already in a pointer register
8772 then don't need anything more */
8773 if (!AOP_INPREG(AOP(result))) {
8774 /* otherwise get a free pointer register */
8776 preg = getFreePtr(ic,&aop,FALSE);
8777 pic14_emitcode("mov","%s,%s",
8779 aopGet(AOP(result),0,FALSE,TRUE));
8780 rname = preg->name ;
8782 rname = aopGet(AOP(result),0,FALSE,FALSE);
8784 freeAsmop(result,NULL,ic,TRUE);
8785 aopOp (right,ic,FALSE);
8787 /* if bitfield then unpack the bits */
8788 if (IS_BITVAR(retype))
8789 genPackBits (retype,right,rname,PPOINTER);
8791 /* we have can just get the values */
8792 int size = AOP_SIZE(right);
8796 l = aopGet(AOP(right),offset,FALSE,TRUE);
8799 pic14_emitcode("movx","@%s,a",rname);
8802 pic14_emitcode("inc","%s",rname);
8808 /* now some housekeeping stuff */
8810 /* we had to allocate for this iCode */
8811 freeAsmop(NULL,aop,ic,TRUE);
8813 /* we did not allocate which means left
8814 already in a pointer register, then
8815 if size > 0 && this could be used again
8816 we have to point it back to where it
8818 if (AOP_SIZE(right) > 1 &&
8819 !OP_SYMBOL(result)->remat &&
8820 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8822 int size = AOP_SIZE(right) - 1;
8824 pic14_emitcode("dec","%s",rname);
8829 freeAsmop(right,NULL,ic,TRUE);
8834 /*-----------------------------------------------------------------*/
8835 /* genFarPointerSet - set value from far space */
8836 /*-----------------------------------------------------------------*/
8837 static void genFarPointerSet (operand *right,
8838 operand *result, iCode *ic)
8841 sym_link *retype = getSpec(operandType(right));
8843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8844 aopOp(result,ic,FALSE);
8846 /* if the operand is already in dptr
8847 then we do nothing else we move the value to dptr */
8848 if (AOP_TYPE(result) != AOP_STR) {
8849 /* if this is remateriazable */
8850 if (AOP_TYPE(result) == AOP_IMMD)
8851 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8852 else { /* we need to get it byte by byte */
8853 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8854 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8855 if (options.model == MODEL_FLAT24)
8857 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8861 /* so dptr know contains the address */
8862 freeAsmop(result,NULL,ic,TRUE);
8863 aopOp(right,ic,FALSE);
8865 /* if bit then unpack */
8866 if (IS_BITVAR(retype))
8867 genPackBits(retype,right,"dptr",FPOINTER);
8869 size = AOP_SIZE(right);
8873 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8875 pic14_emitcode("movx","@dptr,a");
8877 pic14_emitcode("inc","dptr");
8881 freeAsmop(right,NULL,ic,TRUE);
8884 /*-----------------------------------------------------------------*/
8885 /* genGenPointerSet - set value from generic pointer space */
8886 /*-----------------------------------------------------------------*/
8887 static void genGenPointerSet (operand *right,
8888 operand *result, iCode *ic)
8891 sym_link *retype = getSpec(operandType(right));
8893 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8895 aopOp(result,ic,FALSE);
8896 aopOp(right,ic,FALSE);
8897 size = AOP_SIZE(right);
8899 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8901 /* if the operand is already in dptr
8902 then we do nothing else we move the value to dptr */
8903 if (AOP_TYPE(result) != AOP_STR) {
8904 /* if this is remateriazable */
8905 if (AOP_TYPE(result) == AOP_IMMD) {
8906 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8907 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8909 else { /* we need to get it byte by byte */
8910 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8911 size = AOP_SIZE(right);
8914 /* hack hack! see if this the FSR. If so don't load W */
8915 if(AOP_TYPE(right) != AOP_ACC) {
8917 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8918 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8921 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8923 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8924 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8928 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8929 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8932 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8939 if(aopIdx(AOP(result),0) != 4) {
8941 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8945 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8950 /* so dptr know contains the address */
8953 /* if bit then unpack */
8954 if (IS_BITVAR(retype))
8955 genPackBits(retype,right,"dptr",GPOINTER);
8957 size = AOP_SIZE(right);
8960 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8964 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8965 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8967 if (AOP_TYPE(right) == AOP_LIT)
8968 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8970 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8972 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8979 freeAsmop(right,NULL,ic,TRUE);
8980 freeAsmop(result,NULL,ic,TRUE);
8983 /*-----------------------------------------------------------------*/
8984 /* genPointerSet - stores the value into a pointer location */
8985 /*-----------------------------------------------------------------*/
8986 static void genPointerSet (iCode *ic)
8988 operand *right, *result ;
8989 sym_link *type, *etype;
8992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8994 right = IC_RIGHT(ic);
8995 result = IC_RESULT(ic) ;
8997 /* depending on the type of pointer we need to
8998 move it to the correct pointer register */
8999 type = operandType(result);
9000 etype = getSpec(type);
9001 /* if left is of type of pointer then it is simple */
9002 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9003 p_type = DCL_TYPE(type);
9006 /* we have to go by the storage class */
9007 p_type = PTR_TYPE(SPEC_OCLS(etype));
9009 /* if (SPEC_OCLS(etype)->codesp ) { */
9010 /* p_type = CPOINTER ; */
9013 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9014 /* p_type = FPOINTER ; */
9016 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9017 /* p_type = PPOINTER ; */
9019 /* if (SPEC_OCLS(etype) == idata ) */
9020 /* p_type = IPOINTER ; */
9022 /* p_type = POINTER ; */
9025 /* now that we have the pointer type we assign
9026 the pointer values */
9031 genNearPointerSet (right,result,ic);
9035 genPagedPointerSet (right,result,ic);
9039 genFarPointerSet (right,result,ic);
9043 genGenPointerSet (right,result,ic);
9047 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9048 "genPointerSet: illegal pointer type");
9052 /*-----------------------------------------------------------------*/
9053 /* genIfx - generate code for Ifx statement */
9054 /*-----------------------------------------------------------------*/
9055 static void genIfx (iCode *ic, iCode *popIc)
9057 operand *cond = IC_COND(ic);
9060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9062 aopOp(cond,ic,FALSE);
9064 /* get the value into acc */
9065 if (AOP_TYPE(cond) != AOP_CRY)
9066 pic14_toBoolean(cond);
9069 /* the result is now in the accumulator */
9070 freeAsmop(cond,NULL,ic,TRUE);
9072 /* if there was something to be popped then do it */
9076 /* if the condition is a bit variable */
9077 if (isbit && IS_ITEMP(cond) &&
9079 genIfxJump(ic,SPIL_LOC(cond)->rname);
9080 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9083 if (isbit && !IS_ITEMP(cond))
9084 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9092 /*-----------------------------------------------------------------*/
9093 /* genAddrOf - generates code for address of */
9094 /*-----------------------------------------------------------------*/
9095 static void genAddrOf (iCode *ic)
9097 operand *right, *result, *left;
9100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9103 //aopOp(IC_RESULT(ic),ic,FALSE);
9105 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9106 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9107 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9109 DEBUGpic14_AopType(__LINE__,left,right,result);
9111 size = AOP_SIZE(IC_RESULT(ic));
9115 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9116 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9120 freeAsmop(left,NULL,ic,FALSE);
9121 freeAsmop(result,NULL,ic,TRUE);
9126 /*-----------------------------------------------------------------*/
9127 /* genFarFarAssign - assignment when both are in far space */
9128 /*-----------------------------------------------------------------*/
9129 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9131 int size = AOP_SIZE(right);
9134 /* first push the right side on to the stack */
9136 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9138 pic14_emitcode ("push","acc");
9141 freeAsmop(right,NULL,ic,FALSE);
9142 /* now assign DPTR to result */
9143 aopOp(result,ic,FALSE);
9144 size = AOP_SIZE(result);
9146 pic14_emitcode ("pop","acc");
9147 aopPut(AOP(result),"a",--offset);
9149 freeAsmop(result,NULL,ic,FALSE);
9154 /*-----------------------------------------------------------------*/
9155 /* genAssign - generate code for assignment */
9156 /*-----------------------------------------------------------------*/
9157 static void genAssign (iCode *ic)
9159 operand *result, *right;
9160 int size, offset,know_W;
9161 unsigned long lit = 0L;
9163 result = IC_RESULT(ic);
9164 right = IC_RIGHT(ic) ;
9166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9168 /* if they are the same */
9169 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9172 aopOp(right,ic,FALSE);
9173 aopOp(result,ic,TRUE);
9175 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9177 /* if they are the same registers */
9178 if (pic14_sameRegs(AOP(right),AOP(result)))
9181 /* if the result is a bit */
9182 if (AOP_TYPE(result) == AOP_CRY) {
9184 /* if the right size is a literal then
9185 we know what the value is */
9186 if (AOP_TYPE(right) == AOP_LIT) {
9188 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9189 popGet(AOP(result),0));
9191 if (((int) operandLitValue(right)))
9192 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9193 AOP(result)->aopu.aop_dir,
9194 AOP(result)->aopu.aop_dir);
9196 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9197 AOP(result)->aopu.aop_dir,
9198 AOP(result)->aopu.aop_dir);
9202 /* the right is also a bit variable */
9203 if (AOP_TYPE(right) == AOP_CRY) {
9204 emitpcode(POC_BCF, popGet(AOP(result),0));
9205 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9206 emitpcode(POC_BSF, popGet(AOP(result),0));
9208 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9209 AOP(result)->aopu.aop_dir,
9210 AOP(result)->aopu.aop_dir);
9211 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9212 AOP(right)->aopu.aop_dir,
9213 AOP(right)->aopu.aop_dir);
9214 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9215 AOP(result)->aopu.aop_dir,
9216 AOP(result)->aopu.aop_dir);
9221 emitpcode(POC_BCF, popGet(AOP(result),0));
9222 pic14_toBoolean(right);
9224 emitpcode(POC_BSF, popGet(AOP(result),0));
9225 //aopPut(AOP(result),"a",0);
9229 /* bit variables done */
9231 size = AOP_SIZE(result);
9233 if(AOP_TYPE(right) == AOP_LIT)
9234 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9236 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9238 if(aopIdx(AOP(result),0) == 4) {
9239 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9240 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9241 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9244 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9250 if(AOP_TYPE(right) == AOP_LIT) {
9252 if(know_W != (lit&0xff))
9253 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9255 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9257 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9261 } else if (AOP_TYPE(right) == AOP_CRY) {
9262 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9264 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9265 emitpcode(POC_INCF, popGet(AOP(result),0));
9268 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9269 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9270 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9278 freeAsmop (right,NULL,ic,FALSE);
9279 freeAsmop (result,NULL,ic,TRUE);
9282 /*-----------------------------------------------------------------*/
9283 /* genJumpTab - genrates code for jump table */
9284 /*-----------------------------------------------------------------*/
9285 static void genJumpTab (iCode *ic)
9290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9292 aopOp(IC_JTCOND(ic),ic,FALSE);
9293 /* get the condition into accumulator */
9294 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9296 /* multiply by three */
9297 pic14_emitcode("add","a,acc");
9298 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9300 jtab = newiTempLabel(NULL);
9301 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9302 pic14_emitcode("jmp","@a+dptr");
9303 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9305 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9306 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9308 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9309 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9310 emitpLabel(jtab->key);
9312 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9314 /* now generate the jump labels */
9315 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9316 jtab = setNextItem(IC_JTLABELS(ic))) {
9317 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9318 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9324 /*-----------------------------------------------------------------*/
9325 /* genMixedOperation - gen code for operators between mixed types */
9326 /*-----------------------------------------------------------------*/
9328 TSD - Written for the PIC port - but this unfortunately is buggy.
9329 This routine is good in that it is able to efficiently promote
9330 types to different (larger) sizes. Unfortunately, the temporary
9331 variables that are optimized out by this routine are sometimes
9332 used in other places. So until I know how to really parse the
9333 iCode tree, I'm going to not be using this routine :(.
9335 static int genMixedOperation (iCode *ic)
9338 operand *result = IC_RESULT(ic);
9339 sym_link *ctype = operandType(IC_LEFT(ic));
9340 operand *right = IC_RIGHT(ic);
9346 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9348 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9354 nextright = IC_RIGHT(nextic);
9355 nextleft = IC_LEFT(nextic);
9356 nextresult = IC_RESULT(nextic);
9358 aopOp(right,ic,FALSE);
9359 aopOp(result,ic,FALSE);
9360 aopOp(nextright, nextic, FALSE);
9361 aopOp(nextleft, nextic, FALSE);
9362 aopOp(nextresult, nextic, FALSE);
9364 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9370 pic14_emitcode(";remove right +","");
9372 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9378 pic14_emitcode(";remove left +","");
9382 big = AOP_SIZE(nextleft);
9383 small = AOP_SIZE(nextright);
9385 switch(nextic->op) {
9388 pic14_emitcode(";optimize a +","");
9389 /* if unsigned or not an integral type */
9390 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9391 pic14_emitcode(";add a bit to something","");
9394 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9396 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9397 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9398 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9400 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9408 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9409 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9410 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9413 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9415 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9416 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9417 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9418 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9419 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9422 pic14_emitcode("rlf","known_zero,w");
9429 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9430 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9431 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9433 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9443 freeAsmop(right,NULL,ic,TRUE);
9444 freeAsmop(result,NULL,ic,TRUE);
9445 freeAsmop(nextright,NULL,ic,TRUE);
9446 freeAsmop(nextleft,NULL,ic,TRUE);
9448 nextic->generated = 1;
9455 /*-----------------------------------------------------------------*/
9456 /* genCast - gen code for casting */
9457 /*-----------------------------------------------------------------*/
9458 static void genCast (iCode *ic)
9460 operand *result = IC_RESULT(ic);
9461 sym_link *ctype = operandType(IC_LEFT(ic));
9462 sym_link *rtype = operandType(IC_RIGHT(ic));
9463 operand *right = IC_RIGHT(ic);
9466 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9467 /* if they are equivalent then do nothing */
9468 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9471 aopOp(right,ic,FALSE) ;
9472 aopOp(result,ic,FALSE);
9474 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9476 /* if the result is a bit */
9477 if (AOP_TYPE(result) == AOP_CRY) {
9478 /* if the right size is a literal then
9479 we know what the value is */
9480 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9481 if (AOP_TYPE(right) == AOP_LIT) {
9483 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9484 popGet(AOP(result),0));
9486 if (((int) operandLitValue(right)))
9487 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9488 AOP(result)->aopu.aop_dir,
9489 AOP(result)->aopu.aop_dir);
9491 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9492 AOP(result)->aopu.aop_dir,
9493 AOP(result)->aopu.aop_dir);
9498 /* the right is also a bit variable */
9499 if (AOP_TYPE(right) == AOP_CRY) {
9502 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9504 pic14_emitcode("clrc","");
9505 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9506 AOP(right)->aopu.aop_dir,
9507 AOP(right)->aopu.aop_dir);
9508 aopPut(AOP(result),"c",0);
9513 if (AOP_TYPE(right) == AOP_REG) {
9514 emitpcode(POC_BCF, popGet(AOP(result),0));
9515 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9516 emitpcode(POC_BSF, popGet(AOP(result),0));
9518 pic14_toBoolean(right);
9519 aopPut(AOP(result),"a",0);
9523 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9525 size = AOP_SIZE(result);
9527 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9529 emitpcode(POC_CLRF, popGet(AOP(result),0));
9530 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9531 emitpcode(POC_INCF, popGet(AOP(result),0));
9534 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9539 /* if they are the same size : or less */
9540 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9542 /* if they are in the same place */
9543 if (pic14_sameRegs(AOP(right),AOP(result)))
9546 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9547 if (IS_PTR_CONST(rtype))
9548 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9549 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9550 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9552 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9553 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9554 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9555 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9556 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9557 if(AOP_SIZE(result) <2)
9558 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9562 /* if they in different places then copy */
9563 size = AOP_SIZE(result);
9566 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9567 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9569 //aopPut(AOP(result),
9570 // aopGet(AOP(right),offset,FALSE,FALSE),
9580 /* if the result is of type pointer */
9581 if (IS_PTR(ctype)) {
9584 sym_link *type = operandType(right);
9585 sym_link *etype = getSpec(type);
9586 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9588 /* pointer to generic pointer */
9589 if (IS_GENPTR(ctype)) {
9593 p_type = DCL_TYPE(type);
9595 /* we have to go by the storage class */
9596 p_type = PTR_TYPE(SPEC_OCLS(etype));
9598 /* if (SPEC_OCLS(etype)->codesp ) */
9599 /* p_type = CPOINTER ; */
9601 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9602 /* p_type = FPOINTER ; */
9604 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9605 /* p_type = PPOINTER; */
9607 /* if (SPEC_OCLS(etype) == idata ) */
9608 /* p_type = IPOINTER ; */
9610 /* p_type = POINTER ; */
9613 /* the first two bytes are known */
9614 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9615 size = GPTRSIZE - 1;
9618 if(offset < AOP_SIZE(right)) {
9619 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9620 if ((AOP_TYPE(right) == AOP_PCODE) &&
9621 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9622 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9623 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9626 aopGet(AOP(right),offset,FALSE,FALSE),
9630 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9633 /* the last byte depending on type */
9637 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9640 pic14_emitcode(";BUG!? ","%d",__LINE__);
9644 pic14_emitcode(";BUG!? ","%d",__LINE__);
9648 pic14_emitcode(";BUG!? ","%d",__LINE__);
9653 /* this should never happen */
9654 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9655 "got unknown pointer type");
9658 //aopPut(AOP(result),l, GPTRSIZE - 1);
9662 /* just copy the pointers */
9663 size = AOP_SIZE(result);
9667 aopGet(AOP(right),offset,FALSE,FALSE),
9676 /* so we now know that the size of destination is greater
9677 than the size of the source.
9678 Now, if the next iCode is an operator then we might be
9679 able to optimize the operation without performing a cast.
9681 if(genMixedOperation(ic))
9684 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9686 /* we move to result for the size of source */
9687 size = AOP_SIZE(right);
9690 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9691 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9695 /* now depending on the sign of the destination */
9696 size = AOP_SIZE(result) - AOP_SIZE(right);
9697 /* if unsigned or not an integral type */
9698 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9700 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9702 /* we need to extend the sign :{ */
9705 /* Save one instruction of casting char to int */
9706 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9707 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9708 emitpcode(POC_DECF, popGet(AOP(result),offset));
9710 emitpcodeNULLop(POC_CLRW);
9713 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9715 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9717 emitpcode(POC_MOVLW, popGetLit(0xff));
9720 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9725 freeAsmop(right,NULL,ic,TRUE);
9726 freeAsmop(result,NULL,ic,TRUE);
9730 /*-----------------------------------------------------------------*/
9731 /* genDjnz - generate decrement & jump if not zero instrucion */
9732 /*-----------------------------------------------------------------*/
9733 static int genDjnz (iCode *ic, iCode *ifx)
9736 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9741 /* if the if condition has a false label
9742 then we cannot save */
9746 /* if the minus is not of the form
9748 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9749 !IS_OP_LITERAL(IC_RIGHT(ic)))
9752 if (operandLitValue(IC_RIGHT(ic)) != 1)
9755 /* if the size of this greater than one then no
9757 if (getSize(operandType(IC_RESULT(ic))) > 1)
9760 /* otherwise we can save BIG */
9761 lbl = newiTempLabel(NULL);
9762 lbl1= newiTempLabel(NULL);
9764 aopOp(IC_RESULT(ic),ic,FALSE);
9766 if (IS_AOP_PREG(IC_RESULT(ic))) {
9767 pic14_emitcode("dec","%s",
9768 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9769 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9770 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9774 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9775 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9777 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9778 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9781 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9782 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9783 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9784 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9787 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9792 /*-----------------------------------------------------------------*/
9793 /* genReceive - generate code for a receive iCode */
9794 /*-----------------------------------------------------------------*/
9795 static void genReceive (iCode *ic)
9797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9799 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9800 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9801 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9803 int size = getSize(operandType(IC_RESULT(ic)));
9804 int offset = fReturnSizePic - size;
9806 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9807 fReturn[fReturnSizePic - offset - 1] : "acc"));
9810 aopOp(IC_RESULT(ic),ic,FALSE);
9811 size = AOP_SIZE(IC_RESULT(ic));
9814 pic14_emitcode ("pop","acc");
9815 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9820 aopOp(IC_RESULT(ic),ic,FALSE);
9822 assignResultValue(IC_RESULT(ic));
9825 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9828 /*-----------------------------------------------------------------*/
9829 /* genpic14Code - generate code for pic14 based controllers */
9830 /*-----------------------------------------------------------------*/
9832 * At this point, ralloc.c has gone through the iCode and attempted
9833 * to optimize in a way suitable for a PIC. Now we've got to generate
9834 * PIC instructions that correspond to the iCode.
9836 * Once the instructions are generated, we'll pass through both the
9837 * peep hole optimizer and the pCode optimizer.
9838 *-----------------------------------------------------------------*/
9840 void genpic14Code (iCode *lic)
9845 lineHead = lineCurr = NULL;
9847 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9850 /* if debug information required */
9851 if (options.debug && currFunc) {
9853 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9855 if (IS_STATIC(currFunc->etype)) {
9856 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9857 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9859 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9860 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9867 for (ic = lic ; ic ; ic = ic->next ) {
9869 DEBUGpic14_emitcode(";ic","");
9870 if ( cln != ic->lineno ) {
9871 if ( options.debug ) {
9873 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9874 FileBaseName(ic->filename),ic->lineno,
9875 ic->level,ic->block);
9879 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9880 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9881 printCLine(ic->filename, ic->lineno));
9884 newpCodeCSource(ic->lineno,
9886 printCLine(ic->filename, ic->lineno)));
9890 /* if the result is marked as
9891 spilt and rematerializable or code for
9892 this has already been generated then
9894 if (resultRemat(ic) || ic->generated )
9897 /* depending on the operation */
9916 /* IPOP happens only when trying to restore a
9917 spilt live range, if there is an ifx statement
9918 following this pop then the if statement might
9919 be using some of the registers being popped which
9920 would destory the contents of the register so
9921 we need to check for this condition and handle it */
9923 ic->next->op == IFX &&
9924 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9925 genIfx (ic->next,ic);
9943 genEndFunction (ic);
9963 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9980 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9984 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9991 /* note these two are xlated by algebraic equivalence
9992 during parsing SDCC.y */
9993 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9994 "got '>=' or '<=' shouldn't have come here");
9998 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10010 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10014 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10018 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10042 genRightShift (ic);
10045 case GET_VALUE_AT_ADDRESS:
10050 if (POINTER_SET(ic))
10077 addSet(&_G.sendSet,ic);
10086 /* now we are ready to call the
10087 peep hole optimizer */
10088 if (!options.nopeep) {
10089 peepHole (&lineHead);
10091 /* now do the actual printing */
10092 printLine (lineHead,codeOutFile);
10095 DFPRINTF((stderr,"printing pBlock\n\n"));
10096 printpBlock(stdout,pb);