1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic
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"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
81 static char **fReturn = fReturnpic14;
83 static char *accUse[] = {"a","b"};
85 //static short rbank = -1;
97 /* Resolved ifx structure. This structure stores information
98 about an iCode ifx that makes it easier to generate code.
100 typedef struct resolvedIfx {
101 symbol *lbl; /* pointer to a label */
102 int condition; /* true or false ifx */
103 int generated; /* set true when the code associated with the ifx
107 extern int pic14_ptrRegReq ;
108 extern int pic14_nRegs;
109 extern FILE *codeOutFile;
110 static void saverbank (int, iCode *,bool);
112 static lineNode *lineHead = NULL;
113 static lineNode *lineCurr = NULL;
115 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
116 0xE0, 0xC0, 0x80, 0x00};
117 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
118 0x07, 0x03, 0x01, 0x00};
122 /*-----------------------------------------------------------------*/
123 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
124 /* exponent of 2 is returned, otherwise -1 is */
126 /* note that this is similar to the function `powof2' in SDCCsymt */
130 /*-----------------------------------------------------------------*/
131 static int my_powof2 (unsigned long num)
134 if( (num & (num-1)) == 0) {
147 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
150 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
152 ((result) ? AopType(AOP_TYPE(result)) : "-"),
153 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
154 ((left) ? AopType(AOP_TYPE(left)) : "-"),
155 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
156 ((right) ? AopType(AOP_TYPE(right)) : "-"),
157 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
158 ((result) ? AOP_SIZE(result) : 0));
162 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
165 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
167 ((result) ? AopType(AOP_TYPE(result)) : "-"),
168 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
169 ((left) ? AopType(AOP_TYPE(left)) : "-"),
170 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
171 ((right) ? AopType(AOP_TYPE(right)) : "-"),
172 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
176 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
179 char lb[INITIAL_INLINEASM];
189 sprintf(lb,"%s\t",inst);
191 sprintf(lb,"%s",inst);
192 vsprintf(lb+(strlen(lb)),fmt,ap);
196 while (isspace(*lbp)) lbp++;
199 lineCurr = (lineCurr ?
200 connectLine(lineCurr,newLineNode(lb)) :
201 (lineHead = newLineNode(lb)));
202 lineCurr->isInline = _G.inLine;
203 lineCurr->isDebug = _G.debugLine;
205 addpCode2pBlock(pb,newpCodeCharP(lb));
211 void emitpLabel(int key)
213 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
216 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
219 addpCode2pBlock(pb,newpCode(poc,pcop));
221 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
224 void emitpcodeNULLop(PIC_OPCODE poc)
227 addpCode2pBlock(pb,newpCode(poc,NULL));
232 /*-----------------------------------------------------------------*/
233 /* pic14_emitcode - writes the code into a file : for now it is simple */
234 /*-----------------------------------------------------------------*/
235 void pic14_emitcode (char *inst,char *fmt, ...)
238 char lb[INITIAL_INLINEASM];
245 sprintf(lb,"%s\t",inst);
247 sprintf(lb,"%s",inst);
248 vsprintf(lb+(strlen(lb)),fmt,ap);
252 while (isspace(*lbp)) lbp++;
255 lineCurr = (lineCurr ?
256 connectLine(lineCurr,newLineNode(lb)) :
257 (lineHead = newLineNode(lb)));
258 lineCurr->isInline = _G.inLine;
259 lineCurr->isDebug = _G.debugLine;
262 addpCode2pBlock(pb,newpCodeCharP(lb));
267 /*-----------------------------------------------------------------*/
268 /* pic14_emitDebuggerSymbol - associate the current code location */
269 /* with a debugger symbol */
270 /*-----------------------------------------------------------------*/
272 pic14_emitDebuggerSymbol (char * debugSym)
275 pic14_emitcode ("", ";%s ==.", debugSym);
280 /*-----------------------------------------------------------------*/
281 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
282 /*-----------------------------------------------------------------*/
283 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
285 bool r0iu = FALSE , r1iu = FALSE;
286 bool r0ou = FALSE , r1ou = FALSE;
288 /* the logic: if r0 & r1 used in the instruction
289 then we are in trouble otherwise */
291 /* first check if r0 & r1 are used by this
292 instruction, in which case we are in trouble */
293 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
294 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
299 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
300 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
302 /* if no usage of r0 then return it */
303 if (!r0iu && !r0ou) {
304 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
305 (*aopp)->type = AOP_R0;
307 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
310 /* if no usage of r1 then return it */
311 if (!r1iu && !r1ou) {
312 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
313 (*aopp)->type = AOP_R1;
315 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
318 /* now we know they both have usage */
319 /* if r0 not used in this instruction */
321 /* push it if not already pushed */
323 //pic14_emitcode ("push","%s",
324 // pic14_regWithIdx(R0_IDX)->dname);
328 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
329 (*aopp)->type = AOP_R0;
331 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
334 /* if r1 not used then */
337 /* push it if not already pushed */
339 //pic14_emitcode ("push","%s",
340 // pic14_regWithIdx(R1_IDX)->dname);
344 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
345 (*aopp)->type = AOP_R1;
346 return pic14_regWithIdx(R1_IDX);
350 /* I said end of world but not quite end of world yet */
351 /* if this is a result then we can push it on the stack*/
353 (*aopp)->type = AOP_STK;
357 /* other wise this is true end of the world */
358 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
359 "getFreePtr should never reach here");
363 /*-----------------------------------------------------------------*/
364 /* newAsmop - creates a new asmOp */
365 /*-----------------------------------------------------------------*/
366 asmop *newAsmop (short type)
370 aop = Safe_calloc(1,sizeof(asmop));
375 static void genSetDPTR(int n)
379 pic14_emitcode(";", "Select standard DPTR");
380 pic14_emitcode("mov", "dps, #0x00");
384 pic14_emitcode(";", "Select alternate DPTR");
385 pic14_emitcode("mov", "dps, #0x01");
389 /*-----------------------------------------------------------------*/
390 /* resolveIfx - converts an iCode ifx into a form more useful for */
391 /* generating code */
392 /*-----------------------------------------------------------------*/
393 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
398 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
400 resIfx->condition = 1; /* assume that the ifx is true */
401 resIfx->generated = 0; /* indicate that the ifx has not been used */
404 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
406 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
407 __FUNCTION__,__LINE__,resIfx->lbl->key);
411 resIfx->lbl = IC_TRUE(ifx);
413 resIfx->lbl = IC_FALSE(ifx);
414 resIfx->condition = 0;
418 DEBUGpic14_emitcode("; ***","ifx true is non-null");
420 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)) {
538 sym->aop = aop = newAsmop(AOP_PCODE);
539 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
540 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
541 PCOI(aop->aopu.pcop)->_function = 1;
542 PCOI(aop->aopu.pcop)->index = 0;
543 aop->size = FPTRSIZE;
545 sym->aop = aop = newAsmop(AOP_IMMD);
546 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
547 strcpy(aop->aopu.aop_immd,sym->rname);
548 aop->size = FPTRSIZE;
550 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
555 /* only remaining is far space */
556 /* in which case DPTR gets the address */
557 sym->aop = aop = newAsmop(AOP_PCODE);
559 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
560 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
561 PCOI(aop->aopu.pcop)->index = 0;
563 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
564 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
566 allocDirReg (IC_LEFT(ic));
568 aop->size = FPTRSIZE;
570 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
571 sym->aop = aop = newAsmop(AOP_DPTR);
572 pic14_emitcode ("mov","dptr,#%s", sym->rname);
573 aop->size = getSize(sym->type);
575 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
578 /* if it is in code space */
579 if (IN_CODESPACE(space))
585 /*-----------------------------------------------------------------*/
586 /* aopForRemat - rematerialzes an object */
587 /*-----------------------------------------------------------------*/
588 static asmop *aopForRemat (operand *op) // x symbol *sym)
590 symbol *sym = OP_SYMBOL(op);
592 asmop *aop = newAsmop(AOP_PCODE);
596 ic = sym->rematiCode;
598 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
599 if(IS_OP_POINTER(op)) {
600 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
604 val += (int) operandLitValue(IC_RIGHT(ic));
605 } else if (ic->op == '-') {
606 val -= (int) operandLitValue(IC_RIGHT(ic));
610 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
613 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
614 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
615 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
616 PCOI(aop->aopu.pcop)->index = val;
618 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
619 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
620 val, IS_PTR_CONST(operandType(op)));
622 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
624 allocDirReg (IC_LEFT(ic));
629 int aopIdx (asmop *aop, int offset)
634 if(aop->type != AOP_REG)
637 return aop->aopu.aop_reg[offset]->rIdx;
640 /*-----------------------------------------------------------------*/
641 /* regsInCommon - two operands have some registers in common */
642 /*-----------------------------------------------------------------*/
643 static bool regsInCommon (operand *op1, operand *op2)
648 /* if they have registers in common */
649 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
652 sym1 = OP_SYMBOL(op1);
653 sym2 = OP_SYMBOL(op2);
655 if (sym1->nRegs == 0 || sym2->nRegs == 0)
658 for (i = 0 ; i < sym1->nRegs ; i++) {
663 for (j = 0 ; j < sym2->nRegs ;j++ ) {
667 if (sym2->regs[j] == sym1->regs[i])
675 /*-----------------------------------------------------------------*/
676 /* operandsEqu - equivalent */
677 /*-----------------------------------------------------------------*/
678 static bool operandsEqu ( operand *op1, operand *op2)
682 /* if they not symbols */
683 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
686 sym1 = OP_SYMBOL(op1);
687 sym2 = OP_SYMBOL(op2);
689 /* if both are itemps & one is spilt
690 and the other is not then false */
691 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
692 sym1->isspilt != sym2->isspilt )
695 /* if they are the same */
699 if (sym1->rname[0] && sym2->rname[0]
700 && strcmp (sym1->rname, sym2->rname) == 0)
704 /* if left is a tmp & right is not */
708 (sym1->usl.spillLoc == sym2))
715 (sym2->usl.spillLoc == sym1))
721 /*-----------------------------------------------------------------*/
722 /* pic14_sameRegs - two asmops have the same registers */
723 /*-----------------------------------------------------------------*/
724 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
731 if (aop1->type != AOP_REG ||
732 aop2->type != AOP_REG )
735 if (aop1->size != aop2->size )
738 for (i = 0 ; i < aop1->size ; i++ )
739 if (aop1->aopu.aop_reg[i] !=
740 aop2->aopu.aop_reg[i] )
746 /*-----------------------------------------------------------------*/
747 /* aopOp - allocates an asmop for an operand : */
748 /*-----------------------------------------------------------------*/
749 void aopOp (operand *op, iCode *ic, bool result)
758 /* if this a literal */
759 if (IS_OP_LITERAL(op)) {
760 op->aop = aop = newAsmop(AOP_LIT);
761 aop->aopu.aop_lit = op->operand.valOperand;
762 aop->size = getSize(operandType(op));
767 sym_link *type = operandType(op);
768 if(IS_PTR_CONST(type))
769 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
772 /* if already has a asmop then continue */
776 /* if the underlying symbol has a aop */
777 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
778 DEBUGpic14_emitcode(";","%d",__LINE__);
779 op->aop = OP_SYMBOL(op)->aop;
783 /* if this is a true symbol */
784 if (IS_TRUE_SYMOP(op)) {
785 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
786 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
790 /* this is a temporary : this has
796 e) can be a return use only */
801 /* if the type is a conditional */
802 if (sym->regType == REG_CND) {
803 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
808 /* if it is spilt then two situations
810 b) has a spill location */
811 if (sym->isspilt || sym->nRegs == 0) {
813 DEBUGpic14_emitcode(";","%d",__LINE__);
814 /* rematerialize it NOW */
817 sym->aop = op->aop = aop = aopForRemat (op);
818 aop->size = getSize(sym->type);
819 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
825 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
826 aop->size = getSize(sym->type);
827 for ( i = 0 ; i < 2 ; i++ )
828 aop->aopu.aop_str[i] = accUse[i];
829 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
834 if(sym->isptr) { // && sym->uptr
835 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
836 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
838 //PCOI(aop->aopu.pcop)->_const = 0;
839 //PCOI(aop->aopu.pcop)->index = 0;
841 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
842 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
844 //allocDirReg (IC_LEFT(ic));
846 aop->size = getSize(sym->type);
847 DEBUGpic14_emitcode(";","%d",__LINE__);
854 aop = op->aop = sym->aop = newAsmop(AOP_STR);
855 aop->size = getSize(sym->type);
856 for ( i = 0 ; i < fReturnSizePic ; i++ )
857 aop->aopu.aop_str[i] = fReturn[i];
859 DEBUGpic14_emitcode(";","%d",__LINE__);
864 /* else spill location */
865 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
866 /* force a new aop if sizes differ */
867 sym->usl.spillLoc->aop = NULL;
869 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
870 __FUNCTION__,__LINE__,
871 sym->usl.spillLoc->rname,
872 sym->rname, sym->usl.spillLoc->offset);
874 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
875 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
876 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
878 sym->usl.spillLoc->offset);
879 aop->size = getSize(sym->type);
885 sym_link *type = operandType(op);
886 if(IS_PTR_CONST(type))
887 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
890 /* must be in a register */
891 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
892 sym->aop = op->aop = aop = newAsmop(AOP_REG);
893 aop->size = sym->nRegs;
894 for ( i = 0 ; i < sym->nRegs ;i++)
895 aop->aopu.aop_reg[i] = sym->regs[i];
898 /*-----------------------------------------------------------------*/
899 /* freeAsmop - free up the asmop given to an operand */
900 /*----------------------------------------------------------------*/
901 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
918 /* depending on the asmop type only three cases need work AOP_RO
919 , AOP_R1 && AOP_STK */
925 pic14_emitcode ("pop","ar0");
929 bitVectUnSetBit(ic->rUsed,R0_IDX);
935 pic14_emitcode ("pop","ar1");
939 bitVectUnSetBit(ic->rUsed,R1_IDX);
945 int stk = aop->aopu.aop_stk + aop->size;
946 bitVectUnSetBit(ic->rUsed,R0_IDX);
947 bitVectUnSetBit(ic->rUsed,R1_IDX);
949 getFreePtr(ic,&aop,FALSE);
951 if (options.stack10bit)
953 /* I'm not sure what to do here yet... */
956 "*** Warning: probably generating bad code for "
957 "10 bit stack mode.\n");
961 pic14_emitcode ("mov","a,_bp");
962 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
963 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
965 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
969 pic14_emitcode("pop","acc");
970 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
972 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
975 freeAsmop(op,NULL,ic,TRUE);
977 pic14_emitcode("pop","ar0");
982 pic14_emitcode("pop","ar1");
990 /* all other cases just dealloc */
994 OP_SYMBOL(op)->aop = NULL;
995 /* if the symbol has a spill */
997 SPIL_LOC(op)->aop = NULL;
1002 /*-----------------------------------------------------------------*/
1003 /* aopGet - for fetching value of the aop */
1004 /*-----------------------------------------------------------------*/
1005 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1010 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1011 /* offset is greater than
1013 if (offset > (aop->size - 1) &&
1014 aop->type != AOP_LIT)
1017 /* depending on type */
1018 switch (aop->type) {
1022 DEBUGpic14_emitcode(";","%d",__LINE__);
1023 /* if we need to increment it */
1024 while (offset > aop->coff) {
1025 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1029 while (offset < aop->coff) {
1030 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1034 aop->coff = offset ;
1036 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1037 return (dname ? "acc" : "a");
1039 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1040 rs = Safe_calloc(1,strlen(s)+1);
1046 DEBUGpic14_emitcode(";","%d",__LINE__);
1047 if (aop->type == AOP_DPTR2)
1052 while (offset > aop->coff) {
1053 pic14_emitcode ("inc","dptr");
1057 while (offset < aop->coff) {
1058 pic14_emitcode("lcall","__decdptr");
1064 pic14_emitcode("clr","a");
1065 pic14_emitcode("movc","a,@a+dptr");
1068 pic14_emitcode("movx","a,@dptr");
1071 if (aop->type == AOP_DPTR2)
1076 return (dname ? "acc" : "a");
1081 sprintf (s,"%s",aop->aopu.aop_immd);
1084 sprintf(s,"(%s >> %d)",
1089 aop->aopu.aop_immd);
1090 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1091 rs = Safe_calloc(1,strlen(s)+1);
1097 sprintf(s,"(%s + %d)",
1100 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1102 sprintf(s,"%s",aop->aopu.aop_dir);
1103 rs = Safe_calloc(1,strlen(s)+1);
1109 // return aop->aopu.aop_reg[offset]->dname;
1111 return aop->aopu.aop_reg[offset]->name;
1114 //pic14_emitcode(";","%d",__LINE__);
1115 return aop->aopu.aop_dir;
1118 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1119 return "AOP_accumulator_bug";
1122 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1123 rs = Safe_calloc(1,strlen(s)+1);
1128 aop->coff = offset ;
1129 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1132 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1134 return aop->aopu.aop_str[offset];
1138 pCodeOp *pcop = aop->aopu.pcop;
1139 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1141 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1142 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1143 sprintf(s,"%s", pcop->name);
1145 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1148 rs = Safe_calloc(1,strlen(s)+1);
1154 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1155 "aopget got unsupported aop->type");
1160 /*-----------------------------------------------------------------*/
1161 /* popGetTempReg - create a new temporary pCodeOp */
1162 /*-----------------------------------------------------------------*/
1163 pCodeOp *popGetTempReg(void)
1168 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1169 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1170 PCOR(pcop)->r->wasUsed=1;
1171 PCOR(pcop)->r->isFree=0;
1177 /*-----------------------------------------------------------------*/
1178 /* popGetTempReg - create a new temporary pCodeOp */
1179 /*-----------------------------------------------------------------*/
1180 void popReleaseTempReg(pCodeOp *pcop)
1183 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1184 PCOR(pcop)->r->isFree = 1;
1187 /*-----------------------------------------------------------------*/
1188 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1189 /*-----------------------------------------------------------------*/
1190 pCodeOp *popGetLabel(unsigned int key)
1193 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1195 if(key>(unsigned int)max_key)
1198 return newpCodeOpLabel(NULL,key+100+labelOffset);
1201 /*-------------------------------------------------------------------*/
1202 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1203 /*-------------------------------------------------------------------*/
1204 pCodeOp *popGetHighLabel(unsigned int key)
1207 pcop = popGetLabel(key);
1208 PCOLAB(pcop)->offset = 1;
1212 /*-----------------------------------------------------------------*/
1213 /* popGet - asm operator to pcode operator conversion */
1214 /*-----------------------------------------------------------------*/
1215 pCodeOp *popGetLit(unsigned int lit)
1218 return newpCodeOpLit(lit);
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1227 return newpCodeOpImmd(name, offset,index, 0, is_func);
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str, int isExtern)
1240 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1244 pcop = newpCodeOp(str,PO_STR);
1245 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1250 /*-----------------------------------------------------------------*/
1251 /* popRegFromString - */
1252 /*-----------------------------------------------------------------*/
1253 pCodeOp *popRegFromString(char *str, int size, int offset)
1256 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1257 pcop->type = PO_DIR;
1259 DEBUGpic14_emitcode(";","%d",__LINE__);
1264 pcop->name = Safe_calloc(1,strlen(str)+1);
1265 strcpy(pcop->name,str);
1267 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1269 PCOR(pcop)->r = dirregWithName(pcop->name);
1270 if(PCOR(pcop)->r == NULL) {
1271 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1272 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1273 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1275 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1277 PCOR(pcop)->instance = offset;
1282 /*-----------------------------------------------------------------*/
1283 /*-----------------------------------------------------------------*/
1284 pCodeOp *popRegFromIdx(int rIdx)
1288 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1289 __FUNCTION__,__LINE__,rIdx);
1291 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1293 PCOR(pcop)->rIdx = rIdx;
1294 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1295 PCOR(pcop)->r->isFree = 0;
1296 PCOR(pcop)->r->wasUsed = 1;
1298 pcop->type = PCOR(pcop)->r->pc_type;
1304 /*-----------------------------------------------------------------*/
1305 /* popGet - asm operator to pcode operator conversion */
1306 /*-----------------------------------------------------------------*/
1307 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1309 //char *s = buffer ;
1314 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1315 /* offset is greater than
1318 if (offset > (aop->size - 1) &&
1319 aop->type != AOP_LIT)
1320 return NULL; //zero;
1322 /* depending on type */
1323 switch (aop->type) {
1330 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1334 DEBUGpic14_emitcode(";","%d",__LINE__);
1335 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1338 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1340 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1341 pcop->type = PO_DIR;
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 rIdx = r0x%X ",__LINE__,rIdx);
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 %s",__LINE__,aop->aopu.aop_str[offset]);
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,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 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1653 if ( aop->type == AOP_PCODE ||
1654 aop->type == AOP_LIT ||
1655 aop->type == AOP_IMMD )
1656 emitpcode(POC_MOVLW,popGet(aop,offset));
1658 emitpcode(POC_MOVFW,popGet(aop,offset));
1662 /*-----------------------------------------------------------------*/
1663 /* reAdjustPreg - points a register back to where it should */
1664 /*-----------------------------------------------------------------*/
1665 static void reAdjustPreg (asmop *aop)
1669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1671 if ((size = aop->size) <= 1)
1674 switch (aop->type) {
1678 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1682 if (aop->type == AOP_DPTR2)
1688 pic14_emitcode("lcall","__decdptr");
1691 if (aop->type == AOP_DPTR2)
1703 /*-----------------------------------------------------------------*/
1704 /* opIsGptr: returns non-zero if the passed operand is */
1705 /* a generic pointer type. */
1706 /*-----------------------------------------------------------------*/
1707 static int opIsGptr(operand *op)
1709 sym_link *type = operandType(op);
1711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1712 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1720 /*-----------------------------------------------------------------*/
1721 /* pic14_getDataSize - get the operand data size */
1722 /*-----------------------------------------------------------------*/
1723 int pic14_getDataSize(operand *op)
1725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1728 return AOP_SIZE(op);
1730 // tsd- in the pic port, the genptr size is 1, so this code here
1731 // fails. ( in the 8051 port, the size was 4).
1734 size = AOP_SIZE(op);
1735 if (size == GPTRSIZE)
1737 sym_link *type = operandType(op);
1738 if (IS_GENPTR(type))
1740 /* generic pointer; arithmetic operations
1741 * should ignore the high byte (pointer type).
1744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1751 /*-----------------------------------------------------------------*/
1752 /* pic14_outAcc - output Acc */
1753 /*-----------------------------------------------------------------*/
1754 void pic14_outAcc(operand *result)
1757 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1758 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1761 size = pic14_getDataSize(result);
1763 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1766 /* unsigned or positive */
1768 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1773 /*-----------------------------------------------------------------*/
1774 /* pic14_outBitC - output a bit C */
1775 /*-----------------------------------------------------------------*/
1776 void pic14_outBitC(operand *result)
1779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1780 /* if the result is bit */
1781 if (AOP_TYPE(result) == AOP_CRY)
1782 aopPut(AOP(result),"c",0);
1784 pic14_emitcode("clr","a ; %d", __LINE__);
1785 pic14_emitcode("rlc","a");
1786 pic14_outAcc(result);
1790 /*-----------------------------------------------------------------*/
1791 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1792 /*-----------------------------------------------------------------*/
1793 void pic14_toBoolean(operand *oper)
1795 int size = AOP_SIZE(oper) - 1;
1798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1800 if ( AOP_TYPE(oper) != AOP_ACC) {
1801 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1804 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1809 /*-----------------------------------------------------------------*/
1810 /* genNot - generate code for ! operation */
1811 /*-----------------------------------------------------------------*/
1812 static void genNot (iCode *ic)
1817 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1818 /* assign asmOps to operand & result */
1819 aopOp (IC_LEFT(ic),ic,FALSE);
1820 aopOp (IC_RESULT(ic),ic,TRUE);
1822 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1823 /* if in bit space then a special case */
1824 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1825 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1826 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1827 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1829 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1830 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1831 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1836 size = AOP_SIZE(IC_LEFT(ic));
1838 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1839 emitpcode(POC_ANDLW,popGetLit(1));
1840 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1843 pic14_toBoolean(IC_LEFT(ic));
1845 tlbl = newiTempLabel(NULL);
1846 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1847 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1848 pic14_outBitC(IC_RESULT(ic));
1851 /* release the aops */
1852 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1853 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1857 /*-----------------------------------------------------------------*/
1858 /* genCpl - generate code for complement */
1859 /*-----------------------------------------------------------------*/
1860 static void genCpl (iCode *ic)
1862 operand *left, *result;
1866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1867 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1868 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1870 /* if both are in bit space then
1872 if (AOP_TYPE(result) == AOP_CRY &&
1873 AOP_TYPE(left) == AOP_CRY ) {
1875 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1876 pic14_emitcode("cpl","c");
1877 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1881 size = AOP_SIZE(result);
1884 if(AOP_TYPE(left) == AOP_ACC)
1885 emitpcode(POC_XORLW, popGetLit(0xff));
1887 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1889 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1895 /* release the aops */
1896 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1897 freeAsmop(result,NULL,ic,TRUE);
1900 /*-----------------------------------------------------------------*/
1901 /* genUminusFloat - unary minus for floating points */
1902 /*-----------------------------------------------------------------*/
1903 static void genUminusFloat(operand *op,operand *result)
1905 int size ,offset =0 ;
1908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1909 /* for this we just need to flip the
1910 first it then copy the rest in place */
1911 size = AOP_SIZE(op) - 1;
1912 l = aopGet(AOP(op),3,FALSE,FALSE);
1916 pic14_emitcode("cpl","acc.7");
1917 aopPut(AOP(result),"a",3);
1921 aopGet(AOP(op),offset,FALSE,FALSE),
1927 /*-----------------------------------------------------------------*/
1928 /* genUminus - unary minus code generation */
1929 /*-----------------------------------------------------------------*/
1930 static void genUminus (iCode *ic)
1933 sym_link *optype, *rtype;
1936 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1938 aopOp(IC_LEFT(ic),ic,FALSE);
1939 aopOp(IC_RESULT(ic),ic,TRUE);
1941 /* if both in bit space then special
1943 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1944 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1946 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1947 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1948 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1953 optype = operandType(IC_LEFT(ic));
1954 rtype = operandType(IC_RESULT(ic));
1956 /* if float then do float stuff */
1957 if (IS_FLOAT(optype)) {
1958 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1962 /* otherwise subtract from zero by taking the 2's complement */
1963 size = AOP_SIZE(IC_LEFT(ic));
1965 for(i=0; i<size; i++) {
1966 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1967 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1969 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1970 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1974 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1975 for(i=1; i<size; i++) {
1977 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1981 /* release the aops */
1982 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1983 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1986 /*-----------------------------------------------------------------*/
1987 /* saveRegisters - will look for a call and save the registers */
1988 /*-----------------------------------------------------------------*/
1989 static void saveRegisters(iCode *lic)
1996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1998 for (ic = lic ; ic ; ic = ic->next)
1999 if (ic->op == CALL || ic->op == PCALL)
2003 fprintf(stderr,"found parameter push with no function call\n");
2007 /* if the registers have been saved already then
2009 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2012 /* find the registers in use at this time
2013 and push them away to safety */
2014 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2018 if (options.useXstack) {
2019 if (bitVectBitValue(rsave,R0_IDX))
2020 pic14_emitcode("mov","b,r0");
2021 pic14_emitcode("mov","r0,%s",spname);
2022 for (i = 0 ; i < pic14_nRegs ; i++) {
2023 if (bitVectBitValue(rsave,i)) {
2025 pic14_emitcode("mov","a,b");
2027 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2028 pic14_emitcode("movx","@r0,a");
2029 pic14_emitcode("inc","r0");
2032 pic14_emitcode("mov","%s,r0",spname);
2033 if (bitVectBitValue(rsave,R0_IDX))
2034 pic14_emitcode("mov","r0,b");
2036 //for (i = 0 ; i < pic14_nRegs ; i++) {
2037 // if (bitVectBitValue(rsave,i))
2038 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2041 dtype = operandType(IC_LEFT(ic));
2042 if (currFunc && dtype &&
2043 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2044 IFFUNC_ISISR(currFunc->type) &&
2047 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2050 /*-----------------------------------------------------------------*/
2051 /* unsaveRegisters - pop the pushed registers */
2052 /*-----------------------------------------------------------------*/
2053 static void unsaveRegisters (iCode *ic)
2058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2059 /* find the registers in use at this time
2060 and push them away to safety */
2061 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2064 if (options.useXstack) {
2065 pic14_emitcode("mov","r0,%s",spname);
2066 for (i = pic14_nRegs ; i >= 0 ; i--) {
2067 if (bitVectBitValue(rsave,i)) {
2068 pic14_emitcode("dec","r0");
2069 pic14_emitcode("movx","a,@r0");
2071 pic14_emitcode("mov","b,a");
2073 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2077 pic14_emitcode("mov","%s,r0",spname);
2078 if (bitVectBitValue(rsave,R0_IDX))
2079 pic14_emitcode("mov","r0,b");
2081 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2082 // if (bitVectBitValue(rsave,i))
2083 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2089 /*-----------------------------------------------------------------*/
2091 /*-----------------------------------------------------------------*/
2092 static void pushSide(operand * oper, int size)
2096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2098 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2099 if (AOP_TYPE(oper) != AOP_REG &&
2100 AOP_TYPE(oper) != AOP_DIR &&
2102 pic14_emitcode("mov","a,%s",l);
2103 pic14_emitcode("push","acc");
2105 pic14_emitcode("push","%s",l);
2110 /*-----------------------------------------------------------------*/
2111 /* assignResultValue - */
2112 /*-----------------------------------------------------------------*/
2113 static void assignResultValue(operand * oper)
2115 int size = AOP_SIZE(oper);
2117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2119 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2122 if (GpsuedoStkPtr++)
2123 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2124 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2129 /*-----------------------------------------------------------------*/
2130 /* genIpush - genrate code for pushing this gets a little complex */
2131 /*-----------------------------------------------------------------*/
2132 static void genIpush (iCode *ic)
2135 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2137 int size, offset = 0 ;
2141 /* if this is not a parm push : ie. it is spill push
2142 and spill push is always done on the local stack */
2143 if (!ic->parmPush) {
2145 /* and the item is spilt then do nothing */
2146 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2149 aopOp(IC_LEFT(ic),ic,FALSE);
2150 size = AOP_SIZE(IC_LEFT(ic));
2151 /* push it on the stack */
2153 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2158 pic14_emitcode("push","%s",l);
2163 /* this is a paramter push: in this case we call
2164 the routine to find the call and save those
2165 registers that need to be saved */
2168 /* then do the push */
2169 aopOp(IC_LEFT(ic),ic,FALSE);
2172 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2173 size = AOP_SIZE(IC_LEFT(ic));
2176 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2177 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2178 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2180 pic14_emitcode("mov","a,%s",l);
2181 pic14_emitcode("push","acc");
2183 pic14_emitcode("push","%s",l);
2186 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2190 /*-----------------------------------------------------------------*/
2191 /* genIpop - recover the registers: can happen only for spilling */
2192 /*-----------------------------------------------------------------*/
2193 static void genIpop (iCode *ic)
2195 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2200 /* if the temp was not pushed then */
2201 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2204 aopOp(IC_LEFT(ic),ic,FALSE);
2205 size = AOP_SIZE(IC_LEFT(ic));
2208 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2211 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2215 /*-----------------------------------------------------------------*/
2216 /* unsaverbank - restores the resgister bank from stack */
2217 /*-----------------------------------------------------------------*/
2218 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2220 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2228 if (options.useXstack) {
2230 r = getFreePtr(ic,&aop,FALSE);
2233 pic14_emitcode("mov","%s,_spx",r->name);
2234 pic14_emitcode("movx","a,@%s",r->name);
2235 pic14_emitcode("mov","psw,a");
2236 pic14_emitcode("dec","%s",r->name);
2239 pic14_emitcode ("pop","psw");
2242 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2243 if (options.useXstack) {
2244 pic14_emitcode("movx","a,@%s",r->name);
2245 //pic14_emitcode("mov","(%s+%d),a",
2246 // regspic14[i].base,8*bank+regspic14[i].offset);
2247 pic14_emitcode("dec","%s",r->name);
2250 pic14_emitcode("pop",""); //"(%s+%d)",
2251 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2254 if (options.useXstack) {
2256 pic14_emitcode("mov","_spx,%s",r->name);
2257 freeAsmop(NULL,aop,ic,TRUE);
2263 /*-----------------------------------------------------------------*/
2264 /* saverbank - saves an entire register bank on the stack */
2265 /*-----------------------------------------------------------------*/
2266 static void saverbank (int bank, iCode *ic, bool pushPsw)
2268 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2275 if (options.useXstack) {
2278 r = getFreePtr(ic,&aop,FALSE);
2279 pic14_emitcode("mov","%s,_spx",r->name);
2283 for (i = 0 ; i < pic14_nRegs ;i++) {
2284 if (options.useXstack) {
2285 pic14_emitcode("inc","%s",r->name);
2286 //pic14_emitcode("mov","a,(%s+%d)",
2287 // regspic14[i].base,8*bank+regspic14[i].offset);
2288 pic14_emitcode("movx","@%s,a",r->name);
2290 pic14_emitcode("push","");// "(%s+%d)",
2291 //regspic14[i].base,8*bank+regspic14[i].offset);
2295 if (options.useXstack) {
2296 pic14_emitcode("mov","a,psw");
2297 pic14_emitcode("movx","@%s,a",r->name);
2298 pic14_emitcode("inc","%s",r->name);
2299 pic14_emitcode("mov","_spx,%s",r->name);
2300 freeAsmop (NULL,aop,ic,TRUE);
2303 pic14_emitcode("push","psw");
2305 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2311 /*-----------------------------------------------------------------*/
2312 /* genCall - generates a call statement */
2313 /*-----------------------------------------------------------------*/
2314 static void genCall (iCode *ic)
2318 unsigned char *name;
2321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2323 /* if caller saves & we have not saved then */
2327 /* if we are calling a function that is not using
2328 the same register bank then we need to save the
2329 destination registers on the stack */
2330 dtype = operandType(IC_LEFT(ic));
2331 if (currFunc && dtype &&
2332 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2333 IFFUNC_ISISR(currFunc->type) &&
2336 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2338 /* if send set is not empty the assign */
2341 /* For the Pic port, there is no data stack.
2342 * So parameters passed to functions are stored
2343 * in registers. (The pCode optimizer will get
2344 * rid of most of these :).
2346 int psuedoStkPtr=-1;
2347 int firstTimeThruLoop = 1;
2349 _G.sendSet = reverseSet(_G.sendSet);
2351 /* First figure how many parameters are getting passed */
2352 for (sic = setFirstItem(_G.sendSet) ; sic ;
2353 sic = setNextItem(_G.sendSet)) {
2355 aopOp(IC_LEFT(sic),sic,FALSE);
2356 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2357 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2360 for (sic = setFirstItem(_G.sendSet) ; sic ;
2361 sic = setNextItem(_G.sendSet)) {
2362 int size, offset = 0;
2364 aopOp(IC_LEFT(sic),sic,FALSE);
2365 size = AOP_SIZE(IC_LEFT(sic));
2368 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2369 AopType(AOP_TYPE(IC_LEFT(sic))));
2371 if(!firstTimeThruLoop) {
2372 /* If this is not the first time we've been through the loop
2373 * then we need to save the parameter in a temporary
2374 * register. The last byte of the last parameter is
2376 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2379 firstTimeThruLoop=0;
2381 mov2w (AOP(IC_LEFT(sic)), offset);
2384 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2389 sym = OP_SYMBOL(IC_LEFT(ic));
2390 name = sym->rname[0] ? sym->rname : sym->name;
2391 isExtern = IS_EXTERN(sym->etype);
2393 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2395 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2397 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2400 /* if we need assign a result value */
2401 if ((IS_ITEMP(IC_RESULT(ic)) &&
2402 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2403 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2404 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2407 aopOp(IC_RESULT(ic),ic,FALSE);
2410 assignResultValue(IC_RESULT(ic));
2412 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2413 AopType(AOP_TYPE(IC_RESULT(ic))));
2415 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2418 /* adjust the stack for parameters if
2420 if (ic->parmBytes) {
2422 if (ic->parmBytes > 3) {
2423 pic14_emitcode("mov","a,%s",spname);
2424 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2425 pic14_emitcode("mov","%s,a",spname);
2427 for ( i = 0 ; i < ic->parmBytes ;i++)
2428 pic14_emitcode("dec","%s",spname);
2432 /* if register bank was saved then pop them */
2434 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2436 /* if we hade saved some registers then unsave them */
2437 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2438 unsaveRegisters (ic);
2443 /*-----------------------------------------------------------------*/
2444 /* genPcall - generates a call by pointer statement */
2445 /*-----------------------------------------------------------------*/
2446 static void genPcall (iCode *ic)
2449 symbol *albl = newiTempLabel(NULL);
2450 symbol *blbl = newiTempLabel(NULL);
2455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2456 /* if caller saves & we have not saved then */
2460 /* if we are calling a function that is not using
2461 the same register bank then we need to save the
2462 destination registers on the stack */
2463 dtype = operandType(IC_LEFT(ic));
2464 if (currFunc && dtype &&
2465 IFFUNC_ISISR(currFunc->type) &&
2466 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2467 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2470 aopOp(left,ic,FALSE);
2471 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2473 pushSide(IC_LEFT(ic), FPTRSIZE);
2475 /* if send set is not empty, assign parameters */
2478 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2479 /* no way to pass args - W always gets used to make the call */
2481 /* first idea - factor out a common helper function and call it.
2482 But don't know how to get it generated only once in its own block
2484 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2487 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2488 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2489 buffer = Safe_calloc(1,strlen(rname)+16);
2490 sprintf(buffer, "%s_goto_helper", rname);
2491 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2495 emitpcode(POC_CALL,popGetLabel(albl->key));
2496 pcop = popGetLabel(blbl->key);
2497 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2498 emitpcode(POC_GOTO,pcop);
2499 emitpLabel(albl->key);
2501 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2503 emitpcode(poc,popGet(AOP(left),1));
2504 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2505 emitpcode(poc,popGet(AOP(left),0));
2506 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2508 emitpLabel(blbl->key);
2510 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2512 /* if we need to assign a result value */
2513 if ((IS_ITEMP(IC_RESULT(ic)) &&
2514 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2515 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2516 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2519 aopOp(IC_RESULT(ic),ic,FALSE);
2522 assignResultValue(IC_RESULT(ic));
2524 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2527 /* if register bank was saved then unsave them */
2528 if (currFunc && dtype &&
2529 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2530 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2532 /* if we hade saved some registers then
2535 unsaveRegisters (ic);
2539 /*-----------------------------------------------------------------*/
2540 /* resultRemat - result is rematerializable */
2541 /*-----------------------------------------------------------------*/
2542 static int resultRemat (iCode *ic)
2544 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2545 if (SKIP_IC(ic) || ic->op == IFX)
2548 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2549 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2550 if (sym->remat && !POINTER_SET(ic))
2557 #if defined(__BORLANDC__) || defined(_MSC_VER)
2558 #define STRCASECMP stricmp
2560 #define STRCASECMP strcasecmp
2564 /*-----------------------------------------------------------------*/
2565 /* inExcludeList - return 1 if the string is in exclude Reg list */
2566 /*-----------------------------------------------------------------*/
2567 static bool inExcludeList(char *s)
2569 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2573 if (options.excludeRegs[i] &&
2574 STRCASECMP(options.excludeRegs[i],"none") == 0)
2577 for ( i = 0 ; options.excludeRegs[i]; i++) {
2578 if (options.excludeRegs[i] &&
2579 STRCASECMP(s,options.excludeRegs[i]) == 0)
2586 /*-----------------------------------------------------------------*/
2587 /* genFunction - generated code for function entry */
2588 /*-----------------------------------------------------------------*/
2589 static void genFunction (iCode *ic)
2594 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2596 labelOffset += (max_key+4);
2600 /* create the function header */
2601 pic14_emitcode(";","-----------------------------------------");
2602 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2603 pic14_emitcode(";","-----------------------------------------");
2605 pic14_emitcode("","%s:",sym->rname);
2606 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2608 ftype = operandType(IC_LEFT(ic));
2610 /* if critical function then turn interrupts off */
2611 if (IFFUNC_ISCRITICAL(ftype))
2612 pic14_emitcode("clr","ea");
2614 /* here we need to generate the equates for the
2615 register bank if required */
2617 if (FUNC_REGBANK(ftype) != rbank) {
2620 rbank = FUNC_REGBANK(ftype);
2621 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2622 if (strcmp(regspic14[i].base,"0") == 0)
2623 pic14_emitcode("","%s = 0x%02x",
2625 8*rbank+regspic14[i].offset);
2627 pic14_emitcode ("","%s = %s + 0x%02x",
2630 8*rbank+regspic14[i].offset);
2635 /* if this is an interrupt service routine */
2636 if (IFFUNC_ISISR(sym->type)) {
2637 /* already done in pic14createInterruptVect() - delete me
2638 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2639 emitpcodeNULLop(POC_NOP);
2640 emitpcodeNULLop(POC_NOP);
2641 emitpcodeNULLop(POC_NOP);
2643 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2644 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2645 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2646 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2647 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2648 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2649 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2651 pBlockConvert2ISR(pb);
2653 if (!inExcludeList("acc"))
2654 pic14_emitcode ("push","acc");
2655 if (!inExcludeList("b"))
2656 pic14_emitcode ("push","b");
2657 if (!inExcludeList("dpl"))
2658 pic14_emitcode ("push","dpl");
2659 if (!inExcludeList("dph"))
2660 pic14_emitcode ("push","dph");
2661 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2663 pic14_emitcode ("push", "dpx");
2664 /* Make sure we're using standard DPTR */
2665 pic14_emitcode ("push", "dps");
2666 pic14_emitcode ("mov", "dps, #0x00");
2667 if (options.stack10bit)
2669 /* This ISR could conceivably use DPTR2. Better save it. */
2670 pic14_emitcode ("push", "dpl1");
2671 pic14_emitcode ("push", "dph1");
2672 pic14_emitcode ("push", "dpx1");
2675 /* if this isr has no bank i.e. is going to
2676 run with bank 0 , then we need to save more
2678 if (!FUNC_REGBANK(sym->type)) {
2680 /* if this function does not call any other
2681 function then we can be economical and
2682 save only those registers that are used */
2683 if (! IFFUNC_HASFCALL(sym->type)) {
2686 /* if any registers used */
2687 if (sym->regsUsed) {
2688 /* save the registers used */
2689 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2690 if (bitVectBitValue(sym->regsUsed,i) ||
2691 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2692 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2697 /* this function has a function call cannot
2698 determines register usage so we will have the
2700 saverbank(0,ic,FALSE);
2705 /* if callee-save to be used for this function
2706 then save the registers being used in this function */
2707 if (IFFUNC_CALLEESAVES(sym->type)) {
2710 /* if any registers used */
2711 if (sym->regsUsed) {
2712 /* save the registers used */
2713 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2714 if (bitVectBitValue(sym->regsUsed,i) ||
2715 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2716 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2724 /* set the register bank to the desired value */
2725 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2726 pic14_emitcode("push","psw");
2727 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2730 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2732 if (options.useXstack) {
2733 pic14_emitcode("mov","r0,%s",spname);
2734 pic14_emitcode("mov","a,_bp");
2735 pic14_emitcode("movx","@r0,a");
2736 pic14_emitcode("inc","%s",spname);
2740 /* set up the stack */
2741 pic14_emitcode ("push","_bp"); /* save the callers stack */
2743 pic14_emitcode ("mov","_bp,%s",spname);
2746 /* adjust the stack for the function */
2751 werror(W_STACK_OVERFLOW,sym->name);
2753 if (i > 3 && sym->recvSize < 4) {
2755 pic14_emitcode ("mov","a,sp");
2756 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2757 pic14_emitcode ("mov","sp,a");
2762 pic14_emitcode("inc","sp");
2767 pic14_emitcode ("mov","a,_spx");
2768 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2769 pic14_emitcode ("mov","_spx,a");
2774 /*-----------------------------------------------------------------*/
2775 /* genEndFunction - generates epilogue for functions */
2776 /*-----------------------------------------------------------------*/
2777 static void genEndFunction (iCode *ic)
2779 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2783 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2785 pic14_emitcode ("mov","%s,_bp",spname);
2788 /* if use external stack but some variables were
2789 added to the local stack then decrement the
2791 if (options.useXstack && sym->stack) {
2792 pic14_emitcode("mov","a,sp");
2793 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2794 pic14_emitcode("mov","sp,a");
2798 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2799 if (options.useXstack) {
2800 pic14_emitcode("mov","r0,%s",spname);
2801 pic14_emitcode("movx","a,@r0");
2802 pic14_emitcode("mov","_bp,a");
2803 pic14_emitcode("dec","%s",spname);
2807 pic14_emitcode ("pop","_bp");
2811 /* restore the register bank */
2812 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2813 pic14_emitcode ("pop","psw");
2815 if (IFFUNC_ISISR(sym->type)) {
2817 /* now we need to restore the registers */
2818 /* if this isr has no bank i.e. is going to
2819 run with bank 0 , then we need to save more
2821 if (!FUNC_REGBANK(sym->type)) {
2823 /* if this function does not call any other
2824 function then we can be economical and
2825 save only those registers that are used */
2826 if (! IFFUNC_HASFCALL(sym->type)) {
2829 /* if any registers used */
2830 if (sym->regsUsed) {
2831 /* save the registers used */
2832 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2833 if (bitVectBitValue(sym->regsUsed,i) ||
2834 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2835 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2840 /* this function has a function call cannot
2841 determines register usage so we will have the
2843 unsaverbank(0,ic,FALSE);
2847 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2849 if (options.stack10bit)
2851 pic14_emitcode ("pop", "dpx1");
2852 pic14_emitcode ("pop", "dph1");
2853 pic14_emitcode ("pop", "dpl1");
2855 pic14_emitcode ("pop", "dps");
2856 pic14_emitcode ("pop", "dpx");
2858 if (!inExcludeList("dph"))
2859 pic14_emitcode ("pop","dph");
2860 if (!inExcludeList("dpl"))
2861 pic14_emitcode ("pop","dpl");
2862 if (!inExcludeList("b"))
2863 pic14_emitcode ("pop","b");
2864 if (!inExcludeList("acc"))
2865 pic14_emitcode ("pop","acc");
2867 if (IFFUNC_ISCRITICAL(sym->type))
2868 pic14_emitcode("setb","ea");
2871 /* if debug then send end of function */
2872 /* if (options.debug && currFunc) { */
2874 debugFile->writeEndFunction (currFunc, ic, 1);
2877 pic14_emitcode ("reti","");
2878 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2879 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2880 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2881 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2882 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2883 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2884 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2885 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2886 emitpcodeNULLop(POC_RETFIE);
2889 if (IFFUNC_ISCRITICAL(sym->type))
2890 pic14_emitcode("setb","ea");
2892 if (IFFUNC_CALLEESAVES(sym->type)) {
2895 /* if any registers used */
2896 if (sym->regsUsed) {
2897 /* save the registers used */
2898 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2899 if (bitVectBitValue(sym->regsUsed,i) ||
2900 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2901 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2907 /* if debug then send end of function */
2909 debugFile->writeEndFunction (currFunc, ic, 1);
2912 pic14_emitcode ("return","");
2913 emitpcodeNULLop(POC_RETURN);
2915 /* Mark the end of a function */
2916 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2921 /*-----------------------------------------------------------------*/
2922 /* genRet - generate code for return statement */
2923 /*-----------------------------------------------------------------*/
2924 static void genRet (iCode *ic)
2926 int size,offset = 0 , pushed = 0;
2928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2929 /* if we have no return value then
2930 just generate the "ret" */
2934 /* we have something to return then
2935 move the return value into place */
2936 aopOp(IC_LEFT(ic),ic,FALSE);
2937 size = AOP_SIZE(IC_LEFT(ic));
2941 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2943 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2945 pic14_emitcode("push","%s",l);
2948 l = aopGet(AOP(IC_LEFT(ic)),offset,
2950 if (strcmp(fReturn[offset],l)) {
2951 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2952 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2953 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2954 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2955 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2957 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2960 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2970 if (strcmp(fReturn[pushed],"a"))
2971 pic14_emitcode("pop",fReturn[pushed]);
2973 pic14_emitcode("pop","acc");
2976 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2979 /* generate a jump to the return label
2980 if the next is not the return statement */
2981 if (!(ic->next && ic->next->op == LABEL &&
2982 IC_LABEL(ic->next) == returnLabel)) {
2984 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2985 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2990 /*-----------------------------------------------------------------*/
2991 /* genLabel - generates a label */
2992 /*-----------------------------------------------------------------*/
2993 static void genLabel (iCode *ic)
2995 /* special case never generate */
2996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2997 if (IC_LABEL(ic) == entryLabel)
3000 emitpLabel(IC_LABEL(ic)->key);
3001 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3004 /*-----------------------------------------------------------------*/
3005 /* genGoto - generates a goto */
3006 /*-----------------------------------------------------------------*/
3008 static void genGoto (iCode *ic)
3010 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3011 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3015 /*-----------------------------------------------------------------*/
3016 /* genMultbits :- multiplication of bits */
3017 /*-----------------------------------------------------------------*/
3018 static void genMultbits (operand *left,
3022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3024 if(!pic14_sameRegs(AOP(result),AOP(right)))
3025 emitpcode(POC_BSF, popGet(AOP(result),0));
3027 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3028 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3029 emitpcode(POC_BCF, popGet(AOP(result),0));
3034 /*-----------------------------------------------------------------*/
3035 /* genMultOneByte : 8 bit multiplication & division */
3036 /*-----------------------------------------------------------------*/
3037 static void genMultOneByte (operand *left,
3041 sym_link *opetype = operandType(result);
3046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3047 DEBUGpic14_AopType(__LINE__,left,right,result);
3048 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3050 /* (if two literals, the value is computed before) */
3051 /* if one literal, literal on the right */
3052 if (AOP_TYPE(left) == AOP_LIT){
3058 size = AOP_SIZE(result);
3061 if (AOP_TYPE(right) == AOP_LIT){
3062 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3063 aopGet(AOP(right),0,FALSE,FALSE),
3064 aopGet(AOP(left),0,FALSE,FALSE),
3065 aopGet(AOP(result),0,FALSE,FALSE));
3066 pic14_emitcode("call","genMultLit");
3068 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3069 aopGet(AOP(right),0,FALSE,FALSE),
3070 aopGet(AOP(left),0,FALSE,FALSE),
3071 aopGet(AOP(result),0,FALSE,FALSE));
3072 pic14_emitcode("call","genMult8X8_8");
3075 genMult8X8_8 (left, right,result);
3078 /* signed or unsigned */
3079 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3080 //l = aopGet(AOP(left),0,FALSE,FALSE);
3082 //pic14_emitcode("mul","ab");
3083 /* if result size = 1, mul signed = mul unsigned */
3084 //aopPut(AOP(result),"a",0);
3086 } else { // (size > 1)
3088 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3089 aopGet(AOP(right),0,FALSE,FALSE),
3090 aopGet(AOP(left),0,FALSE,FALSE),
3091 aopGet(AOP(result),0,FALSE,FALSE));
3093 if (SPEC_USIGN(opetype)){
3094 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3095 genUMult8X8_16 (left, right, result, NULL);
3098 /* for filling the MSBs */
3099 emitpcode(POC_CLRF, popGet(AOP(result),2));
3100 emitpcode(POC_CLRF, popGet(AOP(result),3));
3104 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3106 pic14_emitcode("mov","a,b");
3108 /* adjust the MSB if left or right neg */
3110 /* if one literal */
3111 if (AOP_TYPE(right) == AOP_LIT){
3112 pic14_emitcode("multiply ","right is a lit");
3113 /* AND literal negative */
3114 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3115 /* adjust MSB (c==0 after mul) */
3116 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3120 genSMult8X8_16 (left, right, result, NULL);
3124 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3126 pic14_emitcode("rlc","a");
3127 pic14_emitcode("subb","a,acc");
3135 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3136 //aopPut(AOP(result),"a",offset++);
3140 /*-----------------------------------------------------------------*/
3141 /* genMult - generates code for multiplication */
3142 /*-----------------------------------------------------------------*/
3143 static void genMult (iCode *ic)
3145 operand *left = IC_LEFT(ic);
3146 operand *right = IC_RIGHT(ic);
3147 operand *result= IC_RESULT(ic);
3149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3150 /* assign the amsops */
3151 aopOp (left,ic,FALSE);
3152 aopOp (right,ic,FALSE);
3153 aopOp (result,ic,TRUE);
3155 DEBUGpic14_AopType(__LINE__,left,right,result);
3157 /* special cases first */
3159 if (AOP_TYPE(left) == AOP_CRY &&
3160 AOP_TYPE(right)== AOP_CRY) {
3161 genMultbits(left,right,result);
3165 /* if both are of size == 1 */
3166 if (AOP_SIZE(left) == 1 &&
3167 AOP_SIZE(right) == 1 ) {
3168 genMultOneByte(left,right,result);
3172 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3174 /* should have been converted to function call */
3178 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3179 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3180 freeAsmop(result,NULL,ic,TRUE);
3183 /*-----------------------------------------------------------------*/
3184 /* genDivbits :- division of bits */
3185 /*-----------------------------------------------------------------*/
3186 static void genDivbits (operand *left,
3193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3194 /* the result must be bit */
3195 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3196 l = aopGet(AOP(left),0,FALSE,FALSE);
3200 pic14_emitcode("div","ab");
3201 pic14_emitcode("rrc","a");
3202 aopPut(AOP(result),"c",0);
3205 /*-----------------------------------------------------------------*/
3206 /* genDivOneByte : 8 bit division */
3207 /*-----------------------------------------------------------------*/
3208 static void genDivOneByte (operand *left,
3212 sym_link *opetype = operandType(result);
3217 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3218 size = AOP_SIZE(result) - 1;
3220 /* signed or unsigned */
3221 if (SPEC_USIGN(opetype)) {
3222 /* unsigned is easy */
3223 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3224 l = aopGet(AOP(left),0,FALSE,FALSE);
3226 pic14_emitcode("div","ab");
3227 aopPut(AOP(result),"a",0);
3229 aopPut(AOP(result),zero,offset++);
3233 /* signed is a little bit more difficult */
3235 /* save the signs of the operands */
3236 l = aopGet(AOP(left),0,FALSE,FALSE);
3238 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3239 pic14_emitcode("push","acc"); /* save it on the stack */
3241 /* now sign adjust for both left & right */
3242 l = aopGet(AOP(right),0,FALSE,FALSE);
3244 lbl = newiTempLabel(NULL);
3245 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3246 pic14_emitcode("cpl","a");
3247 pic14_emitcode("inc","a");
3248 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3249 pic14_emitcode("mov","b,a");
3251 /* sign adjust left side */
3252 l = aopGet(AOP(left),0,FALSE,FALSE);
3255 lbl = newiTempLabel(NULL);
3256 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3257 pic14_emitcode("cpl","a");
3258 pic14_emitcode("inc","a");
3259 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3261 /* now the division */
3262 pic14_emitcode("div","ab");
3263 /* we are interested in the lower order
3265 pic14_emitcode("mov","b,a");
3266 lbl = newiTempLabel(NULL);
3267 pic14_emitcode("pop","acc");
3268 /* if there was an over flow we don't
3269 adjust the sign of the result */
3270 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3271 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3273 pic14_emitcode("clr","a");
3274 pic14_emitcode("subb","a,b");
3275 pic14_emitcode("mov","b,a");
3276 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3278 /* now we are done */
3279 aopPut(AOP(result),"b",0);
3281 pic14_emitcode("mov","c,b.7");
3282 pic14_emitcode("subb","a,acc");
3285 aopPut(AOP(result),"a",offset++);
3289 /*-----------------------------------------------------------------*/
3290 /* genDiv - generates code for division */
3291 /*-----------------------------------------------------------------*/
3292 static void genDiv (iCode *ic)
3294 operand *left = IC_LEFT(ic);
3295 operand *right = IC_RIGHT(ic);
3296 operand *result= IC_RESULT(ic);
3298 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3299 /* assign the amsops */
3300 aopOp (left,ic,FALSE);
3301 aopOp (right,ic,FALSE);
3302 aopOp (result,ic,TRUE);
3304 /* special cases first */
3306 if (AOP_TYPE(left) == AOP_CRY &&
3307 AOP_TYPE(right)== AOP_CRY) {
3308 genDivbits(left,right,result);
3312 /* if both are of size == 1 */
3313 if (AOP_SIZE(left) == 1 &&
3314 AOP_SIZE(right) == 1 ) {
3315 genDivOneByte(left,right,result);
3319 /* should have been converted to function call */
3322 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3323 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3324 freeAsmop(result,NULL,ic,TRUE);
3327 /*-----------------------------------------------------------------*/
3328 /* genModbits :- modulus of bits */
3329 /*-----------------------------------------------------------------*/
3330 static void genModbits (operand *left,
3337 /* the result must be bit */
3338 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3339 l = aopGet(AOP(left),0,FALSE,FALSE);
3343 pic14_emitcode("div","ab");
3344 pic14_emitcode("mov","a,b");
3345 pic14_emitcode("rrc","a");
3346 aopPut(AOP(result),"c",0);
3349 /*-----------------------------------------------------------------*/
3350 /* genModOneByte : 8 bit modulus */
3351 /*-----------------------------------------------------------------*/
3352 static void genModOneByte (operand *left,
3356 sym_link *opetype = operandType(result);
3360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3361 /* signed or unsigned */
3362 if (SPEC_USIGN(opetype)) {
3363 /* unsigned is easy */
3364 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3365 l = aopGet(AOP(left),0,FALSE,FALSE);
3367 pic14_emitcode("div","ab");
3368 aopPut(AOP(result),"b",0);
3372 /* signed is a little bit more difficult */
3374 /* save the signs of the operands */
3375 l = aopGet(AOP(left),0,FALSE,FALSE);
3378 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3379 pic14_emitcode("push","acc"); /* save it on the stack */
3381 /* now sign adjust for both left & right */
3382 l = aopGet(AOP(right),0,FALSE,FALSE);
3385 lbl = newiTempLabel(NULL);
3386 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3387 pic14_emitcode("cpl","a");
3388 pic14_emitcode("inc","a");
3389 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3390 pic14_emitcode("mov","b,a");
3392 /* sign adjust left side */
3393 l = aopGet(AOP(left),0,FALSE,FALSE);
3396 lbl = newiTempLabel(NULL);
3397 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3398 pic14_emitcode("cpl","a");
3399 pic14_emitcode("inc","a");
3400 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3402 /* now the multiplication */
3403 pic14_emitcode("div","ab");
3404 /* we are interested in the lower order
3406 lbl = newiTempLabel(NULL);
3407 pic14_emitcode("pop","acc");
3408 /* if there was an over flow we don't
3409 adjust the sign of the result */
3410 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3411 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3413 pic14_emitcode("clr","a");
3414 pic14_emitcode("subb","a,b");
3415 pic14_emitcode("mov","b,a");
3416 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3418 /* now we are done */
3419 aopPut(AOP(result),"b",0);
3423 /*-----------------------------------------------------------------*/
3424 /* genMod - generates code for division */
3425 /*-----------------------------------------------------------------*/
3426 static void genMod (iCode *ic)
3428 operand *left = IC_LEFT(ic);
3429 operand *right = IC_RIGHT(ic);
3430 operand *result= IC_RESULT(ic);
3432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3433 /* assign the amsops */
3434 aopOp (left,ic,FALSE);
3435 aopOp (right,ic,FALSE);
3436 aopOp (result,ic,TRUE);
3438 /* special cases first */
3440 if (AOP_TYPE(left) == AOP_CRY &&
3441 AOP_TYPE(right)== AOP_CRY) {
3442 genModbits(left,right,result);
3446 /* if both are of size == 1 */
3447 if (AOP_SIZE(left) == 1 &&
3448 AOP_SIZE(right) == 1 ) {
3449 genModOneByte(left,right,result);
3453 /* should have been converted to function call */
3457 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3458 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3459 freeAsmop(result,NULL,ic,TRUE);
3462 /*-----------------------------------------------------------------*/
3463 /* genIfxJump :- will create a jump depending on the ifx */
3464 /*-----------------------------------------------------------------*/
3466 note: May need to add parameter to indicate when a variable is in bit space.
3468 static void genIfxJump (iCode *ic, char *jval)
3471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3472 /* if true label then we jump if condition
3474 if ( IC_TRUE(ic) ) {
3476 if(strcmp(jval,"a") == 0)
3478 else if (strcmp(jval,"c") == 0)
3481 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3482 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3485 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3486 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3490 /* false label is present */
3491 if(strcmp(jval,"a") == 0)
3493 else if (strcmp(jval,"c") == 0)
3496 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3497 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3500 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3501 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3506 /* mark the icode as generated */
3510 /*-----------------------------------------------------------------*/
3512 /*-----------------------------------------------------------------*/
3513 static void genSkip(iCode *ifx,int status_bit)
3518 if ( IC_TRUE(ifx) ) {
3519 switch(status_bit) {
3534 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3535 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3539 switch(status_bit) {
3553 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3554 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3560 /*-----------------------------------------------------------------*/
3562 /*-----------------------------------------------------------------*/
3563 static void genSkipc(resolvedIfx *rifx)
3573 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3574 rifx->generated = 1;
3577 /*-----------------------------------------------------------------*/
3579 /*-----------------------------------------------------------------*/
3580 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3585 if( (rifx->condition ^ invert_condition) & 1)
3590 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3591 rifx->generated = 1;
3594 /*-----------------------------------------------------------------*/
3596 /*-----------------------------------------------------------------*/
3597 static void genSkipz(iCode *ifx, int condition)
3608 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3610 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3613 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3615 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3618 /*-----------------------------------------------------------------*/
3620 /*-----------------------------------------------------------------*/
3621 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3627 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3629 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3632 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3633 rifx->generated = 1;
3637 /*-----------------------------------------------------------------*/
3638 /* genChkZeroes :- greater or less than comparison */
3639 /* For each byte in a literal that is zero, inclusive or the */
3640 /* the corresponding byte in the operand with W */
3641 /* returns true if any of the bytes are zero */
3642 /*-----------------------------------------------------------------*/
3643 static int genChkZeroes(operand *op, int lit, int size)
3650 i = (lit >> (size*8)) & 0xff;
3654 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3656 emitpcode(POC_IORFW, popGet(AOP(op),size));
3665 /*-----------------------------------------------------------------*/
3666 /* genCmp :- greater or less than comparison */
3667 /*-----------------------------------------------------------------*/
3668 static void genCmp (operand *left,operand *right,
3669 operand *result, iCode *ifx, int sign)
3671 int size; //, offset = 0 ;
3672 unsigned long lit = 0L,i = 0;
3673 resolvedIfx rFalseIfx;
3674 // resolvedIfx rTrueIfx;
3676 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3679 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3680 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3684 resolveIfx(&rFalseIfx,ifx);
3685 truelbl = newiTempLabel(NULL);
3686 size = max(AOP_SIZE(left),AOP_SIZE(right));
3688 DEBUGpic14_AopType(__LINE__,left,right,result);
3692 /* if literal is on the right then swap with left */
3693 if ((AOP_TYPE(right) == AOP_LIT)) {
3694 operand *tmp = right ;
3695 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3696 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3699 lit = (lit - 1) & mask;
3702 rFalseIfx.condition ^= 1;
3705 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3706 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3710 //if(IC_TRUE(ifx) == NULL)
3711 /* if left & right are bit variables */
3712 if (AOP_TYPE(left) == AOP_CRY &&
3713 AOP_TYPE(right) == AOP_CRY ) {
3714 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3715 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3717 /* subtract right from left if at the
3718 end the carry flag is set then we know that
3719 left is greater than right */
3721 symbol *lbl = newiTempLabel(NULL);
3724 if(AOP_TYPE(right) == AOP_LIT) {
3726 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3728 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3735 genSkipCond(&rFalseIfx,left,size-1,7);
3737 /* no need to compare to 0...*/
3738 /* NOTE: this is a de-generate compare that most certainly
3739 * creates some dead code. */
3740 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3742 if(ifx) ifx->generated = 1;
3749 //i = (lit >> (size*8)) & 0xff;
3750 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3752 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3754 i = ((0-lit) & 0xff);
3757 /* lit is 0x7f, all signed chars are less than
3758 * this except for 0x7f itself */
3759 emitpcode(POC_XORLW, popGetLit(0x7f));
3760 genSkipz2(&rFalseIfx,0);
3762 emitpcode(POC_ADDLW, popGetLit(0x80));
3763 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3764 genSkipc(&rFalseIfx);
3769 genSkipz2(&rFalseIfx,1);
3771 emitpcode(POC_ADDLW, popGetLit(i));
3772 genSkipc(&rFalseIfx);
3776 if(ifx) ifx->generated = 1;
3780 /* chars are out of the way. now do ints and longs */
3783 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3790 genSkipCond(&rFalseIfx,left,size,7);
3791 if(ifx) ifx->generated = 1;
3796 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3798 //rFalseIfx.condition ^= 1;
3799 //genSkipCond(&rFalseIfx,left,size,7);
3800 //rFalseIfx.condition ^= 1;
3802 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3803 if(rFalseIfx.condition)
3804 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3806 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3808 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3809 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3810 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3813 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3815 if(rFalseIfx.condition) {
3817 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3823 genSkipc(&rFalseIfx);
3824 emitpLabel(truelbl->key);
3825 if(ifx) ifx->generated = 1;
3832 if( (lit & 0xff) == 0) {
3833 /* lower byte is zero */
3834 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3835 i = ((lit >> 8) & 0xff) ^0x80;
3836 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3837 emitpcode(POC_ADDLW, popGetLit( 0x80));
3838 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3839 genSkipc(&rFalseIfx);
3842 if(ifx) ifx->generated = 1;
3847 /* Special cases for signed longs */
3848 if( (lit & 0xffffff) == 0) {
3849 /* lower byte is zero */
3850 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3851 i = ((lit >> 8*3) & 0xff) ^0x80;
3852 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3853 emitpcode(POC_ADDLW, popGetLit( 0x80));
3854 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3855 genSkipc(&rFalseIfx);
3858 if(ifx) ifx->generated = 1;
3866 if(lit & (0x80 << (size*8))) {
3867 /* lit is negative */
3868 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3870 //genSkipCond(&rFalseIfx,left,size,7);
3872 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3874 if(rFalseIfx.condition)
3875 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3877 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3881 /* lit is positive */
3882 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3883 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3884 if(rFalseIfx.condition)
3885 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3887 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3891 /* There are no more special cases, so perform a general compare */
3893 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3894 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3898 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3900 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3902 //rFalseIfx.condition ^= 1;
3903 genSkipc(&rFalseIfx);
3905 emitpLabel(truelbl->key);
3907 if(ifx) ifx->generated = 1;
3914 /* sign is out of the way. So now do an unsigned compare */
3915 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3918 /* General case - compare to an unsigned literal on the right.*/
3920 i = (lit >> (size*8)) & 0xff;
3921 emitpcode(POC_MOVLW, popGetLit(i));
3922 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3924 i = (lit >> (size*8)) & 0xff;
3927 emitpcode(POC_MOVLW, popGetLit(i));
3929 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3931 /* this byte of the lit is zero,
3932 *if it's not the last then OR in the variable */
3934 emitpcode(POC_IORFW, popGet(AOP(left),size));
3939 emitpLabel(lbl->key);
3940 //if(emitFinalCheck)
3941 genSkipc(&rFalseIfx);
3943 emitpLabel(truelbl->key);
3945 if(ifx) ifx->generated = 1;
3952 if(AOP_TYPE(left) == AOP_LIT) {
3953 //symbol *lbl = newiTempLabel(NULL);
3955 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3958 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3961 if((lit == 0) && (sign == 0)){
3964 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3966 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3968 genSkipz2(&rFalseIfx,0);
3969 if(ifx) ifx->generated = 1;
3976 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3977 /* degenerate compare can never be true */
3978 if(rFalseIfx.condition == 0)
3979 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3981 if(ifx) ifx->generated = 1;
3986 /* signed comparisons to a literal byte */
3988 int lp1 = (lit+1) & 0xff;
3990 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3993 rFalseIfx.condition ^= 1;
3994 genSkipCond(&rFalseIfx,right,0,7);
3997 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3998 emitpcode(POC_XORLW, popGetLit(0x7f));
3999 genSkipz2(&rFalseIfx,1);
4002 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4003 emitpcode(POC_ADDLW, popGetLit(0x80));
4004 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4005 rFalseIfx.condition ^= 1;
4006 genSkipc(&rFalseIfx);
4009 if(ifx) ifx->generated = 1;
4011 /* unsigned comparisons to a literal byte */
4013 switch(lit & 0xff ) {
4015 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4016 genSkipz2(&rFalseIfx,0);
4017 if(ifx) ifx->generated = 1;
4020 genSkipCond(&rFalseIfx,right,0,7);
4021 if(ifx) ifx->generated = 1;
4025 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4026 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4027 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4028 rFalseIfx.condition ^= 1;
4029 if (AOP_TYPE(result) == AOP_CRY) {
4030 genSkipc(&rFalseIfx);
4031 if(ifx) ifx->generated = 1;
4033 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4034 emitpcode(POC_CLRF, popGet(AOP(result),0));
4035 emitpcode(POC_RLF, popGet(AOP(result),0));
4036 emitpcode(POC_MOVLW, popGetLit(0x01));
4037 emitpcode(POC_XORWF, popGet(AOP(result),0));
4048 /* Size is greater than 1 */
4056 /* this means lit = 0xffffffff, or -1 */
4059 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4060 rFalseIfx.condition ^= 1;
4061 genSkipCond(&rFalseIfx,right,size,7);
4062 if(ifx) ifx->generated = 1;
4069 if(rFalseIfx.condition) {
4070 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4071 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4074 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4076 emitpcode(POC_IORFW, popGet(AOP(right),size));
4080 if(rFalseIfx.condition) {
4081 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4082 emitpLabel(truelbl->key);
4084 rFalseIfx.condition ^= 1;
4085 genSkipCond(&rFalseIfx,right,s,7);
4088 if(ifx) ifx->generated = 1;
4092 if((size == 1) && (0 == (lp1&0xff))) {
4093 /* lower byte of signed word is zero */
4094 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4095 i = ((lp1 >> 8) & 0xff) ^0x80;
4096 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4097 emitpcode(POC_ADDLW, popGetLit( 0x80));
4098 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4099 rFalseIfx.condition ^= 1;
4100 genSkipc(&rFalseIfx);
4103 if(ifx) ifx->generated = 1;
4107 if(lit & (0x80 << (size*8))) {
4108 /* Lit is less than zero */
4109 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4110 //rFalseIfx.condition ^= 1;
4111 //genSkipCond(&rFalseIfx,left,size,7);
4112 //rFalseIfx.condition ^= 1;
4113 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4114 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4116 if(rFalseIfx.condition)
4117 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4119 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4123 /* Lit is greater than or equal to zero */
4124 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4125 //rFalseIfx.condition ^= 1;
4126 //genSkipCond(&rFalseIfx,right,size,7);
4127 //rFalseIfx.condition ^= 1;
4129 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4130 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4132 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4133 if(rFalseIfx.condition)
4134 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4136 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4141 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4142 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4146 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4148 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4150 rFalseIfx.condition ^= 1;
4151 //rFalseIfx.condition = 1;
4152 genSkipc(&rFalseIfx);
4154 emitpLabel(truelbl->key);
4156 if(ifx) ifx->generated = 1;
4161 /* compare word or long to an unsigned literal on the right.*/
4166 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4169 break; /* handled above */
4172 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4174 emitpcode(POC_IORFW, popGet(AOP(right),size));
4175 genSkipz2(&rFalseIfx,0);
4179 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4181 emitpcode(POC_IORFW, popGet(AOP(right),size));
4184 if(rFalseIfx.condition)
4185 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4187 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4190 emitpcode(POC_MOVLW, popGetLit(lit+1));
4191 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4193 rFalseIfx.condition ^= 1;
4194 genSkipc(&rFalseIfx);
4197 emitpLabel(truelbl->key);
4199 if(ifx) ifx->generated = 1;
4205 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4206 i = (lit >> (size*8)) & 0xff;
4208 emitpcode(POC_MOVLW, popGetLit(i));
4209 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4212 i = (lit >> (size*8)) & 0xff;
4215 emitpcode(POC_MOVLW, popGetLit(i));
4217 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4219 /* this byte of the lit is zero,
4220 *if it's not the last then OR in the variable */
4222 emitpcode(POC_IORFW, popGet(AOP(right),size));
4227 emitpLabel(lbl->key);
4229 rFalseIfx.condition ^= 1;
4230 genSkipc(&rFalseIfx);
4234 emitpLabel(truelbl->key);
4235 if(ifx) ifx->generated = 1;
4239 /* Compare two variables */
4241 DEBUGpic14_emitcode(";sign","%d",sign);
4245 /* Sigh. thus sucks... */
4247 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4248 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4249 emitpcode(POC_MOVLW, popGetLit(0x80));
4250 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4251 emitpcode(POC_XORFW, popGet(AOP(right),size));
4252 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4254 /* Signed char comparison */
4255 /* Special thanks to Nikolai Golovchenko for this snippet */
4256 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4257 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4258 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4259 emitpcode(POC_XORFW, popGet(AOP(left),0));
4260 emitpcode(POC_XORFW, popGet(AOP(right),0));
4261 emitpcode(POC_ADDLW, popGetLit(0x80));
4263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4264 genSkipc(&rFalseIfx);
4266 if(ifx) ifx->generated = 1;
4272 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4273 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4277 /* The rest of the bytes of a multi-byte compare */
4281 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4284 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4285 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4290 emitpLabel(lbl->key);
4292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4293 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4294 (AOP_TYPE(result) == AOP_REG)) {
4295 emitpcode(POC_CLRF, popGet(AOP(result),0));
4296 emitpcode(POC_RLF, popGet(AOP(result),0));
4298 genSkipc(&rFalseIfx);
4300 //genSkipc(&rFalseIfx);
4301 if(ifx) ifx->generated = 1;
4308 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4310 pic14_outBitC(result);
4312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4313 /* if the result is used in the next
4314 ifx conditional branch then generate
4315 code a little differently */
4317 genIfxJump (ifx,"c");
4319 pic14_outBitC(result);
4320 /* leave the result in acc */
4325 /*-----------------------------------------------------------------*/
4326 /* genCmpGt :- greater than comparison */
4327 /*-----------------------------------------------------------------*/
4328 static void genCmpGt (iCode *ic, iCode *ifx)
4330 operand *left, *right, *result;
4331 sym_link *letype , *retype;
4334 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4336 right= IC_RIGHT(ic);
4337 result = IC_RESULT(ic);
4339 letype = getSpec(operandType(left));
4340 retype =getSpec(operandType(right));
4341 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4342 /* assign the amsops */
4343 aopOp (left,ic,FALSE);
4344 aopOp (right,ic,FALSE);
4345 aopOp (result,ic,TRUE);
4347 genCmp(right, left, result, ifx, sign);
4349 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4350 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4351 freeAsmop(result,NULL,ic,TRUE);
4354 /*-----------------------------------------------------------------*/
4355 /* genCmpLt - less than comparisons */
4356 /*-----------------------------------------------------------------*/
4357 static void genCmpLt (iCode *ic, iCode *ifx)
4359 operand *left, *right, *result;
4360 sym_link *letype , *retype;
4363 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4365 right= IC_RIGHT(ic);
4366 result = IC_RESULT(ic);
4368 letype = getSpec(operandType(left));
4369 retype =getSpec(operandType(right));
4370 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4372 /* assign the amsops */
4373 aopOp (left,ic,FALSE);
4374 aopOp (right,ic,FALSE);
4375 aopOp (result,ic,TRUE);
4377 genCmp(left, right, result, ifx, sign);
4379 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4381 freeAsmop(result,NULL,ic,TRUE);
4384 /*-----------------------------------------------------------------*/
4385 /* genc16bit2lit - compare a 16 bit value to a literal */
4386 /*-----------------------------------------------------------------*/
4387 static void genc16bit2lit(operand *op, int lit, int offset)
4391 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4392 if( (lit&0xff) == 0)
4397 switch( BYTEofLONG(lit,i)) {
4399 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4402 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4405 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4408 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4409 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4414 switch( BYTEofLONG(lit,i)) {
4416 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4420 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4424 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4427 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4429 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4435 /*-----------------------------------------------------------------*/
4436 /* gencjneshort - compare and jump if not equal */
4437 /*-----------------------------------------------------------------*/
4438 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4440 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4442 int res_offset = 0; /* the result may be a different size then left or right */
4443 int res_size = AOP_SIZE(result);
4447 unsigned long lit = 0L;
4448 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4449 DEBUGpic14_AopType(__LINE__,left,right,result);
4451 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4452 resolveIfx(&rIfx,ifx);
4453 lbl = newiTempLabel(NULL);
4456 /* if the left side is a literal or
4457 if the right is in a pointer register and left
4459 if ((AOP_TYPE(left) == AOP_LIT) ||
4460 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4465 if(AOP_TYPE(right) == AOP_LIT)
4466 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4468 /* if the right side is a literal then anything goes */
4469 if (AOP_TYPE(right) == AOP_LIT &&
4470 AOP_TYPE(left) != AOP_DIR ) {
4473 genc16bit2lit(left, lit, 0);
4475 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4480 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4481 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4483 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4487 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4489 if(res_offset < res_size-1)
4497 /* if the right side is in a register or in direct space or
4498 if the left is a pointer register & right is not */
4499 else if (AOP_TYPE(right) == AOP_REG ||
4500 AOP_TYPE(right) == AOP_DIR ||
4501 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4502 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4503 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4504 int lbl_key = lbl->key;
4507 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4508 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4510 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4511 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4512 __FUNCTION__,__LINE__);
4516 /* switch(size) { */
4518 /* genc16bit2lit(left, lit, 0); */
4520 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4525 if((AOP_TYPE(left) == AOP_DIR) &&
4526 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4528 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4529 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4531 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4533 switch (lit & 0xff) {
4535 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4538 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4539 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4540 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4544 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4545 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4546 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4547 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4551 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4552 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4557 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4560 if(AOP_TYPE(result) == AOP_CRY) {
4561 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4566 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4568 /* fix me. probably need to check result size too */
4569 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4574 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4575 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4582 if(res_offset < res_size-1)
4587 } else if(AOP_TYPE(right) == AOP_REG &&
4588 AOP_TYPE(left) != AOP_DIR){
4591 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4592 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4593 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4598 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4600 if(res_offset < res_size-1)
4605 /* right is a pointer reg need both a & b */
4607 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4609 pic14_emitcode("mov","b,%s",l);
4610 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4611 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4616 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4618 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4620 emitpLabel(lbl->key);
4622 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4629 /*-----------------------------------------------------------------*/
4630 /* gencjne - compare and jump if not equal */
4631 /*-----------------------------------------------------------------*/
4632 static void gencjne(operand *left, operand *right, iCode *ifx)
4634 symbol *tlbl = newiTempLabel(NULL);
4636 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4637 gencjneshort(left, right, lbl);
4639 pic14_emitcode("mov","a,%s",one);
4640 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4641 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4642 pic14_emitcode("clr","a");
4643 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4645 emitpLabel(lbl->key);
4646 emitpLabel(tlbl->key);
4651 /*-----------------------------------------------------------------*/
4652 /* genCmpEq - generates code for equal to */
4653 /*-----------------------------------------------------------------*/
4654 static void genCmpEq (iCode *ic, iCode *ifx)
4656 operand *left, *right, *result;
4657 unsigned long lit = 0L;
4660 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4663 DEBUGpic14_emitcode ("; ifx is non-null","");
4665 DEBUGpic14_emitcode ("; ifx is null","");
4667 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4668 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4669 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4671 size = max(AOP_SIZE(left),AOP_SIZE(right));
4673 DEBUGpic14_AopType(__LINE__,left,right,result);
4675 /* if literal, literal on the right or
4676 if the right is in a pointer register and left
4678 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4679 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4680 operand *tmp = right ;
4686 if(ifx && !AOP_SIZE(result)){
4688 /* if they are both bit variables */
4689 if (AOP_TYPE(left) == AOP_CRY &&
4690 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4691 if(AOP_TYPE(right) == AOP_LIT){
4692 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4694 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4695 pic14_emitcode("cpl","c");
4696 } else if(lit == 1L) {
4697 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4699 pic14_emitcode("clr","c");
4701 /* AOP_TYPE(right) == AOP_CRY */
4703 symbol *lbl = newiTempLabel(NULL);
4704 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4705 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4706 pic14_emitcode("cpl","c");
4707 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4709 /* if true label then we jump if condition
4711 tlbl = newiTempLabel(NULL);
4712 if ( IC_TRUE(ifx) ) {
4713 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4714 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4716 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4717 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4719 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4722 /* left and right are both bit variables, result is carry */
4725 resolveIfx(&rIfx,ifx);
4727 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4728 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4729 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4730 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4735 /* They're not both bit variables. Is the right a literal? */
4736 if(AOP_TYPE(right) == AOP_LIT) {
4737 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4742 switch(lit & 0xff) {
4744 if ( IC_TRUE(ifx) ) {
4745 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4747 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4749 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4750 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4754 if ( IC_TRUE(ifx) ) {
4755 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4757 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4759 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4760 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4764 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4766 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4771 /* end of size == 1 */
4775 genc16bit2lit(left,lit,offset);
4778 /* end of size == 2 */
4783 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4784 emitpcode(POC_IORFW,popGet(AOP(left),1));
4785 emitpcode(POC_IORFW,popGet(AOP(left),2));
4786 emitpcode(POC_IORFW,popGet(AOP(left),3));
4790 /* search for patterns that can be optimized */
4792 genc16bit2lit(left,lit,0);
4795 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4797 genc16bit2lit(left,lit,2);
4799 emitpcode(POC_IORFW,popGet(AOP(left),2));
4800 emitpcode(POC_IORFW,popGet(AOP(left),3));
4813 } else if(AOP_TYPE(right) == AOP_CRY ) {
4814 /* we know the left is not a bit, but that the right is */
4815 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4816 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4817 popGet(AOP(right),offset));
4818 emitpcode(POC_XORLW,popGetLit(1));
4820 /* if the two are equal, then W will be 0 and the Z bit is set
4821 * we could test Z now, or go ahead and check the high order bytes if
4822 * the variable we're comparing is larger than a byte. */
4825 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4827 if ( IC_TRUE(ifx) ) {
4829 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4830 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4833 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4834 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4838 /* They're both variables that are larger than bits */
4841 tlbl = newiTempLabel(NULL);
4844 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4845 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4847 if ( IC_TRUE(ifx) ) {
4850 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4851 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4854 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4855 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4859 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4860 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4864 if(s>1 && IC_TRUE(ifx)) {
4865 emitpLabel(tlbl->key);
4866 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4870 /* mark the icode as generated */
4875 /* if they are both bit variables */
4876 if (AOP_TYPE(left) == AOP_CRY &&
4877 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4878 if(AOP_TYPE(right) == AOP_LIT){
4879 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4881 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4882 pic14_emitcode("cpl","c");
4883 } else if(lit == 1L) {
4884 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4886 pic14_emitcode("clr","c");
4888 /* AOP_TYPE(right) == AOP_CRY */
4890 symbol *lbl = newiTempLabel(NULL);
4891 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4892 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4893 pic14_emitcode("cpl","c");
4894 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4897 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4898 pic14_outBitC(result);
4902 genIfxJump (ifx,"c");
4905 /* if the result is used in an arithmetic operation
4906 then put the result in place */
4907 pic14_outBitC(result);
4910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4911 gencjne(left,right,result,ifx);
4914 gencjne(left,right,newiTempLabel(NULL));
4916 if(IC_TRUE(ifx)->key)
4917 gencjne(left,right,IC_TRUE(ifx)->key);
4919 gencjne(left,right,IC_FALSE(ifx)->key);
4923 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4924 aopPut(AOP(result),"a",0);
4929 genIfxJump (ifx,"a");
4933 /* if the result is used in an arithmetic operation
4934 then put the result in place */
4936 if (AOP_TYPE(result) != AOP_CRY)
4937 pic14_outAcc(result);
4939 /* leave the result in acc */
4943 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4944 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4945 freeAsmop(result,NULL,ic,TRUE);
4948 /*-----------------------------------------------------------------*/
4949 /* ifxForOp - returns the icode containing the ifx for operand */
4950 /*-----------------------------------------------------------------*/
4951 static iCode *ifxForOp ( operand *op, iCode *ic )
4953 /* if true symbol then needs to be assigned */
4954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4955 if (IS_TRUE_SYMOP(op))
4958 /* if this has register type condition and
4959 the next instruction is ifx with the same operand
4960 and live to of the operand is upto the ifx only then */
4962 ic->next->op == IFX &&
4963 IC_COND(ic->next)->key == op->key &&
4964 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4968 ic->next->op == IFX &&
4969 IC_COND(ic->next)->key == op->key) {
4970 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4974 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4976 ic->next->op == IFX)
4977 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4980 ic->next->op == IFX &&
4981 IC_COND(ic->next)->key == op->key) {
4982 DEBUGpic14_emitcode ("; "," key is okay");
4983 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4984 OP_SYMBOL(op)->liveTo,
4991 /*-----------------------------------------------------------------*/
4992 /* genAndOp - for && operation */
4993 /*-----------------------------------------------------------------*/
4994 static void genAndOp (iCode *ic)
4996 operand *left,*right, *result;
4999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5000 /* note here that && operations that are in an
5001 if statement are taken away by backPatchLabels
5002 only those used in arthmetic operations remain */
5003 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5004 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5005 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5007 DEBUGpic14_AopType(__LINE__,left,right,result);
5009 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5010 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5011 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5013 /* if both are bit variables */
5014 /* if (AOP_TYPE(left) == AOP_CRY && */
5015 /* AOP_TYPE(right) == AOP_CRY ) { */
5016 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5017 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5018 /* pic14_outBitC(result); */
5020 /* tlbl = newiTempLabel(NULL); */
5021 /* pic14_toBoolean(left); */
5022 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5023 /* pic14_toBoolean(right); */
5024 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5025 /* pic14_outBitAcc(result); */
5028 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5029 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5030 freeAsmop(result,NULL,ic,TRUE);
5034 /*-----------------------------------------------------------------*/
5035 /* genOrOp - for || operation */
5036 /*-----------------------------------------------------------------*/
5039 modified this code, but it doesn't appear to ever get called
5042 static void genOrOp (iCode *ic)
5044 operand *left,*right, *result;
5047 /* note here that || operations that are in an
5048 if statement are taken away by backPatchLabels
5049 only those used in arthmetic operations remain */
5050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5051 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5052 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5053 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5055 DEBUGpic14_AopType(__LINE__,left,right,result);
5057 /* if both are bit variables */
5058 if (AOP_TYPE(left) == AOP_CRY &&
5059 AOP_TYPE(right) == AOP_CRY ) {
5060 pic14_emitcode("clrc","");
5061 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5062 AOP(left)->aopu.aop_dir,
5063 AOP(left)->aopu.aop_dir);
5064 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5065 AOP(right)->aopu.aop_dir,
5066 AOP(right)->aopu.aop_dir);
5067 pic14_emitcode("setc","");
5070 tlbl = newiTempLabel(NULL);
5071 pic14_toBoolean(left);
5073 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5074 pic14_toBoolean(right);
5075 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5077 pic14_outBitAcc(result);
5080 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5081 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5082 freeAsmop(result,NULL,ic,TRUE);
5085 /*-----------------------------------------------------------------*/
5086 /* isLiteralBit - test if lit == 2^n */
5087 /*-----------------------------------------------------------------*/
5088 static int isLiteralBit(unsigned long lit)
5090 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5091 0x100L,0x200L,0x400L,0x800L,
5092 0x1000L,0x2000L,0x4000L,0x8000L,
5093 0x10000L,0x20000L,0x40000L,0x80000L,
5094 0x100000L,0x200000L,0x400000L,0x800000L,
5095 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5096 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5100 for(idx = 0; idx < 32; idx++)
5106 /*-----------------------------------------------------------------*/
5107 /* continueIfTrue - */
5108 /*-----------------------------------------------------------------*/
5109 static void continueIfTrue (iCode *ic)
5111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5113 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5117 /*-----------------------------------------------------------------*/
5119 /*-----------------------------------------------------------------*/
5120 static void jumpIfTrue (iCode *ic)
5122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5124 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5128 /*-----------------------------------------------------------------*/
5129 /* jmpTrueOrFalse - */
5130 /*-----------------------------------------------------------------*/
5131 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5133 // ugly but optimized by peephole
5134 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5136 symbol *nlbl = newiTempLabel(NULL);
5137 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5138 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5139 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5140 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5143 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5144 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5149 /*-----------------------------------------------------------------*/
5150 /* genAnd - code for and */
5151 /*-----------------------------------------------------------------*/
5152 static void genAnd (iCode *ic, iCode *ifx)
5154 operand *left, *right, *result;
5156 unsigned long lit = 0L;
5161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5162 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5163 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5164 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5166 resolveIfx(&rIfx,ifx);
5168 /* if left is a literal & right is not then exchange them */
5169 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5170 AOP_NEEDSACC(left)) {
5171 operand *tmp = right ;
5176 /* if result = right then exchange them */
5177 if(pic14_sameRegs(AOP(result),AOP(right))){
5178 operand *tmp = right ;
5183 /* if right is bit then exchange them */
5184 if (AOP_TYPE(right) == AOP_CRY &&
5185 AOP_TYPE(left) != AOP_CRY){
5186 operand *tmp = right ;
5190 if(AOP_TYPE(right) == AOP_LIT)
5191 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5193 size = AOP_SIZE(result);
5195 DEBUGpic14_AopType(__LINE__,left,right,result);
5198 // result = bit & yy;
5199 if (AOP_TYPE(left) == AOP_CRY){
5200 // c = bit & literal;
5201 if(AOP_TYPE(right) == AOP_LIT){
5203 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5206 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5209 if(size && (AOP_TYPE(result) == AOP_CRY)){
5210 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5213 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5217 pic14_emitcode("clr","c");
5220 if (AOP_TYPE(right) == AOP_CRY){
5222 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5223 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5226 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5228 pic14_emitcode("rrc","a");
5229 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5235 pic14_outBitC(result);
5237 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5238 genIfxJump(ifx, "c");
5242 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5243 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5244 if((AOP_TYPE(right) == AOP_LIT) &&
5245 (AOP_TYPE(result) == AOP_CRY) &&
5246 (AOP_TYPE(left) != AOP_CRY)){
5247 int posbit = isLiteralBit(lit);
5251 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5254 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5259 while (posbit > 7) {
5263 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5264 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5265 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5272 symbol *tlbl = newiTempLabel(NULL);
5273 int sizel = AOP_SIZE(left);
5275 pic14_emitcode("setb","c");
5277 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5278 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5280 if((posbit = isLiteralBit(bytelit)) != 0)
5281 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5283 if(bytelit != 0x0FFL)
5284 pic14_emitcode("anl","a,%s",
5285 aopGet(AOP(right),offset,FALSE,TRUE));
5286 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5291 // bit = left & literal
5293 pic14_emitcode("clr","c");
5294 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5296 // if(left & literal)
5299 jmpTrueOrFalse(ifx, tlbl);
5303 pic14_outBitC(result);
5307 /* if left is same as result */
5308 if(pic14_sameRegs(AOP(result),AOP(left))){
5310 for(;size--; offset++,lit>>=8) {
5311 if(AOP_TYPE(right) == AOP_LIT){
5312 switch(lit & 0xff) {
5314 /* and'ing with 0 has clears the result */
5315 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5318 /* and'ing with 0xff is a nop when the result and left are the same */
5323 int p = my_powof2( (~lit) & 0xff );
5325 /* only one bit is set in the literal, so use a bcf instruction */
5326 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5329 if(know_W != (int)(lit&0xff))
5330 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5332 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5337 if (AOP_TYPE(left) == AOP_ACC) {
5338 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5340 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5341 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5348 // left & result in different registers
5349 if(AOP_TYPE(result) == AOP_CRY){
5351 // if(size), result in bit
5352 // if(!size && ifx), conditional oper: if(left & right)
5353 symbol *tlbl = newiTempLabel(NULL);
5354 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5356 pic14_emitcode("setb","c");
5358 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5359 pic14_emitcode("anl","a,%s",
5360 aopGet(AOP(left),offset,FALSE,FALSE));
5361 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5366 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5367 pic14_outBitC(result);
5369 jmpTrueOrFalse(ifx, tlbl);
5371 for(;(size--);offset++) {
5373 // result = left & right
5374 if(AOP_TYPE(right) == AOP_LIT){
5375 int t = (lit >> (offset*8)) & 0x0FFL;
5378 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5381 if(AOP_TYPE(left) != AOP_ACC) {
5382 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5384 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5387 if(AOP_TYPE(left) == AOP_ACC) {
5388 emitpcode(POC_ANDLW, popGetLit(t));
5390 emitpcode(POC_MOVLW, popGetLit(t));
5391 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5393 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5398 if (AOP_TYPE(left) == AOP_ACC) {
5399 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5401 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5402 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5404 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5410 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5411 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5412 freeAsmop(result,NULL,ic,TRUE);
5415 /*-----------------------------------------------------------------*/
5416 /* genOr - code for or */
5417 /*-----------------------------------------------------------------*/
5418 static void genOr (iCode *ic, iCode *ifx)
5420 operand *left, *right, *result;
5422 unsigned long lit = 0L;
5424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5426 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5427 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5428 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5430 DEBUGpic14_AopType(__LINE__,left,right,result);
5432 /* if left is a literal & right is not then exchange them */
5433 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5434 AOP_NEEDSACC(left)) {
5435 operand *tmp = right ;
5440 /* if result = right then exchange them */
5441 if(pic14_sameRegs(AOP(result),AOP(right))){
5442 operand *tmp = right ;
5447 /* if right is bit then exchange them */
5448 if (AOP_TYPE(right) == AOP_CRY &&
5449 AOP_TYPE(left) != AOP_CRY){
5450 operand *tmp = right ;
5455 DEBUGpic14_AopType(__LINE__,left,right,result);
5457 if(AOP_TYPE(right) == AOP_LIT)
5458 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5460 size = AOP_SIZE(result);
5464 if (AOP_TYPE(left) == AOP_CRY){
5465 if(AOP_TYPE(right) == AOP_LIT){
5466 // c = bit & literal;
5468 // lit != 0 => result = 1
5469 if(AOP_TYPE(result) == AOP_CRY){
5471 emitpcode(POC_BSF, popGet(AOP(result),0));
5472 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5473 // AOP(result)->aopu.aop_dir,
5474 // AOP(result)->aopu.aop_dir);
5476 continueIfTrue(ifx);
5480 // lit == 0 => result = left
5481 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5483 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5486 if (AOP_TYPE(right) == AOP_CRY){
5487 if(pic14_sameRegs(AOP(result),AOP(left))){
5489 emitpcode(POC_BCF, popGet(AOP(result),0));
5490 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5491 emitpcode(POC_BSF, popGet(AOP(result),0));
5493 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5494 AOP(result)->aopu.aop_dir,
5495 AOP(result)->aopu.aop_dir);
5496 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5497 AOP(right)->aopu.aop_dir,
5498 AOP(right)->aopu.aop_dir);
5499 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5500 AOP(result)->aopu.aop_dir,
5501 AOP(result)->aopu.aop_dir);
5503 if( AOP_TYPE(result) == AOP_ACC) {
5504 emitpcode(POC_MOVLW, popGetLit(0));
5505 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5506 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5507 emitpcode(POC_MOVLW, popGetLit(1));
5511 emitpcode(POC_BCF, popGet(AOP(result),0));
5512 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5513 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5514 emitpcode(POC_BSF, popGet(AOP(result),0));
5516 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5517 AOP(result)->aopu.aop_dir,
5518 AOP(result)->aopu.aop_dir);
5519 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5520 AOP(right)->aopu.aop_dir,
5521 AOP(right)->aopu.aop_dir);
5522 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5523 AOP(left)->aopu.aop_dir,
5524 AOP(left)->aopu.aop_dir);
5525 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5526 AOP(result)->aopu.aop_dir,
5527 AOP(result)->aopu.aop_dir);
5532 symbol *tlbl = newiTempLabel(NULL);
5533 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5536 emitpcode(POC_BCF, popGet(AOP(result),0));
5537 if( AOP_TYPE(right) == AOP_ACC) {
5538 emitpcode(POC_IORLW, popGetLit(0));
5540 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5541 emitpcode(POC_BSF, popGet(AOP(result),0));
5546 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5547 pic14_emitcode(";XXX setb","c");
5548 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5549 AOP(left)->aopu.aop_dir,tlbl->key+100);
5550 pic14_toBoolean(right);
5551 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5552 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5553 jmpTrueOrFalse(ifx, tlbl);
5557 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5564 pic14_outBitC(result);
5566 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5567 genIfxJump(ifx, "c");
5571 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5572 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5573 if((AOP_TYPE(right) == AOP_LIT) &&
5574 (AOP_TYPE(result) == AOP_CRY) &&
5575 (AOP_TYPE(left) != AOP_CRY)){
5577 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5580 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5582 continueIfTrue(ifx);
5585 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5586 // lit = 0, result = boolean(left)
5588 pic14_emitcode(";XXX setb","c");
5589 pic14_toBoolean(right);
5591 symbol *tlbl = newiTempLabel(NULL);
5592 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5594 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5596 genIfxJump (ifx,"a");
5600 pic14_outBitC(result);
5604 /* if left is same as result */
5605 if(pic14_sameRegs(AOP(result),AOP(left))){
5607 for(;size--; offset++,lit>>=8) {
5608 if(AOP_TYPE(right) == AOP_LIT){
5609 if((lit & 0xff) == 0)
5610 /* or'ing with 0 has no effect */
5613 int p = my_powof2(lit & 0xff);
5615 /* only one bit is set in the literal, so use a bsf instruction */
5617 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5619 if(know_W != (int)(lit & 0xff))
5620 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5621 know_W = lit & 0xff;
5622 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5627 if (AOP_TYPE(left) == AOP_ACC) {
5628 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5629 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5631 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5632 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5634 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5635 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5641 // left & result in different registers
5642 if(AOP_TYPE(result) == AOP_CRY){
5644 // if(size), result in bit
5645 // if(!size && ifx), conditional oper: if(left | right)
5646 symbol *tlbl = newiTempLabel(NULL);
5647 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5648 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5652 pic14_emitcode(";XXX setb","c");
5654 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5655 pic14_emitcode(";XXX orl","a,%s",
5656 aopGet(AOP(left),offset,FALSE,FALSE));
5657 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5662 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5663 pic14_outBitC(result);
5665 jmpTrueOrFalse(ifx, tlbl);
5666 } else for(;(size--);offset++){
5668 // result = left & right
5669 if(AOP_TYPE(right) == AOP_LIT){
5670 int t = (lit >> (offset*8)) & 0x0FFL;
5673 if (AOP_TYPE(left) != AOP_ACC) {
5674 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5676 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5680 if (AOP_TYPE(left) == AOP_ACC) {
5681 emitpcode(POC_IORLW, popGetLit(t));
5683 emitpcode(POC_MOVLW, popGetLit(t));
5684 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5686 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5691 // faster than result <- left, anl result,right
5692 // and better if result is SFR
5693 if (AOP_TYPE(left) == AOP_ACC) {
5694 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5695 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5697 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5698 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5700 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5701 pic14_emitcode("iorwf","%s,w",
5702 aopGet(AOP(left),offset,FALSE,FALSE));
5704 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5705 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5710 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5711 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5712 freeAsmop(result,NULL,ic,TRUE);
5715 /*-----------------------------------------------------------------*/
5716 /* genXor - code for xclusive or */
5717 /*-----------------------------------------------------------------*/
5718 static void genXor (iCode *ic, iCode *ifx)
5720 operand *left, *right, *result;
5722 unsigned long lit = 0L;
5724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5726 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5727 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5728 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5730 /* if left is a literal & right is not ||
5731 if left needs acc & right does not */
5732 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5733 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5734 operand *tmp = right ;
5739 /* if result = right then exchange them */
5740 if(pic14_sameRegs(AOP(result),AOP(right))){
5741 operand *tmp = right ;
5746 /* if right is bit then exchange them */
5747 if (AOP_TYPE(right) == AOP_CRY &&
5748 AOP_TYPE(left) != AOP_CRY){
5749 operand *tmp = right ;
5753 if(AOP_TYPE(right) == AOP_LIT)
5754 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5756 size = AOP_SIZE(result);
5760 if (AOP_TYPE(left) == AOP_CRY){
5761 if(AOP_TYPE(right) == AOP_LIT){
5762 // c = bit & literal;
5764 // lit>>1 != 0 => result = 1
5765 if(AOP_TYPE(result) == AOP_CRY){
5767 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5768 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5770 continueIfTrue(ifx);
5773 pic14_emitcode("setb","c");
5777 // lit == 0, result = left
5778 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5780 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5782 // lit == 1, result = not(left)
5783 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5784 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5785 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5786 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5789 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5790 pic14_emitcode("cpl","c");
5797 symbol *tlbl = newiTempLabel(NULL);
5798 if (AOP_TYPE(right) == AOP_CRY){
5800 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5803 int sizer = AOP_SIZE(right);
5805 // if val>>1 != 0, result = 1
5806 pic14_emitcode("setb","c");
5808 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5810 // test the msb of the lsb
5811 pic14_emitcode("anl","a,#0xfe");
5812 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5816 pic14_emitcode("rrc","a");
5818 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5819 pic14_emitcode("cpl","c");
5820 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5825 pic14_outBitC(result);
5827 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5828 genIfxJump(ifx, "c");
5832 if(pic14_sameRegs(AOP(result),AOP(left))){
5833 /* if left is same as result */
5834 for(;size--; offset++) {
5835 if(AOP_TYPE(right) == AOP_LIT){
5836 int t = (lit >> (offset*8)) & 0x0FFL;
5840 if (IS_AOP_PREG(left)) {
5841 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5842 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5843 aopPut(AOP(result),"a",offset);
5845 emitpcode(POC_MOVLW, popGetLit(t));
5846 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5847 pic14_emitcode("xrl","%s,%s",
5848 aopGet(AOP(left),offset,FALSE,TRUE),
5849 aopGet(AOP(right),offset,FALSE,FALSE));
5852 if (AOP_TYPE(left) == AOP_ACC)
5853 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5855 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5856 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5858 if (IS_AOP_PREG(left)) {
5859 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5860 aopPut(AOP(result),"a",offset);
5862 pic14_emitcode("xrl","%s,a",
5863 aopGet(AOP(left),offset,FALSE,TRUE));
5869 // left & result in different registers
5870 if(AOP_TYPE(result) == AOP_CRY){
5872 // if(size), result in bit
5873 // if(!size && ifx), conditional oper: if(left ^ right)
5874 symbol *tlbl = newiTempLabel(NULL);
5875 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5877 pic14_emitcode("setb","c");
5879 if((AOP_TYPE(right) == AOP_LIT) &&
5880 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5881 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5883 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5884 pic14_emitcode("xrl","a,%s",
5885 aopGet(AOP(left),offset,FALSE,FALSE));
5887 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5892 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5893 pic14_outBitC(result);
5895 jmpTrueOrFalse(ifx, tlbl);
5896 } else for(;(size--);offset++){
5898 // result = left & right
5899 if(AOP_TYPE(right) == AOP_LIT){
5900 int t = (lit >> (offset*8)) & 0x0FFL;
5903 if (AOP_TYPE(left) != AOP_ACC) {
5904 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5906 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5907 pic14_emitcode("movf","%s,w",
5908 aopGet(AOP(left),offset,FALSE,FALSE));
5909 pic14_emitcode("movwf","%s",
5910 aopGet(AOP(result),offset,FALSE,FALSE));
5913 if (AOP_TYPE(left) == AOP_ACC) {
5914 emitpcode(POC_XORLW, popGetLit(t));
5916 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5918 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5921 if (AOP_TYPE(left) == AOP_ACC) {
5922 emitpcode(POC_XORLW, popGetLit(t));
5924 emitpcode(POC_MOVLW, popGetLit(t));
5925 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5927 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5928 pic14_emitcode("movlw","0x%x",t);
5929 pic14_emitcode("xorwf","%s,w",
5930 aopGet(AOP(left),offset,FALSE,FALSE));
5931 pic14_emitcode("movwf","%s",
5932 aopGet(AOP(result),offset,FALSE,FALSE));
5938 // faster than result <- left, anl result,right
5939 // and better if result is SFR
5940 if (AOP_TYPE(left) == AOP_ACC) {
5941 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5942 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5944 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5945 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5946 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5947 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5949 if ( AOP_TYPE(result) != AOP_ACC){
5950 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5951 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5957 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5958 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5959 freeAsmop(result,NULL,ic,TRUE);
5962 /*-----------------------------------------------------------------*/
5963 /* genInline - write the inline code out */
5964 /*-----------------------------------------------------------------*/
5965 static void genInline (iCode *ic)
5967 char *buffer, *bp, *bp1;
5969 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5971 _G.inLine += (!options.asmpeep);
5973 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5974 strcpy(buffer,IC_INLINE(ic));
5976 /* emit each line as a code */
5982 addpCode2pBlock(pb,AssembleLine(bp1));
5989 pic14_emitcode(bp1,"");
5995 if ((bp1 != bp) && *bp1)
5996 addpCode2pBlock(pb,AssembleLine(bp1));
6000 _G.inLine -= (!options.asmpeep);
6003 /*-----------------------------------------------------------------*/
6004 /* genRRC - rotate right with carry */
6005 /*-----------------------------------------------------------------*/
6006 static void genRRC (iCode *ic)
6008 operand *left , *result ;
6009 int size, offset = 0, same;
6011 /* rotate right with carry */
6013 result=IC_RESULT(ic);
6014 aopOp (left,ic,FALSE);
6015 aopOp (result,ic,FALSE);
6017 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6019 same = pic14_sameRegs(AOP(result),AOP(left));
6021 size = AOP_SIZE(result);
6023 /* get the lsb and put it into the carry */
6024 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6031 emitpcode(POC_RRF, popGet(AOP(left),offset));
6033 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6034 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6040 freeAsmop(left,NULL,ic,TRUE);
6041 freeAsmop(result,NULL,ic,TRUE);
6044 /*-----------------------------------------------------------------*/
6045 /* genRLC - generate code for rotate left with carry */
6046 /*-----------------------------------------------------------------*/
6047 static void genRLC (iCode *ic)
6049 operand *left , *result ;
6050 int size, offset = 0;
6053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
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 /* move it to the result */
6065 size = AOP_SIZE(result);
6067 /* get the msb and put it into the carry */
6068 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6075 emitpcode(POC_RLF, popGet(AOP(left),offset));
6077 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6078 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6085 freeAsmop(left,NULL,ic,TRUE);
6086 freeAsmop(result,NULL,ic,TRUE);
6089 /*-----------------------------------------------------------------*/
6090 /* genGetHbit - generates code get highest order bit */
6091 /*-----------------------------------------------------------------*/
6092 static void genGetHbit (iCode *ic)
6094 operand *left, *result;
6096 result=IC_RESULT(ic);
6097 aopOp (left,ic,FALSE);
6098 aopOp (result,ic,FALSE);
6100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6101 /* get the highest order byte into a */
6102 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6103 if(AOP_TYPE(result) == AOP_CRY){
6104 pic14_emitcode("rlc","a");
6105 pic14_outBitC(result);
6108 pic14_emitcode("rl","a");
6109 pic14_emitcode("anl","a,#0x01");
6110 pic14_outAcc(result);
6114 freeAsmop(left,NULL,ic,TRUE);
6115 freeAsmop(result,NULL,ic,TRUE);
6118 /*-----------------------------------------------------------------*/
6119 /* AccRol - rotate left accumulator by known count */
6120 /*-----------------------------------------------------------------*/
6121 static void AccRol (int shCount)
6123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6124 shCount &= 0x0007; // shCount : 0..7
6129 pic14_emitcode("rl","a");
6132 pic14_emitcode("rl","a");
6133 pic14_emitcode("rl","a");
6136 pic14_emitcode("swap","a");
6137 pic14_emitcode("rr","a");
6140 pic14_emitcode("swap","a");
6143 pic14_emitcode("swap","a");
6144 pic14_emitcode("rl","a");
6147 pic14_emitcode("rr","a");
6148 pic14_emitcode("rr","a");
6151 pic14_emitcode("rr","a");
6156 /*-----------------------------------------------------------------*/
6157 /* AccLsh - left shift accumulator by known count */
6158 /*-----------------------------------------------------------------*/
6159 static void AccLsh (int shCount)
6161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6164 pic14_emitcode("add","a,acc");
6167 pic14_emitcode("add","a,acc");
6168 pic14_emitcode("add","a,acc");
6170 /* rotate left accumulator */
6172 /* and kill the lower order bits */
6173 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6178 /*-----------------------------------------------------------------*/
6179 /* AccRsh - right shift accumulator by known count */
6180 /*-----------------------------------------------------------------*/
6181 static void AccRsh (int shCount)
6183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6187 pic14_emitcode("rrc","a");
6189 /* rotate right accumulator */
6190 AccRol(8 - shCount);
6191 /* and kill the higher order bits */
6192 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6198 /*-----------------------------------------------------------------*/
6199 /* AccSRsh - signed right shift accumulator by known count */
6200 /*-----------------------------------------------------------------*/
6201 static void AccSRsh (int shCount)
6204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6207 pic14_emitcode("mov","c,acc.7");
6208 pic14_emitcode("rrc","a");
6209 } else if(shCount == 2){
6210 pic14_emitcode("mov","c,acc.7");
6211 pic14_emitcode("rrc","a");
6212 pic14_emitcode("mov","c,acc.7");
6213 pic14_emitcode("rrc","a");
6215 tlbl = newiTempLabel(NULL);
6216 /* rotate right accumulator */
6217 AccRol(8 - shCount);
6218 /* and kill the higher order bits */
6219 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6220 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6221 pic14_emitcode("orl","a,#0x%02x",
6222 (unsigned char)~SRMask[shCount]);
6223 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6228 /*-----------------------------------------------------------------*/
6229 /* shiftR1Left2Result - shift right one byte from left to result */
6230 /*-----------------------------------------------------------------*/
6231 static void shiftR1Left2ResultSigned (operand *left, int offl,
6232 operand *result, int offr,
6237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6239 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6243 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6245 emitpcode(POC_RRF, popGet(AOP(result),offr));
6247 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6248 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6254 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6256 emitpcode(POC_RRF, popGet(AOP(result),offr));
6258 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6259 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6261 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6262 emitpcode(POC_RRF, popGet(AOP(result),offr));
6268 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6270 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6271 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6274 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6275 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6276 emitpcode(POC_ANDLW, popGetLit(0x1f));
6278 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6279 emitpcode(POC_IORLW, popGetLit(0xe0));
6281 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6285 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6286 emitpcode(POC_ANDLW, popGetLit(0x0f));
6287 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6288 emitpcode(POC_IORLW, popGetLit(0xf0));
6289 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6293 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6295 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6296 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6298 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6299 emitpcode(POC_ANDLW, popGetLit(0x07));
6300 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6301 emitpcode(POC_IORLW, popGetLit(0xf8));
6302 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6307 emitpcode(POC_MOVLW, popGetLit(0x00));
6308 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6309 emitpcode(POC_MOVLW, popGetLit(0xfe));
6310 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6311 emitpcode(POC_IORLW, popGetLit(0x01));
6312 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6314 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6315 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6316 emitpcode(POC_DECF, popGet(AOP(result),offr));
6317 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6318 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6324 emitpcode(POC_MOVLW, popGetLit(0x00));
6325 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6326 emitpcode(POC_MOVLW, popGetLit(0xff));
6327 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6329 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6330 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6331 emitpcode(POC_DECF, popGet(AOP(result),offr));
6339 /*-----------------------------------------------------------------*/
6340 /* shiftR1Left2Result - shift right one byte from left to result */
6341 /*-----------------------------------------------------------------*/
6342 static void shiftR1Left2Result (operand *left, int offl,
6343 operand *result, int offr,
6344 int shCount, int sign)
6348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6350 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6352 /* Copy the msb into the carry if signed. */
6354 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6364 emitpcode(POC_RRF, popGet(AOP(result),offr));
6366 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6367 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6373 emitpcode(POC_RRF, popGet(AOP(result),offr));
6375 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6376 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6379 emitpcode(POC_RRF, popGet(AOP(result),offr));
6384 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6386 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6387 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6390 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6391 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6392 emitpcode(POC_ANDLW, popGetLit(0x1f));
6393 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6397 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6398 emitpcode(POC_ANDLW, popGetLit(0x0f));
6399 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6403 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6404 emitpcode(POC_ANDLW, popGetLit(0x0f));
6405 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6407 emitpcode(POC_RRF, popGet(AOP(result),offr));
6412 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6413 emitpcode(POC_ANDLW, popGetLit(0x80));
6414 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415 emitpcode(POC_RLF, popGet(AOP(result),offr));
6416 emitpcode(POC_RLF, popGet(AOP(result),offr));
6421 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6422 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6423 emitpcode(POC_RLF, popGet(AOP(result),offr));
6432 /*-----------------------------------------------------------------*/
6433 /* shiftL1Left2Result - shift left one byte from left to result */
6434 /*-----------------------------------------------------------------*/
6435 static void shiftL1Left2Result (operand *left, int offl,
6436 operand *result, int offr, int shCount)
6441 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6443 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6444 DEBUGpic14_emitcode ("; ***","same = %d",same);
6445 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6447 /* shift left accumulator */
6448 //AccLsh(shCount); // don't comment out just yet...
6449 // aopPut(AOP(result),"a",offr);
6453 /* Shift left 1 bit position */
6454 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6456 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6458 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6459 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6463 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6464 emitpcode(POC_ANDLW,popGetLit(0x7e));
6465 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6466 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6469 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6470 emitpcode(POC_ANDLW,popGetLit(0x3e));
6471 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6472 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6473 emitpcode(POC_RLF, popGet(AOP(result),offr));
6476 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6477 emitpcode(POC_ANDLW, popGetLit(0xf0));
6478 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6481 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6482 emitpcode(POC_ANDLW, popGetLit(0xf0));
6483 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6484 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6487 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6488 emitpcode(POC_ANDLW, popGetLit(0x30));
6489 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6490 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6491 emitpcode(POC_RLF, popGet(AOP(result),offr));
6494 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6495 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6496 emitpcode(POC_RRF, popGet(AOP(result),offr));
6500 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6505 /*-----------------------------------------------------------------*/
6506 /* movLeft2Result - move byte from left to result */
6507 /*-----------------------------------------------------------------*/
6508 static void movLeft2Result (operand *left, int offl,
6509 operand *result, int offr)
6512 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6513 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6514 l = aopGet(AOP(left),offl,FALSE,FALSE);
6516 if (*l == '@' && (IS_AOP_PREG(result))) {
6517 pic14_emitcode("mov","a,%s",l);
6518 aopPut(AOP(result),"a",offr);
6520 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6521 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6526 /*-----------------------------------------------------------------*/
6527 /* shiftL2Left2Result - shift left two bytes from left to result */
6528 /*-----------------------------------------------------------------*/
6529 static void shiftL2Left2Result (operand *left, int offl,
6530 operand *result, int offr, int shCount)
6534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6536 if(pic14_sameRegs(AOP(result), AOP(left))) {
6544 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6545 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6546 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6550 emitpcode(POC_RLF, popGet(AOP(result),offr));
6551 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6557 emitpcode(POC_MOVLW, popGetLit(0x0f));
6558 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6559 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6560 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6561 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6562 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6563 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6565 emitpcode(POC_RLF, popGet(AOP(result),offr));
6566 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6570 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6571 emitpcode(POC_RRF, popGet(AOP(result),offr));
6572 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6573 emitpcode(POC_RRF, popGet(AOP(result),offr));
6574 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6575 emitpcode(POC_ANDLW,popGetLit(0xc0));
6576 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6577 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6578 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6579 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6582 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6584 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6585 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6586 emitpcode(POC_RRF, popGet(AOP(result),offr));
6596 /* note, use a mov/add for the shift since the mov has a
6597 chance of getting optimized out */
6598 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6599 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6600 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6601 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6602 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RLF, popGet(AOP(result),offr));
6607 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6614 emitpcode(POC_ANDLW, popGetLit(0xF0));
6615 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6616 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6617 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6618 emitpcode(POC_ANDLW, popGetLit(0xF0));
6619 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6620 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6624 emitpcode(POC_RLF, popGet(AOP(result),offr));
6625 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6629 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6630 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6631 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6632 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6634 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6635 emitpcode(POC_RRF, popGet(AOP(result),offr));
6636 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6637 emitpcode(POC_ANDLW,popGetLit(0xc0));
6638 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6639 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6640 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6641 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6644 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6645 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6646 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6647 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6648 emitpcode(POC_RRF, popGet(AOP(result),offr));
6653 /*-----------------------------------------------------------------*/
6654 /* shiftR2Left2Result - shift right two bytes from left to result */
6655 /*-----------------------------------------------------------------*/
6656 static void shiftR2Left2Result (operand *left, int offl,
6657 operand *result, int offr,
6658 int shCount, int sign)
6662 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6663 same = pic14_sameRegs(AOP(result), AOP(left));
6665 if(same && ((offl + MSB16) == offr)){
6667 /* don't crash result[offr] */
6668 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6669 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6672 movLeft2Result(left,offl, result, offr);
6673 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6676 /* a:x >> shCount (x = lsb(result))*/
6679 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6681 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6690 emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6695 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6696 emitpcode(POC_RRF,popGet(AOP(result),offr));
6698 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6699 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6700 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6701 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6706 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6709 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6710 emitpcode(POC_RRF,popGet(AOP(result),offr));
6717 emitpcode(POC_MOVLW, popGetLit(0xf0));
6718 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6719 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6721 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6722 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6723 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6724 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6726 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6727 emitpcode(POC_ANDLW, popGetLit(0x0f));
6728 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6730 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6731 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6732 emitpcode(POC_ANDLW, popGetLit(0xf0));
6733 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6734 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6738 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RRF, popGet(AOP(result),offr));
6743 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6744 emitpcode(POC_BTFSC,
6745 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6746 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6754 emitpcode(POC_RLF, popGet(AOP(result),offr));
6755 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6757 emitpcode(POC_RLF, popGet(AOP(result),offr));
6758 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6759 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6760 emitpcode(POC_ANDLW,popGetLit(0x03));
6762 emitpcode(POC_BTFSC,
6763 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6764 emitpcode(POC_IORLW,popGetLit(0xfc));
6766 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6767 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6768 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6769 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6771 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6772 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6774 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6775 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6776 emitpcode(POC_RLF, popGet(AOP(result),offr));
6777 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6778 emitpcode(POC_ANDLW,popGetLit(0x03));
6780 emitpcode(POC_BTFSC,
6781 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6782 emitpcode(POC_IORLW,popGetLit(0xfc));
6784 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6785 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6792 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6793 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6794 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6795 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6798 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6805 /*-----------------------------------------------------------------*/
6806 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6807 /*-----------------------------------------------------------------*/
6808 static void shiftLLeftOrResult (operand *left, int offl,
6809 operand *result, int offr, int shCount)
6811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6812 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6813 /* shift left accumulator */
6815 /* or with result */
6816 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6817 /* back to result */
6818 aopPut(AOP(result),"a",offr);
6821 /*-----------------------------------------------------------------*/
6822 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6823 /*-----------------------------------------------------------------*/
6824 static void shiftRLeftOrResult (operand *left, int offl,
6825 operand *result, int offr, int shCount)
6827 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6828 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6829 /* shift right accumulator */
6831 /* or with result */
6832 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6833 /* back to result */
6834 aopPut(AOP(result),"a",offr);
6837 /*-----------------------------------------------------------------*/
6838 /* genlshOne - left shift a one byte quantity by known count */
6839 /*-----------------------------------------------------------------*/
6840 static void genlshOne (operand *result, operand *left, int shCount)
6842 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6843 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6846 /*-----------------------------------------------------------------*/
6847 /* genlshTwo - left shift two bytes by known amount != 0 */
6848 /*-----------------------------------------------------------------*/
6849 static void genlshTwo (operand *result,operand *left, int shCount)
6853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6854 size = pic14_getDataSize(result);
6856 /* if shCount >= 8 */
6862 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6864 movLeft2Result(left, LSB, result, MSB16);
6866 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6869 /* 1 <= shCount <= 7 */
6872 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6874 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6878 /*-----------------------------------------------------------------*/
6879 /* shiftLLong - shift left one long from left to result */
6880 /* offl = LSB or MSB16 */
6881 /*-----------------------------------------------------------------*/
6882 static void shiftLLong (operand *left, operand *result, int offr )
6885 int size = AOP_SIZE(result);
6887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6888 if(size >= LSB+offr){
6889 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6891 pic14_emitcode("add","a,acc");
6892 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6893 size >= MSB16+offr && offr != LSB )
6894 pic14_emitcode("xch","a,%s",
6895 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6897 aopPut(AOP(result),"a",LSB+offr);
6900 if(size >= MSB16+offr){
6901 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6902 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6905 pic14_emitcode("rlc","a");
6906 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6907 size >= MSB24+offr && offr != LSB)
6908 pic14_emitcode("xch","a,%s",
6909 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6911 aopPut(AOP(result),"a",MSB16+offr);
6914 if(size >= MSB24+offr){
6915 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6916 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6919 pic14_emitcode("rlc","a");
6920 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6921 size >= MSB32+offr && offr != LSB )
6922 pic14_emitcode("xch","a,%s",
6923 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6925 aopPut(AOP(result),"a",MSB24+offr);
6928 if(size > MSB32+offr){
6929 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6930 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6933 pic14_emitcode("rlc","a");
6934 aopPut(AOP(result),"a",MSB32+offr);
6937 aopPut(AOP(result),zero,LSB);
6940 /*-----------------------------------------------------------------*/
6941 /* genlshFour - shift four byte by a known amount != 0 */
6942 /*-----------------------------------------------------------------*/
6943 static void genlshFour (operand *result, operand *left, int shCount)
6947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6948 size = AOP_SIZE(result);
6950 /* if shifting more that 3 bytes */
6951 if (shCount >= 24 ) {
6954 /* lowest order of left goes to the highest
6955 order of the destination */
6956 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6958 movLeft2Result(left, LSB, result, MSB32);
6959 aopPut(AOP(result),zero,LSB);
6960 aopPut(AOP(result),zero,MSB16);
6961 aopPut(AOP(result),zero,MSB32);
6965 /* more than two bytes */
6966 else if ( shCount >= 16 ) {
6967 /* lower order two bytes goes to higher order two bytes */
6969 /* if some more remaining */
6971 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6973 movLeft2Result(left, MSB16, result, MSB32);
6974 movLeft2Result(left, LSB, result, MSB24);
6976 aopPut(AOP(result),zero,MSB16);
6977 aopPut(AOP(result),zero,LSB);
6981 /* if more than 1 byte */
6982 else if ( shCount >= 8 ) {
6983 /* lower order three bytes goes to higher order three bytes */
6987 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6989 movLeft2Result(left, LSB, result, MSB16);
6991 else{ /* size = 4 */
6993 movLeft2Result(left, MSB24, result, MSB32);
6994 movLeft2Result(left, MSB16, result, MSB24);
6995 movLeft2Result(left, LSB, result, MSB16);
6996 aopPut(AOP(result),zero,LSB);
6998 else if(shCount == 1)
6999 shiftLLong(left, result, MSB16);
7001 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7002 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7003 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7004 aopPut(AOP(result),zero,LSB);
7009 /* 1 <= shCount <= 7 */
7010 else if(shCount <= 2){
7011 shiftLLong(left, result, LSB);
7013 shiftLLong(result, result, LSB);
7015 /* 3 <= shCount <= 7, optimize */
7017 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7018 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7019 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7023 /*-----------------------------------------------------------------*/
7024 /* genLeftShiftLiteral - left shifting by known count */
7025 /*-----------------------------------------------------------------*/
7026 static void genLeftShiftLiteral (operand *left,
7031 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7035 freeAsmop(right,NULL,ic,TRUE);
7037 aopOp(left,ic,FALSE);
7038 aopOp(result,ic,FALSE);
7040 size = getSize(operandType(result));
7043 pic14_emitcode("; shift left ","result %d, left %d",size,
7047 /* I suppose that the left size >= result size */
7050 movLeft2Result(left, size, result, size);
7054 else if(shCount >= (size * 8))
7056 aopPut(AOP(result),zero,size);
7060 genlshOne (result,left,shCount);
7065 genlshTwo (result,left,shCount);
7069 genlshFour (result,left,shCount);
7073 freeAsmop(left,NULL,ic,TRUE);
7074 freeAsmop(result,NULL,ic,TRUE);
7077 /*-----------------------------------------------------------------*
7078 * genMultiAsm - repeat assembly instruction for size of register.
7079 * if endian == 1, then the high byte (i.e base address + size of
7080 * register) is used first else the low byte is used first;
7081 *-----------------------------------------------------------------*/
7082 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7100 emitpcode(poc, popGet(AOP(reg),offset));
7105 /*-----------------------------------------------------------------*/
7106 /* genLeftShift - generates code for left shifting */
7107 /*-----------------------------------------------------------------*/
7108 static void genLeftShift (iCode *ic)
7110 operand *left,*right, *result;
7113 symbol *tlbl , *tlbl1;
7116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7118 right = IC_RIGHT(ic);
7120 result = IC_RESULT(ic);
7122 aopOp(right,ic,FALSE);
7124 /* if the shift count is known then do it
7125 as efficiently as possible */
7126 if (AOP_TYPE(right) == AOP_LIT) {
7127 genLeftShiftLiteral (left,right,result,ic);
7131 /* shift count is unknown then we have to form
7132 a loop get the loop count in B : Note: we take
7133 only the lower order byte since shifting
7134 more that 32 bits make no sense anyway, ( the
7135 largest size of an object can be only 32 bits ) */
7138 aopOp(left,ic,FALSE);
7139 aopOp(result,ic,FALSE);
7141 /* now move the left to the result if they are not the
7143 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7144 AOP_SIZE(result) > 1) {
7146 size = AOP_SIZE(result);
7149 l = aopGet(AOP(left),offset,FALSE,TRUE);
7150 if (*l == '@' && (IS_AOP_PREG(result))) {
7152 pic14_emitcode("mov","a,%s",l);
7153 aopPut(AOP(result),"a",offset);
7155 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7156 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7157 //aopPut(AOP(result),l,offset);
7163 size = AOP_SIZE(result);
7165 /* if it is only one byte then */
7167 if(optimized_for_speed) {
7168 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7169 emitpcode(POC_ANDLW, popGetLit(0xf0));
7170 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7171 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7172 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7173 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7174 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7175 emitpcode(POC_RLFW, popGet(AOP(result),0));
7176 emitpcode(POC_ANDLW, popGetLit(0xfe));
7177 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7178 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7179 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7182 tlbl = newiTempLabel(NULL);
7183 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7184 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7185 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7188 emitpcode(POC_COMFW, popGet(AOP(right),0));
7189 emitpcode(POC_RRF, popGet(AOP(result),0));
7190 emitpLabel(tlbl->key);
7191 emitpcode(POC_RLF, popGet(AOP(result),0));
7192 emitpcode(POC_ADDLW, popGetLit(1));
7194 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7199 if (pic14_sameRegs(AOP(left),AOP(result))) {
7201 tlbl = newiTempLabel(NULL);
7202 emitpcode(POC_COMFW, popGet(AOP(right),0));
7203 genMultiAsm(POC_RRF, result, size,1);
7204 emitpLabel(tlbl->key);
7205 genMultiAsm(POC_RLF, result, size,0);
7206 emitpcode(POC_ADDLW, popGetLit(1));
7208 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7212 //tlbl = newiTempLabel(NULL);
7214 //tlbl1 = newiTempLabel(NULL);
7216 //reAdjustPreg(AOP(result));
7218 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7219 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7220 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7222 //pic14_emitcode("add","a,acc");
7223 //aopPut(AOP(result),"a",offset++);
7225 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7227 // pic14_emitcode("rlc","a");
7228 // aopPut(AOP(result),"a",offset++);
7230 //reAdjustPreg(AOP(result));
7232 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7233 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7236 tlbl = newiTempLabel(NULL);
7237 tlbl1= newiTempLabel(NULL);
7239 size = AOP_SIZE(result);
7242 pctemp = popGetTempReg(); /* grab a temporary working register. */
7244 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7246 /* offset should be 0, 1 or 3 */
7247 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7249 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7251 emitpcode(POC_MOVWF, pctemp);
7254 emitpLabel(tlbl->key);
7257 emitpcode(POC_RLF, popGet(AOP(result),0));
7259 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7261 emitpcode(POC_DECFSZ, pctemp);
7262 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7263 emitpLabel(tlbl1->key);
7265 popReleaseTempReg(pctemp);
7269 freeAsmop (right,NULL,ic,TRUE);
7270 freeAsmop(left,NULL,ic,TRUE);
7271 freeAsmop(result,NULL,ic,TRUE);
7274 /*-----------------------------------------------------------------*/
7275 /* genrshOne - right shift a one byte quantity by known count */
7276 /*-----------------------------------------------------------------*/
7277 static void genrshOne (operand *result, operand *left,
7278 int shCount, int sign)
7280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7281 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7284 /*-----------------------------------------------------------------*/
7285 /* genrshTwo - right shift two bytes by known amount != 0 */
7286 /*-----------------------------------------------------------------*/
7287 static void genrshTwo (operand *result,operand *left,
7288 int shCount, int sign)
7290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7291 /* if shCount >= 8 */
7295 shiftR1Left2Result(left, MSB16, result, LSB,
7298 movLeft2Result(left, MSB16, result, LSB);
7300 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7303 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7304 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7308 /* 1 <= shCount <= 7 */
7310 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7313 /*-----------------------------------------------------------------*/
7314 /* shiftRLong - shift right one long from left to result */
7315 /* offl = LSB or MSB16 */
7316 /*-----------------------------------------------------------------*/
7317 static void shiftRLong (operand *left, int offl,
7318 operand *result, int sign)
7320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7322 pic14_emitcode("clr","c");
7323 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7325 pic14_emitcode("mov","c,acc.7");
7326 pic14_emitcode("rrc","a");
7327 aopPut(AOP(result),"a",MSB32-offl);
7329 /* add sign of "a" */
7330 addSign(result, MSB32, sign);
7332 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7333 pic14_emitcode("rrc","a");
7334 aopPut(AOP(result),"a",MSB24-offl);
7336 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7337 pic14_emitcode("rrc","a");
7338 aopPut(AOP(result),"a",MSB16-offl);
7341 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7342 pic14_emitcode("rrc","a");
7343 aopPut(AOP(result),"a",LSB);
7347 /*-----------------------------------------------------------------*/
7348 /* genrshFour - shift four byte by a known amount != 0 */
7349 /*-----------------------------------------------------------------*/
7350 static void genrshFour (operand *result, operand *left,
7351 int shCount, int sign)
7353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7354 /* if shifting more that 3 bytes */
7355 if(shCount >= 24 ) {
7358 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7360 movLeft2Result(left, MSB32, result, LSB);
7362 addSign(result, MSB16, sign);
7364 else if(shCount >= 16){
7367 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7369 movLeft2Result(left, MSB24, result, LSB);
7370 movLeft2Result(left, MSB32, result, MSB16);
7372 addSign(result, MSB24, sign);
7374 else if(shCount >= 8){
7377 shiftRLong(left, MSB16, result, sign);
7378 else if(shCount == 0){
7379 movLeft2Result(left, MSB16, result, LSB);
7380 movLeft2Result(left, MSB24, result, MSB16);
7381 movLeft2Result(left, MSB32, result, MSB24);
7382 addSign(result, MSB32, sign);
7385 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7386 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7387 /* the last shift is signed */
7388 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7389 addSign(result, MSB32, sign);
7392 else{ /* 1 <= shCount <= 7 */
7394 shiftRLong(left, LSB, result, sign);
7396 shiftRLong(result, LSB, result, sign);
7399 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7400 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7401 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7406 /*-----------------------------------------------------------------*/
7407 /* genRightShiftLiteral - right shifting by known count */
7408 /*-----------------------------------------------------------------*/
7409 static void genRightShiftLiteral (operand *left,
7415 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7419 freeAsmop(right,NULL,ic,TRUE);
7421 aopOp(left,ic,FALSE);
7422 aopOp(result,ic,FALSE);
7425 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7429 lsize = pic14_getDataSize(left);
7430 res_size = pic14_getDataSize(result);
7431 /* test the LEFT size !!! */
7433 /* I suppose that the left size >= result size */
7436 movLeft2Result(left, lsize, result, res_size);
7439 else if(shCount >= (lsize * 8)){
7442 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7444 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7445 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7450 emitpcode(POC_MOVLW, popGetLit(0));
7451 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7452 emitpcode(POC_MOVLW, popGetLit(0xff));
7454 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7459 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7466 genrshOne (result,left,shCount,sign);
7470 genrshTwo (result,left,shCount,sign);
7474 genrshFour (result,left,shCount,sign);
7482 freeAsmop(left,NULL,ic,TRUE);
7483 freeAsmop(result,NULL,ic,TRUE);
7486 /*-----------------------------------------------------------------*/
7487 /* genSignedRightShift - right shift of signed number */
7488 /*-----------------------------------------------------------------*/
7489 static void genSignedRightShift (iCode *ic)
7491 operand *right, *left, *result;
7494 symbol *tlbl, *tlbl1 ;
7497 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7499 /* we do it the hard way put the shift count in b
7500 and loop thru preserving the sign */
7501 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7503 right = IC_RIGHT(ic);
7505 result = IC_RESULT(ic);
7507 aopOp(right,ic,FALSE);
7508 aopOp(left,ic,FALSE);
7509 aopOp(result,ic,FALSE);
7512 if ( AOP_TYPE(right) == AOP_LIT) {
7513 genRightShiftLiteral (left,right,result,ic,1);
7516 /* shift count is unknown then we have to form
7517 a loop get the loop count in B : Note: we take
7518 only the lower order byte since shifting
7519 more that 32 bits make no sense anyway, ( the
7520 largest size of an object can be only 32 bits ) */
7522 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7523 //pic14_emitcode("inc","b");
7524 //freeAsmop (right,NULL,ic,TRUE);
7525 //aopOp(left,ic,FALSE);
7526 //aopOp(result,ic,FALSE);
7528 /* now move the left to the result if they are not the
7530 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7531 AOP_SIZE(result) > 1) {
7533 size = AOP_SIZE(result);
7537 l = aopGet(AOP(left),offset,FALSE,TRUE);
7538 if (*l == '@' && IS_AOP_PREG(result)) {
7540 pic14_emitcode("mov","a,%s",l);
7541 aopPut(AOP(result),"a",offset);
7543 aopPut(AOP(result),l,offset);
7545 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7546 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7552 /* mov the highest order bit to OVR */
7553 tlbl = newiTempLabel(NULL);
7554 tlbl1= newiTempLabel(NULL);
7556 size = AOP_SIZE(result);
7559 pctemp = popGetTempReg(); /* grab a temporary working register. */
7561 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7563 /* offset should be 0, 1 or 3 */
7564 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7566 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7568 emitpcode(POC_MOVWF, pctemp);
7571 emitpLabel(tlbl->key);
7573 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7574 emitpcode(POC_RRF, popGet(AOP(result),offset));
7577 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7580 emitpcode(POC_DECFSZ, pctemp);
7581 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7582 emitpLabel(tlbl1->key);
7584 popReleaseTempReg(pctemp);
7586 size = AOP_SIZE(result);
7588 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7589 pic14_emitcode("rlc","a");
7590 pic14_emitcode("mov","ov,c");
7591 /* if it is only one byte then */
7593 l = aopGet(AOP(left),0,FALSE,FALSE);
7595 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7596 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7597 pic14_emitcode("mov","c,ov");
7598 pic14_emitcode("rrc","a");
7599 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7600 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7601 aopPut(AOP(result),"a",0);
7605 reAdjustPreg(AOP(result));
7606 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7607 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7608 pic14_emitcode("mov","c,ov");
7610 l = aopGet(AOP(result),offset,FALSE,FALSE);
7612 pic14_emitcode("rrc","a");
7613 aopPut(AOP(result),"a",offset--);
7615 reAdjustPreg(AOP(result));
7616 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7617 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7622 freeAsmop(left,NULL,ic,TRUE);
7623 freeAsmop(result,NULL,ic,TRUE);
7624 freeAsmop(right,NULL,ic,TRUE);
7627 /*-----------------------------------------------------------------*/
7628 /* genRightShift - generate code for right shifting */
7629 /*-----------------------------------------------------------------*/
7630 static void genRightShift (iCode *ic)
7632 operand *right, *left, *result;
7636 symbol *tlbl, *tlbl1 ;
7638 /* if signed then we do it the hard way preserve the
7639 sign bit moving it inwards */
7640 retype = getSpec(operandType(IC_RESULT(ic)));
7641 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7643 if (!SPEC_USIGN(retype)) {
7644 genSignedRightShift (ic);
7648 /* signed & unsigned types are treated the same : i.e. the
7649 signed is NOT propagated inwards : quoting from the
7650 ANSI - standard : "for E1 >> E2, is equivalent to division
7651 by 2**E2 if unsigned or if it has a non-negative value,
7652 otherwise the result is implementation defined ", MY definition
7653 is that the sign does not get propagated */
7655 right = IC_RIGHT(ic);
7657 result = IC_RESULT(ic);
7659 aopOp(right,ic,FALSE);
7661 /* if the shift count is known then do it
7662 as efficiently as possible */
7663 if (AOP_TYPE(right) == AOP_LIT) {
7664 genRightShiftLiteral (left,right,result,ic, 0);
7668 /* shift count is unknown then we have to form
7669 a loop get the loop count in B : Note: we take
7670 only the lower order byte since shifting
7671 more that 32 bits make no sense anyway, ( the
7672 largest size of an object can be only 32 bits ) */
7674 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7675 pic14_emitcode("inc","b");
7676 aopOp(left,ic,FALSE);
7677 aopOp(result,ic,FALSE);
7679 /* now move the left to the result if they are not the
7681 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7682 AOP_SIZE(result) > 1) {
7684 size = AOP_SIZE(result);
7687 l = aopGet(AOP(left),offset,FALSE,TRUE);
7688 if (*l == '@' && IS_AOP_PREG(result)) {
7690 pic14_emitcode("mov","a,%s",l);
7691 aopPut(AOP(result),"a",offset);
7693 aopPut(AOP(result),l,offset);
7698 tlbl = newiTempLabel(NULL);
7699 tlbl1= newiTempLabel(NULL);
7700 size = AOP_SIZE(result);
7703 /* if it is only one byte then */
7706 tlbl = newiTempLabel(NULL);
7707 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7708 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7709 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7712 emitpcode(POC_COMFW, popGet(AOP(right),0));
7713 emitpcode(POC_RLF, popGet(AOP(result),0));
7714 emitpLabel(tlbl->key);
7715 emitpcode(POC_RRF, popGet(AOP(result),0));
7716 emitpcode(POC_ADDLW, popGetLit(1));
7718 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7723 reAdjustPreg(AOP(result));
7724 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7725 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7728 l = aopGet(AOP(result),offset,FALSE,FALSE);
7730 pic14_emitcode("rrc","a");
7731 aopPut(AOP(result),"a",offset--);
7733 reAdjustPreg(AOP(result));
7735 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7736 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7739 freeAsmop(left,NULL,ic,TRUE);
7740 freeAsmop (right,NULL,ic,TRUE);
7741 freeAsmop(result,NULL,ic,TRUE);
7744 /*-----------------------------------------------------------------*/
7745 /* genUnpackBits - generates code for unpacking bits */
7746 /*-----------------------------------------------------------------*/
7747 static void genUnpackBits (operand *result, char *rname, int ptype)
7754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7755 etype = getSpec(operandType(result));
7757 /* read the first byte */
7762 pic14_emitcode("mov","a,@%s",rname);
7766 pic14_emitcode("movx","a,@%s",rname);
7770 pic14_emitcode("movx","a,@dptr");
7774 pic14_emitcode("clr","a");
7775 pic14_emitcode("movc","a","@a+dptr");
7779 pic14_emitcode("lcall","__gptrget");
7783 /* if we have bitdisplacement then it fits */
7784 /* into this byte completely or if length is */
7785 /* less than a byte */
7786 if ((shCnt = SPEC_BSTR(etype)) ||
7787 (SPEC_BLEN(etype) <= 8)) {
7789 /* shift right acc */
7792 pic14_emitcode("anl","a,#0x%02x",
7793 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7794 aopPut(AOP(result),"a",offset);
7798 /* bit field did not fit in a byte */
7799 rlen = SPEC_BLEN(etype) - 8;
7800 aopPut(AOP(result),"a",offset++);
7807 pic14_emitcode("inc","%s",rname);
7808 pic14_emitcode("mov","a,@%s",rname);
7812 pic14_emitcode("inc","%s",rname);
7813 pic14_emitcode("movx","a,@%s",rname);
7817 pic14_emitcode("inc","dptr");
7818 pic14_emitcode("movx","a,@dptr");
7822 pic14_emitcode("clr","a");
7823 pic14_emitcode("inc","dptr");
7824 pic14_emitcode("movc","a","@a+dptr");
7828 pic14_emitcode("inc","dptr");
7829 pic14_emitcode("lcall","__gptrget");
7834 /* if we are done */
7838 aopPut(AOP(result),"a",offset++);
7843 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7844 aopPut(AOP(result),"a",offset);
7851 /*-----------------------------------------------------------------*/
7852 /* genDataPointerGet - generates code when ptr offset is known */
7853 /*-----------------------------------------------------------------*/
7854 static void genDataPointerGet (operand *left,
7858 int size , offset = 0;
7861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7864 /* optimization - most of the time, left and result are the same
7865 * address, but different types. for the pic code, we could omit
7869 aopOp(result,ic,TRUE);
7871 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7873 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7875 size = AOP_SIZE(result);
7878 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7882 freeAsmop(left,NULL,ic,TRUE);
7883 freeAsmop(result,NULL,ic,TRUE);
7886 /*-----------------------------------------------------------------*/
7887 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7888 /*-----------------------------------------------------------------*/
7889 static void genNearPointerGet (operand *left,
7894 //regs *preg = NULL ;
7896 sym_link *rtype, *retype;
7897 sym_link *ltype = operandType(left);
7900 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7902 rtype = operandType(result);
7903 retype= getSpec(rtype);
7905 aopOp(left,ic,FALSE);
7907 /* if left is rematerialisable and
7908 result is not bit variable type and
7909 the left is pointer to data space i.e
7910 lower 128 bytes of space */
7911 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7912 !IS_BITVAR(retype) &&
7913 DCL_TYPE(ltype) == POINTER) {
7914 //genDataPointerGet (left,result,ic);
7918 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7920 /* if the value is already in a pointer register
7921 then don't need anything more */
7922 if (!AOP_INPREG(AOP(left))) {
7923 /* otherwise get a free pointer register */
7924 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7927 preg = getFreePtr(ic,&aop,FALSE);
7928 pic14_emitcode("mov","%s,%s",
7930 aopGet(AOP(left),0,FALSE,TRUE));
7931 rname = preg->name ;
7935 rname = aopGet(AOP(left),0,FALSE,FALSE);
7937 aopOp (result,ic,FALSE);
7939 /* if bitfield then unpack the bits */
7940 if (IS_BITFIELD(retype))
7941 genUnpackBits (result,rname,POINTER);
7943 /* we have can just get the values */
7944 int size = AOP_SIZE(result);
7947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7949 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7950 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7952 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7953 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7955 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7959 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7961 pic14_emitcode("mov","a,@%s",rname);
7962 aopPut(AOP(result),"a",offset);
7964 sprintf(buffer,"@%s",rname);
7965 aopPut(AOP(result),buffer,offset);
7969 pic14_emitcode("inc","%s",rname);
7974 /* now some housekeeping stuff */
7976 /* we had to allocate for this iCode */
7977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7978 freeAsmop(NULL,aop,ic,TRUE);
7980 /* we did not allocate which means left
7981 already in a pointer register, then
7982 if size > 0 && this could be used again
7983 we have to point it back to where it
7985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7986 if (AOP_SIZE(result) > 1 &&
7987 !OP_SYMBOL(left)->remat &&
7988 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7990 int size = AOP_SIZE(result) - 1;
7992 pic14_emitcode("dec","%s",rname);
7997 freeAsmop(left,NULL,ic,TRUE);
7998 freeAsmop(result,NULL,ic,TRUE);
8002 /*-----------------------------------------------------------------*/
8003 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8004 /*-----------------------------------------------------------------*/
8005 static void genPagedPointerGet (operand *left,
8012 sym_link *rtype, *retype;
8014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8016 rtype = operandType(result);
8017 retype= getSpec(rtype);
8019 aopOp(left,ic,FALSE);
8021 /* if the value is already in a pointer register
8022 then don't need anything more */
8023 if (!AOP_INPREG(AOP(left))) {
8024 /* otherwise get a free pointer register */
8026 preg = getFreePtr(ic,&aop,FALSE);
8027 pic14_emitcode("mov","%s,%s",
8029 aopGet(AOP(left),0,FALSE,TRUE));
8030 rname = preg->name ;
8032 rname = aopGet(AOP(left),0,FALSE,FALSE);
8034 freeAsmop(left,NULL,ic,TRUE);
8035 aopOp (result,ic,FALSE);
8037 /* if bitfield then unpack the bits */
8038 if (IS_BITFIELD(retype))
8039 genUnpackBits (result,rname,PPOINTER);
8041 /* we have can just get the values */
8042 int size = AOP_SIZE(result);
8047 pic14_emitcode("movx","a,@%s",rname);
8048 aopPut(AOP(result),"a",offset);
8053 pic14_emitcode("inc","%s",rname);
8057 /* now some housekeeping stuff */
8059 /* we had to allocate for this iCode */
8060 freeAsmop(NULL,aop,ic,TRUE);
8062 /* we did not allocate which means left
8063 already in a pointer register, then
8064 if size > 0 && this could be used again
8065 we have to point it back to where it
8067 if (AOP_SIZE(result) > 1 &&
8068 !OP_SYMBOL(left)->remat &&
8069 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8071 int size = AOP_SIZE(result) - 1;
8073 pic14_emitcode("dec","%s",rname);
8078 freeAsmop(result,NULL,ic,TRUE);
8083 /*-----------------------------------------------------------------*/
8084 /* genFarPointerGet - gget value from far space */
8085 /*-----------------------------------------------------------------*/
8086 static void genFarPointerGet (operand *left,
8087 operand *result, iCode *ic)
8090 sym_link *retype = getSpec(operandType(result));
8092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8094 aopOp(left,ic,FALSE);
8096 /* if the operand is already in dptr
8097 then we do nothing else we move the value to dptr */
8098 if (AOP_TYPE(left) != AOP_STR) {
8099 /* if this is remateriazable */
8100 if (AOP_TYPE(left) == AOP_IMMD)
8101 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8102 else { /* we need to get it byte by byte */
8103 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8104 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8105 if (options.model == MODEL_FLAT24)
8107 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8111 /* so dptr know contains the address */
8112 freeAsmop(left,NULL,ic,TRUE);
8113 aopOp(result,ic,FALSE);
8115 /* if bit then unpack */
8116 if (IS_BITFIELD(retype))
8117 genUnpackBits(result,"dptr",FPOINTER);
8119 size = AOP_SIZE(result);
8123 pic14_emitcode("movx","a,@dptr");
8124 aopPut(AOP(result),"a",offset++);
8126 pic14_emitcode("inc","dptr");
8130 freeAsmop(result,NULL,ic,TRUE);
8133 /*-----------------------------------------------------------------*/
8134 /* genCodePointerGet - get value from code space */
8135 /*-----------------------------------------------------------------*/
8136 static void genCodePointerGet (operand *left,
8137 operand *result, iCode *ic)
8140 sym_link *retype = getSpec(operandType(result));
8142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8144 aopOp(left,ic,FALSE);
8146 /* if the operand is already in dptr
8147 then we do nothing else we move the value to dptr */
8148 if (AOP_TYPE(left) != AOP_STR) {
8149 /* if this is remateriazable */
8150 if (AOP_TYPE(left) == AOP_IMMD)
8151 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8152 else { /* we need to get it byte by byte */
8153 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8154 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8155 if (options.model == MODEL_FLAT24)
8157 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8161 /* so dptr know contains the address */
8162 freeAsmop(left,NULL,ic,TRUE);
8163 aopOp(result,ic,FALSE);
8165 /* if bit then unpack */
8166 if (IS_BITFIELD(retype))
8167 genUnpackBits(result,"dptr",CPOINTER);
8169 size = AOP_SIZE(result);
8173 pic14_emitcode("clr","a");
8174 pic14_emitcode("movc","a,@a+dptr");
8175 aopPut(AOP(result),"a",offset++);
8177 pic14_emitcode("inc","dptr");
8181 freeAsmop(result,NULL,ic,TRUE);
8184 /*-----------------------------------------------------------------*/
8185 /* genGenPointerGet - gget value from generic pointer space */
8186 /*-----------------------------------------------------------------*/
8187 static void genGenPointerGet (operand *left,
8188 operand *result, iCode *ic)
8191 sym_link *retype = getSpec(operandType(result));
8193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8194 aopOp(left,ic,FALSE);
8195 aopOp(result,ic,FALSE);
8198 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8200 /* if the operand is already in dptr
8201 then we do nothing else we move the value to dptr */
8202 // if (AOP_TYPE(left) != AOP_STR) {
8203 /* if this is remateriazable */
8204 if (AOP_TYPE(left) == AOP_IMMD) {
8205 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8206 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8208 else { /* we need to get it byte by byte */
8210 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8211 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8213 size = AOP_SIZE(result);
8217 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8218 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8220 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8225 /* so dptr know contains the address */
8227 /* if bit then unpack */
8228 //if (IS_BITFIELD(retype))
8229 // genUnpackBits(result,"dptr",GPOINTER);
8232 freeAsmop(left,NULL,ic,TRUE);
8233 freeAsmop(result,NULL,ic,TRUE);
8237 /*-----------------------------------------------------------------*/
8238 /* genConstPointerGet - get value from const generic pointer space */
8239 /*-----------------------------------------------------------------*/
8240 static void genConstPointerGet (operand *left,
8241 operand *result, iCode *ic)
8243 //sym_link *retype = getSpec(operandType(result));
8244 symbol *albl = newiTempLabel(NULL);
8245 symbol *blbl = newiTempLabel(NULL);
8249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8250 aopOp(left,ic,FALSE);
8251 aopOp(result,ic,FALSE);
8254 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8256 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8258 emitpcode(POC_CALL,popGetLabel(albl->key));
8259 pcop = popGetLabel(blbl->key);
8260 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8261 emitpcode(POC_GOTO,pcop);
8262 emitpLabel(albl->key);
8264 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8266 emitpcode(poc,popGet(AOP(left),1));
8267 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8268 emitpcode(poc,popGet(AOP(left),0));
8269 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8271 emitpLabel(blbl->key);
8273 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8276 freeAsmop(left,NULL,ic,TRUE);
8277 freeAsmop(result,NULL,ic,TRUE);
8280 /*-----------------------------------------------------------------*/
8281 /* genPointerGet - generate code for pointer get */
8282 /*-----------------------------------------------------------------*/
8283 static void genPointerGet (iCode *ic)
8285 operand *left, *result ;
8286 sym_link *type, *etype;
8289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8292 result = IC_RESULT(ic) ;
8294 /* depending on the type of pointer we need to
8295 move it to the correct pointer register */
8296 type = operandType(left);
8297 etype = getSpec(type);
8299 if (IS_PTR_CONST(type))
8300 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8302 /* if left is of type of pointer then it is simple */
8303 if (IS_PTR(type) && !IS_FUNC(type->next))
8304 p_type = DCL_TYPE(type);
8306 /* we have to go by the storage class */
8307 p_type = PTR_TYPE(SPEC_OCLS(etype));
8309 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8311 if (SPEC_OCLS(etype)->codesp ) {
8312 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8313 //p_type = CPOINTER ;
8316 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8317 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8318 /*p_type = FPOINTER ;*/
8320 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8321 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8322 /* p_type = PPOINTER; */
8324 if (SPEC_OCLS(etype) == idata )
8325 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8326 /* p_type = IPOINTER; */
8328 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8329 /* p_type = POINTER ; */
8332 /* now that we have the pointer type we assign
8333 the pointer values */
8338 genNearPointerGet (left,result,ic);
8342 genPagedPointerGet(left,result,ic);
8346 genFarPointerGet (left,result,ic);
8350 genConstPointerGet (left,result,ic);
8351 //pic14_emitcodePointerGet (left,result,ic);
8355 if (IS_PTR_CONST(type))
8356 genConstPointerGet (left,result,ic);
8358 genGenPointerGet (left,result,ic);
8364 /*-----------------------------------------------------------------*/
8365 /* genPackBits - generates code for packed bit storage */
8366 /*-----------------------------------------------------------------*/
8367 static void genPackBits (sym_link *etype ,
8369 char *rname, int p_type)
8377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8378 blen = SPEC_BLEN(etype);
8379 bstr = SPEC_BSTR(etype);
8381 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8384 /* if the bit lenth is less than or */
8385 /* it exactly fits a byte then */
8386 if (SPEC_BLEN(etype) <= 8 ) {
8387 shCount = SPEC_BSTR(etype) ;
8389 /* shift left acc */
8392 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8397 pic14_emitcode ("mov","b,a");
8398 pic14_emitcode("mov","a,@%s",rname);
8402 pic14_emitcode ("mov","b,a");
8403 pic14_emitcode("movx","a,@dptr");
8407 pic14_emitcode ("push","b");
8408 pic14_emitcode ("push","acc");
8409 pic14_emitcode ("lcall","__gptrget");
8410 pic14_emitcode ("pop","b");
8414 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8415 ((unsigned char)(0xFF << (blen+bstr)) |
8416 (unsigned char)(0xFF >> (8-bstr)) ) );
8417 pic14_emitcode ("orl","a,b");
8418 if (p_type == GPOINTER)
8419 pic14_emitcode("pop","b");
8425 pic14_emitcode("mov","@%s,a",rname);
8429 pic14_emitcode("movx","@dptr,a");
8433 DEBUGpic14_emitcode(";lcall","__gptrput");
8438 if ( SPEC_BLEN(etype) <= 8 )
8441 pic14_emitcode("inc","%s",rname);
8442 rLen = SPEC_BLEN(etype) ;
8444 /* now generate for lengths greater than one byte */
8447 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8457 pic14_emitcode("mov","@%s,a",rname);
8459 pic14_emitcode("mov","@%s,%s",rname,l);
8464 pic14_emitcode("movx","@dptr,a");
8469 DEBUGpic14_emitcode(";lcall","__gptrput");
8472 pic14_emitcode ("inc","%s",rname);
8477 /* last last was not complete */
8479 /* save the byte & read byte */
8482 pic14_emitcode ("mov","b,a");
8483 pic14_emitcode("mov","a,@%s",rname);
8487 pic14_emitcode ("mov","b,a");
8488 pic14_emitcode("movx","a,@dptr");
8492 pic14_emitcode ("push","b");
8493 pic14_emitcode ("push","acc");
8494 pic14_emitcode ("lcall","__gptrget");
8495 pic14_emitcode ("pop","b");
8499 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8500 pic14_emitcode ("orl","a,b");
8503 if (p_type == GPOINTER)
8504 pic14_emitcode("pop","b");
8509 pic14_emitcode("mov","@%s,a",rname);
8513 pic14_emitcode("movx","@dptr,a");
8517 DEBUGpic14_emitcode(";lcall","__gptrput");
8521 /*-----------------------------------------------------------------*/
8522 /* genDataPointerSet - remat pointer to data space */
8523 /*-----------------------------------------------------------------*/
8524 static void genDataPointerSet(operand *right,
8528 int size, offset = 0 ;
8529 char *l, buffer[256];
8531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8532 aopOp(right,ic,FALSE);
8534 l = aopGet(AOP(result),0,FALSE,TRUE);
8535 size = AOP_SIZE(right);
8537 if ( AOP_TYPE(result) == AOP_PCODE) {
8538 fprintf(stderr,"genDataPointerSet %s, %d\n",
8539 AOP(result)->aopu.pcop->name,
8540 PCOI(AOP(result)->aopu.pcop)->offset);
8544 // tsd, was l+1 - the underline `_' prefix was being stripped
8547 sprintf(buffer,"(%s + %d)",l,offset);
8548 fprintf(stderr,"oops %s\n",buffer);
8550 sprintf(buffer,"%s",l);
8552 if (AOP_TYPE(right) == AOP_LIT) {
8553 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8554 lit = lit >> (8*offset);
8556 pic14_emitcode("movlw","%d",lit);
8557 pic14_emitcode("movwf","%s",buffer);
8559 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8560 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8561 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8564 pic14_emitcode("clrf","%s",buffer);
8565 //emitpcode(POC_CLRF, popRegFromString(buffer));
8566 emitpcode(POC_CLRF, popGet(AOP(result),0));
8569 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8570 pic14_emitcode("movwf","%s",buffer);
8572 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8573 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8574 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8581 freeAsmop(right,NULL,ic,TRUE);
8582 freeAsmop(result,NULL,ic,TRUE);
8585 /*-----------------------------------------------------------------*/
8586 /* genNearPointerSet - pic14_emitcode for near pointer put */
8587 /*-----------------------------------------------------------------*/
8588 static void genNearPointerSet (operand *right,
8595 sym_link *ptype = operandType(result);
8598 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8599 retype= getSpec(operandType(right));
8601 aopOp(result,ic,FALSE);
8604 /* if the result is rematerializable &
8605 in data space & not a bit variable */
8606 //if (AOP_TYPE(result) == AOP_IMMD &&
8607 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8608 DCL_TYPE(ptype) == POINTER &&
8609 !IS_BITFIELD(retype)) {
8610 genDataPointerSet (right,result,ic);
8611 freeAsmop(result,NULL,ic,TRUE);
8615 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8616 aopOp(right,ic,FALSE);
8617 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8619 /* if the value is already in a pointer register
8620 then don't need anything more */
8621 if (!AOP_INPREG(AOP(result))) {
8622 /* otherwise get a free pointer register */
8623 //aop = newAsmop(0);
8624 //preg = getFreePtr(ic,&aop,FALSE);
8625 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8626 //pic14_emitcode("mov","%s,%s",
8628 // aopGet(AOP(result),0,FALSE,TRUE));
8629 //rname = preg->name ;
8630 //pic14_emitcode("movwf","fsr");
8631 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8632 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8633 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8634 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8638 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8641 /* if bitfield then unpack the bits */
8642 if (IS_BITFIELD(retype)) {
8643 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8644 "The programmer is obviously confused");
8645 //genPackBits (retype,right,rname,POINTER);
8649 /* we have can just get the values */
8650 int size = AOP_SIZE(right);
8653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8655 l = aopGet(AOP(right),offset,FALSE,TRUE);
8658 //pic14_emitcode("mov","@%s,a",rname);
8659 pic14_emitcode("movf","indf,w ;1");
8662 if (AOP_TYPE(right) == AOP_LIT) {
8663 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8665 pic14_emitcode("movlw","%s",l);
8666 pic14_emitcode("movwf","indf ;2");
8668 pic14_emitcode("clrf","indf");
8670 pic14_emitcode("movf","%s,w",l);
8671 pic14_emitcode("movwf","indf ;2");
8673 //pic14_emitcode("mov","@%s,%s",rname,l);
8676 pic14_emitcode("incf","fsr,f ;3");
8677 //pic14_emitcode("inc","%s",rname);
8682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8683 /* now some housekeeping stuff */
8685 /* we had to allocate for this iCode */
8686 freeAsmop(NULL,aop,ic,TRUE);
8688 /* we did not allocate which means left
8689 already in a pointer register, then
8690 if size > 0 && this could be used again
8691 we have to point it back to where it
8693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8694 if (AOP_SIZE(right) > 1 &&
8695 !OP_SYMBOL(result)->remat &&
8696 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8698 int size = AOP_SIZE(right) - 1;
8700 pic14_emitcode("decf","fsr,f");
8701 //pic14_emitcode("dec","%s",rname);
8705 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8708 freeAsmop(right,NULL,ic,TRUE);
8709 freeAsmop(result,NULL,ic,TRUE);
8712 /*-----------------------------------------------------------------*/
8713 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8714 /*-----------------------------------------------------------------*/
8715 static void genPagedPointerSet (operand *right,
8724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8726 retype= getSpec(operandType(right));
8728 aopOp(result,ic,FALSE);
8730 /* if the value is already in a pointer register
8731 then don't need anything more */
8732 if (!AOP_INPREG(AOP(result))) {
8733 /* otherwise get a free pointer register */
8735 preg = getFreePtr(ic,&aop,FALSE);
8736 pic14_emitcode("mov","%s,%s",
8738 aopGet(AOP(result),0,FALSE,TRUE));
8739 rname = preg->name ;
8741 rname = aopGet(AOP(result),0,FALSE,FALSE);
8743 freeAsmop(result,NULL,ic,TRUE);
8744 aopOp (right,ic,FALSE);
8746 /* if bitfield then unpack the bits */
8747 if (IS_BITFIELD(retype))
8748 genPackBits (retype,right,rname,PPOINTER);
8750 /* we have can just get the values */
8751 int size = AOP_SIZE(right);
8755 l = aopGet(AOP(right),offset,FALSE,TRUE);
8758 pic14_emitcode("movx","@%s,a",rname);
8761 pic14_emitcode("inc","%s",rname);
8767 /* now some housekeeping stuff */
8769 /* we had to allocate for this iCode */
8770 freeAsmop(NULL,aop,ic,TRUE);
8772 /* we did not allocate which means left
8773 already in a pointer register, then
8774 if size > 0 && this could be used again
8775 we have to point it back to where it
8777 if (AOP_SIZE(right) > 1 &&
8778 !OP_SYMBOL(result)->remat &&
8779 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8781 int size = AOP_SIZE(right) - 1;
8783 pic14_emitcode("dec","%s",rname);
8788 freeAsmop(right,NULL,ic,TRUE);
8793 /*-----------------------------------------------------------------*/
8794 /* genFarPointerSet - set value from far space */
8795 /*-----------------------------------------------------------------*/
8796 static void genFarPointerSet (operand *right,
8797 operand *result, iCode *ic)
8800 sym_link *retype = getSpec(operandType(right));
8802 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8803 aopOp(result,ic,FALSE);
8805 /* if the operand is already in dptr
8806 then we do nothing else we move the value to dptr */
8807 if (AOP_TYPE(result) != AOP_STR) {
8808 /* if this is remateriazable */
8809 if (AOP_TYPE(result) == AOP_IMMD)
8810 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8811 else { /* we need to get it byte by byte */
8812 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8813 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8814 if (options.model == MODEL_FLAT24)
8816 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8820 /* so dptr know contains the address */
8821 freeAsmop(result,NULL,ic,TRUE);
8822 aopOp(right,ic,FALSE);
8824 /* if bit then unpack */
8825 if (IS_BITFIELD(retype))
8826 genPackBits(retype,right,"dptr",FPOINTER);
8828 size = AOP_SIZE(right);
8832 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8834 pic14_emitcode("movx","@dptr,a");
8836 pic14_emitcode("inc","dptr");
8840 freeAsmop(right,NULL,ic,TRUE);
8843 /*-----------------------------------------------------------------*/
8844 /* genGenPointerSet - set value from generic pointer space */
8845 /*-----------------------------------------------------------------*/
8846 static void genGenPointerSet (operand *right,
8847 operand *result, iCode *ic)
8850 sym_link *retype = getSpec(operandType(right));
8852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8854 aopOp(result,ic,FALSE);
8855 aopOp(right,ic,FALSE);
8856 size = AOP_SIZE(right);
8858 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8860 /* if the operand is already in dptr
8861 then we do nothing else we move the value to dptr */
8862 if (AOP_TYPE(result) != AOP_STR) {
8863 /* if this is remateriazable */
8864 if (AOP_TYPE(result) == AOP_IMMD) {
8865 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8866 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8868 else { /* we need to get it byte by byte */
8869 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8870 size = AOP_SIZE(right);
8873 /* hack hack! see if this the FSR. If so don't load W */
8874 if(AOP_TYPE(right) != AOP_ACC) {
8877 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8878 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8880 if(AOP_SIZE(result) > 1) {
8881 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8882 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8883 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8888 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8890 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8891 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8895 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8896 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8899 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8906 if(aopIdx(AOP(result),0) != 4) {
8908 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8912 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8917 /* so dptr know contains the address */
8920 /* if bit then unpack */
8921 if (IS_BITFIELD(retype))
8922 genPackBits(retype,right,"dptr",GPOINTER);
8924 size = AOP_SIZE(right);
8927 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8931 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8932 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8934 if (AOP_TYPE(right) == AOP_LIT)
8935 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8937 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8939 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8946 freeAsmop(right,NULL,ic,TRUE);
8947 freeAsmop(result,NULL,ic,TRUE);
8950 /*-----------------------------------------------------------------*/
8951 /* genPointerSet - stores the value into a pointer location */
8952 /*-----------------------------------------------------------------*/
8953 static void genPointerSet (iCode *ic)
8955 operand *right, *result ;
8956 sym_link *type, *etype;
8959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8961 right = IC_RIGHT(ic);
8962 result = IC_RESULT(ic) ;
8964 /* depending on the type of pointer we need to
8965 move it to the correct pointer register */
8966 type = operandType(result);
8967 etype = getSpec(type);
8968 /* if left is of type of pointer then it is simple */
8969 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8970 p_type = DCL_TYPE(type);
8973 /* we have to go by the storage class */
8974 p_type = PTR_TYPE(SPEC_OCLS(etype));
8976 /* if (SPEC_OCLS(etype)->codesp ) { */
8977 /* p_type = CPOINTER ; */
8980 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8981 /* p_type = FPOINTER ; */
8983 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8984 /* p_type = PPOINTER ; */
8986 /* if (SPEC_OCLS(etype) == idata ) */
8987 /* p_type = IPOINTER ; */
8989 /* p_type = POINTER ; */
8992 /* now that we have the pointer type we assign
8993 the pointer values */
8998 genNearPointerSet (right,result,ic);
9002 genPagedPointerSet (right,result,ic);
9006 genFarPointerSet (right,result,ic);
9010 genGenPointerSet (right,result,ic);
9014 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9015 "genPointerSet: illegal pointer type");
9019 /*-----------------------------------------------------------------*/
9020 /* genIfx - generate code for Ifx statement */
9021 /*-----------------------------------------------------------------*/
9022 static void genIfx (iCode *ic, iCode *popIc)
9024 operand *cond = IC_COND(ic);
9027 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9029 aopOp(cond,ic,FALSE);
9031 /* get the value into acc */
9032 if (AOP_TYPE(cond) != AOP_CRY)
9033 pic14_toBoolean(cond);
9036 /* the result is now in the accumulator */
9037 freeAsmop(cond,NULL,ic,TRUE);
9039 /* if there was something to be popped then do it */
9043 /* if the condition is a bit variable */
9044 if (isbit && IS_ITEMP(cond) &&
9046 genIfxJump(ic,SPIL_LOC(cond)->rname);
9047 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9050 if (isbit && !IS_ITEMP(cond))
9051 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9059 /*-----------------------------------------------------------------*/
9060 /* genAddrOf - generates code for address of */
9061 /*-----------------------------------------------------------------*/
9062 static void genAddrOf (iCode *ic)
9064 operand *right, *result, *left;
9067 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9070 //aopOp(IC_RESULT(ic),ic,FALSE);
9072 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9073 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9074 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9076 DEBUGpic14_AopType(__LINE__,left,right,result);
9078 size = AOP_SIZE(IC_RESULT(ic));
9082 /* fixing bug #863624, reported from (errolv) */
9083 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9084 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9087 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9088 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9093 freeAsmop(left,NULL,ic,FALSE);
9094 freeAsmop(result,NULL,ic,TRUE);
9099 /*-----------------------------------------------------------------*/
9100 /* genFarFarAssign - assignment when both are in far space */
9101 /*-----------------------------------------------------------------*/
9102 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9104 int size = AOP_SIZE(right);
9107 /* first push the right side on to the stack */
9109 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9111 pic14_emitcode ("push","acc");
9114 freeAsmop(right,NULL,ic,FALSE);
9115 /* now assign DPTR to result */
9116 aopOp(result,ic,FALSE);
9117 size = AOP_SIZE(result);
9119 pic14_emitcode ("pop","acc");
9120 aopPut(AOP(result),"a",--offset);
9122 freeAsmop(result,NULL,ic,FALSE);
9127 /*-----------------------------------------------------------------*/
9128 /* genAssign - generate code for assignment */
9129 /*-----------------------------------------------------------------*/
9130 static void genAssign (iCode *ic)
9132 operand *result, *right;
9133 int size, offset,know_W;
9134 unsigned long lit = 0L;
9136 result = IC_RESULT(ic);
9137 right = IC_RIGHT(ic) ;
9139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9141 /* if they are the same */
9142 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9145 aopOp(right,ic,FALSE);
9146 aopOp(result,ic,TRUE);
9148 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9150 /* if they are the same registers */
9151 if (pic14_sameRegs(AOP(right),AOP(result)))
9154 /* if the result is a bit */
9155 if (AOP_TYPE(result) == AOP_CRY) {
9157 /* if the right size is a literal then
9158 we know what the value is */
9159 if (AOP_TYPE(right) == AOP_LIT) {
9161 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9162 popGet(AOP(result),0));
9164 if (((int) operandLitValue(right)))
9165 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9166 AOP(result)->aopu.aop_dir,
9167 AOP(result)->aopu.aop_dir);
9169 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9170 AOP(result)->aopu.aop_dir,
9171 AOP(result)->aopu.aop_dir);
9175 /* the right is also a bit variable */
9176 if (AOP_TYPE(right) == AOP_CRY) {
9177 emitpcode(POC_BCF, popGet(AOP(result),0));
9178 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9179 emitpcode(POC_BSF, popGet(AOP(result),0));
9181 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9182 AOP(result)->aopu.aop_dir,
9183 AOP(result)->aopu.aop_dir);
9184 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9185 AOP(right)->aopu.aop_dir,
9186 AOP(right)->aopu.aop_dir);
9187 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9188 AOP(result)->aopu.aop_dir,
9189 AOP(result)->aopu.aop_dir);
9194 emitpcode(POC_BCF, popGet(AOP(result),0));
9195 pic14_toBoolean(right);
9197 emitpcode(POC_BSF, popGet(AOP(result),0));
9198 //aopPut(AOP(result),"a",0);
9202 /* bit variables done */
9204 size = AOP_SIZE(result);
9206 if(AOP_TYPE(right) == AOP_LIT)
9207 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9209 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9210 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9211 if(aopIdx(AOP(result),0) == 4) {
9212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9213 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9214 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9217 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9223 if(AOP_TYPE(right) == AOP_LIT) {
9225 if(know_W != (int)(lit&0xff))
9226 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9228 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9230 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9234 } else if (AOP_TYPE(right) == AOP_CRY) {
9235 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9237 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9238 emitpcode(POC_INCF, popGet(AOP(result),0));
9241 mov2w (AOP(right), offset);
9242 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9250 freeAsmop (right,NULL,ic,FALSE);
9251 freeAsmop (result,NULL,ic,TRUE);
9254 /*-----------------------------------------------------------------*/
9255 /* genJumpTab - genrates code for jump table */
9256 /*-----------------------------------------------------------------*/
9257 static void genJumpTab (iCode *ic)
9262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9264 aopOp(IC_JTCOND(ic),ic,FALSE);
9265 /* get the condition into accumulator */
9266 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9268 /* multiply by three */
9269 pic14_emitcode("add","a,acc");
9270 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9272 jtab = newiTempLabel(NULL);
9273 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9274 pic14_emitcode("jmp","@a+dptr");
9275 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9277 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9278 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9279 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9280 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9282 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9283 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9284 emitpLabel(jtab->key);
9286 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9288 /* now generate the jump labels */
9289 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9290 jtab = setNextItem(IC_JTLABELS(ic))) {
9291 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9292 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9298 /*-----------------------------------------------------------------*/
9299 /* genMixedOperation - gen code for operators between mixed types */
9300 /*-----------------------------------------------------------------*/
9302 TSD - Written for the PIC port - but this unfortunately is buggy.
9303 This routine is good in that it is able to efficiently promote
9304 types to different (larger) sizes. Unfortunately, the temporary
9305 variables that are optimized out by this routine are sometimes
9306 used in other places. So until I know how to really parse the
9307 iCode tree, I'm going to not be using this routine :(.
9309 static int genMixedOperation (iCode *ic)
9312 operand *result = IC_RESULT(ic);
9313 sym_link *ctype = operandType(IC_LEFT(ic));
9314 operand *right = IC_RIGHT(ic);
9320 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9322 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9328 nextright = IC_RIGHT(nextic);
9329 nextleft = IC_LEFT(nextic);
9330 nextresult = IC_RESULT(nextic);
9332 aopOp(right,ic,FALSE);
9333 aopOp(result,ic,FALSE);
9334 aopOp(nextright, nextic, FALSE);
9335 aopOp(nextleft, nextic, FALSE);
9336 aopOp(nextresult, nextic, FALSE);
9338 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9344 pic14_emitcode(";remove right +","");
9346 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9352 pic14_emitcode(";remove left +","");
9356 big = AOP_SIZE(nextleft);
9357 small = AOP_SIZE(nextright);
9359 switch(nextic->op) {
9362 pic14_emitcode(";optimize a +","");
9363 /* if unsigned or not an integral type */
9364 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9365 pic14_emitcode(";add a bit to something","");
9368 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9370 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9371 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9372 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9374 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9382 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9383 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9384 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9387 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9389 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9390 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9391 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9392 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9393 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9396 pic14_emitcode("rlf","known_zero,w");
9403 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9404 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9405 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9407 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9417 freeAsmop(right,NULL,ic,TRUE);
9418 freeAsmop(result,NULL,ic,TRUE);
9419 freeAsmop(nextright,NULL,ic,TRUE);
9420 freeAsmop(nextleft,NULL,ic,TRUE);
9422 nextic->generated = 1;
9429 /*-----------------------------------------------------------------*/
9430 /* genCast - gen code for casting */
9431 /*-----------------------------------------------------------------*/
9432 static void genCast (iCode *ic)
9434 operand *result = IC_RESULT(ic);
9435 sym_link *ctype = operandType(IC_LEFT(ic));
9436 sym_link *rtype = operandType(IC_RIGHT(ic));
9437 operand *right = IC_RIGHT(ic);
9440 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9441 /* if they are equivalent then do nothing */
9442 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9445 aopOp(right,ic,FALSE) ;
9446 aopOp(result,ic,FALSE);
9448 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9450 /* if the result is a bit */
9451 if (AOP_TYPE(result) == AOP_CRY) {
9452 /* if the right size is a literal then
9453 we know what the value is */
9454 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9455 if (AOP_TYPE(right) == AOP_LIT) {
9457 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9458 popGet(AOP(result),0));
9460 if (((int) operandLitValue(right)))
9461 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9462 AOP(result)->aopu.aop_dir,
9463 AOP(result)->aopu.aop_dir);
9465 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9466 AOP(result)->aopu.aop_dir,
9467 AOP(result)->aopu.aop_dir);
9472 /* the right is also a bit variable */
9473 if (AOP_TYPE(right) == AOP_CRY) {
9476 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9478 pic14_emitcode("clrc","");
9479 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9480 AOP(right)->aopu.aop_dir,
9481 AOP(right)->aopu.aop_dir);
9482 aopPut(AOP(result),"c",0);
9487 if (AOP_TYPE(right) == AOP_REG) {
9488 emitpcode(POC_BCF, popGet(AOP(result),0));
9489 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9490 emitpcode(POC_BSF, popGet(AOP(result),0));
9492 pic14_toBoolean(right);
9493 aopPut(AOP(result),"a",0);
9497 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9499 size = AOP_SIZE(result);
9501 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9503 emitpcode(POC_CLRF, popGet(AOP(result),0));
9504 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9505 emitpcode(POC_INCF, popGet(AOP(result),0));
9508 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9513 /* if they are the same size : or less */
9514 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9516 /* if they are in the same place */
9517 if (pic14_sameRegs(AOP(right),AOP(result)))
9520 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9521 if (IS_PTR_CONST(rtype))
9522 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9523 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9524 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9526 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9527 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9528 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9529 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9530 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9531 if(AOP_SIZE(result) <2)
9532 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9536 /* if they in different places then copy */
9537 size = AOP_SIZE(result);
9540 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9541 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9543 //aopPut(AOP(result),
9544 // aopGet(AOP(right),offset,FALSE,FALSE),
9554 /* if the result is of type pointer */
9555 if (IS_PTR(ctype)) {
9558 sym_link *type = operandType(right);
9559 sym_link *etype = getSpec(type);
9560 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9562 /* pointer to generic pointer */
9563 if (IS_GENPTR(ctype)) {
9567 p_type = DCL_TYPE(type);
9569 /* we have to go by the storage class */
9570 p_type = PTR_TYPE(SPEC_OCLS(etype));
9572 /* if (SPEC_OCLS(etype)->codesp ) */
9573 /* p_type = CPOINTER ; */
9575 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9576 /* p_type = FPOINTER ; */
9578 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9579 /* p_type = PPOINTER; */
9581 /* if (SPEC_OCLS(etype) == idata ) */
9582 /* p_type = IPOINTER ; */
9584 /* p_type = POINTER ; */
9587 /* the first two bytes are known */
9588 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9589 size = GPTRSIZE - 1;
9592 if(offset < AOP_SIZE(right)) {
9593 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9594 if ((AOP_TYPE(right) == AOP_PCODE) &&
9595 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9596 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9597 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9600 aopGet(AOP(right),offset,FALSE,FALSE),
9604 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9607 /* the last byte depending on type */
9611 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9614 pic14_emitcode(";BUG!? ","%d",__LINE__);
9618 pic14_emitcode(";BUG!? ","%d",__LINE__);
9622 pic14_emitcode(";BUG!? ","%d",__LINE__);
9627 /* this should never happen */
9628 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9629 "got unknown pointer type");
9632 //aopPut(AOP(result),l, GPTRSIZE - 1);
9636 /* just copy the pointers */
9637 size = AOP_SIZE(result);
9641 aopGet(AOP(right),offset,FALSE,FALSE),
9650 /* so we now know that the size of destination is greater
9651 than the size of the source.
9652 Now, if the next iCode is an operator then we might be
9653 able to optimize the operation without performing a cast.
9655 if(genMixedOperation(ic))
9658 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9660 /* we move to result for the size of source */
9661 size = AOP_SIZE(right);
9664 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9665 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9669 /* now depending on the sign of the destination */
9670 size = AOP_SIZE(result) - AOP_SIZE(right);
9671 /* if unsigned or not an integral type */
9672 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9674 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9676 /* we need to extend the sign :{ */
9679 /* Save one instruction of casting char to int */
9680 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9681 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9682 emitpcode(POC_DECF, popGet(AOP(result),offset));
9684 emitpcodeNULLop(POC_CLRW);
9687 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9689 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9691 emitpcode(POC_MOVLW, popGetLit(0xff));
9694 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9699 freeAsmop(right,NULL,ic,TRUE);
9700 freeAsmop(result,NULL,ic,TRUE);
9704 /*-----------------------------------------------------------------*/
9705 /* genDjnz - generate decrement & jump if not zero instrucion */
9706 /*-----------------------------------------------------------------*/
9707 static int genDjnz (iCode *ic, iCode *ifx)
9710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9715 /* if the if condition has a false label
9716 then we cannot save */
9720 /* if the minus is not of the form
9722 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9723 !IS_OP_LITERAL(IC_RIGHT(ic)))
9726 if (operandLitValue(IC_RIGHT(ic)) != 1)
9729 /* if the size of this greater than one then no
9731 if (getSize(operandType(IC_RESULT(ic))) > 1)
9734 /* otherwise we can save BIG */
9735 lbl = newiTempLabel(NULL);
9736 lbl1= newiTempLabel(NULL);
9738 aopOp(IC_RESULT(ic),ic,FALSE);
9740 if (IS_AOP_PREG(IC_RESULT(ic))) {
9741 pic14_emitcode("dec","%s",
9742 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9743 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9744 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9748 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9749 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9751 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9752 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9755 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9756 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9757 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9758 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9761 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9766 /*-----------------------------------------------------------------*/
9767 /* genReceive - generate code for a receive iCode */
9768 /*-----------------------------------------------------------------*/
9769 static void genReceive (iCode *ic)
9771 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9773 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9774 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9775 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9777 int size = getSize(operandType(IC_RESULT(ic)));
9778 int offset = fReturnSizePic - size;
9780 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9781 fReturn[fReturnSizePic - offset - 1] : "acc"));
9784 aopOp(IC_RESULT(ic),ic,FALSE);
9785 size = AOP_SIZE(IC_RESULT(ic));
9788 pic14_emitcode ("pop","acc");
9789 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9794 aopOp(IC_RESULT(ic),ic,FALSE);
9796 assignResultValue(IC_RESULT(ic));
9799 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9802 /*-----------------------------------------------------------------*/
9803 /* genDummyRead - generate code for dummy read of volatiles */
9804 /*-----------------------------------------------------------------*/
9806 genDummyRead (iCode * ic)
9808 pic14_emitcode ("; genDummyRead","");
9809 pic14_emitcode ("; not implemented","");
9814 /*-----------------------------------------------------------------*/
9815 /* genpic14Code - generate code for pic14 based controllers */
9816 /*-----------------------------------------------------------------*/
9818 * At this point, ralloc.c has gone through the iCode and attempted
9819 * to optimize in a way suitable for a PIC. Now we've got to generate
9820 * PIC instructions that correspond to the iCode.
9822 * Once the instructions are generated, we'll pass through both the
9823 * peep hole optimizer and the pCode optimizer.
9824 *-----------------------------------------------------------------*/
9826 void genpic14Code (iCode *lic)
9831 lineHead = lineCurr = NULL;
9833 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9836 /* if debug information required */
9837 if (options.debug && currFunc) {
9839 debugFile->writeFunction (currFunc, lic);
9844 for (ic = lic ; ic ; ic = ic->next ) {
9846 DEBUGpic14_emitcode(";ic","");
9847 if ( cln != ic->lineno ) {
9848 if ( options.debug ) {
9849 debugFile->writeCLine (ic);
9852 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9853 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9854 printCLine(ic->filename, ic->lineno));
9856 if (!options.noCcodeInAsm) {
9858 newpCodeCSource(ic->lineno,
9860 printCLine(ic->filename, ic->lineno)));
9866 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9868 /* if the result is marked as
9869 spilt and rematerializable or code for
9870 this has already been generated then
9872 if (resultRemat(ic) || ic->generated )
9875 /* depending on the operation */
9894 /* IPOP happens only when trying to restore a
9895 spilt live range, if there is an ifx statement
9896 following this pop then the if statement might
9897 be using some of the registers being popped which
9898 would destory the contents of the register so
9899 we need to check for this condition and handle it */
9901 ic->next->op == IFX &&
9902 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9903 genIfx (ic->next,ic);
9921 genEndFunction (ic);
9941 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9958 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9962 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9969 /* note these two are xlated by algebraic equivalence
9970 during parsing SDCC.y */
9971 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9972 "got '>=' or '<=' shouldn't have come here");
9976 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9988 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9992 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9996 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10020 genRightShift (ic);
10023 case GET_VALUE_AT_ADDRESS:
10028 if (POINTER_SET(ic))
10055 addSet(&_G.sendSet,ic);
10058 case DUMMY_READ_VOLATILE:
10068 /* now we are ready to call the
10069 peep hole optimizer */
10070 if (!options.nopeep) {
10071 peepHole (&lineHead);
10073 /* now do the actual printing */
10074 printLine (lineHead,codeOutFile);
10077 DFPRINTF((stderr,"printing pBlock\n\n"));
10078 printpBlock(stdout,pb);