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 *);
67 static int labelOffset=0;
68 static int debug_verbose=1;
69 static int optimized_for_speed = 0;
71 /* max_key keeps track of the largest label number used in
72 a function. This is then used to adjust the label offset
73 for the next function.
76 static int GpsuedoStkPtr=0;
78 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
79 unsigned int pic14aopLiteral (value *val, int offset);
80 const char *AopType(short type);
81 static iCode *ifxForOp ( operand *op, iCode *ic );
83 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
85 /* this is the down and dirty file with all kinds of
86 kludgy & hacky stuff. This is what it is all about
87 CODE GENERATION for a specific MCU . some of the
88 routines may be reusable, will have to see */
90 static char *zero = "#0x00";
91 static char *one = "#0x01";
92 static char *spname = "sp";
94 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
95 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
96 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
97 static char **fReturn = fReturnpic14;
99 static char *accUse[] = {"a","b"};
101 //static short rbank = -1;
113 /* Resolved ifx structure. This structure stores information
114 about an iCode ifx that makes it easier to generate code.
116 typedef struct resolvedIfx {
117 symbol *lbl; /* pointer to a label */
118 int condition; /* true or false ifx */
119 int generated; /* set true when the code associated with the ifx
123 extern int pic14_ptrRegReq ;
124 extern int pic14_nRegs;
125 extern FILE *codeOutFile;
126 static void saverbank (int, iCode *,bool);
128 static lineNode *lineHead = NULL;
129 static lineNode *lineCurr = NULL;
131 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
132 0xE0, 0xC0, 0x80, 0x00};
133 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
134 0x07, 0x03, 0x01, 0x00};
138 /*-----------------------------------------------------------------*/
139 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
140 /* exponent of 2 is returned, otherwise -1 is */
142 /* note that this is similar to the function `powof2' in SDCCsymt */
146 /*-----------------------------------------------------------------*/
147 static int my_powof2 (unsigned long num)
150 if( (num & (num-1)) == 0) {
163 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
174 ((result) ? AOP_SIZE(result) : 0));
178 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
183 ((result) ? AopType(AOP_TYPE(result)) : "-"),
184 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
185 ((left) ? AopType(AOP_TYPE(left)) : "-"),
186 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
187 ((right) ? AopType(AOP_TYPE(right)) : "-"),
188 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
192 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 char lb[INITIAL_INLINEASM];
205 sprintf(lb,"%s\t",inst);
207 sprintf(lb,"%s",inst);
208 vsprintf(lb+(strlen(lb)),fmt,ap);
212 while (isspace(*lbp)) lbp++;
215 lineCurr = (lineCurr ?
216 connectLine(lineCurr,newLineNode(lb)) :
217 (lineHead = newLineNode(lb)));
218 lineCurr->isInline = _G.inLine;
219 lineCurr->isDebug = _G.debugLine;
221 addpCode2pBlock(pb,newpCodeCharP(lb));
227 void emitpLabel(int key)
229 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
236 addpCode2pBlock(pb,newpCode(poc,pcop));
238 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
241 void emitpcodeNULLop(PIC_OPCODE poc)
244 addpCode2pBlock(pb,newpCode(poc,NULL));
248 /*-----------------------------------------------------------------*/
249 /* pic14_emitcode - writes the code into a file : for now it is simple */
250 /*-----------------------------------------------------------------*/
251 void pic14_emitcode (char *inst,char *fmt, ...)
254 char lb[INITIAL_INLINEASM];
261 sprintf(lb,"%s\t",inst);
263 sprintf(lb,"%s",inst);
264 vsprintf(lb+(strlen(lb)),fmt,ap);
268 while (isspace(*lbp)) lbp++;
271 lineCurr = (lineCurr ?
272 connectLine(lineCurr,newLineNode(lb)) :
273 (lineHead = newLineNode(lb)));
274 lineCurr->isInline = _G.inLine;
275 lineCurr->isDebug = _G.debugLine;
278 addpCode2pBlock(pb,newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 /* the logic: if r0 & r1 used in the instruction
293 then we are in trouble otherwise */
295 /* first check if r0 & r1 are used by this
296 instruction, in which case we are in trouble */
297 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
298 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
303 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
304 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
306 /* if no usage of r0 then return it */
307 if (!r0iu && !r0ou) {
308 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
309 (*aopp)->type = AOP_R0;
311 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314 /* if no usage of r1 then return it */
315 if (!r1iu && !r1ou) {
316 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
317 (*aopp)->type = AOP_R1;
319 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322 /* now we know they both have usage */
323 /* if r0 not used in this instruction */
325 /* push it if not already pushed */
327 //pic14_emitcode ("push","%s",
328 // pic14_regWithIdx(R0_IDX)->dname);
332 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
333 (*aopp)->type = AOP_R0;
335 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338 /* if r1 not used then */
341 /* push it if not already pushed */
343 //pic14_emitcode ("push","%s",
344 // pic14_regWithIdx(R1_IDX)->dname);
348 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349 (*aopp)->type = AOP_R1;
350 return pic14_regWithIdx(R1_IDX);
354 /* I said end of world but not quite end of world yet */
355 /* if this is a result then we can push it on the stack*/
357 (*aopp)->type = AOP_STK;
361 /* other wise this is true end of the world */
362 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
363 "getFreePtr should never reach here");
367 /*-----------------------------------------------------------------*/
368 /* newAsmop - creates a new asmOp */
369 /*-----------------------------------------------------------------*/
370 asmop *newAsmop (short type)
374 aop = Safe_calloc(1,sizeof(asmop));
379 static void genSetDPTR(int n)
383 pic14_emitcode(";", "Select standard DPTR");
384 pic14_emitcode("mov", "dps, #0x00");
388 pic14_emitcode(";", "Select alternate DPTR");
389 pic14_emitcode("mov", "dps, #0x01");
393 /*-----------------------------------------------------------------*/
394 /* resolveIfx - converts an iCode ifx into a form more useful for */
395 /* generating code */
396 /*-----------------------------------------------------------------*/
397 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
402 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
404 resIfx->condition = 1; /* assume that the ifx is true */
405 resIfx->generated = 0; /* indicate that the ifx has not been used */
408 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
409 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
410 __FUNCTION__,__LINE__,resIfx->lbl->key);
413 resIfx->lbl = IC_TRUE(ifx);
415 resIfx->lbl = IC_FALSE(ifx);
416 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
424 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
433 return PTR_TYPE(SPEC_OCLS(etype));
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
443 memmap *space= SPEC_OCLS(sym->etype);
445 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446 /* if already has one */
450 /* assign depending on the storage class */
451 /* if it is on the stack or indirectly addressable */
452 /* space we need to assign either r0 or r1 to it */
453 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454 sym->aop = aop = newAsmop(0);
455 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456 aop->size = getSize(sym->type);
458 /* now assign the address of the variable to
459 the pointer register */
460 if (aop->type != AOP_STK) {
464 pic14_emitcode("push","acc");
466 pic14_emitcode("mov","a,_bp");
467 pic14_emitcode("add","a,#0x%02x",
469 ((char)(sym->stack - _G.nRegsSaved )) :
470 ((char)sym->stack)) & 0xff);
471 pic14_emitcode("mov","%s,a",
472 aop->aopu.aop_ptr->name);
475 pic14_emitcode("pop","acc");
477 pic14_emitcode("mov","%s,#%s",
478 aop->aopu.aop_ptr->name,
480 aop->paged = space->paged;
482 aop->aopu.aop_stk = sym->stack;
486 if (sym->onStack && options.stack10bit)
488 /* It's on the 10 bit stack, which is located in
492 //DEBUGpic14_emitcode(";","%d",__LINE__);
495 pic14_emitcode("push","acc");
497 pic14_emitcode("mov","a,_bp");
498 pic14_emitcode("add","a,#0x%02x",
500 ((char)(sym->stack - _G.nRegsSaved )) :
501 ((char)sym->stack)) & 0xff);
504 pic14_emitcode ("mov","dpx1,#0x40");
505 pic14_emitcode ("mov","dph1,#0x00");
506 pic14_emitcode ("mov","dpl1, a");
510 pic14_emitcode("pop","acc");
512 sym->aop = aop = newAsmop(AOP_DPTR2);
513 aop->size = getSize(sym->type);
517 //DEBUGpic14_emitcode(";","%d",__LINE__);
518 /* if in bit space */
519 if (IN_BITSPACE(space)) {
520 sym->aop = aop = newAsmop (AOP_CRY);
521 aop->aopu.aop_dir = sym->rname ;
522 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
526 /* if it is in direct space */
527 if (IN_DIRSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_DIR);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
535 /* special case for a function */
536 if (IS_FUNC(sym->type)) {
537 sym->aop = aop = newAsmop(AOP_IMMD);
538 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
539 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
540 strcpy(aop->aopu.aop_immd,sym->rname);
541 aop->size = FPTRSIZE;
542 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
547 /* only remaining is far space */
548 /* in which case DPTR gets the address */
549 sym->aop = aop = newAsmop(AOP_PCODE);
551 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
552 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
553 PCOI(aop->aopu.pcop)->index = 0;
555 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
556 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
558 allocDirReg (IC_LEFT(ic));
560 aop->size = FPTRSIZE;
562 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
563 sym->aop = aop = newAsmop(AOP_DPTR);
564 pic14_emitcode ("mov","dptr,#%s", sym->rname);
565 aop->size = getSize(sym->type);
567 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
570 /* if it is in code space */
571 if (IN_CODESPACE(space))
577 /*-----------------------------------------------------------------*/
578 /* aopForRemat - rematerialzes an object */
579 /*-----------------------------------------------------------------*/
580 static asmop *aopForRemat (operand *op) // x symbol *sym)
582 symbol *sym = OP_SYMBOL(op);
584 asmop *aop = newAsmop(AOP_PCODE);
588 ic = sym->rematiCode;
590 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
591 if(IS_OP_POINTER(op)) {
592 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
596 val += (int) operandLitValue(IC_RIGHT(ic));
597 } else if (ic->op == '-') {
598 val -= (int) operandLitValue(IC_RIGHT(ic));
602 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
605 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
606 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
607 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
608 PCOI(aop->aopu.pcop)->index = val;
610 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
611 OP_SYMBOL(IC_LEFT(ic))->rname,
612 val, IS_PTR_CONST(operandType(op)));
614 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
616 allocDirReg (IC_LEFT(ic));
621 int aopIdx (asmop *aop, int offset)
626 if(aop->type != AOP_REG)
629 return aop->aopu.aop_reg[offset]->rIdx;
632 /*-----------------------------------------------------------------*/
633 /* regsInCommon - two operands have some registers in common */
634 /*-----------------------------------------------------------------*/
635 static bool regsInCommon (operand *op1, operand *op2)
640 /* if they have registers in common */
641 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
644 sym1 = OP_SYMBOL(op1);
645 sym2 = OP_SYMBOL(op2);
647 if (sym1->nRegs == 0 || sym2->nRegs == 0)
650 for (i = 0 ; i < sym1->nRegs ; i++) {
655 for (j = 0 ; j < sym2->nRegs ;j++ ) {
659 if (sym2->regs[j] == sym1->regs[i])
667 /*-----------------------------------------------------------------*/
668 /* operandsEqu - equivalent */
669 /*-----------------------------------------------------------------*/
670 static bool operandsEqu ( operand *op1, operand *op2)
674 /* if they not symbols */
675 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
678 sym1 = OP_SYMBOL(op1);
679 sym2 = OP_SYMBOL(op2);
681 /* if both are itemps & one is spilt
682 and the other is not then false */
683 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
684 sym1->isspilt != sym2->isspilt )
687 /* if they are the same */
691 if (strcmp(sym1->rname,sym2->rname) == 0)
695 /* if left is a tmp & right is not */
699 (sym1->usl.spillLoc == sym2))
706 (sym2->usl.spillLoc == sym1))
712 /*-----------------------------------------------------------------*/
713 /* pic14_sameRegs - two asmops have the same registers */
714 /*-----------------------------------------------------------------*/
715 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 if (aop1->type != AOP_REG ||
723 aop2->type != AOP_REG )
726 if (aop1->size != aop2->size )
729 for (i = 0 ; i < aop1->size ; i++ )
730 if (aop1->aopu.aop_reg[i] !=
731 aop2->aopu.aop_reg[i] )
737 /*-----------------------------------------------------------------*/
738 /* aopOp - allocates an asmop for an operand : */
739 /*-----------------------------------------------------------------*/
740 void aopOp (operand *op, iCode *ic, bool result)
749 // DEBUGpic14_emitcode(";","%d",__LINE__);
750 /* if this a literal */
751 if (IS_OP_LITERAL(op)) {
752 op->aop = aop = newAsmop(AOP_LIT);
753 aop->aopu.aop_lit = op->operand.valOperand;
754 aop->size = getSize(operandType(op));
759 sym_link *type = operandType(op);
760 if(IS_PTR_CONST(type))
761 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
764 /* if already has a asmop then continue */
768 /* if the underlying symbol has a aop */
769 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
770 DEBUGpic14_emitcode(";","%d",__LINE__);
771 op->aop = OP_SYMBOL(op)->aop;
775 /* if this is a true symbol */
776 if (IS_TRUE_SYMOP(op)) {
777 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
778 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
782 /* this is a temporary : this has
788 e) can be a return use only */
793 /* if the type is a conditional */
794 if (sym->regType == REG_CND) {
795 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
800 /* if it is spilt then two situations
802 b) has a spill location */
803 if (sym->isspilt || sym->nRegs == 0) {
805 DEBUGpic14_emitcode(";","%d",__LINE__);
806 /* rematerialize it NOW */
809 sym->aop = op->aop = aop =
811 aop->size = getSize(sym->type);
812 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
818 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
819 aop->size = getSize(sym->type);
820 for ( i = 0 ; i < 2 ; i++ )
821 aop->aopu.aop_str[i] = accUse[i];
822 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
828 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
829 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
830 //allocDirReg (IC_LEFT(ic));
831 aop->size = getSize(sym->type);
836 aop = op->aop = sym->aop = newAsmop(AOP_STR);
837 aop->size = getSize(sym->type);
838 for ( i = 0 ; i < fReturnSizePic ; i++ )
839 aop->aopu.aop_str[i] = fReturn[i];
841 DEBUGpic14_emitcode(";","%d",__LINE__);
845 /* else spill location */
846 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
847 /* force a new aop if sizes differ */
848 sym->usl.spillLoc->aop = NULL;
850 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
851 __FUNCTION__,__LINE__,
852 sym->usl.spillLoc->rname,
853 sym->rname, sym->usl.spillLoc->offset);
855 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
856 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
857 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
859 sym->usl.spillLoc->offset);
860 aop->size = getSize(sym->type);
866 sym_link *type = operandType(op);
867 if(IS_PTR_CONST(type))
868 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
871 /* must be in a register */
872 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
873 sym->aop = op->aop = aop = newAsmop(AOP_REG);
874 aop->size = sym->nRegs;
875 for ( i = 0 ; i < sym->nRegs ;i++)
876 aop->aopu.aop_reg[i] = sym->regs[i];
879 /*-----------------------------------------------------------------*/
880 /* freeAsmop - free up the asmop given to an operand */
881 /*----------------------------------------------------------------*/
882 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
899 /* depending on the asmop type only three cases need work AOP_RO
900 , AOP_R1 && AOP_STK */
906 pic14_emitcode ("pop","ar0");
910 bitVectUnSetBit(ic->rUsed,R0_IDX);
916 pic14_emitcode ("pop","ar1");
920 bitVectUnSetBit(ic->rUsed,R1_IDX);
926 int stk = aop->aopu.aop_stk + aop->size;
927 bitVectUnSetBit(ic->rUsed,R0_IDX);
928 bitVectUnSetBit(ic->rUsed,R1_IDX);
930 getFreePtr(ic,&aop,FALSE);
932 if (options.stack10bit)
934 /* I'm not sure what to do here yet... */
937 "*** Warning: probably generating bad code for "
938 "10 bit stack mode.\n");
942 pic14_emitcode ("mov","a,_bp");
943 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
944 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
946 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
950 pic14_emitcode("pop","acc");
951 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
953 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
956 freeAsmop(op,NULL,ic,TRUE);
958 pic14_emitcode("pop","ar0");
963 pic14_emitcode("pop","ar1");
971 /* all other cases just dealloc */
975 OP_SYMBOL(op)->aop = NULL;
976 /* if the symbol has a spill */
978 SPIL_LOC(op)->aop = NULL;
983 /*-----------------------------------------------------------------*/
984 /* aopGet - for fetching value of the aop */
985 /*-----------------------------------------------------------------*/
986 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
991 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
992 /* offset is greater than
994 if (offset > (aop->size - 1) &&
995 aop->type != AOP_LIT)
998 /* depending on type */
1003 DEBUGpic14_emitcode(";","%d",__LINE__);
1004 /* if we need to increment it */
1005 while (offset > aop->coff) {
1006 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1010 while (offset < aop->coff) {
1011 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1015 aop->coff = offset ;
1017 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1018 return (dname ? "acc" : "a");
1020 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1021 rs = Safe_calloc(1,strlen(s)+1);
1027 DEBUGpic14_emitcode(";","%d",__LINE__);
1028 if (aop->type == AOP_DPTR2)
1033 while (offset > aop->coff) {
1034 pic14_emitcode ("inc","dptr");
1038 while (offset < aop->coff) {
1039 pic14_emitcode("lcall","__decdptr");
1045 pic14_emitcode("clr","a");
1046 pic14_emitcode("movc","a,@a+dptr");
1049 pic14_emitcode("movx","a,@dptr");
1052 if (aop->type == AOP_DPTR2)
1057 return (dname ? "acc" : "a");
1062 sprintf (s,"%s",aop->aopu.aop_immd);
1065 sprintf(s,"(%s >> %d)",
1070 aop->aopu.aop_immd);
1071 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1072 rs = Safe_calloc(1,strlen(s)+1);
1078 sprintf(s,"(%s + %d)",
1081 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1083 sprintf(s,"%s",aop->aopu.aop_dir);
1084 rs = Safe_calloc(1,strlen(s)+1);
1090 // return aop->aopu.aop_reg[offset]->dname;
1092 return aop->aopu.aop_reg[offset]->name;
1095 //pic14_emitcode(";","%d",__LINE__);
1096 return aop->aopu.aop_dir;
1099 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1100 return "AOP_accumulator_bug";
1103 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1104 rs = Safe_calloc(1,strlen(s)+1);
1109 DEBUGpic14_emitcode(";","%d",__LINE__);
1110 aop->coff = offset ;
1111 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1115 return aop->aopu.aop_str[offset];
1119 pCodeOp *pcop = aop->aopu.pcop;
1120 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1122 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1123 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1124 sprintf(s,"%s", pcop->name);
1126 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1129 rs = Safe_calloc(1,strlen(s)+1);
1135 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1136 "aopget got unsupported aop->type");
1141 /*-----------------------------------------------------------------*/
1142 /* popGetTempReg - create a new temporary pCodeOp */
1143 /*-----------------------------------------------------------------*/
1144 pCodeOp *popGetTempReg(void)
1149 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1150 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1151 PCOR(pcop)->r->wasUsed=1;
1152 PCOR(pcop)->r->isFree=0;
1158 /*-----------------------------------------------------------------*/
1159 /* popGetTempReg - create a new temporary pCodeOp */
1160 /*-----------------------------------------------------------------*/
1161 void popReleaseTempReg(pCodeOp *pcop)
1164 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1165 PCOR(pcop)->r->isFree = 1;
1168 /*-----------------------------------------------------------------*/
1169 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1170 /*-----------------------------------------------------------------*/
1171 pCodeOp *popGetLabel(unsigned int key)
1174 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1179 return newpCodeOpLabel(NULL,key+100+labelOffset);
1182 /*-----------------------------------------------------------------*/
1183 /* popCopyReg - copy a pcode operator */
1184 /*-----------------------------------------------------------------*/
1185 pCodeOp *popCopyReg(pCodeOpReg *pc)
1189 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1190 pcor->pcop.type = pc->pcop.type;
1192 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1193 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1195 pcor->pcop.name = NULL;
1198 pcor->rIdx = pc->rIdx;
1201 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1205 /*-----------------------------------------------------------------*/
1206 /* popGet - asm operator to pcode operator conversion */
1207 /*-----------------------------------------------------------------*/
1208 pCodeOp *popGetLit(unsigned int lit)
1211 return newpCodeOpLit(lit);
1215 /*-----------------------------------------------------------------*/
1216 /* popGetImmd - asm operator to pcode immediate conversion */
1217 /*-----------------------------------------------------------------*/
1218 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1221 return newpCodeOpImmd(name, offset,index, 0);
1225 /*-----------------------------------------------------------------*/
1226 /* popGet - asm operator to pcode operator conversion */
1227 /*-----------------------------------------------------------------*/
1228 pCodeOp *popGetWithString(char *str)
1234 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1238 pcop = newpCodeOp(str,PO_STR);
1243 /*-----------------------------------------------------------------*/
1244 /* popRegFromString - */
1245 /*-----------------------------------------------------------------*/
1246 pCodeOp *popRegFromString(char *str, int size, int offset)
1249 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1250 pcop->type = PO_DIR;
1252 DEBUGpic14_emitcode(";","%d",__LINE__);
1257 pcop->name = Safe_calloc(1,strlen(str)+1);
1258 strcpy(pcop->name,str);
1260 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1262 PCOR(pcop)->r = dirregWithName(pcop->name);
1263 if(PCOR(pcop)->r == NULL) {
1264 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1265 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1266 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1268 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1270 PCOR(pcop)->instance = offset;
1275 pCodeOp *popRegFromIdx(int rIdx)
1279 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1280 __FUNCTION__,__LINE__,rIdx);
1282 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1284 PCOR(pcop)->rIdx = rIdx;
1285 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1286 PCOR(pcop)->r->isFree = 0;
1287 PCOR(pcop)->r->wasUsed = 1;
1289 pcop->type = PCOR(pcop)->r->pc_type;
1294 /*-----------------------------------------------------------------*/
1295 /* popGet - asm operator to pcode operator conversion */
1296 /*-----------------------------------------------------------------*/
1297 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1299 //char *s = buffer ;
1304 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1305 /* offset is greater than
1308 if (offset > (aop->size - 1) &&
1309 aop->type != AOP_LIT)
1310 return NULL; //zero;
1312 /* depending on type */
1313 switch (aop->type) {
1320 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1324 DEBUGpic14_emitcode(";","%d",__LINE__);
1325 return popGetImmd(aop->aopu.aop_immd,offset,0);
1328 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1330 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1331 pcop->type = PO_DIR;
1335 sprintf(s,"(%s + %d)",
1339 sprintf(s,"%s",aop->aopu.aop_dir);
1340 pcop->name = Safe_calloc(1,strlen(s)+1);
1341 strcpy(pcop->name,s);
1343 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1344 strcpy(pcop->name,aop->aopu.aop_dir);
1345 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1346 if(PCOR(pcop)->r == NULL) {
1347 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1348 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1349 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1351 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1353 PCOR(pcop)->instance = offset;
1360 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1362 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1363 PCOR(pcop)->rIdx = rIdx;
1364 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1365 PCOR(pcop)->r->wasUsed=1;
1366 PCOR(pcop)->r->isFree=0;
1368 PCOR(pcop)->instance = offset;
1369 pcop->type = PCOR(pcop)->r->pc_type;
1370 //rs = aop->aopu.aop_reg[offset]->name;
1371 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1376 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1377 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1378 //if(PCOR(pcop)->r == NULL)
1379 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1383 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1386 DEBUGpic14_emitcode(";","%d",__LINE__);
1387 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1389 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1390 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1391 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1392 pcop->type = PCOR(pcop)->r->pc_type;
1393 pcop->name = PCOR(pcop)->r->name;
1399 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1401 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1402 pcop = pCodeOpCopy(aop->aopu.pcop);
1403 PCOI(pcop)->offset = offset;
1407 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1408 "popGet got unsupported aop->type");
1411 /*-----------------------------------------------------------------*/
1412 /* aopPut - puts a string for a aop */
1413 /*-----------------------------------------------------------------*/
1414 void aopPut (asmop *aop, char *s, int offset)
1419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1421 if (aop->size && offset > ( aop->size - 1)) {
1422 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1423 "aopPut got offset > aop->size");
1427 /* will assign value to value */
1428 /* depending on where it is ofcourse */
1429 switch (aop->type) {
1432 sprintf(d,"(%s + %d)",
1433 aop->aopu.aop_dir,offset);
1434 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1437 sprintf(d,"%s",aop->aopu.aop_dir);
1440 DEBUGpic14_emitcode(";","%d",__LINE__);
1442 pic14_emitcode("movf","%s,w",s);
1443 pic14_emitcode("movwf","%s",d);
1446 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1447 if(offset >= aop->size) {
1448 emitpcode(POC_CLRF,popGet(aop,offset));
1451 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1454 emitpcode(POC_MOVWF,popGet(aop,offset));
1461 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1462 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1465 strcmp(s,"r0") == 0 ||
1466 strcmp(s,"r1") == 0 ||
1467 strcmp(s,"r2") == 0 ||
1468 strcmp(s,"r3") == 0 ||
1469 strcmp(s,"r4") == 0 ||
1470 strcmp(s,"r5") == 0 ||
1471 strcmp(s,"r6") == 0 ||
1472 strcmp(s,"r7") == 0 )
1473 pic14_emitcode("mov","%s,%s ; %d",
1474 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1478 if(strcmp(s,"W")==0 )
1479 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1481 pic14_emitcode("movwf","%s",
1482 aop->aopu.aop_reg[offset]->name);
1484 if(strcmp(s,zero)==0) {
1485 emitpcode(POC_CLRF,popGet(aop,offset));
1487 } else if(strcmp(s,"W")==0) {
1488 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1489 pcop->type = PO_GPR_REGISTER;
1491 PCOR(pcop)->rIdx = -1;
1492 PCOR(pcop)->r = NULL;
1494 DEBUGpic14_emitcode(";","%d",__LINE__);
1495 pcop->name = Safe_strdup(s);
1496 emitpcode(POC_MOVFW,pcop);
1497 emitpcode(POC_MOVWF,popGet(aop,offset));
1498 } else if(strcmp(s,one)==0) {
1499 emitpcode(POC_CLRF,popGet(aop,offset));
1500 emitpcode(POC_INCF,popGet(aop,offset));
1502 emitpcode(POC_MOVWF,popGet(aop,offset));
1510 if (aop->type == AOP_DPTR2)
1516 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1517 "aopPut writting to code space");
1521 while (offset > aop->coff) {
1523 pic14_emitcode ("inc","dptr");
1526 while (offset < aop->coff) {
1528 pic14_emitcode("lcall","__decdptr");
1533 /* if not in accumulater */
1536 pic14_emitcode ("movx","@dptr,a");
1538 if (aop->type == AOP_DPTR2)
1546 while (offset > aop->coff) {
1548 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1550 while (offset < aop->coff) {
1552 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1558 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1563 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1565 if (strcmp(s,"r0") == 0 ||
1566 strcmp(s,"r1") == 0 ||
1567 strcmp(s,"r2") == 0 ||
1568 strcmp(s,"r3") == 0 ||
1569 strcmp(s,"r4") == 0 ||
1570 strcmp(s,"r5") == 0 ||
1571 strcmp(s,"r6") == 0 ||
1572 strcmp(s,"r7") == 0 ) {
1574 sprintf(buffer,"a%s",s);
1575 pic14_emitcode("mov","@%s,%s",
1576 aop->aopu.aop_ptr->name,buffer);
1578 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1583 if (strcmp(s,"a") == 0)
1584 pic14_emitcode("push","acc");
1586 pic14_emitcode("push","%s",s);
1591 /* if bit variable */
1592 if (!aop->aopu.aop_dir) {
1593 pic14_emitcode("clr","a");
1594 pic14_emitcode("rlc","a");
1597 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1600 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1603 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1605 lbl = newiTempLabel(NULL);
1607 if (strcmp(s,"a")) {
1610 pic14_emitcode("clr","c");
1611 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1612 pic14_emitcode("cpl","c");
1613 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1614 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1621 if (strcmp(aop->aopu.aop_str[offset],s))
1622 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1627 if (!offset && (strcmp(s,"acc") == 0))
1630 if (strcmp(aop->aopu.aop_str[offset],s))
1631 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1635 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1636 "aopPut got unsupported aop->type");
1642 /*-----------------------------------------------------------------*/
1643 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1644 /*-----------------------------------------------------------------*/
1645 void mov2w (asmop *aop, int offset)
1651 if ( aop->type == AOP_PCODE ||
1652 aop->type == AOP_LIT )
1653 emitpcode(POC_MOVLW,popGet(aop,offset));
1655 emitpcode(POC_MOVFW,popGet(aop,offset));
1659 /*-----------------------------------------------------------------*/
1660 /* reAdjustPreg - points a register back to where it should */
1661 /*-----------------------------------------------------------------*/
1662 static void reAdjustPreg (asmop *aop)
1666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1668 if ((size = aop->size) <= 1)
1671 switch (aop->type) {
1675 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1679 if (aop->type == AOP_DPTR2)
1685 pic14_emitcode("lcall","__decdptr");
1688 if (aop->type == AOP_DPTR2)
1698 /*-----------------------------------------------------------------*/
1699 /* genNotFloat - generates not for float operations */
1700 /*-----------------------------------------------------------------*/
1701 static void genNotFloat (operand *op, operand *res)
1707 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1708 /* we will put 127 in the first byte of
1710 aopPut(AOP(res),"#127",0);
1711 size = AOP_SIZE(op) - 1;
1714 l = aopGet(op->aop,offset++,FALSE,FALSE);
1718 pic14_emitcode("orl","a,%s",
1720 offset++,FALSE,FALSE));
1722 tlbl = newiTempLabel(NULL);
1724 tlbl = newiTempLabel(NULL);
1725 aopPut(res->aop,one,1);
1726 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1727 aopPut(res->aop,zero,1);
1728 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1730 size = res->aop->size - 2;
1732 /* put zeros in the rest */
1734 aopPut(res->aop,zero,offset++);
1738 /*-----------------------------------------------------------------*/
1739 /* opIsGptr: returns non-zero if the passed operand is */
1740 /* a generic pointer type. */
1741 /*-----------------------------------------------------------------*/
1742 static int opIsGptr(operand *op)
1744 sym_link *type = operandType(op);
1746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1747 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1755 /*-----------------------------------------------------------------*/
1756 /* pic14_getDataSize - get the operand data size */
1757 /*-----------------------------------------------------------------*/
1758 int pic14_getDataSize(operand *op)
1760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1763 return AOP_SIZE(op);
1765 // tsd- in the pic port, the genptr size is 1, so this code here
1766 // fails. ( in the 8051 port, the size was 4).
1769 size = AOP_SIZE(op);
1770 if (size == GPTRSIZE)
1772 sym_link *type = operandType(op);
1773 if (IS_GENPTR(type))
1775 /* generic pointer; arithmetic operations
1776 * should ignore the high byte (pointer type).
1779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1786 /*-----------------------------------------------------------------*/
1787 /* pic14_outAcc - output Acc */
1788 /*-----------------------------------------------------------------*/
1789 void pic14_outAcc(operand *result)
1792 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1793 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1796 size = pic14_getDataSize(result);
1798 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1801 /* unsigned or positive */
1803 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1808 /*-----------------------------------------------------------------*/
1809 /* pic14_outBitC - output a bit C */
1810 /*-----------------------------------------------------------------*/
1811 void pic14_outBitC(operand *result)
1814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1815 /* if the result is bit */
1816 if (AOP_TYPE(result) == AOP_CRY)
1817 aopPut(AOP(result),"c",0);
1819 pic14_emitcode("clr","a ; %d", __LINE__);
1820 pic14_emitcode("rlc","a");
1821 pic14_outAcc(result);
1825 /*-----------------------------------------------------------------*/
1826 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1827 /*-----------------------------------------------------------------*/
1828 void pic14_toBoolean(operand *oper)
1830 int size = AOP_SIZE(oper) - 1;
1833 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1835 if ( AOP_TYPE(oper) != AOP_ACC) {
1836 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1839 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1844 /*-----------------------------------------------------------------*/
1845 /* genNot - generate code for ! operation */
1846 /*-----------------------------------------------------------------*/
1847 static void genNot (iCode *ic)
1850 sym_link *optype = operandType(IC_LEFT(ic));
1853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1854 /* assign asmOps to operand & result */
1855 aopOp (IC_LEFT(ic),ic,FALSE);
1856 aopOp (IC_RESULT(ic),ic,TRUE);
1858 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1859 /* if in bit space then a special case */
1860 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1861 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1862 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1863 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1865 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1866 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1867 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1872 /* if type float then do float */
1873 if (IS_FLOAT(optype)) {
1874 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1878 size = AOP_SIZE(IC_RESULT(ic));
1880 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1881 emitpcode(POC_ANDLW,popGetLit(1));
1882 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1885 pic14_toBoolean(IC_LEFT(ic));
1887 tlbl = newiTempLabel(NULL);
1888 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1889 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1890 pic14_outBitC(IC_RESULT(ic));
1893 /* release the aops */
1894 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1895 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1899 /*-----------------------------------------------------------------*/
1900 /* genCpl - generate code for complement */
1901 /*-----------------------------------------------------------------*/
1902 static void genCpl (iCode *ic)
1908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1909 /* assign asmOps to operand & result */
1910 aopOp (IC_LEFT(ic),ic,FALSE);
1911 aopOp (IC_RESULT(ic),ic,TRUE);
1913 /* if both are in bit space then
1915 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1916 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1918 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1919 pic14_emitcode("cpl","c");
1920 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1924 size = AOP_SIZE(IC_RESULT(ic));
1926 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1928 pic14_emitcode("cpl","a");
1929 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1934 /* release the aops */
1935 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1936 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1939 /*-----------------------------------------------------------------*/
1940 /* genUminusFloat - unary minus for floating points */
1941 /*-----------------------------------------------------------------*/
1942 static void genUminusFloat(operand *op,operand *result)
1944 int size ,offset =0 ;
1947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1948 /* for this we just need to flip the
1949 first it then copy the rest in place */
1950 size = AOP_SIZE(op) - 1;
1951 l = aopGet(AOP(op),3,FALSE,FALSE);
1955 pic14_emitcode("cpl","acc.7");
1956 aopPut(AOP(result),"a",3);
1960 aopGet(AOP(op),offset,FALSE,FALSE),
1966 /*-----------------------------------------------------------------*/
1967 /* genUminus - unary minus code generation */
1968 /*-----------------------------------------------------------------*/
1969 static void genUminus (iCode *ic)
1972 sym_link *optype, *rtype;
1975 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1977 aopOp(IC_LEFT(ic),ic,FALSE);
1978 aopOp(IC_RESULT(ic),ic,TRUE);
1980 /* if both in bit space then special
1982 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1983 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1985 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1986 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1987 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1992 optype = operandType(IC_LEFT(ic));
1993 rtype = operandType(IC_RESULT(ic));
1995 /* if float then do float stuff */
1996 if (IS_FLOAT(optype)) {
1997 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2001 /* otherwise subtract from zero by taking the 2's complement */
2002 size = AOP_SIZE(IC_LEFT(ic));
2004 for(i=0; i<size; i++) {
2005 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2006 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2008 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2009 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2013 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2014 for(i=1; i<size; i++) {
2016 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2020 /* release the aops */
2021 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2022 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2025 /*-----------------------------------------------------------------*/
2026 /* saveRegisters - will look for a call and save the registers */
2027 /*-----------------------------------------------------------------*/
2028 static void saveRegisters(iCode *lic)
2035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2037 for (ic = lic ; ic ; ic = ic->next)
2038 if (ic->op == CALL || ic->op == PCALL)
2042 fprintf(stderr,"found parameter push with no function call\n");
2046 /* if the registers have been saved already then
2048 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2051 /* find the registers in use at this time
2052 and push them away to safety */
2053 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2057 if (options.useXstack) {
2058 if (bitVectBitValue(rsave,R0_IDX))
2059 pic14_emitcode("mov","b,r0");
2060 pic14_emitcode("mov","r0,%s",spname);
2061 for (i = 0 ; i < pic14_nRegs ; i++) {
2062 if (bitVectBitValue(rsave,i)) {
2064 pic14_emitcode("mov","a,b");
2066 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2067 pic14_emitcode("movx","@r0,a");
2068 pic14_emitcode("inc","r0");
2071 pic14_emitcode("mov","%s,r0",spname);
2072 if (bitVectBitValue(rsave,R0_IDX))
2073 pic14_emitcode("mov","r0,b");
2075 //for (i = 0 ; i < pic14_nRegs ; i++) {
2076 // if (bitVectBitValue(rsave,i))
2077 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2080 dtype = operandType(IC_LEFT(ic));
2081 if (currFunc && dtype &&
2082 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2083 IFFUNC_ISISR(currFunc->type) &&
2086 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2089 /*-----------------------------------------------------------------*/
2090 /* unsaveRegisters - pop the pushed registers */
2091 /*-----------------------------------------------------------------*/
2092 static void unsaveRegisters (iCode *ic)
2097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2098 /* find the registers in use at this time
2099 and push them away to safety */
2100 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2103 if (options.useXstack) {
2104 pic14_emitcode("mov","r0,%s",spname);
2105 for (i = pic14_nRegs ; i >= 0 ; i--) {
2106 if (bitVectBitValue(rsave,i)) {
2107 pic14_emitcode("dec","r0");
2108 pic14_emitcode("movx","a,@r0");
2110 pic14_emitcode("mov","b,a");
2112 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2116 pic14_emitcode("mov","%s,r0",spname);
2117 if (bitVectBitValue(rsave,R0_IDX))
2118 pic14_emitcode("mov","r0,b");
2120 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2121 // if (bitVectBitValue(rsave,i))
2122 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2128 /*-----------------------------------------------------------------*/
2130 /*-----------------------------------------------------------------*/
2131 static void pushSide(operand * oper, int size)
2135 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2137 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2138 if (AOP_TYPE(oper) != AOP_REG &&
2139 AOP_TYPE(oper) != AOP_DIR &&
2141 pic14_emitcode("mov","a,%s",l);
2142 pic14_emitcode("push","acc");
2144 pic14_emitcode("push","%s",l);
2149 /*-----------------------------------------------------------------*/
2150 /* assignResultValue - */
2151 /*-----------------------------------------------------------------*/
2152 static void assignResultValue(operand * oper)
2154 int size = AOP_SIZE(oper);
2156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2158 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2160 if(!GpsuedoStkPtr) {
2161 /* The last byte in the assignment is in W */
2163 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2168 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2170 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2175 /*-----------------------------------------------------------------*/
2176 /* genIpush - genrate code for pushing this gets a little complex */
2177 /*-----------------------------------------------------------------*/
2178 static void genIpush (iCode *ic)
2181 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2183 int size, offset = 0 ;
2187 /* if this is not a parm push : ie. it is spill push
2188 and spill push is always done on the local stack */
2189 if (!ic->parmPush) {
2191 /* and the item is spilt then do nothing */
2192 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2195 aopOp(IC_LEFT(ic),ic,FALSE);
2196 size = AOP_SIZE(IC_LEFT(ic));
2197 /* push it on the stack */
2199 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2204 pic14_emitcode("push","%s",l);
2209 /* this is a paramter push: in this case we call
2210 the routine to find the call and save those
2211 registers that need to be saved */
2214 /* then do the push */
2215 aopOp(IC_LEFT(ic),ic,FALSE);
2218 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2219 size = AOP_SIZE(IC_LEFT(ic));
2222 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2223 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2224 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2226 pic14_emitcode("mov","a,%s",l);
2227 pic14_emitcode("push","acc");
2229 pic14_emitcode("push","%s",l);
2232 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2236 /*-----------------------------------------------------------------*/
2237 /* genIpop - recover the registers: can happen only for spilling */
2238 /*-----------------------------------------------------------------*/
2239 static void genIpop (iCode *ic)
2241 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2246 /* if the temp was not pushed then */
2247 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2250 aopOp(IC_LEFT(ic),ic,FALSE);
2251 size = AOP_SIZE(IC_LEFT(ic));
2254 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2257 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2261 /*-----------------------------------------------------------------*/
2262 /* unsaverbank - restores the resgister bank from stack */
2263 /*-----------------------------------------------------------------*/
2264 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2266 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2274 if (options.useXstack) {
2276 r = getFreePtr(ic,&aop,FALSE);
2279 pic14_emitcode("mov","%s,_spx",r->name);
2280 pic14_emitcode("movx","a,@%s",r->name);
2281 pic14_emitcode("mov","psw,a");
2282 pic14_emitcode("dec","%s",r->name);
2285 pic14_emitcode ("pop","psw");
2288 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2289 if (options.useXstack) {
2290 pic14_emitcode("movx","a,@%s",r->name);
2291 //pic14_emitcode("mov","(%s+%d),a",
2292 // regspic14[i].base,8*bank+regspic14[i].offset);
2293 pic14_emitcode("dec","%s",r->name);
2296 pic14_emitcode("pop",""); //"(%s+%d)",
2297 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2300 if (options.useXstack) {
2302 pic14_emitcode("mov","_spx,%s",r->name);
2303 freeAsmop(NULL,aop,ic,TRUE);
2309 /*-----------------------------------------------------------------*/
2310 /* saverbank - saves an entire register bank on the stack */
2311 /*-----------------------------------------------------------------*/
2312 static void saverbank (int bank, iCode *ic, bool pushPsw)
2314 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2321 if (options.useXstack) {
2324 r = getFreePtr(ic,&aop,FALSE);
2325 pic14_emitcode("mov","%s,_spx",r->name);
2329 for (i = 0 ; i < pic14_nRegs ;i++) {
2330 if (options.useXstack) {
2331 pic14_emitcode("inc","%s",r->name);
2332 //pic14_emitcode("mov","a,(%s+%d)",
2333 // regspic14[i].base,8*bank+regspic14[i].offset);
2334 pic14_emitcode("movx","@%s,a",r->name);
2336 pic14_emitcode("push","");// "(%s+%d)",
2337 //regspic14[i].base,8*bank+regspic14[i].offset);
2341 if (options.useXstack) {
2342 pic14_emitcode("mov","a,psw");
2343 pic14_emitcode("movx","@%s,a",r->name);
2344 pic14_emitcode("inc","%s",r->name);
2345 pic14_emitcode("mov","_spx,%s",r->name);
2346 freeAsmop (NULL,aop,ic,TRUE);
2349 pic14_emitcode("push","psw");
2351 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2357 /*-----------------------------------------------------------------*/
2358 /* genCall - generates a call statement */
2359 /*-----------------------------------------------------------------*/
2360 static void genCall (iCode *ic)
2364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2366 /* if caller saves & we have not saved then */
2370 /* if we are calling a function that is not using
2371 the same register bank then we need to save the
2372 destination registers on the stack */
2373 dtype = operandType(IC_LEFT(ic));
2374 if (currFunc && dtype &&
2375 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2376 IFFUNC_ISISR(currFunc->type) &&
2379 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2381 /* if send set is not empty the assign */
2384 /* For the Pic port, there is no data stack.
2385 * So parameters passed to functions are stored
2386 * in registers. (The pCode optimizer will get
2387 * rid of most of these :).
2389 int psuedoStkPtr=-1;
2390 int firstTimeThruLoop = 1;
2392 _G.sendSet = reverseSet(_G.sendSet);
2394 /* First figure how many parameters are getting passed */
2395 for (sic = setFirstItem(_G.sendSet) ; sic ;
2396 sic = setNextItem(_G.sendSet)) {
2398 aopOp(IC_LEFT(sic),sic,FALSE);
2399 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2400 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2403 for (sic = setFirstItem(_G.sendSet) ; sic ;
2404 sic = setNextItem(_G.sendSet)) {
2405 int size, offset = 0;
2407 aopOp(IC_LEFT(sic),sic,FALSE);
2408 size = AOP_SIZE(IC_LEFT(sic));
2411 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2412 AopType(AOP_TYPE(IC_LEFT(sic))));
2414 if(!firstTimeThruLoop) {
2415 /* If this is not the first time we've been through the loop
2416 * then we need to save the parameter in a temporary
2417 * register. The last byte of the last parameter is
2419 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2422 firstTimeThruLoop=0;
2424 //if (strcmp(l,fReturn[offset])) {
2425 mov2w (AOP(IC_LEFT(sic)), offset);
2427 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2428 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2429 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2431 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2436 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2441 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2442 OP_SYMBOL(IC_LEFT(ic))->rname :
2443 OP_SYMBOL(IC_LEFT(ic))->name));
2446 /* if we need assign a result value */
2447 if ((IS_ITEMP(IC_RESULT(ic)) &&
2448 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2449 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2450 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2453 aopOp(IC_RESULT(ic),ic,FALSE);
2456 assignResultValue(IC_RESULT(ic));
2458 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2459 AopType(AOP_TYPE(IC_RESULT(ic))));
2461 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2464 /* adjust the stack for parameters if
2466 if (ic->parmBytes) {
2468 if (ic->parmBytes > 3) {
2469 pic14_emitcode("mov","a,%s",spname);
2470 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2471 pic14_emitcode("mov","%s,a",spname);
2473 for ( i = 0 ; i < ic->parmBytes ;i++)
2474 pic14_emitcode("dec","%s",spname);
2478 /* if register bank was saved then pop them */
2480 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2482 /* if we hade saved some registers then unsave them */
2483 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2484 unsaveRegisters (ic);
2489 /*-----------------------------------------------------------------*/
2490 /* genPcall - generates a call by pointer statement */
2491 /*-----------------------------------------------------------------*/
2492 static void genPcall (iCode *ic)
2495 symbol *rlbl = newiTempLabel(NULL);
2498 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2499 /* if caller saves & we have not saved then */
2503 /* if we are calling a function that is not using
2504 the same register bank then we need to save the
2505 destination registers on the stack */
2506 dtype = operandType(IC_LEFT(ic));
2507 if (currFunc && dtype &&
2508 IFFUNC_ISISR(currFunc->type) &&
2509 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2510 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2513 /* push the return address on to the stack */
2514 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2515 pic14_emitcode("push","acc");
2516 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2517 pic14_emitcode("push","acc");
2519 if (options.model == MODEL_FLAT24)
2521 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2522 pic14_emitcode("push","acc");
2525 /* now push the calling address */
2526 aopOp(IC_LEFT(ic),ic,FALSE);
2528 pushSide(IC_LEFT(ic), FPTRSIZE);
2530 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2532 /* if send set is not empty the assign */
2536 for (sic = setFirstItem(_G.sendSet) ; sic ;
2537 sic = setNextItem(_G.sendSet)) {
2538 int size, offset = 0;
2539 aopOp(IC_LEFT(sic),sic,FALSE);
2540 size = AOP_SIZE(IC_LEFT(sic));
2542 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2544 if (strcmp(l,fReturn[offset]))
2545 pic14_emitcode("mov","%s,%s",
2550 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2555 pic14_emitcode("ret","");
2556 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2559 /* if we need assign a result value */
2560 if ((IS_ITEMP(IC_RESULT(ic)) &&
2561 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2562 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2563 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2566 aopOp(IC_RESULT(ic),ic,FALSE);
2569 assignResultValue(IC_RESULT(ic));
2571 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2574 /* adjust the stack for parameters if
2576 if (ic->parmBytes) {
2578 if (ic->parmBytes > 3) {
2579 pic14_emitcode("mov","a,%s",spname);
2580 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2581 pic14_emitcode("mov","%s,a",spname);
2583 for ( i = 0 ; i < ic->parmBytes ;i++)
2584 pic14_emitcode("dec","%s",spname);
2588 /* if register bank was saved then unsave them */
2589 if (currFunc && dtype &&
2590 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2591 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2593 /* if we hade saved some registers then
2596 unsaveRegisters (ic);
2600 /*-----------------------------------------------------------------*/
2601 /* resultRemat - result is rematerializable */
2602 /*-----------------------------------------------------------------*/
2603 static int resultRemat (iCode *ic)
2605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2606 if (SKIP_IC(ic) || ic->op == IFX)
2609 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2610 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2611 if (sym->remat && !POINTER_SET(ic))
2618 #if defined(__BORLANDC__) || defined(_MSC_VER)
2619 #define STRCASECMP stricmp
2621 #define STRCASECMP strcasecmp
2625 /*-----------------------------------------------------------------*/
2626 /* inExcludeList - return 1 if the string is in exclude Reg list */
2627 /*-----------------------------------------------------------------*/
2628 static bool inExcludeList(char *s)
2630 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2634 if (options.excludeRegs[i] &&
2635 STRCASECMP(options.excludeRegs[i],"none") == 0)
2638 for ( i = 0 ; options.excludeRegs[i]; i++) {
2639 if (options.excludeRegs[i] &&
2640 STRCASECMP(s,options.excludeRegs[i]) == 0)
2647 /*-----------------------------------------------------------------*/
2648 /* genFunction - generated code for function entry */
2649 /*-----------------------------------------------------------------*/
2650 static void genFunction (iCode *ic)
2655 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2657 labelOffset += (max_key+4);
2661 /* create the function header */
2662 pic14_emitcode(";","-----------------------------------------");
2663 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2664 pic14_emitcode(";","-----------------------------------------");
2666 pic14_emitcode("","%s:",sym->rname);
2667 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2669 ftype = operandType(IC_LEFT(ic));
2671 /* if critical function then turn interrupts off */
2672 if (IFFUNC_ISCRITICAL(ftype))
2673 pic14_emitcode("clr","ea");
2675 /* here we need to generate the equates for the
2676 register bank if required */
2678 if (FUNC_REGBANK(ftype) != rbank) {
2681 rbank = FUNC_REGBANK(ftype);
2682 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2683 if (strcmp(regspic14[i].base,"0") == 0)
2684 pic14_emitcode("","%s = 0x%02x",
2686 8*rbank+regspic14[i].offset);
2688 pic14_emitcode ("","%s = %s + 0x%02x",
2691 8*rbank+regspic14[i].offset);
2696 /* if this is an interrupt service routine then
2697 save acc, b, dpl, dph */
2698 if (IFFUNC_ISISR(sym->type)) {
2699 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2700 emitpcodeNULLop(POC_NOP);
2701 emitpcodeNULLop(POC_NOP);
2702 emitpcodeNULLop(POC_NOP);
2703 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2704 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2705 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2706 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2708 pBlockConvert2ISR(pb);
2710 if (!inExcludeList("acc"))
2711 pic14_emitcode ("push","acc");
2712 if (!inExcludeList("b"))
2713 pic14_emitcode ("push","b");
2714 if (!inExcludeList("dpl"))
2715 pic14_emitcode ("push","dpl");
2716 if (!inExcludeList("dph"))
2717 pic14_emitcode ("push","dph");
2718 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2720 pic14_emitcode ("push", "dpx");
2721 /* Make sure we're using standard DPTR */
2722 pic14_emitcode ("push", "dps");
2723 pic14_emitcode ("mov", "dps, #0x00");
2724 if (options.stack10bit)
2726 /* This ISR could conceivably use DPTR2. Better save it. */
2727 pic14_emitcode ("push", "dpl1");
2728 pic14_emitcode ("push", "dph1");
2729 pic14_emitcode ("push", "dpx1");
2732 /* if this isr has no bank i.e. is going to
2733 run with bank 0 , then we need to save more
2735 if (!FUNC_REGBANK(sym->type)) {
2737 /* if this function does not call any other
2738 function then we can be economical and
2739 save only those registers that are used */
2740 if (! IFFUNC_HASFCALL(sym->type)) {
2743 /* if any registers used */
2744 if (sym->regsUsed) {
2745 /* save the registers used */
2746 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2747 if (bitVectBitValue(sym->regsUsed,i) ||
2748 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2749 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2754 /* this function has a function call cannot
2755 determines register usage so we will have the
2757 saverbank(0,ic,FALSE);
2762 /* if callee-save to be used for this function
2763 then save the registers being used in this function */
2764 if (IFFUNC_CALLEESAVES(sym->type)) {
2767 /* if any registers used */
2768 if (sym->regsUsed) {
2769 /* save the registers used */
2770 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2771 if (bitVectBitValue(sym->regsUsed,i) ||
2772 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2773 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2781 /* set the register bank to the desired value */
2782 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2783 pic14_emitcode("push","psw");
2784 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2787 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2789 if (options.useXstack) {
2790 pic14_emitcode("mov","r0,%s",spname);
2791 pic14_emitcode("mov","a,_bp");
2792 pic14_emitcode("movx","@r0,a");
2793 pic14_emitcode("inc","%s",spname);
2797 /* set up the stack */
2798 pic14_emitcode ("push","_bp"); /* save the callers stack */
2800 pic14_emitcode ("mov","_bp,%s",spname);
2803 /* adjust the stack for the function */
2808 werror(W_STACK_OVERFLOW,sym->name);
2810 if (i > 3 && sym->recvSize < 4) {
2812 pic14_emitcode ("mov","a,sp");
2813 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2814 pic14_emitcode ("mov","sp,a");
2819 pic14_emitcode("inc","sp");
2824 pic14_emitcode ("mov","a,_spx");
2825 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2826 pic14_emitcode ("mov","_spx,a");
2831 /*-----------------------------------------------------------------*/
2832 /* genEndFunction - generates epilogue for functions */
2833 /*-----------------------------------------------------------------*/
2834 static void genEndFunction (iCode *ic)
2836 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2840 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2842 pic14_emitcode ("mov","%s,_bp",spname);
2845 /* if use external stack but some variables were
2846 added to the local stack then decrement the
2848 if (options.useXstack && sym->stack) {
2849 pic14_emitcode("mov","a,sp");
2850 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2851 pic14_emitcode("mov","sp,a");
2855 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2856 if (options.useXstack) {
2857 pic14_emitcode("mov","r0,%s",spname);
2858 pic14_emitcode("movx","a,@r0");
2859 pic14_emitcode("mov","_bp,a");
2860 pic14_emitcode("dec","%s",spname);
2864 pic14_emitcode ("pop","_bp");
2868 /* restore the register bank */
2869 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2870 pic14_emitcode ("pop","psw");
2872 if (IFFUNC_ISISR(sym->type)) {
2874 /* now we need to restore the registers */
2875 /* if this isr has no bank i.e. is going to
2876 run with bank 0 , then we need to save more
2878 if (!FUNC_REGBANK(sym->type)) {
2880 /* if this function does not call any other
2881 function then we can be economical and
2882 save only those registers that are used */
2883 if (! IFFUNC_HASFCALL(sym->type)) {
2886 /* if any registers used */
2887 if (sym->regsUsed) {
2888 /* save the registers used */
2889 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2890 if (bitVectBitValue(sym->regsUsed,i) ||
2891 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2892 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2897 /* this function has a function call cannot
2898 determines register usage so we will have the
2900 unsaverbank(0,ic,FALSE);
2904 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2906 if (options.stack10bit)
2908 pic14_emitcode ("pop", "dpx1");
2909 pic14_emitcode ("pop", "dph1");
2910 pic14_emitcode ("pop", "dpl1");
2912 pic14_emitcode ("pop", "dps");
2913 pic14_emitcode ("pop", "dpx");
2915 if (!inExcludeList("dph"))
2916 pic14_emitcode ("pop","dph");
2917 if (!inExcludeList("dpl"))
2918 pic14_emitcode ("pop","dpl");
2919 if (!inExcludeList("b"))
2920 pic14_emitcode ("pop","b");
2921 if (!inExcludeList("acc"))
2922 pic14_emitcode ("pop","acc");
2924 if (IFFUNC_ISCRITICAL(sym->type))
2925 pic14_emitcode("setb","ea");
2928 /* if debug then send end of function */
2929 /* if (options.debug && currFunc) { */
2932 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2933 FileBaseName(ic->filename),currFunc->lastLine,
2934 ic->level,ic->block);
2935 if (IS_STATIC(currFunc->etype))
2936 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2938 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2942 pic14_emitcode ("reti","");
2944 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2945 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2946 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2947 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2948 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2949 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2951 emitpcodeNULLop(POC_RETFIE);
2955 if (IFFUNC_ISCRITICAL(sym->type))
2956 pic14_emitcode("setb","ea");
2958 if (IFFUNC_CALLEESAVES(sym->type)) {
2961 /* if any registers used */
2962 if (sym->regsUsed) {
2963 /* save the registers used */
2964 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2965 if (bitVectBitValue(sym->regsUsed,i) ||
2966 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2967 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2973 /* if debug then send end of function */
2976 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2977 FileBaseName(ic->filename),currFunc->lastLine,
2978 ic->level,ic->block);
2979 if (IS_STATIC(currFunc->etype))
2980 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2982 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2986 pic14_emitcode ("return","");
2987 emitpcodeNULLop(POC_RETURN);
2989 /* Mark the end of a function */
2990 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2995 /*-----------------------------------------------------------------*/
2996 /* genRet - generate code for return statement */
2997 /*-----------------------------------------------------------------*/
2998 static void genRet (iCode *ic)
3000 int size,offset = 0 , pushed = 0;
3002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3003 /* if we have no return value then
3004 just generate the "ret" */
3008 /* we have something to return then
3009 move the return value into place */
3010 aopOp(IC_LEFT(ic),ic,FALSE);
3011 size = AOP_SIZE(IC_LEFT(ic));
3015 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3017 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3019 pic14_emitcode("push","%s",l);
3022 l = aopGet(AOP(IC_LEFT(ic)),offset,
3024 if (strcmp(fReturn[offset],l)) {
3025 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3026 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3027 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3029 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3032 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3033 pic14_emitcode("movwf","%s",fReturn[offset]);
3043 if (strcmp(fReturn[pushed],"a"))
3044 pic14_emitcode("pop",fReturn[pushed]);
3046 pic14_emitcode("pop","acc");
3049 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3052 /* generate a jump to the return label
3053 if the next is not the return statement */
3054 if (!(ic->next && ic->next->op == LABEL &&
3055 IC_LABEL(ic->next) == returnLabel)) {
3057 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3058 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3063 /*-----------------------------------------------------------------*/
3064 /* genLabel - generates a label */
3065 /*-----------------------------------------------------------------*/
3066 static void genLabel (iCode *ic)
3068 /* special case never generate */
3069 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3070 if (IC_LABEL(ic) == entryLabel)
3073 emitpLabel(IC_LABEL(ic)->key);
3074 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3077 /*-----------------------------------------------------------------*/
3078 /* genGoto - generates a goto */
3079 /*-----------------------------------------------------------------*/
3081 static void genGoto (iCode *ic)
3083 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3084 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3088 /*-----------------------------------------------------------------*/
3089 /* genMultbits :- multiplication of bits */
3090 /*-----------------------------------------------------------------*/
3091 static void genMultbits (operand *left,
3095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3097 if(!pic14_sameRegs(AOP(result),AOP(right)))
3098 emitpcode(POC_BSF, popGet(AOP(result),0));
3100 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3101 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3102 emitpcode(POC_BCF, popGet(AOP(result),0));
3107 /*-----------------------------------------------------------------*/
3108 /* genMultOneByte : 8 bit multiplication & division */
3109 /*-----------------------------------------------------------------*/
3110 static void genMultOneByte (operand *left,
3114 sym_link *opetype = operandType(result);
3119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3120 DEBUGpic14_AopType(__LINE__,left,right,result);
3121 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3123 /* (if two literals, the value is computed before) */
3124 /* if one literal, literal on the right */
3125 if (AOP_TYPE(left) == AOP_LIT){
3131 size = AOP_SIZE(result);
3134 if (AOP_TYPE(right) == AOP_LIT){
3135 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3136 aopGet(AOP(right),0,FALSE,FALSE),
3137 aopGet(AOP(left),0,FALSE,FALSE),
3138 aopGet(AOP(result),0,FALSE,FALSE));
3139 pic14_emitcode("call","genMultLit");
3141 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3142 aopGet(AOP(right),0,FALSE,FALSE),
3143 aopGet(AOP(left),0,FALSE,FALSE),
3144 aopGet(AOP(result),0,FALSE,FALSE));
3145 pic14_emitcode("call","genMult8X8_8");
3148 genMult8X8_8 (left, right,result);
3151 /* signed or unsigned */
3152 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3153 //l = aopGet(AOP(left),0,FALSE,FALSE);
3155 //pic14_emitcode("mul","ab");
3156 /* if result size = 1, mul signed = mul unsigned */
3157 //aopPut(AOP(result),"a",0);
3159 } else { // (size > 1)
3161 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3162 aopGet(AOP(right),0,FALSE,FALSE),
3163 aopGet(AOP(left),0,FALSE,FALSE),
3164 aopGet(AOP(result),0,FALSE,FALSE));
3166 if (SPEC_USIGN(opetype)){
3167 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3168 genUMult8X8_16 (left, right, result, NULL);
3171 /* for filling the MSBs */
3172 emitpcode(POC_CLRF, popGet(AOP(result),2));
3173 emitpcode(POC_CLRF, popGet(AOP(result),3));
3177 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3179 pic14_emitcode("mov","a,b");
3181 /* adjust the MSB if left or right neg */
3183 /* if one literal */
3184 if (AOP_TYPE(right) == AOP_LIT){
3185 pic14_emitcode("multiply ","right is a lit");
3186 /* AND literal negative */
3187 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3188 /* adjust MSB (c==0 after mul) */
3189 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3193 genSMult8X8_16 (left, right, result, NULL);
3197 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3199 pic14_emitcode("rlc","a");
3200 pic14_emitcode("subb","a,acc");
3208 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3209 //aopPut(AOP(result),"a",offset++);
3213 /*-----------------------------------------------------------------*/
3214 /* genMult - generates code for multiplication */
3215 /*-----------------------------------------------------------------*/
3216 static void genMult (iCode *ic)
3218 operand *left = IC_LEFT(ic);
3219 operand *right = IC_RIGHT(ic);
3220 operand *result= IC_RESULT(ic);
3222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3223 /* assign the amsops */
3224 aopOp (left,ic,FALSE);
3225 aopOp (right,ic,FALSE);
3226 aopOp (result,ic,TRUE);
3228 DEBUGpic14_AopType(__LINE__,left,right,result);
3230 /* special cases first */
3232 if (AOP_TYPE(left) == AOP_CRY &&
3233 AOP_TYPE(right)== AOP_CRY) {
3234 genMultbits(left,right,result);
3238 /* if both are of size == 1 */
3239 if (AOP_SIZE(left) == 1 &&
3240 AOP_SIZE(right) == 1 ) {
3241 genMultOneByte(left,right,result);
3245 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3247 /* should have been converted to function call */
3251 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3252 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3253 freeAsmop(result,NULL,ic,TRUE);
3256 /*-----------------------------------------------------------------*/
3257 /* genDivbits :- division of bits */
3258 /*-----------------------------------------------------------------*/
3259 static void genDivbits (operand *left,
3266 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3267 /* the result must be bit */
3268 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3269 l = aopGet(AOP(left),0,FALSE,FALSE);
3273 pic14_emitcode("div","ab");
3274 pic14_emitcode("rrc","a");
3275 aopPut(AOP(result),"c",0);
3278 /*-----------------------------------------------------------------*/
3279 /* genDivOneByte : 8 bit division */
3280 /*-----------------------------------------------------------------*/
3281 static void genDivOneByte (operand *left,
3285 sym_link *opetype = operandType(result);
3290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3291 size = AOP_SIZE(result) - 1;
3293 /* signed or unsigned */
3294 if (SPEC_USIGN(opetype)) {
3295 /* unsigned is easy */
3296 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3297 l = aopGet(AOP(left),0,FALSE,FALSE);
3299 pic14_emitcode("div","ab");
3300 aopPut(AOP(result),"a",0);
3302 aopPut(AOP(result),zero,offset++);
3306 /* signed is a little bit more difficult */
3308 /* save the signs of the operands */
3309 l = aopGet(AOP(left),0,FALSE,FALSE);
3311 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3312 pic14_emitcode("push","acc"); /* save it on the stack */
3314 /* now sign adjust for both left & right */
3315 l = aopGet(AOP(right),0,FALSE,FALSE);
3317 lbl = newiTempLabel(NULL);
3318 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3319 pic14_emitcode("cpl","a");
3320 pic14_emitcode("inc","a");
3321 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3322 pic14_emitcode("mov","b,a");
3324 /* sign adjust left side */
3325 l = aopGet(AOP(left),0,FALSE,FALSE);
3328 lbl = newiTempLabel(NULL);
3329 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3330 pic14_emitcode("cpl","a");
3331 pic14_emitcode("inc","a");
3332 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3334 /* now the division */
3335 pic14_emitcode("div","ab");
3336 /* we are interested in the lower order
3338 pic14_emitcode("mov","b,a");
3339 lbl = newiTempLabel(NULL);
3340 pic14_emitcode("pop","acc");
3341 /* if there was an over flow we don't
3342 adjust the sign of the result */
3343 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3344 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3346 pic14_emitcode("clr","a");
3347 pic14_emitcode("subb","a,b");
3348 pic14_emitcode("mov","b,a");
3349 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3351 /* now we are done */
3352 aopPut(AOP(result),"b",0);
3354 pic14_emitcode("mov","c,b.7");
3355 pic14_emitcode("subb","a,acc");
3358 aopPut(AOP(result),"a",offset++);
3362 /*-----------------------------------------------------------------*/
3363 /* genDiv - generates code for division */
3364 /*-----------------------------------------------------------------*/
3365 static void genDiv (iCode *ic)
3367 operand *left = IC_LEFT(ic);
3368 operand *right = IC_RIGHT(ic);
3369 operand *result= IC_RESULT(ic);
3371 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3372 /* assign the amsops */
3373 aopOp (left,ic,FALSE);
3374 aopOp (right,ic,FALSE);
3375 aopOp (result,ic,TRUE);
3377 /* special cases first */
3379 if (AOP_TYPE(left) == AOP_CRY &&
3380 AOP_TYPE(right)== AOP_CRY) {
3381 genDivbits(left,right,result);
3385 /* if both are of size == 1 */
3386 if (AOP_SIZE(left) == 1 &&
3387 AOP_SIZE(right) == 1 ) {
3388 genDivOneByte(left,right,result);
3392 /* should have been converted to function call */
3395 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3396 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3397 freeAsmop(result,NULL,ic,TRUE);
3400 /*-----------------------------------------------------------------*/
3401 /* genModbits :- modulus of bits */
3402 /*-----------------------------------------------------------------*/
3403 static void genModbits (operand *left,
3410 /* the result must be bit */
3411 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3412 l = aopGet(AOP(left),0,FALSE,FALSE);
3416 pic14_emitcode("div","ab");
3417 pic14_emitcode("mov","a,b");
3418 pic14_emitcode("rrc","a");
3419 aopPut(AOP(result),"c",0);
3422 /*-----------------------------------------------------------------*/
3423 /* genModOneByte : 8 bit modulus */
3424 /*-----------------------------------------------------------------*/
3425 static void genModOneByte (operand *left,
3429 sym_link *opetype = operandType(result);
3433 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3434 /* signed or unsigned */
3435 if (SPEC_USIGN(opetype)) {
3436 /* unsigned is easy */
3437 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3438 l = aopGet(AOP(left),0,FALSE,FALSE);
3440 pic14_emitcode("div","ab");
3441 aopPut(AOP(result),"b",0);
3445 /* signed is a little bit more difficult */
3447 /* save the signs of the operands */
3448 l = aopGet(AOP(left),0,FALSE,FALSE);
3451 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3452 pic14_emitcode("push","acc"); /* save it on the stack */
3454 /* now sign adjust for both left & right */
3455 l = aopGet(AOP(right),0,FALSE,FALSE);
3458 lbl = newiTempLabel(NULL);
3459 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3460 pic14_emitcode("cpl","a");
3461 pic14_emitcode("inc","a");
3462 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3463 pic14_emitcode("mov","b,a");
3465 /* sign adjust left side */
3466 l = aopGet(AOP(left),0,FALSE,FALSE);
3469 lbl = newiTempLabel(NULL);
3470 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3471 pic14_emitcode("cpl","a");
3472 pic14_emitcode("inc","a");
3473 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3475 /* now the multiplication */
3476 pic14_emitcode("div","ab");
3477 /* we are interested in the lower order
3479 lbl = newiTempLabel(NULL);
3480 pic14_emitcode("pop","acc");
3481 /* if there was an over flow we don't
3482 adjust the sign of the result */
3483 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3484 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3486 pic14_emitcode("clr","a");
3487 pic14_emitcode("subb","a,b");
3488 pic14_emitcode("mov","b,a");
3489 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3491 /* now we are done */
3492 aopPut(AOP(result),"b",0);
3496 /*-----------------------------------------------------------------*/
3497 /* genMod - generates code for division */
3498 /*-----------------------------------------------------------------*/
3499 static void genMod (iCode *ic)
3501 operand *left = IC_LEFT(ic);
3502 operand *right = IC_RIGHT(ic);
3503 operand *result= IC_RESULT(ic);
3505 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3506 /* assign the amsops */
3507 aopOp (left,ic,FALSE);
3508 aopOp (right,ic,FALSE);
3509 aopOp (result,ic,TRUE);
3511 /* special cases first */
3513 if (AOP_TYPE(left) == AOP_CRY &&
3514 AOP_TYPE(right)== AOP_CRY) {
3515 genModbits(left,right,result);
3519 /* if both are of size == 1 */
3520 if (AOP_SIZE(left) == 1 &&
3521 AOP_SIZE(right) == 1 ) {
3522 genModOneByte(left,right,result);
3526 /* should have been converted to function call */
3530 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3531 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3532 freeAsmop(result,NULL,ic,TRUE);
3535 /*-----------------------------------------------------------------*/
3536 /* genIfxJump :- will create a jump depending on the ifx */
3537 /*-----------------------------------------------------------------*/
3539 note: May need to add parameter to indicate when a variable is in bit space.
3541 static void genIfxJump (iCode *ic, char *jval)
3544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3545 /* if true label then we jump if condition
3547 if ( IC_TRUE(ic) ) {
3549 if(strcmp(jval,"a") == 0)
3551 else if (strcmp(jval,"c") == 0)
3554 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3555 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3558 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3559 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3563 /* false label is present */
3564 if(strcmp(jval,"a") == 0)
3566 else if (strcmp(jval,"c") == 0)
3569 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3570 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3573 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3574 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3579 /* mark the icode as generated */
3583 /*-----------------------------------------------------------------*/
3585 /*-----------------------------------------------------------------*/
3586 static void genSkip(iCode *ifx,int status_bit)
3591 if ( IC_TRUE(ifx) ) {
3592 switch(status_bit) {
3607 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3608 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3612 switch(status_bit) {
3626 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3627 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3633 /*-----------------------------------------------------------------*/
3635 /*-----------------------------------------------------------------*/
3636 static void genSkipc(resolvedIfx *rifx)
3646 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3647 rifx->generated = 1;
3650 /*-----------------------------------------------------------------*/
3652 /*-----------------------------------------------------------------*/
3653 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3658 if( (rifx->condition ^ invert_condition) & 1)
3663 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3664 rifx->generated = 1;
3667 /*-----------------------------------------------------------------*/
3669 /*-----------------------------------------------------------------*/
3670 static void genSkipz(iCode *ifx, int condition)
3681 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3683 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3686 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3688 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3691 /*-----------------------------------------------------------------*/
3693 /*-----------------------------------------------------------------*/
3694 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3700 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3702 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3705 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3706 rifx->generated = 1;
3710 /*-----------------------------------------------------------------*/
3711 /* genChkZeroes :- greater or less than comparison */
3712 /* For each byte in a literal that is zero, inclusive or the */
3713 /* the corresponding byte in the operand with W */
3714 /* returns true if any of the bytes are zero */
3715 /*-----------------------------------------------------------------*/
3716 static int genChkZeroes(operand *op, int lit, int size)
3723 i = (lit >> (size*8)) & 0xff;
3727 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3729 emitpcode(POC_IORFW, popGet(AOP(op),size));
3738 /*-----------------------------------------------------------------*/
3739 /* genCmp :- greater or less than comparison */
3740 /*-----------------------------------------------------------------*/
3741 static void genCmp (operand *left,operand *right,
3742 operand *result, iCode *ifx, int sign)
3744 int size; //, offset = 0 ;
3745 unsigned long lit = 0L,i = 0;
3746 resolvedIfx rFalseIfx;
3747 // resolvedIfx rTrueIfx;
3749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3751 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3752 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3756 resolveIfx(&rFalseIfx,ifx);
3757 truelbl = newiTempLabel(NULL);
3758 size = max(AOP_SIZE(left),AOP_SIZE(right));
3762 /* if literal is on the right then swap with left */
3763 if ((AOP_TYPE(right) == AOP_LIT)) {
3764 operand *tmp = right ;
3765 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3766 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3768 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
3769 lit = (lit - 1) & mask;
3770 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
3774 rFalseIfx.condition ^= 1;
3777 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3778 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3782 //if(IC_TRUE(ifx) == NULL)
3783 /* if left & right are bit variables */
3784 if (AOP_TYPE(left) == AOP_CRY &&
3785 AOP_TYPE(right) == AOP_CRY ) {
3786 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3787 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3789 /* subtract right from left if at the
3790 end the carry flag is set then we know that
3791 left is greater than right */
3795 symbol *lbl = newiTempLabel(NULL);
3798 if(AOP_TYPE(right) == AOP_LIT) {
3800 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3802 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3809 genSkipCond(&rFalseIfx,left,size-1,7);
3811 /* no need to compare to 0...*/
3812 /* NOTE: this is a de-generate compare that most certainly
3813 * creates some dead code. */
3814 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3816 if(ifx) ifx->generated = 1;
3823 //i = (lit >> (size*8)) & 0xff;
3824 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3826 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3828 i = ((0-lit) & 0xff);
3831 /* lit is 0x7f, all signed chars are less than
3832 * this except for 0x7f itself */
3833 emitpcode(POC_XORLW, popGetLit(0x7f));
3834 genSkipz2(&rFalseIfx,0);
3836 emitpcode(POC_ADDLW, popGetLit(0x80));
3837 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3838 genSkipc(&rFalseIfx);
3843 genSkipz2(&rFalseIfx,1);
3845 emitpcode(POC_ADDLW, popGetLit(i));
3846 genSkipc(&rFalseIfx);
3850 if(ifx) ifx->generated = 1;
3854 /* chars are out of the way. now do ints and longs */
3857 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3864 genSkipCond(&rFalseIfx,left,size,7);
3865 if(ifx) ifx->generated = 1;
3870 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3872 //rFalseIfx.condition ^= 1;
3873 //genSkipCond(&rFalseIfx,left,size,7);
3874 //rFalseIfx.condition ^= 1;
3876 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3877 if(rFalseIfx.condition)
3878 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3880 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3882 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3883 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3884 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3887 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3889 if(rFalseIfx.condition) {
3891 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3897 genSkipc(&rFalseIfx);
3898 emitpLabel(truelbl->key);
3899 if(ifx) ifx->generated = 1;
3906 if( (lit & 0xff) == 0) {
3907 /* lower byte is zero */
3908 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3909 i = ((lit >> 8) & 0xff) ^0x80;
3910 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3911 emitpcode(POC_ADDLW, popGetLit( 0x80));
3912 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3913 genSkipc(&rFalseIfx);
3916 if(ifx) ifx->generated = 1;
3921 /* Special cases for signed longs */
3922 if( (lit & 0xffffff) == 0) {
3923 /* lower byte is zero */
3924 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3925 i = ((lit >> 8*3) & 0xff) ^0x80;
3926 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3927 emitpcode(POC_ADDLW, popGetLit( 0x80));
3928 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3929 genSkipc(&rFalseIfx);
3932 if(ifx) ifx->generated = 1;
3940 if(lit & (0x80 << (size*8))) {
3941 /* lit is negative */
3942 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3944 //genSkipCond(&rFalseIfx,left,size,7);
3946 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3948 if(rFalseIfx.condition)
3949 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3951 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3955 /* lit is positive */
3956 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3957 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3958 if(rFalseIfx.condition)
3959 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3961 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3966 This works, but is only good for ints.
3967 It also requires a "known zero" register.
3968 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3969 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3970 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3971 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3972 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3973 genSkipc(&rFalseIfx);
3975 emitpLabel(truelbl->key);
3976 if(ifx) ifx->generated = 1;
3980 /* There are no more special cases, so perform a general compare */
3982 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3983 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3987 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3989 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3991 //rFalseIfx.condition ^= 1;
3992 genSkipc(&rFalseIfx);
3994 emitpLabel(truelbl->key);
3996 if(ifx) ifx->generated = 1;
4003 /* sign is out of the way. So now do an unsigned compare */
4004 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4007 /* General case - compare to an unsigned literal on the right.*/
4009 i = (lit >> (size*8)) & 0xff;
4010 emitpcode(POC_MOVLW, popGetLit(i));
4011 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4013 i = (lit >> (size*8)) & 0xff;
4016 emitpcode(POC_MOVLW, popGetLit(i));
4018 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4020 /* this byte of the lit is zero,
4021 *if it's not the last then OR in the variable */
4023 emitpcode(POC_IORFW, popGet(AOP(left),size));
4028 emitpLabel(lbl->key);
4029 //if(emitFinalCheck)
4030 genSkipc(&rFalseIfx);
4032 emitpLabel(truelbl->key);
4034 if(ifx) ifx->generated = 1;
4040 if(AOP_TYPE(left) == AOP_LIT) {
4041 //symbol *lbl = newiTempLabel(NULL);
4043 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4046 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4049 if((lit == 0) && (sign == 0)){
4052 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4054 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4056 genSkipz2(&rFalseIfx,0);
4057 if(ifx) ifx->generated = 1;
4064 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4065 /* degenerate compare can never be true */
4066 if(rFalseIfx.condition == 0)
4067 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4069 if(ifx) ifx->generated = 1;
4074 /* signed comparisons to a literal byte */
4076 int lp1 = (lit+1) & 0xff;
4078 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4081 rFalseIfx.condition ^= 1;
4082 genSkipCond(&rFalseIfx,right,0,7);
4085 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4086 emitpcode(POC_XORLW, popGetLit(0x7f));
4087 genSkipz2(&rFalseIfx,1);
4090 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4091 emitpcode(POC_ADDLW, popGetLit(0x80));
4092 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4093 rFalseIfx.condition ^= 1;
4094 genSkipc(&rFalseIfx);
4098 /* unsigned comparisons to a literal byte */
4100 switch(lit & 0xff ) {
4102 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4103 genSkipz2(&rFalseIfx,0);
4106 rFalseIfx.condition ^= 1;
4107 genSkipCond(&rFalseIfx,right,0,7);
4111 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4112 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4114 rFalseIfx.condition ^= 1;
4115 genSkipc(&rFalseIfx);
4120 if(ifx) ifx->generated = 1;
4125 /* Size is greater than 1 */
4133 /* this means lit = 0xffffffff, or -1 */
4136 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4137 rFalseIfx.condition ^= 1;
4138 genSkipCond(&rFalseIfx,right,size,7);
4139 if(ifx) ifx->generated = 1;
4146 if(rFalseIfx.condition) {
4147 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4148 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4151 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4153 emitpcode(POC_IORFW, popGet(AOP(right),size));
4157 if(rFalseIfx.condition) {
4158 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4159 emitpLabel(truelbl->key);
4161 rFalseIfx.condition ^= 1;
4162 genSkipCond(&rFalseIfx,right,s,7);
4165 if(ifx) ifx->generated = 1;
4169 if((size == 1) && (0 == (lp1&0xff))) {
4170 /* lower byte of signed word is zero */
4171 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4172 i = ((lp1 >> 8) & 0xff) ^0x80;
4173 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4174 emitpcode(POC_ADDLW, popGetLit( 0x80));
4175 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4176 rFalseIfx.condition ^= 1;
4177 genSkipc(&rFalseIfx);
4180 if(ifx) ifx->generated = 1;
4184 if(lit & (0x80 << (size*8))) {
4185 /* Lit is less than zero */
4186 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4187 //rFalseIfx.condition ^= 1;
4188 //genSkipCond(&rFalseIfx,left,size,7);
4189 //rFalseIfx.condition ^= 1;
4190 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4191 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4193 if(rFalseIfx.condition)
4194 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4196 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4200 /* Lit is greater than or equal to zero */
4201 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4202 //rFalseIfx.condition ^= 1;
4203 //genSkipCond(&rFalseIfx,right,size,7);
4204 //rFalseIfx.condition ^= 1;
4206 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4207 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4209 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4210 if(rFalseIfx.condition)
4211 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4213 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4218 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4219 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4223 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4225 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4227 rFalseIfx.condition ^= 1;
4228 //rFalseIfx.condition = 1;
4229 genSkipc(&rFalseIfx);
4231 emitpLabel(truelbl->key);
4233 if(ifx) ifx->generated = 1;
4238 /* compare word or long to an unsigned literal on the right.*/
4243 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4246 break; /* handled above */
4249 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4251 emitpcode(POC_IORFW, popGet(AOP(right),size));
4252 genSkipz2(&rFalseIfx,0);
4256 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4258 emitpcode(POC_IORFW, popGet(AOP(right),size));
4261 if(rFalseIfx.condition)
4262 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4264 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4267 emitpcode(POC_MOVLW, popGetLit(lit+1));
4268 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4270 rFalseIfx.condition ^= 1;
4271 genSkipc(&rFalseIfx);
4274 emitpLabel(truelbl->key);
4276 if(ifx) ifx->generated = 1;
4282 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4283 i = (lit >> (size*8)) & 0xff;
4285 emitpcode(POC_MOVLW, popGetLit(i));
4286 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4289 i = (lit >> (size*8)) & 0xff;
4292 emitpcode(POC_MOVLW, popGetLit(i));
4294 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4296 /* this byte of the lit is zero,
4297 *if it's not the last then OR in the variable */
4299 emitpcode(POC_IORFW, popGet(AOP(right),size));
4304 emitpLabel(lbl->key);
4306 rFalseIfx.condition ^= 1;
4307 genSkipc(&rFalseIfx);
4311 emitpLabel(truelbl->key);
4312 if(ifx) ifx->generated = 1;
4316 /* Compare two variables */
4318 DEBUGpic14_emitcode(";sign","%d",sign);
4322 /* Sigh. thus sucks... */
4324 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4325 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4326 emitpcode(POC_MOVLW, popGetLit(0x80));
4327 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4328 emitpcode(POC_XORFW, popGet(AOP(right),size));
4329 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4331 /* Signed char comparison */
4332 /* Special thanks to Nikolai Golovchenko for this snippet */
4333 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4334 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4335 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4336 emitpcode(POC_XORFW, popGet(AOP(left),0));
4337 emitpcode(POC_XORFW, popGet(AOP(right),0));
4338 emitpcode(POC_ADDLW, popGetLit(0x80));
4340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4341 genSkipc(&rFalseIfx);
4343 if(ifx) ifx->generated = 1;
4349 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4350 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4354 /* The rest of the bytes of a multi-byte compare */
4358 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4361 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4362 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4367 emitpLabel(lbl->key);
4369 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4370 genSkipc(&rFalseIfx);
4371 if(ifx) ifx->generated = 1;
4376 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4377 pic14_outBitC(result);
4379 /* if the result is used in the next
4380 ifx conditional branch then generate
4381 code a little differently */
4383 genIfxJump (ifx,"c");
4385 pic14_outBitC(result);
4386 /* leave the result in acc */
4391 /*-----------------------------------------------------------------*/
4392 /* genCmpGt :- greater than comparison */
4393 /*-----------------------------------------------------------------*/
4394 static void genCmpGt (iCode *ic, iCode *ifx)
4396 operand *left, *right, *result;
4397 sym_link *letype , *retype;
4400 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4402 right= IC_RIGHT(ic);
4403 result = IC_RESULT(ic);
4405 letype = getSpec(operandType(left));
4406 retype =getSpec(operandType(right));
4407 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4408 /* assign the amsops */
4409 aopOp (left,ic,FALSE);
4410 aopOp (right,ic,FALSE);
4411 aopOp (result,ic,TRUE);
4413 genCmp(right, left, result, ifx, sign);
4415 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4416 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4417 freeAsmop(result,NULL,ic,TRUE);
4420 /*-----------------------------------------------------------------*/
4421 /* genCmpLt - less than comparisons */
4422 /*-----------------------------------------------------------------*/
4423 static void genCmpLt (iCode *ic, iCode *ifx)
4425 operand *left, *right, *result;
4426 sym_link *letype , *retype;
4429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4431 right= IC_RIGHT(ic);
4432 result = IC_RESULT(ic);
4434 letype = getSpec(operandType(left));
4435 retype =getSpec(operandType(right));
4436 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4438 /* assign the amsops */
4439 aopOp (left,ic,FALSE);
4440 aopOp (right,ic,FALSE);
4441 aopOp (result,ic,TRUE);
4443 genCmp(left, right, result, ifx, sign);
4445 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4446 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4447 freeAsmop(result,NULL,ic,TRUE);
4450 /*-----------------------------------------------------------------*/
4451 /* genc16bit2lit - compare a 16 bit value to a literal */
4452 /*-----------------------------------------------------------------*/
4453 static void genc16bit2lit(operand *op, int lit, int offset)
4457 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4458 if( (lit&0xff) == 0)
4463 switch( BYTEofLONG(lit,i)) {
4465 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4468 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4471 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4474 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4475 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4480 switch( BYTEofLONG(lit,i)) {
4482 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4486 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4490 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4493 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4495 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4501 /*-----------------------------------------------------------------*/
4502 /* gencjneshort - compare and jump if not equal */
4503 /*-----------------------------------------------------------------*/
4504 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4506 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4511 unsigned long lit = 0L;
4512 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4513 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4515 resolveIfx(&rIfx,ifx);
4516 lbl = newiTempLabel(NULL);
4519 /* if the left side is a literal or
4520 if the right is in a pointer register and left
4522 if ((AOP_TYPE(left) == AOP_LIT) ||
4523 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4528 if(AOP_TYPE(right) == AOP_LIT)
4529 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4531 /* if the right side is a literal then anything goes */
4532 if (AOP_TYPE(right) == AOP_LIT &&
4533 AOP_TYPE(left) != AOP_DIR ) {
4536 genc16bit2lit(left, lit, 0);
4538 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4543 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4544 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4546 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4550 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4558 /* if the right side is in a register or in direct space or
4559 if the left is a pointer register & right is not */
4560 else if (AOP_TYPE(right) == AOP_REG ||
4561 AOP_TYPE(right) == AOP_DIR ||
4562 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4563 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4566 genc16bit2lit(left, lit, 0);
4568 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4573 if((AOP_TYPE(left) == AOP_DIR) &&
4574 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4576 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4577 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4579 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4581 switch (lit & 0xff) {
4583 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4586 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4587 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4591 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4592 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4596 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4597 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4602 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4605 if(AOP_TYPE(result) == AOP_CRY) {
4606 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4611 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4613 /* fix me. probably need to check result size too */
4614 emitpcode(POC_CLRF,popGet(AOP(result),0));
4619 emitpcode(POC_INCF,popGet(AOP(result),0));
4629 } else if(AOP_TYPE(right) == AOP_REG &&
4630 AOP_TYPE(left) != AOP_DIR){
4633 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4634 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4635 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4640 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4645 /* right is a pointer reg need both a & b */
4647 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4649 pic14_emitcode("mov","b,%s",l);
4650 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4651 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4655 emitpLabel(lbl->key);
4662 /*-----------------------------------------------------------------*/
4663 /* gencjne - compare and jump if not equal */
4664 /*-----------------------------------------------------------------*/
4665 static void gencjne(operand *left, operand *right, iCode *ifx)
4667 symbol *tlbl = newiTempLabel(NULL);
4669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4670 gencjneshort(left, right, lbl);
4672 pic14_emitcode("mov","a,%s",one);
4673 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4674 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4675 pic14_emitcode("clr","a");
4676 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4678 emitpLabel(lbl->key);
4679 emitpLabel(tlbl->key);
4684 /*-----------------------------------------------------------------*/
4685 /* genCmpEq - generates code for equal to */
4686 /*-----------------------------------------------------------------*/
4687 static void genCmpEq (iCode *ic, iCode *ifx)
4689 operand *left, *right, *result;
4690 unsigned long lit = 0L;
4693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4696 DEBUGpic14_emitcode ("; ifx is non-null","");
4698 DEBUGpic14_emitcode ("; ifx is null","");
4700 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4701 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4702 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4704 size = max(AOP_SIZE(left),AOP_SIZE(right));
4706 DEBUGpic14_AopType(__LINE__,left,right,result);
4708 /* if literal, literal on the right or
4709 if the right is in a pointer register and left
4711 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4712 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4713 operand *tmp = right ;
4719 if(ifx && !AOP_SIZE(result)){
4721 /* if they are both bit variables */
4722 if (AOP_TYPE(left) == AOP_CRY &&
4723 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4724 if(AOP_TYPE(right) == AOP_LIT){
4725 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4727 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4728 pic14_emitcode("cpl","c");
4729 } else if(lit == 1L) {
4730 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4732 pic14_emitcode("clr","c");
4734 /* AOP_TYPE(right) == AOP_CRY */
4736 symbol *lbl = newiTempLabel(NULL);
4737 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4738 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4739 pic14_emitcode("cpl","c");
4740 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4742 /* if true label then we jump if condition
4744 tlbl = newiTempLabel(NULL);
4745 if ( IC_TRUE(ifx) ) {
4746 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4747 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4749 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4750 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4752 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4755 /* left and right are both bit variables, result is carry */
4758 resolveIfx(&rIfx,ifx);
4760 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4761 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4762 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4763 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4768 /* They're not both bit variables. Is the right a literal? */
4769 if(AOP_TYPE(right) == AOP_LIT) {
4770 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4775 switch(lit & 0xff) {
4777 if ( IC_TRUE(ifx) ) {
4778 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4780 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4782 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4783 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4787 if ( IC_TRUE(ifx) ) {
4788 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4790 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4792 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4793 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4797 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4799 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4804 /* end of size == 1 */
4808 genc16bit2lit(left,lit,offset);
4811 /* end of size == 2 */
4816 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4817 emitpcode(POC_IORFW,popGet(AOP(left),1));
4818 emitpcode(POC_IORFW,popGet(AOP(left),2));
4819 emitpcode(POC_IORFW,popGet(AOP(left),3));
4823 /* search for patterns that can be optimized */
4825 genc16bit2lit(left,lit,0);
4828 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4830 genc16bit2lit(left,lit,2);
4832 emitpcode(POC_IORFW,popGet(AOP(left),2));
4833 emitpcode(POC_IORFW,popGet(AOP(left),3));
4846 } else if(AOP_TYPE(right) == AOP_CRY ) {
4847 /* we know the left is not a bit, but that the right is */
4848 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4849 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4850 popGet(AOP(right),offset));
4851 emitpcode(POC_XORLW,popGetLit(1));
4853 /* if the two are equal, then W will be 0 and the Z bit is set
4854 * we could test Z now, or go ahead and check the high order bytes if
4855 * the variable we're comparing is larger than a byte. */
4858 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4860 if ( IC_TRUE(ifx) ) {
4862 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4863 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4866 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4867 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4871 /* They're both variables that are larger than bits */
4874 tlbl = newiTempLabel(NULL);
4877 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4878 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4880 if ( IC_TRUE(ifx) ) {
4883 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4884 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4887 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4888 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4892 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4893 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4897 if(s>1 && IC_TRUE(ifx)) {
4898 emitpLabel(tlbl->key);
4899 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4903 /* mark the icode as generated */
4908 /* if they are both bit variables */
4909 if (AOP_TYPE(left) == AOP_CRY &&
4910 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4911 if(AOP_TYPE(right) == AOP_LIT){
4912 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4914 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4915 pic14_emitcode("cpl","c");
4916 } else if(lit == 1L) {
4917 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4919 pic14_emitcode("clr","c");
4921 /* AOP_TYPE(right) == AOP_CRY */
4923 symbol *lbl = newiTempLabel(NULL);
4924 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4925 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4926 pic14_emitcode("cpl","c");
4927 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4930 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4931 pic14_outBitC(result);
4935 genIfxJump (ifx,"c");
4938 /* if the result is used in an arithmetic operation
4939 then put the result in place */
4940 pic14_outBitC(result);
4943 gencjne(left,right,result,ifx);
4946 gencjne(left,right,newiTempLabel(NULL));
4948 if(IC_TRUE(ifx)->key)
4949 gencjne(left,right,IC_TRUE(ifx)->key);
4951 gencjne(left,right,IC_FALSE(ifx)->key);
4955 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4956 aopPut(AOP(result),"a",0);
4961 genIfxJump (ifx,"a");
4965 /* if the result is used in an arithmetic operation
4966 then put the result in place */
4968 if (AOP_TYPE(result) != AOP_CRY)
4969 pic14_outAcc(result);
4971 /* leave the result in acc */
4975 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4976 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4977 freeAsmop(result,NULL,ic,TRUE);
4980 /*-----------------------------------------------------------------*/
4981 /* ifxForOp - returns the icode containing the ifx for operand */
4982 /*-----------------------------------------------------------------*/
4983 static iCode *ifxForOp ( operand *op, iCode *ic )
4985 /* if true symbol then needs to be assigned */
4986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4987 if (IS_TRUE_SYMOP(op))
4990 /* if this has register type condition and
4991 the next instruction is ifx with the same operand
4992 and live to of the operand is upto the ifx only then */
4994 ic->next->op == IFX &&
4995 IC_COND(ic->next)->key == op->key &&
4996 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5000 ic->next->op == IFX &&
5001 IC_COND(ic->next)->key == op->key) {
5002 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5006 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5008 ic->next->op == IFX)
5009 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5012 ic->next->op == IFX &&
5013 IC_COND(ic->next)->key == op->key) {
5014 DEBUGpic14_emitcode ("; "," key is okay");
5015 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5016 OP_SYMBOL(op)->liveTo,
5023 /*-----------------------------------------------------------------*/
5024 /* genAndOp - for && operation */
5025 /*-----------------------------------------------------------------*/
5026 static void genAndOp (iCode *ic)
5028 operand *left,*right, *result;
5031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5032 /* note here that && operations that are in an
5033 if statement are taken away by backPatchLabels
5034 only those used in arthmetic operations remain */
5035 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5036 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5037 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5039 /* if both are bit variables */
5040 if (AOP_TYPE(left) == AOP_CRY &&
5041 AOP_TYPE(right) == AOP_CRY ) {
5042 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5043 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5044 pic14_outBitC(result);
5046 tlbl = newiTempLabel(NULL);
5047 pic14_toBoolean(left);
5048 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5049 pic14_toBoolean(right);
5050 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5051 pic14_outBitAcc(result);
5054 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5055 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5056 freeAsmop(result,NULL,ic,TRUE);
5060 /*-----------------------------------------------------------------*/
5061 /* genOrOp - for || operation */
5062 /*-----------------------------------------------------------------*/
5065 modified this code, but it doesn't appear to ever get called
5068 static void genOrOp (iCode *ic)
5070 operand *left,*right, *result;
5073 /* note here that || operations that are in an
5074 if statement are taken away by backPatchLabels
5075 only those used in arthmetic operations remain */
5076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5077 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5078 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5079 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5081 DEBUGpic14_AopType(__LINE__,left,right,result);
5083 /* if both are bit variables */
5084 if (AOP_TYPE(left) == AOP_CRY &&
5085 AOP_TYPE(right) == AOP_CRY ) {
5086 pic14_emitcode("clrc","");
5087 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5088 AOP(left)->aopu.aop_dir,
5089 AOP(left)->aopu.aop_dir);
5090 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5091 AOP(right)->aopu.aop_dir,
5092 AOP(right)->aopu.aop_dir);
5093 pic14_emitcode("setc","");
5096 tlbl = newiTempLabel(NULL);
5097 pic14_toBoolean(left);
5099 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5100 pic14_toBoolean(right);
5101 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5103 pic14_outBitAcc(result);
5106 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5107 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5108 freeAsmop(result,NULL,ic,TRUE);
5111 /*-----------------------------------------------------------------*/
5112 /* isLiteralBit - test if lit == 2^n */
5113 /*-----------------------------------------------------------------*/
5114 static int isLiteralBit(unsigned long lit)
5116 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5117 0x100L,0x200L,0x400L,0x800L,
5118 0x1000L,0x2000L,0x4000L,0x8000L,
5119 0x10000L,0x20000L,0x40000L,0x80000L,
5120 0x100000L,0x200000L,0x400000L,0x800000L,
5121 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5122 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5126 for(idx = 0; idx < 32; idx++)
5132 /*-----------------------------------------------------------------*/
5133 /* continueIfTrue - */
5134 /*-----------------------------------------------------------------*/
5135 static void continueIfTrue (iCode *ic)
5137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5139 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5143 /*-----------------------------------------------------------------*/
5145 /*-----------------------------------------------------------------*/
5146 static void jumpIfTrue (iCode *ic)
5148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5150 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5154 /*-----------------------------------------------------------------*/
5155 /* jmpTrueOrFalse - */
5156 /*-----------------------------------------------------------------*/
5157 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5159 // ugly but optimized by peephole
5160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5162 symbol *nlbl = newiTempLabel(NULL);
5163 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5164 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5165 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5166 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5169 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5170 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5175 /*-----------------------------------------------------------------*/
5176 /* genAnd - code for and */
5177 /*-----------------------------------------------------------------*/
5178 static void genAnd (iCode *ic, iCode *ifx)
5180 operand *left, *right, *result;
5182 unsigned long lit = 0L;
5187 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5188 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5189 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5190 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5192 resolveIfx(&rIfx,ifx);
5194 /* if left is a literal & right is not then exchange them */
5195 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5196 AOP_NEEDSACC(left)) {
5197 operand *tmp = right ;
5202 /* if result = right then exchange them */
5203 if(pic14_sameRegs(AOP(result),AOP(right))){
5204 operand *tmp = right ;
5209 /* if right is bit then exchange them */
5210 if (AOP_TYPE(right) == AOP_CRY &&
5211 AOP_TYPE(left) != AOP_CRY){
5212 operand *tmp = right ;
5216 if(AOP_TYPE(right) == AOP_LIT)
5217 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5219 size = AOP_SIZE(result);
5221 DEBUGpic14_AopType(__LINE__,left,right,result);
5224 // result = bit & yy;
5225 if (AOP_TYPE(left) == AOP_CRY){
5226 // c = bit & literal;
5227 if(AOP_TYPE(right) == AOP_LIT){
5229 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5232 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5235 if(size && (AOP_TYPE(result) == AOP_CRY)){
5236 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5239 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5243 pic14_emitcode("clr","c");
5246 if (AOP_TYPE(right) == AOP_CRY){
5248 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5249 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5252 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5254 pic14_emitcode("rrc","a");
5255 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5261 pic14_outBitC(result);
5263 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5264 genIfxJump(ifx, "c");
5268 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5269 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5270 if((AOP_TYPE(right) == AOP_LIT) &&
5271 (AOP_TYPE(result) == AOP_CRY) &&
5272 (AOP_TYPE(left) != AOP_CRY)){
5273 int posbit = isLiteralBit(lit);
5277 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5280 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5286 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5287 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5289 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5290 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5293 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5294 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5295 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5302 symbol *tlbl = newiTempLabel(NULL);
5303 int sizel = AOP_SIZE(left);
5305 pic14_emitcode("setb","c");
5307 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5308 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5310 if((posbit = isLiteralBit(bytelit)) != 0)
5311 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5313 if(bytelit != 0x0FFL)
5314 pic14_emitcode("anl","a,%s",
5315 aopGet(AOP(right),offset,FALSE,TRUE));
5316 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5321 // bit = left & literal
5323 pic14_emitcode("clr","c");
5324 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5326 // if(left & literal)
5329 jmpTrueOrFalse(ifx, tlbl);
5333 pic14_outBitC(result);
5337 /* if left is same as result */
5338 if(pic14_sameRegs(AOP(result),AOP(left))){
5340 for(;size--; offset++,lit>>=8) {
5341 if(AOP_TYPE(right) == AOP_LIT){
5342 switch(lit & 0xff) {
5344 /* and'ing with 0 has clears the result */
5345 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5346 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5349 /* and'ing with 0xff is a nop when the result and left are the same */
5354 int p = my_powof2( (~lit) & 0xff );
5356 /* only one bit is set in the literal, so use a bcf instruction */
5357 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5358 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5361 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5362 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5363 if(know_W != (lit&0xff))
5364 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5366 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5371 if (AOP_TYPE(left) == AOP_ACC) {
5372 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5374 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5375 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5382 // left & result in different registers
5383 if(AOP_TYPE(result) == AOP_CRY){
5385 // if(size), result in bit
5386 // if(!size && ifx), conditional oper: if(left & right)
5387 symbol *tlbl = newiTempLabel(NULL);
5388 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5390 pic14_emitcode("setb","c");
5392 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5393 pic14_emitcode("anl","a,%s",
5394 aopGet(AOP(left),offset,FALSE,FALSE));
5395 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5400 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5401 pic14_outBitC(result);
5403 jmpTrueOrFalse(ifx, tlbl);
5405 for(;(size--);offset++) {
5407 // result = left & right
5408 if(AOP_TYPE(right) == AOP_LIT){
5409 int t = (lit >> (offset*8)) & 0x0FFL;
5412 pic14_emitcode("clrf","%s",
5413 aopGet(AOP(result),offset,FALSE,FALSE));
5414 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5417 pic14_emitcode("movf","%s,w",
5418 aopGet(AOP(left),offset,FALSE,FALSE));
5419 pic14_emitcode("movwf","%s",
5420 aopGet(AOP(result),offset,FALSE,FALSE));
5421 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5422 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5425 pic14_emitcode("movlw","0x%x",t);
5426 pic14_emitcode("andwf","%s,w",
5427 aopGet(AOP(left),offset,FALSE,FALSE));
5428 pic14_emitcode("movwf","%s",
5429 aopGet(AOP(result),offset,FALSE,FALSE));
5431 emitpcode(POC_MOVLW, popGetLit(t));
5432 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5433 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5438 if (AOP_TYPE(left) == AOP_ACC) {
5439 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5440 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5442 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5443 pic14_emitcode("andwf","%s,w",
5444 aopGet(AOP(left),offset,FALSE,FALSE));
5445 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5446 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5448 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5449 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5455 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5456 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5457 freeAsmop(result,NULL,ic,TRUE);
5460 /*-----------------------------------------------------------------*/
5461 /* genOr - code for or */
5462 /*-----------------------------------------------------------------*/
5463 static void genOr (iCode *ic, iCode *ifx)
5465 operand *left, *right, *result;
5467 unsigned long lit = 0L;
5469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5471 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5472 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5473 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5475 DEBUGpic14_AopType(__LINE__,left,right,result);
5477 /* if left is a literal & right is not then exchange them */
5478 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5479 AOP_NEEDSACC(left)) {
5480 operand *tmp = right ;
5485 /* if result = right then exchange them */
5486 if(pic14_sameRegs(AOP(result),AOP(right))){
5487 operand *tmp = right ;
5492 /* if right is bit then exchange them */
5493 if (AOP_TYPE(right) == AOP_CRY &&
5494 AOP_TYPE(left) != AOP_CRY){
5495 operand *tmp = right ;
5500 DEBUGpic14_AopType(__LINE__,left,right,result);
5502 if(AOP_TYPE(right) == AOP_LIT)
5503 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5505 size = AOP_SIZE(result);
5509 if (AOP_TYPE(left) == AOP_CRY){
5510 if(AOP_TYPE(right) == AOP_LIT){
5511 // c = bit & literal;
5513 // lit != 0 => result = 1
5514 if(AOP_TYPE(result) == AOP_CRY){
5516 emitpcode(POC_BSF, popGet(AOP(result),0));
5517 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5518 // AOP(result)->aopu.aop_dir,
5519 // AOP(result)->aopu.aop_dir);
5521 continueIfTrue(ifx);
5525 // lit == 0 => result = left
5526 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5528 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5531 if (AOP_TYPE(right) == AOP_CRY){
5532 if(pic14_sameRegs(AOP(result),AOP(left))){
5534 emitpcode(POC_BCF, popGet(AOP(result),0));
5535 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5536 emitpcode(POC_BSF, popGet(AOP(result),0));
5538 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5539 AOP(result)->aopu.aop_dir,
5540 AOP(result)->aopu.aop_dir);
5541 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5542 AOP(right)->aopu.aop_dir,
5543 AOP(right)->aopu.aop_dir);
5544 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5545 AOP(result)->aopu.aop_dir,
5546 AOP(result)->aopu.aop_dir);
5548 if( AOP_TYPE(result) == AOP_ACC) {
5549 emitpcode(POC_MOVLW, popGetLit(0));
5550 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5551 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5552 emitpcode(POC_MOVLW, popGetLit(1));
5556 emitpcode(POC_BCF, popGet(AOP(result),0));
5557 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5558 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5559 emitpcode(POC_BSF, popGet(AOP(result),0));
5561 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5562 AOP(result)->aopu.aop_dir,
5563 AOP(result)->aopu.aop_dir);
5564 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5565 AOP(right)->aopu.aop_dir,
5566 AOP(right)->aopu.aop_dir);
5567 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5568 AOP(left)->aopu.aop_dir,
5569 AOP(left)->aopu.aop_dir);
5570 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5571 AOP(result)->aopu.aop_dir,
5572 AOP(result)->aopu.aop_dir);
5577 symbol *tlbl = newiTempLabel(NULL);
5578 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5581 emitpcode(POC_BCF, popGet(AOP(result),0));
5582 if( AOP_TYPE(right) == AOP_ACC) {
5583 emitpcode(POC_IORLW, popGetLit(0));
5585 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5586 emitpcode(POC_BSF, popGet(AOP(result),0));
5591 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5592 pic14_emitcode(";XXX setb","c");
5593 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5594 AOP(left)->aopu.aop_dir,tlbl->key+100);
5595 pic14_toBoolean(right);
5596 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5597 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5598 jmpTrueOrFalse(ifx, tlbl);
5602 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5609 pic14_outBitC(result);
5611 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5612 genIfxJump(ifx, "c");
5616 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5617 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5618 if((AOP_TYPE(right) == AOP_LIT) &&
5619 (AOP_TYPE(result) == AOP_CRY) &&
5620 (AOP_TYPE(left) != AOP_CRY)){
5622 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5625 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5627 continueIfTrue(ifx);
5630 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5631 // lit = 0, result = boolean(left)
5633 pic14_emitcode(";XXX setb","c");
5634 pic14_toBoolean(right);
5636 symbol *tlbl = newiTempLabel(NULL);
5637 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5639 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5641 genIfxJump (ifx,"a");
5645 pic14_outBitC(result);
5649 /* if left is same as result */
5650 if(pic14_sameRegs(AOP(result),AOP(left))){
5652 for(;size--; offset++,lit>>=8) {
5653 if(AOP_TYPE(right) == AOP_LIT){
5654 if((lit & 0xff) == 0)
5655 /* or'ing with 0 has no effect */
5658 int p = my_powof2(lit & 0xff);
5660 /* only one bit is set in the literal, so use a bsf instruction */
5662 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5664 if(know_W != (lit & 0xff))
5665 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5666 know_W = lit & 0xff;
5667 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5672 if (AOP_TYPE(left) == AOP_ACC) {
5673 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5674 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5676 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5677 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5679 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5680 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5686 // left & result in different registers
5687 if(AOP_TYPE(result) == AOP_CRY){
5689 // if(size), result in bit
5690 // if(!size && ifx), conditional oper: if(left | right)
5691 symbol *tlbl = newiTempLabel(NULL);
5692 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5693 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5697 pic14_emitcode(";XXX setb","c");
5699 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5700 pic14_emitcode(";XXX orl","a,%s",
5701 aopGet(AOP(left),offset,FALSE,FALSE));
5702 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5707 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5708 pic14_outBitC(result);
5710 jmpTrueOrFalse(ifx, tlbl);
5711 } else for(;(size--);offset++){
5713 // result = left & right
5714 if(AOP_TYPE(right) == AOP_LIT){
5715 int t = (lit >> (offset*8)) & 0x0FFL;
5718 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5719 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5721 pic14_emitcode("movf","%s,w",
5722 aopGet(AOP(left),offset,FALSE,FALSE));
5723 pic14_emitcode("movwf","%s",
5724 aopGet(AOP(result),offset,FALSE,FALSE));
5727 emitpcode(POC_MOVLW, popGetLit(t));
5728 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5729 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5731 pic14_emitcode("movlw","0x%x",t);
5732 pic14_emitcode("iorwf","%s,w",
5733 aopGet(AOP(left),offset,FALSE,FALSE));
5734 pic14_emitcode("movwf","%s",
5735 aopGet(AOP(result),offset,FALSE,FALSE));
5741 // faster than result <- left, anl result,right
5742 // and better if result is SFR
5743 if (AOP_TYPE(left) == AOP_ACC) {
5744 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5745 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5747 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5748 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5750 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5751 pic14_emitcode("iorwf","%s,w",
5752 aopGet(AOP(left),offset,FALSE,FALSE));
5754 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5755 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5760 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5761 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5762 freeAsmop(result,NULL,ic,TRUE);
5765 /*-----------------------------------------------------------------*/
5766 /* genXor - code for xclusive or */
5767 /*-----------------------------------------------------------------*/
5768 static void genXor (iCode *ic, iCode *ifx)
5770 operand *left, *right, *result;
5772 unsigned long lit = 0L;
5774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5776 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5777 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5778 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5780 /* if left is a literal & right is not ||
5781 if left needs acc & right does not */
5782 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5783 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5784 operand *tmp = right ;
5789 /* if result = right then exchange them */
5790 if(pic14_sameRegs(AOP(result),AOP(right))){
5791 operand *tmp = right ;
5796 /* if right is bit then exchange them */
5797 if (AOP_TYPE(right) == AOP_CRY &&
5798 AOP_TYPE(left) != AOP_CRY){
5799 operand *tmp = right ;
5803 if(AOP_TYPE(right) == AOP_LIT)
5804 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5806 size = AOP_SIZE(result);
5810 if (AOP_TYPE(left) == AOP_CRY){
5811 if(AOP_TYPE(right) == AOP_LIT){
5812 // c = bit & literal;
5814 // lit>>1 != 0 => result = 1
5815 if(AOP_TYPE(result) == AOP_CRY){
5817 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5818 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5820 continueIfTrue(ifx);
5823 pic14_emitcode("setb","c");
5827 // lit == 0, result = left
5828 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5830 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5832 // lit == 1, result = not(left)
5833 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5834 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5835 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5836 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5839 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5840 pic14_emitcode("cpl","c");
5847 symbol *tlbl = newiTempLabel(NULL);
5848 if (AOP_TYPE(right) == AOP_CRY){
5850 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5853 int sizer = AOP_SIZE(right);
5855 // if val>>1 != 0, result = 1
5856 pic14_emitcode("setb","c");
5858 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5860 // test the msb of the lsb
5861 pic14_emitcode("anl","a,#0xfe");
5862 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5866 pic14_emitcode("rrc","a");
5868 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5869 pic14_emitcode("cpl","c");
5870 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5875 pic14_outBitC(result);
5877 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5878 genIfxJump(ifx, "c");
5882 if(pic14_sameRegs(AOP(result),AOP(left))){
5883 /* if left is same as result */
5884 for(;size--; offset++) {
5885 if(AOP_TYPE(right) == AOP_LIT){
5886 int t = (lit >> (offset*8)) & 0x0FFL;
5890 if (IS_AOP_PREG(left)) {
5891 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5892 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5893 aopPut(AOP(result),"a",offset);
5895 emitpcode(POC_MOVLW, popGetLit(t));
5896 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5897 pic14_emitcode("xrl","%s,%s",
5898 aopGet(AOP(left),offset,FALSE,TRUE),
5899 aopGet(AOP(right),offset,FALSE,FALSE));
5902 if (AOP_TYPE(left) == AOP_ACC)
5903 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5905 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5906 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5908 if (IS_AOP_PREG(left)) {
5909 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5910 aopPut(AOP(result),"a",offset);
5912 pic14_emitcode("xrl","%s,a",
5913 aopGet(AOP(left),offset,FALSE,TRUE));
5919 // left & result in different registers
5920 if(AOP_TYPE(result) == AOP_CRY){
5922 // if(size), result in bit
5923 // if(!size && ifx), conditional oper: if(left ^ right)
5924 symbol *tlbl = newiTempLabel(NULL);
5925 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5927 pic14_emitcode("setb","c");
5929 if((AOP_TYPE(right) == AOP_LIT) &&
5930 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5931 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5933 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5934 pic14_emitcode("xrl","a,%s",
5935 aopGet(AOP(left),offset,FALSE,FALSE));
5937 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5942 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5943 pic14_outBitC(result);
5945 jmpTrueOrFalse(ifx, tlbl);
5946 } else for(;(size--);offset++){
5948 // result = left & right
5949 if(AOP_TYPE(right) == AOP_LIT){
5950 int t = (lit >> (offset*8)) & 0x0FFL;
5953 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5954 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5955 pic14_emitcode("movf","%s,w",
5956 aopGet(AOP(left),offset,FALSE,FALSE));
5957 pic14_emitcode("movwf","%s",
5958 aopGet(AOP(result),offset,FALSE,FALSE));
5961 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5962 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5963 pic14_emitcode("comf","%s,w",
5964 aopGet(AOP(left),offset,FALSE,FALSE));
5965 pic14_emitcode("movwf","%s",
5966 aopGet(AOP(result),offset,FALSE,FALSE));
5969 emitpcode(POC_MOVLW, popGetLit(t));
5970 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5971 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5972 pic14_emitcode("movlw","0x%x",t);
5973 pic14_emitcode("xorwf","%s,w",
5974 aopGet(AOP(left),offset,FALSE,FALSE));
5975 pic14_emitcode("movwf","%s",
5976 aopGet(AOP(result),offset,FALSE,FALSE));
5982 // faster than result <- left, anl result,right
5983 // and better if result is SFR
5984 if (AOP_TYPE(left) == AOP_ACC) {
5985 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5986 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5988 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5989 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5990 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5991 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5993 if ( AOP_TYPE(result) != AOP_ACC){
5994 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5995 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6001 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6002 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6003 freeAsmop(result,NULL,ic,TRUE);
6006 /*-----------------------------------------------------------------*/
6007 /* genInline - write the inline code out */
6008 /*-----------------------------------------------------------------*/
6009 static void genInline (iCode *ic)
6011 char *buffer, *bp, *bp1;
6013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6015 _G.inLine += (!options.asmpeep);
6017 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6018 strcpy(buffer,IC_INLINE(ic));
6020 /* emit each line as a code */
6024 pic14_emitcode(bp1,"");
6025 addpCode2pBlock(pb,newpCodeInlineP(bp1));
6032 pic14_emitcode(bp1,"");
6039 pic14_emitcode(bp1,"");
6040 addpCode2pBlock(pb,newpCodeInlineP(bp1));
6042 /* pic14_emitcode("",buffer); */
6043 _G.inLine -= (!options.asmpeep);
6046 /*-----------------------------------------------------------------*/
6047 /* genRRC - rotate right with carry */
6048 /*-----------------------------------------------------------------*/
6049 static void genRRC (iCode *ic)
6051 operand *left , *result ;
6052 int size, offset = 0, same;
6054 /* rotate right with carry */
6056 result=IC_RESULT(ic);
6057 aopOp (left,ic,FALSE);
6058 aopOp (result,ic,FALSE);
6060 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6062 same = pic14_sameRegs(AOP(result),AOP(left));
6064 size = AOP_SIZE(result);
6066 /* get the lsb and put it into the carry */
6067 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6074 emitpcode(POC_RRF, popGet(AOP(left),offset));
6076 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6077 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6083 freeAsmop(left,NULL,ic,TRUE);
6084 freeAsmop(result,NULL,ic,TRUE);
6087 /*-----------------------------------------------------------------*/
6088 /* genRLC - generate code for rotate left with carry */
6089 /*-----------------------------------------------------------------*/
6090 static void genRLC (iCode *ic)
6092 operand *left , *result ;
6093 int size, offset = 0;
6096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6097 /* rotate right with carry */
6099 result=IC_RESULT(ic);
6100 aopOp (left,ic,FALSE);
6101 aopOp (result,ic,FALSE);
6103 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6105 same = pic14_sameRegs(AOP(result),AOP(left));
6107 /* move it to the result */
6108 size = AOP_SIZE(result);
6110 /* get the msb and put it into the carry */
6111 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6118 emitpcode(POC_RLF, popGet(AOP(left),offset));
6120 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6121 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6128 freeAsmop(left,NULL,ic,TRUE);
6129 freeAsmop(result,NULL,ic,TRUE);
6132 /*-----------------------------------------------------------------*/
6133 /* genGetHbit - generates code get highest order bit */
6134 /*-----------------------------------------------------------------*/
6135 static void genGetHbit (iCode *ic)
6137 operand *left, *result;
6139 result=IC_RESULT(ic);
6140 aopOp (left,ic,FALSE);
6141 aopOp (result,ic,FALSE);
6143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6144 /* get the highest order byte into a */
6145 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6146 if(AOP_TYPE(result) == AOP_CRY){
6147 pic14_emitcode("rlc","a");
6148 pic14_outBitC(result);
6151 pic14_emitcode("rl","a");
6152 pic14_emitcode("anl","a,#0x01");
6153 pic14_outAcc(result);
6157 freeAsmop(left,NULL,ic,TRUE);
6158 freeAsmop(result,NULL,ic,TRUE);
6161 /*-----------------------------------------------------------------*/
6162 /* AccRol - rotate left accumulator by known count */
6163 /*-----------------------------------------------------------------*/
6164 static void AccRol (int shCount)
6166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6167 shCount &= 0x0007; // shCount : 0..7
6172 pic14_emitcode("rl","a");
6175 pic14_emitcode("rl","a");
6176 pic14_emitcode("rl","a");
6179 pic14_emitcode("swap","a");
6180 pic14_emitcode("rr","a");
6183 pic14_emitcode("swap","a");
6186 pic14_emitcode("swap","a");
6187 pic14_emitcode("rl","a");
6190 pic14_emitcode("rr","a");
6191 pic14_emitcode("rr","a");
6194 pic14_emitcode("rr","a");
6199 /*-----------------------------------------------------------------*/
6200 /* AccLsh - left shift accumulator by known count */
6201 /*-----------------------------------------------------------------*/
6202 static void AccLsh (int shCount)
6204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6207 pic14_emitcode("add","a,acc");
6210 pic14_emitcode("add","a,acc");
6211 pic14_emitcode("add","a,acc");
6213 /* rotate left accumulator */
6215 /* and kill the lower order bits */
6216 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6221 /*-----------------------------------------------------------------*/
6222 /* AccRsh - right shift accumulator by known count */
6223 /*-----------------------------------------------------------------*/
6224 static void AccRsh (int shCount)
6226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6230 pic14_emitcode("rrc","a");
6232 /* rotate right accumulator */
6233 AccRol(8 - shCount);
6234 /* and kill the higher order bits */
6235 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6241 /*-----------------------------------------------------------------*/
6242 /* AccSRsh - signed right shift accumulator by known count */
6243 /*-----------------------------------------------------------------*/
6244 static void AccSRsh (int shCount)
6247 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6250 pic14_emitcode("mov","c,acc.7");
6251 pic14_emitcode("rrc","a");
6252 } else if(shCount == 2){
6253 pic14_emitcode("mov","c,acc.7");
6254 pic14_emitcode("rrc","a");
6255 pic14_emitcode("mov","c,acc.7");
6256 pic14_emitcode("rrc","a");
6258 tlbl = newiTempLabel(NULL);
6259 /* rotate right accumulator */
6260 AccRol(8 - shCount);
6261 /* and kill the higher order bits */
6262 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6263 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6264 pic14_emitcode("orl","a,#0x%02x",
6265 (unsigned char)~SRMask[shCount]);
6266 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6271 /*-----------------------------------------------------------------*/
6272 /* shiftR1Left2Result - shift right one byte from left to result */
6273 /*-----------------------------------------------------------------*/
6274 static void shiftR1Left2ResultSigned (operand *left, int offl,
6275 operand *result, int offr,
6280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6282 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6286 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6288 emitpcode(POC_RRF, popGet(AOP(result),offr));
6290 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6291 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6297 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6299 emitpcode(POC_RRF, popGet(AOP(result),offr));
6301 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6302 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6304 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6305 emitpcode(POC_RRF, popGet(AOP(result),offr));
6311 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6313 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6314 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6317 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6318 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6319 emitpcode(POC_ANDLW, popGetLit(0x1f));
6321 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6322 emitpcode(POC_IORLW, popGetLit(0xe0));
6324 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6328 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6329 emitpcode(POC_ANDLW, popGetLit(0x0f));
6330 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6331 emitpcode(POC_IORLW, popGetLit(0xf0));
6332 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6336 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6338 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6339 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6341 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6342 emitpcode(POC_ANDLW, popGetLit(0x07));
6343 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6344 emitpcode(POC_IORLW, popGetLit(0xf8));
6345 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6350 emitpcode(POC_MOVLW, popGetLit(0x00));
6351 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6352 emitpcode(POC_MOVLW, popGetLit(0xfe));
6353 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6354 emitpcode(POC_IORLW, popGetLit(0x01));
6355 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6357 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6358 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6359 emitpcode(POC_DECF, popGet(AOP(result),offr));
6360 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6361 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6367 emitpcode(POC_MOVLW, popGetLit(0x00));
6368 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6369 emitpcode(POC_MOVLW, popGetLit(0xff));
6370 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6372 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6373 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6374 emitpcode(POC_DECF, popGet(AOP(result),offr));
6382 /*-----------------------------------------------------------------*/
6383 /* shiftR1Left2Result - shift right one byte from left to result */
6384 /*-----------------------------------------------------------------*/
6385 static void shiftR1Left2Result (operand *left, int offl,
6386 operand *result, int offr,
6387 int shCount, int sign)
6391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6393 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6395 /* Copy the msb into the carry if signed. */
6397 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6407 emitpcode(POC_RRF, popGet(AOP(result),offr));
6409 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6410 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416 emitpcode(POC_RRF, popGet(AOP(result),offr));
6418 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6419 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422 emitpcode(POC_RRF, popGet(AOP(result),offr));
6427 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6429 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6430 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6433 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6434 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6435 emitpcode(POC_ANDLW, popGetLit(0x1f));
6436 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6440 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6441 emitpcode(POC_ANDLW, popGetLit(0x0f));
6442 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6446 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6447 emitpcode(POC_ANDLW, popGetLit(0x0f));
6448 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6450 emitpcode(POC_RRF, popGet(AOP(result),offr));
6455 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6456 emitpcode(POC_ANDLW, popGetLit(0x80));
6457 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6458 emitpcode(POC_RLF, popGet(AOP(result),offr));
6459 emitpcode(POC_RLF, popGet(AOP(result),offr));
6464 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6465 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6466 emitpcode(POC_RLF, popGet(AOP(result),offr));
6475 /*-----------------------------------------------------------------*/
6476 /* shiftL1Left2Result - shift left one byte from left to result */
6477 /*-----------------------------------------------------------------*/
6478 static void shiftL1Left2Result (operand *left, int offl,
6479 operand *result, int offr, int shCount)
6484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6486 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6487 DEBUGpic14_emitcode ("; ***","same = %d",same);
6488 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6490 /* shift left accumulator */
6491 //AccLsh(shCount); // don't comment out just yet...
6492 // aopPut(AOP(result),"a",offr);
6496 /* Shift left 1 bit position */
6497 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6499 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6501 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6502 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6506 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6507 emitpcode(POC_ANDLW,popGetLit(0x7e));
6508 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6509 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6512 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6513 emitpcode(POC_ANDLW,popGetLit(0x3e));
6514 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6515 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6516 emitpcode(POC_RLF, popGet(AOP(result),offr));
6519 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6520 emitpcode(POC_ANDLW, popGetLit(0xf0));
6521 emitpcode(POC_MOVWF,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));
6527 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6530 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6531 emitpcode(POC_ANDLW, popGetLit(0x30));
6532 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6533 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6534 emitpcode(POC_RLF, popGet(AOP(result),offr));
6537 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6538 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6539 emitpcode(POC_RRF, popGet(AOP(result),offr));
6543 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6548 /*-----------------------------------------------------------------*/
6549 /* movLeft2Result - move byte from left to result */
6550 /*-----------------------------------------------------------------*/
6551 static void movLeft2Result (operand *left, int offl,
6552 operand *result, int offr)
6555 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6556 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6557 l = aopGet(AOP(left),offl,FALSE,FALSE);
6559 if (*l == '@' && (IS_AOP_PREG(result))) {
6560 pic14_emitcode("mov","a,%s",l);
6561 aopPut(AOP(result),"a",offr);
6563 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6564 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6569 /*-----------------------------------------------------------------*/
6570 /* shiftL2Left2Result - shift left two bytes from left to result */
6571 /*-----------------------------------------------------------------*/
6572 static void shiftL2Left2Result (operand *left, int offl,
6573 operand *result, int offr, int shCount)
6577 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6579 if(pic14_sameRegs(AOP(result), AOP(left))) {
6587 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6588 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6589 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6593 emitpcode(POC_RLF, popGet(AOP(result),offr));
6594 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6600 emitpcode(POC_MOVLW, popGetLit(0x0f));
6601 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6602 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6603 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6604 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6605 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6606 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_RLF, popGet(AOP(result),offr));
6609 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6614 emitpcode(POC_RRF, popGet(AOP(result),offr));
6615 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6616 emitpcode(POC_RRF, popGet(AOP(result),offr));
6617 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_ANDLW,popGetLit(0xc0));
6619 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6620 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6621 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6622 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6625 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6626 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6627 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6628 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6629 emitpcode(POC_RRF, popGet(AOP(result),offr));
6639 /* note, use a mov/add for the shift since the mov has a
6640 chance of getting optimized out */
6641 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6642 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6643 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6644 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6645 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_RLF, popGet(AOP(result),offr));
6650 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6656 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6657 emitpcode(POC_ANDLW, popGetLit(0xF0));
6658 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6659 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6660 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6661 emitpcode(POC_ANDLW, popGetLit(0xF0));
6662 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6663 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_RLF, popGet(AOP(result),offr));
6668 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6673 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6675 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6677 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_RRF, popGet(AOP(result),offr));
6679 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_ANDLW,popGetLit(0xc0));
6681 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6682 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6683 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6684 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6687 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6688 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6689 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6690 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6691 emitpcode(POC_RRF, popGet(AOP(result),offr));
6696 /*-----------------------------------------------------------------*/
6697 /* shiftR2Left2Result - shift right two bytes from left to result */
6698 /*-----------------------------------------------------------------*/
6699 static void shiftR2Left2Result (operand *left, int offl,
6700 operand *result, int offr,
6701 int shCount, int sign)
6705 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6706 same = pic14_sameRegs(AOP(result), AOP(left));
6708 if(same && ((offl + MSB16) == offr)){
6710 /* don't crash result[offr] */
6711 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6712 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6714 movLeft2Result(left,offl, result, offr);
6715 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6717 /* a:x >> shCount (x = lsb(result))*/
6720 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6722 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6731 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6737 emitpcode(POC_RRF,popGet(AOP(result),offr));
6739 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6740 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6742 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6747 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_RRF,popGet(AOP(result),offr));
6758 emitpcode(POC_MOVLW, popGetLit(0xf0));
6759 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6760 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6762 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6763 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6764 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6765 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6767 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6768 emitpcode(POC_ANDLW, popGetLit(0x0f));
6769 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6771 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6772 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_ANDLW, popGetLit(0xf0));
6774 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6779 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6780 emitpcode(POC_RRF, popGet(AOP(result),offr));
6784 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6785 emitpcode(POC_BTFSC,
6786 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6787 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_RLF, popGet(AOP(result),offr));
6796 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6798 emitpcode(POC_RLF, popGet(AOP(result),offr));
6799 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6801 emitpcode(POC_ANDLW,popGetLit(0x03));
6803 emitpcode(POC_BTFSC,
6804 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6805 emitpcode(POC_IORLW,popGetLit(0xfc));
6807 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6812 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6813 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6814 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6815 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6816 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_ANDLW,popGetLit(0x03));
6819 emitpcode(POC_BTFSC,
6820 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6821 emitpcode(POC_IORLW,popGetLit(0xfc));
6823 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6824 emitpcode(POC_RLF, popGet(AOP(result),offr));
6831 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6832 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6833 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6834 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6837 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6844 /*-----------------------------------------------------------------*/
6845 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6846 /*-----------------------------------------------------------------*/
6847 static void shiftLLeftOrResult (operand *left, int offl,
6848 operand *result, int offr, int shCount)
6850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6851 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6852 /* shift left accumulator */
6854 /* or with result */
6855 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6856 /* back to result */
6857 aopPut(AOP(result),"a",offr);
6860 /*-----------------------------------------------------------------*/
6861 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6862 /*-----------------------------------------------------------------*/
6863 static void shiftRLeftOrResult (operand *left, int offl,
6864 operand *result, int offr, int shCount)
6866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6867 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6868 /* shift right accumulator */
6870 /* or with result */
6871 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6872 /* back to result */
6873 aopPut(AOP(result),"a",offr);
6876 /*-----------------------------------------------------------------*/
6877 /* genlshOne - left shift a one byte quantity by known count */
6878 /*-----------------------------------------------------------------*/
6879 static void genlshOne (operand *result, operand *left, int shCount)
6881 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6882 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6885 /*-----------------------------------------------------------------*/
6886 /* genlshTwo - left shift two bytes by known amount != 0 */
6887 /*-----------------------------------------------------------------*/
6888 static void genlshTwo (operand *result,operand *left, int shCount)
6892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6893 size = pic14_getDataSize(result);
6895 /* if shCount >= 8 */
6901 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6903 movLeft2Result(left, LSB, result, MSB16);
6905 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6908 /* 1 <= shCount <= 7 */
6911 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6913 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6917 /*-----------------------------------------------------------------*/
6918 /* shiftLLong - shift left one long from left to result */
6919 /* offl = LSB or MSB16 */
6920 /*-----------------------------------------------------------------*/
6921 static void shiftLLong (operand *left, operand *result, int offr )
6924 int size = AOP_SIZE(result);
6926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 if(size >= LSB+offr){
6928 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6930 pic14_emitcode("add","a,acc");
6931 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6932 size >= MSB16+offr && offr != LSB )
6933 pic14_emitcode("xch","a,%s",
6934 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6936 aopPut(AOP(result),"a",LSB+offr);
6939 if(size >= MSB16+offr){
6940 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6941 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6944 pic14_emitcode("rlc","a");
6945 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6946 size >= MSB24+offr && offr != LSB)
6947 pic14_emitcode("xch","a,%s",
6948 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6950 aopPut(AOP(result),"a",MSB16+offr);
6953 if(size >= MSB24+offr){
6954 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6955 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6958 pic14_emitcode("rlc","a");
6959 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6960 size >= MSB32+offr && offr != LSB )
6961 pic14_emitcode("xch","a,%s",
6962 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6964 aopPut(AOP(result),"a",MSB24+offr);
6967 if(size > MSB32+offr){
6968 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6969 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6972 pic14_emitcode("rlc","a");
6973 aopPut(AOP(result),"a",MSB32+offr);
6976 aopPut(AOP(result),zero,LSB);
6979 /*-----------------------------------------------------------------*/
6980 /* genlshFour - shift four byte by a known amount != 0 */
6981 /*-----------------------------------------------------------------*/
6982 static void genlshFour (operand *result, operand *left, int shCount)
6986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 size = AOP_SIZE(result);
6989 /* if shifting more that 3 bytes */
6990 if (shCount >= 24 ) {
6993 /* lowest order of left goes to the highest
6994 order of the destination */
6995 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6997 movLeft2Result(left, LSB, result, MSB32);
6998 aopPut(AOP(result),zero,LSB);
6999 aopPut(AOP(result),zero,MSB16);
7000 aopPut(AOP(result),zero,MSB32);
7004 /* more than two bytes */
7005 else if ( shCount >= 16 ) {
7006 /* lower order two bytes goes to higher order two bytes */
7008 /* if some more remaining */
7010 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7012 movLeft2Result(left, MSB16, result, MSB32);
7013 movLeft2Result(left, LSB, result, MSB24);
7015 aopPut(AOP(result),zero,MSB16);
7016 aopPut(AOP(result),zero,LSB);
7020 /* if more than 1 byte */
7021 else if ( shCount >= 8 ) {
7022 /* lower order three bytes goes to higher order three bytes */
7026 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7028 movLeft2Result(left, LSB, result, MSB16);
7030 else{ /* size = 4 */
7032 movLeft2Result(left, MSB24, result, MSB32);
7033 movLeft2Result(left, MSB16, result, MSB24);
7034 movLeft2Result(left, LSB, result, MSB16);
7035 aopPut(AOP(result),zero,LSB);
7037 else if(shCount == 1)
7038 shiftLLong(left, result, MSB16);
7040 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7041 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7042 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7043 aopPut(AOP(result),zero,LSB);
7048 /* 1 <= shCount <= 7 */
7049 else if(shCount <= 2){
7050 shiftLLong(left, result, LSB);
7052 shiftLLong(result, result, LSB);
7054 /* 3 <= shCount <= 7, optimize */
7056 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7057 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7058 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7062 /*-----------------------------------------------------------------*/
7063 /* genLeftShiftLiteral - left shifting by known count */
7064 /*-----------------------------------------------------------------*/
7065 static void genLeftShiftLiteral (operand *left,
7070 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7074 freeAsmop(right,NULL,ic,TRUE);
7076 aopOp(left,ic,FALSE);
7077 aopOp(result,ic,FALSE);
7079 size = getSize(operandType(result));
7082 pic14_emitcode("; shift left ","result %d, left %d",size,
7086 /* I suppose that the left size >= result size */
7089 movLeft2Result(left, size, result, size);
7093 else if(shCount >= (size * 8))
7095 aopPut(AOP(result),zero,size);
7099 genlshOne (result,left,shCount);
7104 genlshTwo (result,left,shCount);
7108 genlshFour (result,left,shCount);
7112 freeAsmop(left,NULL,ic,TRUE);
7113 freeAsmop(result,NULL,ic,TRUE);
7116 /*-----------------------------------------------------------------*
7117 * genMultiAsm - repeat assembly instruction for size of register.
7118 * if endian == 1, then the high byte (i.e base address + size of
7119 * register) is used first else the low byte is used first;
7120 *-----------------------------------------------------------------*/
7121 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7139 emitpcode(poc, popGet(AOP(reg),offset));
7144 /*-----------------------------------------------------------------*/
7145 /* genLeftShift - generates code for left shifting */
7146 /*-----------------------------------------------------------------*/
7147 static void genLeftShift (iCode *ic)
7149 operand *left,*right, *result;
7152 symbol *tlbl , *tlbl1;
7155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7157 right = IC_RIGHT(ic);
7159 result = IC_RESULT(ic);
7161 aopOp(right,ic,FALSE);
7163 /* if the shift count is known then do it
7164 as efficiently as possible */
7165 if (AOP_TYPE(right) == AOP_LIT) {
7166 genLeftShiftLiteral (left,right,result,ic);
7170 /* shift count is unknown then we have to form
7171 a loop get the loop count in B : Note: we take
7172 only the lower order byte since shifting
7173 more that 32 bits make no sense anyway, ( the
7174 largest size of an object can be only 32 bits ) */
7177 aopOp(left,ic,FALSE);
7178 aopOp(result,ic,FALSE);
7180 /* now move the left to the result if they are not the
7182 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7183 AOP_SIZE(result) > 1) {
7185 size = AOP_SIZE(result);
7188 l = aopGet(AOP(left),offset,FALSE,TRUE);
7189 if (*l == '@' && (IS_AOP_PREG(result))) {
7191 pic14_emitcode("mov","a,%s",l);
7192 aopPut(AOP(result),"a",offset);
7194 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7195 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7196 //aopPut(AOP(result),l,offset);
7202 size = AOP_SIZE(result);
7204 /* if it is only one byte then */
7206 if(optimized_for_speed) {
7207 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7208 emitpcode(POC_ANDLW, popGetLit(0xf0));
7209 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7210 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7211 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7212 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7213 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7214 emitpcode(POC_RLFW, popGet(AOP(result),0));
7215 emitpcode(POC_ANDLW, popGetLit(0xfe));
7216 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7217 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7218 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7221 tlbl = newiTempLabel(NULL);
7222 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7223 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7224 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7227 emitpcode(POC_COMFW, popGet(AOP(right),0));
7228 emitpcode(POC_RRF, popGet(AOP(result),0));
7229 emitpLabel(tlbl->key);
7230 emitpcode(POC_RLF, popGet(AOP(result),0));
7231 emitpcode(POC_ADDLW, popGetLit(1));
7233 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7238 if (pic14_sameRegs(AOP(left),AOP(result))) {
7240 tlbl = newiTempLabel(NULL);
7241 emitpcode(POC_COMFW, popGet(AOP(right),0));
7242 genMultiAsm(POC_RRF, result, size,1);
7243 emitpLabel(tlbl->key);
7244 genMultiAsm(POC_RLF, result, size,0);
7245 emitpcode(POC_ADDLW, popGetLit(1));
7247 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7251 //tlbl = newiTempLabel(NULL);
7253 //tlbl1 = newiTempLabel(NULL);
7255 //reAdjustPreg(AOP(result));
7257 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7258 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7259 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7261 //pic14_emitcode("add","a,acc");
7262 //aopPut(AOP(result),"a",offset++);
7264 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7266 // pic14_emitcode("rlc","a");
7267 // aopPut(AOP(result),"a",offset++);
7269 //reAdjustPreg(AOP(result));
7271 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7272 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7275 tlbl = newiTempLabel(NULL);
7276 tlbl1= newiTempLabel(NULL);
7278 size = AOP_SIZE(result);
7281 pctemp = popGetTempReg(); /* grab a temporary working register. */
7283 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7285 /* offset should be 0, 1 or 3 */
7286 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7288 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7290 emitpcode(POC_MOVWF, pctemp);
7293 emitpLabel(tlbl->key);
7296 emitpcode(POC_RLF, popGet(AOP(result),0));
7298 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7300 emitpcode(POC_DECFSZ, pctemp);
7301 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7302 emitpLabel(tlbl1->key);
7304 popReleaseTempReg(pctemp);
7308 freeAsmop (right,NULL,ic,TRUE);
7309 freeAsmop(left,NULL,ic,TRUE);
7310 freeAsmop(result,NULL,ic,TRUE);
7313 /*-----------------------------------------------------------------*/
7314 /* genrshOne - right shift a one byte quantity by known count */
7315 /*-----------------------------------------------------------------*/
7316 static void genrshOne (operand *result, operand *left,
7317 int shCount, int sign)
7319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7320 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7323 /*-----------------------------------------------------------------*/
7324 /* genrshTwo - right shift two bytes by known amount != 0 */
7325 /*-----------------------------------------------------------------*/
7326 static void genrshTwo (operand *result,operand *left,
7327 int shCount, int sign)
7329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7330 /* if shCount >= 8 */
7334 shiftR1Left2Result(left, MSB16, result, LSB,
7337 movLeft2Result(left, MSB16, result, LSB);
7339 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7342 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7343 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7347 /* 1 <= shCount <= 7 */
7349 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7352 /*-----------------------------------------------------------------*/
7353 /* shiftRLong - shift right one long from left to result */
7354 /* offl = LSB or MSB16 */
7355 /*-----------------------------------------------------------------*/
7356 static void shiftRLong (operand *left, int offl,
7357 operand *result, int sign)
7359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7361 pic14_emitcode("clr","c");
7362 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7364 pic14_emitcode("mov","c,acc.7");
7365 pic14_emitcode("rrc","a");
7366 aopPut(AOP(result),"a",MSB32-offl);
7368 /* add sign of "a" */
7369 addSign(result, MSB32, sign);
7371 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7372 pic14_emitcode("rrc","a");
7373 aopPut(AOP(result),"a",MSB24-offl);
7375 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7376 pic14_emitcode("rrc","a");
7377 aopPut(AOP(result),"a",MSB16-offl);
7380 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7381 pic14_emitcode("rrc","a");
7382 aopPut(AOP(result),"a",LSB);
7386 /*-----------------------------------------------------------------*/
7387 /* genrshFour - shift four byte by a known amount != 0 */
7388 /*-----------------------------------------------------------------*/
7389 static void genrshFour (operand *result, operand *left,
7390 int shCount, int sign)
7392 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7393 /* if shifting more that 3 bytes */
7394 if(shCount >= 24 ) {
7397 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7399 movLeft2Result(left, MSB32, result, LSB);
7401 addSign(result, MSB16, sign);
7403 else if(shCount >= 16){
7406 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7408 movLeft2Result(left, MSB24, result, LSB);
7409 movLeft2Result(left, MSB32, result, MSB16);
7411 addSign(result, MSB24, sign);
7413 else if(shCount >= 8){
7416 shiftRLong(left, MSB16, result, sign);
7417 else if(shCount == 0){
7418 movLeft2Result(left, MSB16, result, LSB);
7419 movLeft2Result(left, MSB24, result, MSB16);
7420 movLeft2Result(left, MSB32, result, MSB24);
7421 addSign(result, MSB32, sign);
7424 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7425 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7426 /* the last shift is signed */
7427 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7428 addSign(result, MSB32, sign);
7431 else{ /* 1 <= shCount <= 7 */
7433 shiftRLong(left, LSB, result, sign);
7435 shiftRLong(result, LSB, result, sign);
7438 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7439 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7440 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7445 /*-----------------------------------------------------------------*/
7446 /* genRightShiftLiteral - right shifting by known count */
7447 /*-----------------------------------------------------------------*/
7448 static void genRightShiftLiteral (operand *left,
7454 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7458 freeAsmop(right,NULL,ic,TRUE);
7460 aopOp(left,ic,FALSE);
7461 aopOp(result,ic,FALSE);
7464 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7468 lsize = pic14_getDataSize(left);
7469 res_size = pic14_getDataSize(result);
7470 /* test the LEFT size !!! */
7472 /* I suppose that the left size >= result size */
7475 movLeft2Result(left, lsize, result, res_size);
7478 else if(shCount >= (lsize * 8)){
7481 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7483 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7484 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7489 emitpcode(POC_MOVLW, popGetLit(0));
7490 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7491 emitpcode(POC_MOVLW, popGetLit(0xff));
7493 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7498 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7505 genrshOne (result,left,shCount,sign);
7509 genrshTwo (result,left,shCount,sign);
7513 genrshFour (result,left,shCount,sign);
7521 freeAsmop(left,NULL,ic,TRUE);
7522 freeAsmop(result,NULL,ic,TRUE);
7525 /*-----------------------------------------------------------------*/
7526 /* genSignedRightShift - right shift of signed number */
7527 /*-----------------------------------------------------------------*/
7528 static void genSignedRightShift (iCode *ic)
7530 operand *right, *left, *result;
7533 symbol *tlbl, *tlbl1 ;
7536 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7538 /* we do it the hard way put the shift count in b
7539 and loop thru preserving the sign */
7540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7542 right = IC_RIGHT(ic);
7544 result = IC_RESULT(ic);
7546 aopOp(right,ic,FALSE);
7547 aopOp(left,ic,FALSE);
7548 aopOp(result,ic,FALSE);
7551 if ( AOP_TYPE(right) == AOP_LIT) {
7552 genRightShiftLiteral (left,right,result,ic,1);
7555 /* shift count is unknown then we have to form
7556 a loop get the loop count in B : Note: we take
7557 only the lower order byte since shifting
7558 more that 32 bits make no sense anyway, ( the
7559 largest size of an object can be only 32 bits ) */
7561 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7562 //pic14_emitcode("inc","b");
7563 //freeAsmop (right,NULL,ic,TRUE);
7564 //aopOp(left,ic,FALSE);
7565 //aopOp(result,ic,FALSE);
7567 /* now move the left to the result if they are not the
7569 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7570 AOP_SIZE(result) > 1) {
7572 size = AOP_SIZE(result);
7576 l = aopGet(AOP(left),offset,FALSE,TRUE);
7577 if (*l == '@' && IS_AOP_PREG(result)) {
7579 pic14_emitcode("mov","a,%s",l);
7580 aopPut(AOP(result),"a",offset);
7582 aopPut(AOP(result),l,offset);
7584 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7585 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7591 /* mov the highest order bit to OVR */
7592 tlbl = newiTempLabel(NULL);
7593 tlbl1= newiTempLabel(NULL);
7595 size = AOP_SIZE(result);
7598 pctemp = popGetTempReg(); /* grab a temporary working register. */
7600 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7602 /* offset should be 0, 1 or 3 */
7603 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7605 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7607 emitpcode(POC_MOVWF, pctemp);
7610 emitpLabel(tlbl->key);
7612 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7613 emitpcode(POC_RRF, popGet(AOP(result),offset));
7616 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7619 emitpcode(POC_DECFSZ, pctemp);
7620 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7621 emitpLabel(tlbl1->key);
7623 popReleaseTempReg(pctemp);
7625 size = AOP_SIZE(result);
7627 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7628 pic14_emitcode("rlc","a");
7629 pic14_emitcode("mov","ov,c");
7630 /* if it is only one byte then */
7632 l = aopGet(AOP(left),0,FALSE,FALSE);
7634 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7635 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7636 pic14_emitcode("mov","c,ov");
7637 pic14_emitcode("rrc","a");
7638 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7639 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7640 aopPut(AOP(result),"a",0);
7644 reAdjustPreg(AOP(result));
7645 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7646 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7647 pic14_emitcode("mov","c,ov");
7649 l = aopGet(AOP(result),offset,FALSE,FALSE);
7651 pic14_emitcode("rrc","a");
7652 aopPut(AOP(result),"a",offset--);
7654 reAdjustPreg(AOP(result));
7655 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7656 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7661 freeAsmop(left,NULL,ic,TRUE);
7662 freeAsmop(result,NULL,ic,TRUE);
7663 freeAsmop(right,NULL,ic,TRUE);
7666 /*-----------------------------------------------------------------*/
7667 /* genRightShift - generate code for right shifting */
7668 /*-----------------------------------------------------------------*/
7669 static void genRightShift (iCode *ic)
7671 operand *right, *left, *result;
7675 symbol *tlbl, *tlbl1 ;
7677 /* if signed then we do it the hard way preserve the
7678 sign bit moving it inwards */
7679 retype = getSpec(operandType(IC_RESULT(ic)));
7680 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7682 if (!SPEC_USIGN(retype)) {
7683 genSignedRightShift (ic);
7687 /* signed & unsigned types are treated the same : i.e. the
7688 signed is NOT propagated inwards : quoting from the
7689 ANSI - standard : "for E1 >> E2, is equivalent to division
7690 by 2**E2 if unsigned or if it has a non-negative value,
7691 otherwise the result is implementation defined ", MY definition
7692 is that the sign does not get propagated */
7694 right = IC_RIGHT(ic);
7696 result = IC_RESULT(ic);
7698 aopOp(right,ic,FALSE);
7700 /* if the shift count is known then do it
7701 as efficiently as possible */
7702 if (AOP_TYPE(right) == AOP_LIT) {
7703 genRightShiftLiteral (left,right,result,ic, 0);
7707 /* shift count is unknown then we have to form
7708 a loop get the loop count in B : Note: we take
7709 only the lower order byte since shifting
7710 more that 32 bits make no sense anyway, ( the
7711 largest size of an object can be only 32 bits ) */
7713 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7714 pic14_emitcode("inc","b");
7715 aopOp(left,ic,FALSE);
7716 aopOp(result,ic,FALSE);
7718 /* now move the left to the result if they are not the
7720 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7721 AOP_SIZE(result) > 1) {
7723 size = AOP_SIZE(result);
7726 l = aopGet(AOP(left),offset,FALSE,TRUE);
7727 if (*l == '@' && IS_AOP_PREG(result)) {
7729 pic14_emitcode("mov","a,%s",l);
7730 aopPut(AOP(result),"a",offset);
7732 aopPut(AOP(result),l,offset);
7737 tlbl = newiTempLabel(NULL);
7738 tlbl1= newiTempLabel(NULL);
7739 size = AOP_SIZE(result);
7742 /* if it is only one byte then */
7745 tlbl = newiTempLabel(NULL);
7746 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7747 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7748 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7751 emitpcode(POC_COMFW, popGet(AOP(right),0));
7752 emitpcode(POC_RLF, popGet(AOP(result),0));
7753 emitpLabel(tlbl->key);
7754 emitpcode(POC_RRF, popGet(AOP(result),0));
7755 emitpcode(POC_ADDLW, popGetLit(1));
7757 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7762 reAdjustPreg(AOP(result));
7763 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7764 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7767 l = aopGet(AOP(result),offset,FALSE,FALSE);
7769 pic14_emitcode("rrc","a");
7770 aopPut(AOP(result),"a",offset--);
7772 reAdjustPreg(AOP(result));
7774 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7775 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7778 freeAsmop(left,NULL,ic,TRUE);
7779 freeAsmop (right,NULL,ic,TRUE);
7780 freeAsmop(result,NULL,ic,TRUE);
7783 /*-----------------------------------------------------------------*/
7784 /* genUnpackBits - generates code for unpacking bits */
7785 /*-----------------------------------------------------------------*/
7786 static void genUnpackBits (operand *result, char *rname, int ptype)
7793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7794 etype = getSpec(operandType(result));
7796 /* read the first byte */
7801 pic14_emitcode("mov","a,@%s",rname);
7805 pic14_emitcode("movx","a,@%s",rname);
7809 pic14_emitcode("movx","a,@dptr");
7813 pic14_emitcode("clr","a");
7814 pic14_emitcode("movc","a","@a+dptr");
7818 pic14_emitcode("lcall","__gptrget");
7822 /* if we have bitdisplacement then it fits */
7823 /* into this byte completely or if length is */
7824 /* less than a byte */
7825 if ((shCnt = SPEC_BSTR(etype)) ||
7826 (SPEC_BLEN(etype) <= 8)) {
7828 /* shift right acc */
7831 pic14_emitcode("anl","a,#0x%02x",
7832 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7833 aopPut(AOP(result),"a",offset);
7837 /* bit field did not fit in a byte */
7838 rlen = SPEC_BLEN(etype) - 8;
7839 aopPut(AOP(result),"a",offset++);
7846 pic14_emitcode("inc","%s",rname);
7847 pic14_emitcode("mov","a,@%s",rname);
7851 pic14_emitcode("inc","%s",rname);
7852 pic14_emitcode("movx","a,@%s",rname);
7856 pic14_emitcode("inc","dptr");
7857 pic14_emitcode("movx","a,@dptr");
7861 pic14_emitcode("clr","a");
7862 pic14_emitcode("inc","dptr");
7863 pic14_emitcode("movc","a","@a+dptr");
7867 pic14_emitcode("inc","dptr");
7868 pic14_emitcode("lcall","__gptrget");
7873 /* if we are done */
7877 aopPut(AOP(result),"a",offset++);
7882 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7883 aopPut(AOP(result),"a",offset);
7890 /*-----------------------------------------------------------------*/
7891 /* genDataPointerGet - generates code when ptr offset is known */
7892 /*-----------------------------------------------------------------*/
7893 static void genDataPointerGet (operand *left,
7897 int size , offset = 0;
7900 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7903 /* optimization - most of the time, left and result are the same
7904 * address, but different types. for the pic code, we could omit
7908 aopOp(result,ic,TRUE);
7910 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7912 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7914 size = AOP_SIZE(result);
7917 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7921 freeAsmop(left,NULL,ic,TRUE);
7922 freeAsmop(result,NULL,ic,TRUE);
7925 /*-----------------------------------------------------------------*/
7926 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7927 /*-----------------------------------------------------------------*/
7928 static void genNearPointerGet (operand *left,
7935 sym_link *rtype, *retype;
7936 sym_link *ltype = operandType(left);
7939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7941 rtype = operandType(result);
7942 retype= getSpec(rtype);
7944 aopOp(left,ic,FALSE);
7946 /* if left is rematerialisable and
7947 result is not bit variable type and
7948 the left is pointer to data space i.e
7949 lower 128 bytes of space */
7950 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7951 !IS_BITVAR(retype) &&
7952 DCL_TYPE(ltype) == POINTER) {
7953 //genDataPointerGet (left,result,ic);
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7959 /* if the value is already in a pointer register
7960 then don't need anything more */
7961 if (!AOP_INPREG(AOP(left))) {
7962 /* otherwise get a free pointer register */
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 preg = getFreePtr(ic,&aop,FALSE);
7967 pic14_emitcode("mov","%s,%s",
7969 aopGet(AOP(left),0,FALSE,TRUE));
7970 rname = preg->name ;
7974 rname = aopGet(AOP(left),0,FALSE,FALSE);
7976 aopOp (result,ic,FALSE);
7978 /* if bitfield then unpack the bits */
7979 if (IS_BITVAR(retype))
7980 genUnpackBits (result,rname,POINTER);
7982 /* we have can just get the values */
7983 int size = AOP_SIZE(result);
7986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7988 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7989 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7991 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7992 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7994 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7998 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8000 pic14_emitcode("mov","a,@%s",rname);
8001 aopPut(AOP(result),"a",offset);
8003 sprintf(buffer,"@%s",rname);
8004 aopPut(AOP(result),buffer,offset);
8008 pic14_emitcode("inc","%s",rname);
8013 /* now some housekeeping stuff */
8015 /* we had to allocate for this iCode */
8016 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8017 freeAsmop(NULL,aop,ic,TRUE);
8019 /* we did not allocate which means left
8020 already in a pointer register, then
8021 if size > 0 && this could be used again
8022 we have to point it back to where it
8024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8025 if (AOP_SIZE(result) > 1 &&
8026 !OP_SYMBOL(left)->remat &&
8027 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8029 int size = AOP_SIZE(result) - 1;
8031 pic14_emitcode("dec","%s",rname);
8036 freeAsmop(left,NULL,ic,TRUE);
8037 freeAsmop(result,NULL,ic,TRUE);
8041 /*-----------------------------------------------------------------*/
8042 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8043 /*-----------------------------------------------------------------*/
8044 static void genPagedPointerGet (operand *left,
8051 sym_link *rtype, *retype;
8053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8055 rtype = operandType(result);
8056 retype= getSpec(rtype);
8058 aopOp(left,ic,FALSE);
8060 /* if the value is already in a pointer register
8061 then don't need anything more */
8062 if (!AOP_INPREG(AOP(left))) {
8063 /* otherwise get a free pointer register */
8065 preg = getFreePtr(ic,&aop,FALSE);
8066 pic14_emitcode("mov","%s,%s",
8068 aopGet(AOP(left),0,FALSE,TRUE));
8069 rname = preg->name ;
8071 rname = aopGet(AOP(left),0,FALSE,FALSE);
8073 freeAsmop(left,NULL,ic,TRUE);
8074 aopOp (result,ic,FALSE);
8076 /* if bitfield then unpack the bits */
8077 if (IS_BITVAR(retype))
8078 genUnpackBits (result,rname,PPOINTER);
8080 /* we have can just get the values */
8081 int size = AOP_SIZE(result);
8086 pic14_emitcode("movx","a,@%s",rname);
8087 aopPut(AOP(result),"a",offset);
8092 pic14_emitcode("inc","%s",rname);
8096 /* now some housekeeping stuff */
8098 /* we had to allocate for this iCode */
8099 freeAsmop(NULL,aop,ic,TRUE);
8101 /* we did not allocate which means left
8102 already in a pointer register, then
8103 if size > 0 && this could be used again
8104 we have to point it back to where it
8106 if (AOP_SIZE(result) > 1 &&
8107 !OP_SYMBOL(left)->remat &&
8108 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8110 int size = AOP_SIZE(result) - 1;
8112 pic14_emitcode("dec","%s",rname);
8117 freeAsmop(result,NULL,ic,TRUE);
8122 /*-----------------------------------------------------------------*/
8123 /* genFarPointerGet - gget value from far space */
8124 /*-----------------------------------------------------------------*/
8125 static void genFarPointerGet (operand *left,
8126 operand *result, iCode *ic)
8129 sym_link *retype = getSpec(operandType(result));
8131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8133 aopOp(left,ic,FALSE);
8135 /* if the operand is already in dptr
8136 then we do nothing else we move the value to dptr */
8137 if (AOP_TYPE(left) != AOP_STR) {
8138 /* if this is remateriazable */
8139 if (AOP_TYPE(left) == AOP_IMMD)
8140 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8141 else { /* we need to get it byte by byte */
8142 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8143 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8144 if (options.model == MODEL_FLAT24)
8146 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8150 /* so dptr know contains the address */
8151 freeAsmop(left,NULL,ic,TRUE);
8152 aopOp(result,ic,FALSE);
8154 /* if bit then unpack */
8155 if (IS_BITVAR(retype))
8156 genUnpackBits(result,"dptr",FPOINTER);
8158 size = AOP_SIZE(result);
8162 pic14_emitcode("movx","a,@dptr");
8163 aopPut(AOP(result),"a",offset++);
8165 pic14_emitcode("inc","dptr");
8169 freeAsmop(result,NULL,ic,TRUE);
8172 /*-----------------------------------------------------------------*/
8173 /* genCodePointerGet - get value from code space */
8174 /*-----------------------------------------------------------------*/
8175 static void genCodePointerGet (operand *left,
8176 operand *result, iCode *ic)
8179 sym_link *retype = getSpec(operandType(result));
8181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8183 aopOp(left,ic,FALSE);
8185 /* if the operand is already in dptr
8186 then we do nothing else we move the value to dptr */
8187 if (AOP_TYPE(left) != AOP_STR) {
8188 /* if this is remateriazable */
8189 if (AOP_TYPE(left) == AOP_IMMD)
8190 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8191 else { /* we need to get it byte by byte */
8192 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8193 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8194 if (options.model == MODEL_FLAT24)
8196 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8200 /* so dptr know contains the address */
8201 freeAsmop(left,NULL,ic,TRUE);
8202 aopOp(result,ic,FALSE);
8204 /* if bit then unpack */
8205 if (IS_BITVAR(retype))
8206 genUnpackBits(result,"dptr",CPOINTER);
8208 size = AOP_SIZE(result);
8212 pic14_emitcode("clr","a");
8213 pic14_emitcode("movc","a,@a+dptr");
8214 aopPut(AOP(result),"a",offset++);
8216 pic14_emitcode("inc","dptr");
8220 freeAsmop(result,NULL,ic,TRUE);
8223 /*-----------------------------------------------------------------*/
8224 /* genGenPointerGet - gget value from generic pointer space */
8225 /*-----------------------------------------------------------------*/
8226 static void genGenPointerGet (operand *left,
8227 operand *result, iCode *ic)
8230 sym_link *retype = getSpec(operandType(result));
8232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8233 aopOp(left,ic,FALSE);
8234 aopOp(result,ic,FALSE);
8237 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8239 /* if the operand is already in dptr
8240 then we do nothing else we move the value to dptr */
8241 // if (AOP_TYPE(left) != AOP_STR) {
8242 /* if this is remateriazable */
8243 if (AOP_TYPE(left) == AOP_IMMD) {
8244 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8245 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8247 else { /* we need to get it byte by byte */
8249 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8250 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8252 size = AOP_SIZE(result);
8256 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8257 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8259 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8264 /* so dptr know contains the address */
8266 /* if bit then unpack */
8267 //if (IS_BITVAR(retype))
8268 // genUnpackBits(result,"dptr",GPOINTER);
8271 freeAsmop(left,NULL,ic,TRUE);
8272 freeAsmop(result,NULL,ic,TRUE);
8276 /*-----------------------------------------------------------------*/
8277 /* genConstPointerGet - get value from const generic pointer space */
8278 /*-----------------------------------------------------------------*/
8279 static void genConstPointerGet (operand *left,
8280 operand *result, iCode *ic)
8282 //sym_link *retype = getSpec(operandType(result));
8283 symbol *albl = newiTempLabel(NULL);
8284 symbol *blbl = newiTempLabel(NULL);
8287 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8288 aopOp(left,ic,FALSE);
8289 aopOp(result,ic,FALSE);
8292 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8294 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8296 emitpcode(POC_CALL,popGetLabel(albl->key));
8297 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8298 emitpLabel(albl->key);
8300 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8302 emitpcode(poc,popGet(AOP(left),1));
8303 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8304 emitpcode(poc,popGet(AOP(left),0));
8305 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8307 emitpLabel(blbl->key);
8309 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8312 freeAsmop(left,NULL,ic,TRUE);
8313 freeAsmop(result,NULL,ic,TRUE);
8316 /*-----------------------------------------------------------------*/
8317 /* genPointerGet - generate code for pointer get */
8318 /*-----------------------------------------------------------------*/
8319 static void genPointerGet (iCode *ic)
8321 operand *left, *result ;
8322 sym_link *type, *etype;
8325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8328 result = IC_RESULT(ic) ;
8330 /* depending on the type of pointer we need to
8331 move it to the correct pointer register */
8332 type = operandType(left);
8333 etype = getSpec(type);
8335 if (IS_PTR_CONST(type))
8336 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8338 /* if left is of type of pointer then it is simple */
8339 if (IS_PTR(type) && !IS_FUNC(type->next))
8340 p_type = DCL_TYPE(type);
8342 /* we have to go by the storage class */
8343 p_type = PTR_TYPE(SPEC_OCLS(etype));
8345 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8347 if (SPEC_OCLS(etype)->codesp ) {
8348 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8349 //p_type = CPOINTER ;
8352 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8353 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8354 /*p_type = FPOINTER ;*/
8356 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8357 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8358 /* p_type = PPOINTER; */
8360 if (SPEC_OCLS(etype) == idata )
8361 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8362 /* p_type = IPOINTER; */
8364 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8365 /* p_type = POINTER ; */
8368 /* now that we have the pointer type we assign
8369 the pointer values */
8374 genNearPointerGet (left,result,ic);
8378 genPagedPointerGet(left,result,ic);
8382 genFarPointerGet (left,result,ic);
8386 genConstPointerGet (left,result,ic);
8387 //pic14_emitcodePointerGet (left,result,ic);
8391 if (IS_PTR_CONST(type))
8392 genConstPointerGet (left,result,ic);
8394 genGenPointerGet (left,result,ic);
8400 /*-----------------------------------------------------------------*/
8401 /* genPackBits - generates code for packed bit storage */
8402 /*-----------------------------------------------------------------*/
8403 static void genPackBits (sym_link *etype ,
8405 char *rname, int p_type)
8413 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8414 blen = SPEC_BLEN(etype);
8415 bstr = SPEC_BSTR(etype);
8417 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8420 /* if the bit lenth is less than or */
8421 /* it exactly fits a byte then */
8422 if (SPEC_BLEN(etype) <= 8 ) {
8423 shCount = SPEC_BSTR(etype) ;
8425 /* shift left acc */
8428 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8433 pic14_emitcode ("mov","b,a");
8434 pic14_emitcode("mov","a,@%s",rname);
8438 pic14_emitcode ("mov","b,a");
8439 pic14_emitcode("movx","a,@dptr");
8443 pic14_emitcode ("push","b");
8444 pic14_emitcode ("push","acc");
8445 pic14_emitcode ("lcall","__gptrget");
8446 pic14_emitcode ("pop","b");
8450 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8451 ((unsigned char)(0xFF << (blen+bstr)) |
8452 (unsigned char)(0xFF >> (8-bstr)) ) );
8453 pic14_emitcode ("orl","a,b");
8454 if (p_type == GPOINTER)
8455 pic14_emitcode("pop","b");
8461 pic14_emitcode("mov","@%s,a",rname);
8465 pic14_emitcode("movx","@dptr,a");
8469 DEBUGpic14_emitcode(";lcall","__gptrput");
8474 if ( SPEC_BLEN(etype) <= 8 )
8477 pic14_emitcode("inc","%s",rname);
8478 rLen = SPEC_BLEN(etype) ;
8480 /* now generate for lengths greater than one byte */
8483 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8493 pic14_emitcode("mov","@%s,a",rname);
8495 pic14_emitcode("mov","@%s,%s",rname,l);
8500 pic14_emitcode("movx","@dptr,a");
8505 DEBUGpic14_emitcode(";lcall","__gptrput");
8508 pic14_emitcode ("inc","%s",rname);
8513 /* last last was not complete */
8515 /* save the byte & read byte */
8518 pic14_emitcode ("mov","b,a");
8519 pic14_emitcode("mov","a,@%s",rname);
8523 pic14_emitcode ("mov","b,a");
8524 pic14_emitcode("movx","a,@dptr");
8528 pic14_emitcode ("push","b");
8529 pic14_emitcode ("push","acc");
8530 pic14_emitcode ("lcall","__gptrget");
8531 pic14_emitcode ("pop","b");
8535 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8536 pic14_emitcode ("orl","a,b");
8539 if (p_type == GPOINTER)
8540 pic14_emitcode("pop","b");
8545 pic14_emitcode("mov","@%s,a",rname);
8549 pic14_emitcode("movx","@dptr,a");
8553 DEBUGpic14_emitcode(";lcall","__gptrput");
8557 /*-----------------------------------------------------------------*/
8558 /* genDataPointerSet - remat pointer to data space */
8559 /*-----------------------------------------------------------------*/
8560 static void genDataPointerSet(operand *right,
8564 int size, offset = 0 ;
8565 char *l, buffer[256];
8567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8568 aopOp(right,ic,FALSE);
8570 l = aopGet(AOP(result),0,FALSE,TRUE);
8571 size = AOP_SIZE(right);
8573 if ( AOP_TYPE(result) == AOP_PCODE) {
8574 fprintf(stderr,"genDataPointerSet %s, %d\n",
8575 AOP(result)->aopu.pcop->name,
8576 PCOI(AOP(result)->aopu.pcop)->offset);
8580 // tsd, was l+1 - the underline `_' prefix was being stripped
8583 sprintf(buffer,"(%s + %d)",l,offset);
8584 fprintf(stderr,"oops %s\n",buffer);
8586 sprintf(buffer,"%s",l);
8588 if (AOP_TYPE(right) == AOP_LIT) {
8589 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8590 lit = lit >> (8*offset);
8592 pic14_emitcode("movlw","%d",lit);
8593 pic14_emitcode("movwf","%s",buffer);
8595 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8596 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8597 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8600 pic14_emitcode("clrf","%s",buffer);
8601 //emitpcode(POC_CLRF, popRegFromString(buffer));
8602 emitpcode(POC_CLRF, popGet(AOP(result),0));
8605 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8606 pic14_emitcode("movwf","%s",buffer);
8608 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8609 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8610 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8617 freeAsmop(right,NULL,ic,TRUE);
8618 freeAsmop(result,NULL,ic,TRUE);
8621 /*-----------------------------------------------------------------*/
8622 /* genNearPointerSet - pic14_emitcode for near pointer put */
8623 /*-----------------------------------------------------------------*/
8624 static void genNearPointerSet (operand *right,
8631 sym_link *ptype = operandType(result);
8634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8635 retype= getSpec(operandType(right));
8637 aopOp(result,ic,FALSE);
8640 /* if the result is rematerializable &
8641 in data space & not a bit variable */
8642 //if (AOP_TYPE(result) == AOP_IMMD &&
8643 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8644 DCL_TYPE(ptype) == POINTER &&
8645 !IS_BITVAR(retype)) {
8646 genDataPointerSet (right,result,ic);
8647 freeAsmop(result,NULL,ic,TRUE);
8651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8652 aopOp(right,ic,FALSE);
8653 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8655 /* if the value is already in a pointer register
8656 then don't need anything more */
8657 if (!AOP_INPREG(AOP(result))) {
8658 /* otherwise get a free pointer register */
8659 //aop = newAsmop(0);
8660 //preg = getFreePtr(ic,&aop,FALSE);
8661 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8662 //pic14_emitcode("mov","%s,%s",
8664 // aopGet(AOP(result),0,FALSE,TRUE));
8665 //rname = preg->name ;
8666 //pic14_emitcode("movwf","fsr");
8667 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8668 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8669 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8670 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8674 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8677 /* if bitfield then unpack the bits */
8678 if (IS_BITVAR(retype)) {
8679 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8680 "The programmer is obviously confused");
8681 //genPackBits (retype,right,rname,POINTER);
8685 /* we have can just get the values */
8686 int size = AOP_SIZE(right);
8689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8691 l = aopGet(AOP(right),offset,FALSE,TRUE);
8694 //pic14_emitcode("mov","@%s,a",rname);
8695 pic14_emitcode("movf","indf,w ;1");
8698 if (AOP_TYPE(right) == AOP_LIT) {
8699 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8701 pic14_emitcode("movlw","%s",l);
8702 pic14_emitcode("movwf","indf ;2");
8704 pic14_emitcode("clrf","indf");
8706 pic14_emitcode("movf","%s,w",l);
8707 pic14_emitcode("movwf","indf ;2");
8709 //pic14_emitcode("mov","@%s,%s",rname,l);
8712 pic14_emitcode("incf","fsr,f ;3");
8713 //pic14_emitcode("inc","%s",rname);
8718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8719 /* now some housekeeping stuff */
8721 /* we had to allocate for this iCode */
8722 freeAsmop(NULL,aop,ic,TRUE);
8724 /* we did not allocate which means left
8725 already in a pointer register, then
8726 if size > 0 && this could be used again
8727 we have to point it back to where it
8729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8730 if (AOP_SIZE(right) > 1 &&
8731 !OP_SYMBOL(result)->remat &&
8732 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8734 int size = AOP_SIZE(right) - 1;
8736 pic14_emitcode("decf","fsr,f");
8737 //pic14_emitcode("dec","%s",rname);
8741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8744 freeAsmop(right,NULL,ic,TRUE);
8745 freeAsmop(result,NULL,ic,TRUE);
8748 /*-----------------------------------------------------------------*/
8749 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8750 /*-----------------------------------------------------------------*/
8751 static void genPagedPointerSet (operand *right,
8760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8762 retype= getSpec(operandType(right));
8764 aopOp(result,ic,FALSE);
8766 /* if the value is already in a pointer register
8767 then don't need anything more */
8768 if (!AOP_INPREG(AOP(result))) {
8769 /* otherwise get a free pointer register */
8771 preg = getFreePtr(ic,&aop,FALSE);
8772 pic14_emitcode("mov","%s,%s",
8774 aopGet(AOP(result),0,FALSE,TRUE));
8775 rname = preg->name ;
8777 rname = aopGet(AOP(result),0,FALSE,FALSE);
8779 freeAsmop(result,NULL,ic,TRUE);
8780 aopOp (right,ic,FALSE);
8782 /* if bitfield then unpack the bits */
8783 if (IS_BITVAR(retype))
8784 genPackBits (retype,right,rname,PPOINTER);
8786 /* we have can just get the values */
8787 int size = AOP_SIZE(right);
8791 l = aopGet(AOP(right),offset,FALSE,TRUE);
8794 pic14_emitcode("movx","@%s,a",rname);
8797 pic14_emitcode("inc","%s",rname);
8803 /* now some housekeeping stuff */
8805 /* we had to allocate for this iCode */
8806 freeAsmop(NULL,aop,ic,TRUE);
8808 /* we did not allocate which means left
8809 already in a pointer register, then
8810 if size > 0 && this could be used again
8811 we have to point it back to where it
8813 if (AOP_SIZE(right) > 1 &&
8814 !OP_SYMBOL(result)->remat &&
8815 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8817 int size = AOP_SIZE(right) - 1;
8819 pic14_emitcode("dec","%s",rname);
8824 freeAsmop(right,NULL,ic,TRUE);
8829 /*-----------------------------------------------------------------*/
8830 /* genFarPointerSet - set value from far space */
8831 /*-----------------------------------------------------------------*/
8832 static void genFarPointerSet (operand *right,
8833 operand *result, iCode *ic)
8836 sym_link *retype = getSpec(operandType(right));
8838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8839 aopOp(result,ic,FALSE);
8841 /* if the operand is already in dptr
8842 then we do nothing else we move the value to dptr */
8843 if (AOP_TYPE(result) != AOP_STR) {
8844 /* if this is remateriazable */
8845 if (AOP_TYPE(result) == AOP_IMMD)
8846 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8847 else { /* we need to get it byte by byte */
8848 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8849 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8850 if (options.model == MODEL_FLAT24)
8852 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8856 /* so dptr know contains the address */
8857 freeAsmop(result,NULL,ic,TRUE);
8858 aopOp(right,ic,FALSE);
8860 /* if bit then unpack */
8861 if (IS_BITVAR(retype))
8862 genPackBits(retype,right,"dptr",FPOINTER);
8864 size = AOP_SIZE(right);
8868 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8870 pic14_emitcode("movx","@dptr,a");
8872 pic14_emitcode("inc","dptr");
8876 freeAsmop(right,NULL,ic,TRUE);
8879 /*-----------------------------------------------------------------*/
8880 /* genGenPointerSet - set value from generic pointer space */
8881 /*-----------------------------------------------------------------*/
8882 static void genGenPointerSet (operand *right,
8883 operand *result, iCode *ic)
8886 sym_link *retype = getSpec(operandType(right));
8888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8890 aopOp(result,ic,FALSE);
8891 aopOp(right,ic,FALSE);
8892 size = AOP_SIZE(right);
8894 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8896 /* if the operand is already in dptr
8897 then we do nothing else we move the value to dptr */
8898 if (AOP_TYPE(result) != AOP_STR) {
8899 /* if this is remateriazable */
8900 if (AOP_TYPE(result) == AOP_IMMD) {
8901 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8902 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8904 else { /* we need to get it byte by byte */
8905 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8906 size = AOP_SIZE(right);
8909 /* hack hack! see if this the FSR. If so don't load W */
8910 if(AOP_TYPE(right) != AOP_ACC) {
8912 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8913 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8916 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8918 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8919 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8923 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8924 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8927 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8934 if(aopIdx(AOP(result),0) != 4) {
8936 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8940 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8945 /* so dptr know contains the address */
8948 /* if bit then unpack */
8949 if (IS_BITVAR(retype))
8950 genPackBits(retype,right,"dptr",GPOINTER);
8952 size = AOP_SIZE(right);
8955 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8959 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8960 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8962 if (AOP_TYPE(right) == AOP_LIT)
8963 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8965 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8967 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8974 freeAsmop(right,NULL,ic,TRUE);
8975 freeAsmop(result,NULL,ic,TRUE);
8978 /*-----------------------------------------------------------------*/
8979 /* genPointerSet - stores the value into a pointer location */
8980 /*-----------------------------------------------------------------*/
8981 static void genPointerSet (iCode *ic)
8983 operand *right, *result ;
8984 sym_link *type, *etype;
8987 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8989 right = IC_RIGHT(ic);
8990 result = IC_RESULT(ic) ;
8992 /* depending on the type of pointer we need to
8993 move it to the correct pointer register */
8994 type = operandType(result);
8995 etype = getSpec(type);
8996 /* if left is of type of pointer then it is simple */
8997 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8998 p_type = DCL_TYPE(type);
9001 /* we have to go by the storage class */
9002 p_type = PTR_TYPE(SPEC_OCLS(etype));
9004 /* if (SPEC_OCLS(etype)->codesp ) { */
9005 /* p_type = CPOINTER ; */
9008 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9009 /* p_type = FPOINTER ; */
9011 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9012 /* p_type = PPOINTER ; */
9014 /* if (SPEC_OCLS(etype) == idata ) */
9015 /* p_type = IPOINTER ; */
9017 /* p_type = POINTER ; */
9020 /* now that we have the pointer type we assign
9021 the pointer values */
9026 genNearPointerSet (right,result,ic);
9030 genPagedPointerSet (right,result,ic);
9034 genFarPointerSet (right,result,ic);
9038 genGenPointerSet (right,result,ic);
9042 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9043 "genPointerSet: illegal pointer type");
9047 /*-----------------------------------------------------------------*/
9048 /* genIfx - generate code for Ifx statement */
9049 /*-----------------------------------------------------------------*/
9050 static void genIfx (iCode *ic, iCode *popIc)
9052 operand *cond = IC_COND(ic);
9055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9057 aopOp(cond,ic,FALSE);
9059 /* get the value into acc */
9060 if (AOP_TYPE(cond) != AOP_CRY)
9061 pic14_toBoolean(cond);
9064 /* the result is now in the accumulator */
9065 freeAsmop(cond,NULL,ic,TRUE);
9067 /* if there was something to be popped then do it */
9071 /* if the condition is a bit variable */
9072 if (isbit && IS_ITEMP(cond) &&
9074 genIfxJump(ic,SPIL_LOC(cond)->rname);
9075 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9078 if (isbit && !IS_ITEMP(cond))
9079 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9087 /*-----------------------------------------------------------------*/
9088 /* genAddrOf - generates code for address of */
9089 /*-----------------------------------------------------------------*/
9090 static void genAddrOf (iCode *ic)
9092 operand *right, *result, *left;
9095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9098 //aopOp(IC_RESULT(ic),ic,FALSE);
9100 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9101 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9102 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9104 DEBUGpic14_AopType(__LINE__,left,right,result);
9106 size = AOP_SIZE(IC_RESULT(ic));
9110 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9111 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9115 freeAsmop(left,NULL,ic,FALSE);
9116 freeAsmop(result,NULL,ic,TRUE);
9121 /*-----------------------------------------------------------------*/
9122 /* genFarFarAssign - assignment when both are in far space */
9123 /*-----------------------------------------------------------------*/
9124 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9126 int size = AOP_SIZE(right);
9129 /* first push the right side on to the stack */
9131 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9133 pic14_emitcode ("push","acc");
9136 freeAsmop(right,NULL,ic,FALSE);
9137 /* now assign DPTR to result */
9138 aopOp(result,ic,FALSE);
9139 size = AOP_SIZE(result);
9141 pic14_emitcode ("pop","acc");
9142 aopPut(AOP(result),"a",--offset);
9144 freeAsmop(result,NULL,ic,FALSE);
9149 /*-----------------------------------------------------------------*/
9150 /* genAssign - generate code for assignment */
9151 /*-----------------------------------------------------------------*/
9152 static void genAssign (iCode *ic)
9154 operand *result, *right;
9155 int size, offset,know_W;
9156 unsigned long lit = 0L;
9158 result = IC_RESULT(ic);
9159 right = IC_RIGHT(ic) ;
9161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9163 /* if they are the same */
9164 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9167 aopOp(right,ic,FALSE);
9168 aopOp(result,ic,TRUE);
9170 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9172 /* if they are the same registers */
9173 if (pic14_sameRegs(AOP(right),AOP(result)))
9176 /* if the result is a bit */
9177 if (AOP_TYPE(result) == AOP_CRY) {
9179 /* if the right size is a literal then
9180 we know what the value is */
9181 if (AOP_TYPE(right) == AOP_LIT) {
9183 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9184 popGet(AOP(result),0));
9186 if (((int) operandLitValue(right)))
9187 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9188 AOP(result)->aopu.aop_dir,
9189 AOP(result)->aopu.aop_dir);
9191 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9192 AOP(result)->aopu.aop_dir,
9193 AOP(result)->aopu.aop_dir);
9197 /* the right is also a bit variable */
9198 if (AOP_TYPE(right) == AOP_CRY) {
9199 emitpcode(POC_BCF, popGet(AOP(result),0));
9200 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9201 emitpcode(POC_BSF, popGet(AOP(result),0));
9203 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9204 AOP(result)->aopu.aop_dir,
9205 AOP(result)->aopu.aop_dir);
9206 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9207 AOP(right)->aopu.aop_dir,
9208 AOP(right)->aopu.aop_dir);
9209 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9210 AOP(result)->aopu.aop_dir,
9211 AOP(result)->aopu.aop_dir);
9216 emitpcode(POC_BCF, popGet(AOP(result),0));
9217 pic14_toBoolean(right);
9219 emitpcode(POC_BSF, popGet(AOP(result),0));
9220 //aopPut(AOP(result),"a",0);
9224 /* bit variables done */
9226 size = AOP_SIZE(result);
9228 if(AOP_TYPE(right) == AOP_LIT)
9229 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9231 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9233 if(aopIdx(AOP(result),0) == 4) {
9234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9235 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9236 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9239 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9244 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9245 if(AOP_TYPE(right) == AOP_LIT) {
9247 if(know_W != (lit&0xff))
9248 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9250 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9252 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9256 } else if (AOP_TYPE(right) == AOP_CRY) {
9257 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9259 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9260 emitpcode(POC_INCF, popGet(AOP(result),0));
9263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9264 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9265 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9273 freeAsmop (right,NULL,ic,FALSE);
9274 freeAsmop (result,NULL,ic,TRUE);
9277 /*-----------------------------------------------------------------*/
9278 /* genJumpTab - genrates code for jump table */
9279 /*-----------------------------------------------------------------*/
9280 static void genJumpTab (iCode *ic)
9285 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9287 aopOp(IC_JTCOND(ic),ic,FALSE);
9288 /* get the condition into accumulator */
9289 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9291 /* multiply by three */
9292 pic14_emitcode("add","a,acc");
9293 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9295 jtab = newiTempLabel(NULL);
9296 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9297 pic14_emitcode("jmp","@a+dptr");
9298 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9300 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9301 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9303 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9304 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9305 emitpLabel(jtab->key);
9307 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9309 /* now generate the jump labels */
9310 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9311 jtab = setNextItem(IC_JTLABELS(ic))) {
9312 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9313 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9319 /*-----------------------------------------------------------------*/
9320 /* genMixedOperation - gen code for operators between mixed types */
9321 /*-----------------------------------------------------------------*/
9323 TSD - Written for the PIC port - but this unfortunately is buggy.
9324 This routine is good in that it is able to efficiently promote
9325 types to different (larger) sizes. Unfortunately, the temporary
9326 variables that are optimized out by this routine are sometimes
9327 used in other places. So until I know how to really parse the
9328 iCode tree, I'm going to not be using this routine :(.
9330 static int genMixedOperation (iCode *ic)
9333 operand *result = IC_RESULT(ic);
9334 sym_link *ctype = operandType(IC_LEFT(ic));
9335 operand *right = IC_RIGHT(ic);
9341 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9343 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9349 nextright = IC_RIGHT(nextic);
9350 nextleft = IC_LEFT(nextic);
9351 nextresult = IC_RESULT(nextic);
9353 aopOp(right,ic,FALSE);
9354 aopOp(result,ic,FALSE);
9355 aopOp(nextright, nextic, FALSE);
9356 aopOp(nextleft, nextic, FALSE);
9357 aopOp(nextresult, nextic, FALSE);
9359 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9365 pic14_emitcode(";remove right +","");
9367 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9373 pic14_emitcode(";remove left +","");
9377 big = AOP_SIZE(nextleft);
9378 small = AOP_SIZE(nextright);
9380 switch(nextic->op) {
9383 pic14_emitcode(";optimize a +","");
9384 /* if unsigned or not an integral type */
9385 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9386 pic14_emitcode(";add a bit to something","");
9389 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9391 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9392 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9393 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9395 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9403 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9404 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9405 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9408 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9410 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9411 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9412 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9413 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9414 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9417 pic14_emitcode("rlf","known_zero,w");
9424 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9425 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9426 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9428 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9438 freeAsmop(right,NULL,ic,TRUE);
9439 freeAsmop(result,NULL,ic,TRUE);
9440 freeAsmop(nextright,NULL,ic,TRUE);
9441 freeAsmop(nextleft,NULL,ic,TRUE);
9443 nextic->generated = 1;
9450 /*-----------------------------------------------------------------*/
9451 /* genCast - gen code for casting */
9452 /*-----------------------------------------------------------------*/
9453 static void genCast (iCode *ic)
9455 operand *result = IC_RESULT(ic);
9456 sym_link *ctype = operandType(IC_LEFT(ic));
9457 sym_link *rtype = operandType(IC_RIGHT(ic));
9458 operand *right = IC_RIGHT(ic);
9461 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9462 /* if they are equivalent then do nothing */
9463 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9466 aopOp(right,ic,FALSE) ;
9467 aopOp(result,ic,FALSE);
9469 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9471 /* if the result is a bit */
9472 if (AOP_TYPE(result) == AOP_CRY) {
9473 /* if the right size is a literal then
9474 we know what the value is */
9475 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9476 if (AOP_TYPE(right) == AOP_LIT) {
9478 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9479 popGet(AOP(result),0));
9481 if (((int) operandLitValue(right)))
9482 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9483 AOP(result)->aopu.aop_dir,
9484 AOP(result)->aopu.aop_dir);
9486 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9487 AOP(result)->aopu.aop_dir,
9488 AOP(result)->aopu.aop_dir);
9493 /* the right is also a bit variable */
9494 if (AOP_TYPE(right) == AOP_CRY) {
9497 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9499 pic14_emitcode("clrc","");
9500 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9501 AOP(right)->aopu.aop_dir,
9502 AOP(right)->aopu.aop_dir);
9503 aopPut(AOP(result),"c",0);
9508 if (AOP_TYPE(right) == AOP_REG) {
9509 emitpcode(POC_BCF, popGet(AOP(result),0));
9510 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9511 emitpcode(POC_BSF, popGet(AOP(result),0));
9513 pic14_toBoolean(right);
9514 aopPut(AOP(result),"a",0);
9518 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9520 size = AOP_SIZE(result);
9522 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9524 emitpcode(POC_CLRF, popGet(AOP(result),0));
9525 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9526 emitpcode(POC_INCF, popGet(AOP(result),0));
9529 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9534 /* if they are the same size : or less */
9535 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9537 /* if they are in the same place */
9538 if (pic14_sameRegs(AOP(right),AOP(result)))
9541 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9542 if (IS_PTR_CONST(rtype))
9543 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9544 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9545 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9547 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9548 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9549 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9550 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9551 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9552 if(AOP_SIZE(result) <2)
9553 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9557 /* if they in different places then copy */
9558 size = AOP_SIZE(result);
9561 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9562 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9564 //aopPut(AOP(result),
9565 // aopGet(AOP(right),offset,FALSE,FALSE),
9575 /* if the result is of type pointer */
9576 if (IS_PTR(ctype)) {
9579 sym_link *type = operandType(right);
9580 sym_link *etype = getSpec(type);
9581 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9583 /* pointer to generic pointer */
9584 if (IS_GENPTR(ctype)) {
9588 p_type = DCL_TYPE(type);
9590 /* we have to go by the storage class */
9591 p_type = PTR_TYPE(SPEC_OCLS(etype));
9593 /* if (SPEC_OCLS(etype)->codesp ) */
9594 /* p_type = CPOINTER ; */
9596 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9597 /* p_type = FPOINTER ; */
9599 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9600 /* p_type = PPOINTER; */
9602 /* if (SPEC_OCLS(etype) == idata ) */
9603 /* p_type = IPOINTER ; */
9605 /* p_type = POINTER ; */
9608 /* the first two bytes are known */
9609 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9610 size = GPTRSIZE - 1;
9613 if(offset < AOP_SIZE(right)) {
9614 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9615 if ((AOP_TYPE(right) == AOP_PCODE) &&
9616 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9617 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9618 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9621 aopGet(AOP(right),offset,FALSE,FALSE),
9625 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9628 /* the last byte depending on type */
9632 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9635 pic14_emitcode(";BUG!? ","%d",__LINE__);
9639 pic14_emitcode(";BUG!? ","%d",__LINE__);
9643 pic14_emitcode(";BUG!? ","%d",__LINE__);
9648 /* this should never happen */
9649 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9650 "got unknown pointer type");
9653 //aopPut(AOP(result),l, GPTRSIZE - 1);
9657 /* just copy the pointers */
9658 size = AOP_SIZE(result);
9662 aopGet(AOP(right),offset,FALSE,FALSE),
9671 /* so we now know that the size of destination is greater
9672 than the size of the source.
9673 Now, if the next iCode is an operator then we might be
9674 able to optimize the operation without performing a cast.
9676 if(genMixedOperation(ic))
9679 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9681 /* we move to result for the size of source */
9682 size = AOP_SIZE(right);
9685 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9686 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9690 /* now depending on the sign of the destination */
9691 size = AOP_SIZE(result) - AOP_SIZE(right);
9692 /* if unsigned or not an integral type */
9693 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9695 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9697 /* we need to extend the sign :{ */
9700 /* Save one instruction of casting char to int */
9701 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9702 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9703 emitpcode(POC_DECF, popGet(AOP(result),offset));
9705 emitpcodeNULLop(POC_CLRW);
9708 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9710 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9712 emitpcode(POC_MOVLW, popGetLit(0xff));
9715 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9720 freeAsmop(right,NULL,ic,TRUE);
9721 freeAsmop(result,NULL,ic,TRUE);
9725 /*-----------------------------------------------------------------*/
9726 /* genDjnz - generate decrement & jump if not zero instrucion */
9727 /*-----------------------------------------------------------------*/
9728 static int genDjnz (iCode *ic, iCode *ifx)
9731 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9736 /* if the if condition has a false label
9737 then we cannot save */
9741 /* if the minus is not of the form
9743 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9744 !IS_OP_LITERAL(IC_RIGHT(ic)))
9747 if (operandLitValue(IC_RIGHT(ic)) != 1)
9750 /* if the size of this greater than one then no
9752 if (getSize(operandType(IC_RESULT(ic))) > 1)
9755 /* otherwise we can save BIG */
9756 lbl = newiTempLabel(NULL);
9757 lbl1= newiTempLabel(NULL);
9759 aopOp(IC_RESULT(ic),ic,FALSE);
9761 if (IS_AOP_PREG(IC_RESULT(ic))) {
9762 pic14_emitcode("dec","%s",
9763 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9764 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9765 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9769 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9770 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9772 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9773 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9776 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9777 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9778 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9779 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9782 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9787 /*-----------------------------------------------------------------*/
9788 /* genReceive - generate code for a receive iCode */
9789 /*-----------------------------------------------------------------*/
9790 static void genReceive (iCode *ic)
9792 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9794 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9795 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9796 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9798 int size = getSize(operandType(IC_RESULT(ic)));
9799 int offset = fReturnSizePic - size;
9801 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9802 fReturn[fReturnSizePic - offset - 1] : "acc"));
9805 aopOp(IC_RESULT(ic),ic,FALSE);
9806 size = AOP_SIZE(IC_RESULT(ic));
9809 pic14_emitcode ("pop","acc");
9810 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9815 aopOp(IC_RESULT(ic),ic,FALSE);
9817 assignResultValue(IC_RESULT(ic));
9820 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9823 /*-----------------------------------------------------------------*/
9824 /* genpic14Code - generate code for pic14 based controllers */
9825 /*-----------------------------------------------------------------*/
9827 * At this point, ralloc.c has gone through the iCode and attempted
9828 * to optimize in a way suitable for a PIC. Now we've got to generate
9829 * PIC instructions that correspond to the iCode.
9831 * Once the instructions are generated, we'll pass through both the
9832 * peep hole optimizer and the pCode optimizer.
9833 *-----------------------------------------------------------------*/
9835 void genpic14Code (iCode *lic)
9840 lineHead = lineCurr = NULL;
9842 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9845 /* if debug information required */
9846 if (options.debug && currFunc) {
9848 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9850 if (IS_STATIC(currFunc->etype)) {
9851 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9852 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9854 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9855 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9862 for (ic = lic ; ic ; ic = ic->next ) {
9864 DEBUGpic14_emitcode(";ic","");
9865 if ( cln != ic->lineno ) {
9866 if ( options.debug ) {
9868 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9869 FileBaseName(ic->filename),ic->lineno,
9870 ic->level,ic->block);
9874 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9875 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9876 printCLine(ic->filename, ic->lineno));
9879 newpCodeCSource(ic->lineno,
9881 printCLine(ic->filename, ic->lineno)));
9885 /* if the result is marked as
9886 spilt and rematerializable or code for
9887 this has already been generated then
9889 if (resultRemat(ic) || ic->generated )
9892 /* depending on the operation */
9911 /* IPOP happens only when trying to restore a
9912 spilt live range, if there is an ifx statement
9913 following this pop then the if statement might
9914 be using some of the registers being popped which
9915 would destory the contents of the register so
9916 we need to check for this condition and handle it */
9918 ic->next->op == IFX &&
9919 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9920 genIfx (ic->next,ic);
9938 genEndFunction (ic);
9958 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9975 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9979 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9986 /* note these two are xlated by algebraic equivalence
9987 during parsing SDCC.y */
9988 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9989 "got '>=' or '<=' shouldn't have come here");
9993 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10005 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10009 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10013 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10037 genRightShift (ic);
10040 case GET_VALUE_AT_ADDRESS:
10045 if (POINTER_SET(ic))
10072 addSet(&_G.sendSet,ic);
10081 /* now we are ready to call the
10082 peep hole optimizer */
10083 if (!options.nopeep) {
10084 peepHole (&lineHead);
10086 /* now do the actual printing */
10087 printLine (lineHead,codeOutFile);
10090 DFPRINTF((stderr,"printing pBlock\n\n"));
10091 printpBlock(stdout,pb);