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 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
220 addpCode2pBlock(pb,newpCode(poc,pcop));
222 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
225 void emitpcodeNULLop(PIC_OPCODE poc)
228 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
268 /*-----------------------------------------------------------------*/
269 /* pic14_emitDebuggerSymbol - associate the current code location */
270 /* with a debugger symbol */
271 /*-----------------------------------------------------------------*/
273 pic14_emitDebuggerSymbol (char * debugSym)
276 pic14_emitcode ("", ";%s ==.", debugSym);
281 /*-----------------------------------------------------------------*/
282 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
283 /*-----------------------------------------------------------------*/
284 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
286 bool r0iu = FALSE , r1iu = FALSE;
287 bool r0ou = FALSE , r1ou = FALSE;
289 /* the logic: if r0 & r1 used in the instruction
290 then we are in trouble otherwise */
292 /* first check if r0 & r1 are used by this
293 instruction, in which case we are in trouble */
294 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
295 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
300 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
301 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
303 /* if no usage of r0 then return it */
304 if (!r0iu && !r0ou) {
305 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
306 (*aopp)->type = AOP_R0;
308 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
311 /* if no usage of r1 then return it */
312 if (!r1iu && !r1ou) {
313 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
314 (*aopp)->type = AOP_R1;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
319 /* now we know they both have usage */
320 /* if r0 not used in this instruction */
322 /* push it if not already pushed */
324 //pic14_emitcode ("push","%s",
325 // pic14_regWithIdx(R0_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
330 (*aopp)->type = AOP_R0;
332 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
335 /* if r1 not used then */
338 /* push it if not already pushed */
340 //pic14_emitcode ("push","%s",
341 // pic14_regWithIdx(R1_IDX)->dname);
345 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
346 (*aopp)->type = AOP_R1;
347 return pic14_regWithIdx(R1_IDX);
351 /* I said end of world but not quite end of world yet */
352 /* if this is a result then we can push it on the stack*/
354 (*aopp)->type = AOP_STK;
358 /* other wise this is true end of the world */
359 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
360 "getFreePtr should never reach here");
364 /*-----------------------------------------------------------------*/
365 /* newAsmop - creates a new asmOp */
366 /*-----------------------------------------------------------------*/
367 asmop *newAsmop (short type)
371 aop = Safe_calloc(1,sizeof(asmop));
376 static void genSetDPTR(int n)
380 pic14_emitcode(";", "Select standard DPTR");
381 pic14_emitcode("mov", "dps, #0x00");
385 pic14_emitcode(";", "Select alternate DPTR");
386 pic14_emitcode("mov", "dps, #0x01");
390 /*-----------------------------------------------------------------*/
391 /* resolveIfx - converts an iCode ifx into a form more useful for */
392 /* generating code */
393 /*-----------------------------------------------------------------*/
394 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
399 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
401 resIfx->condition = 1; /* assume that the ifx is true */
402 resIfx->generated = 0; /* indicate that the ifx has not been used */
405 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
407 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
408 __FUNCTION__,__LINE__,resIfx->lbl->key);
412 resIfx->lbl = IC_TRUE(ifx);
414 resIfx->lbl = IC_FALSE(ifx);
415 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
425 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
428 /*-----------------------------------------------------------------*/
429 /* pointerCode - returns the code for a pointer type */
430 /*-----------------------------------------------------------------*/
431 static int pointerCode (sym_link *etype)
434 return PTR_TYPE(SPEC_OCLS(etype));
438 /*-----------------------------------------------------------------*/
439 /* aopForSym - for a true symbol */
440 /*-----------------------------------------------------------------*/
441 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
444 memmap *space= SPEC_OCLS(sym->etype);
446 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
447 /* if already has one */
451 /* assign depending on the storage class */
452 /* if it is on the stack or indirectly addressable */
453 /* space we need to assign either r0 or r1 to it */
454 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
455 sym->aop = aop = newAsmop(0);
456 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
457 aop->size = getSize(sym->type);
459 /* now assign the address of the variable to
460 the pointer register */
461 if (aop->type != AOP_STK) {
465 pic14_emitcode("push","acc");
467 pic14_emitcode("mov","a,_bp");
468 pic14_emitcode("add","a,#0x%02x",
470 ((char)(sym->stack - _G.nRegsSaved )) :
471 ((char)sym->stack)) & 0xff);
472 pic14_emitcode("mov","%s,a",
473 aop->aopu.aop_ptr->name);
476 pic14_emitcode("pop","acc");
478 pic14_emitcode("mov","%s,#%s",
479 aop->aopu.aop_ptr->name,
481 aop->paged = space->paged;
483 aop->aopu.aop_stk = sym->stack;
487 if (sym->onStack && options.stack10bit)
489 /* It's on the 10 bit stack, which is located in
493 //DEBUGpic14_emitcode(";","%d",__LINE__);
496 pic14_emitcode("push","acc");
498 pic14_emitcode("mov","a,_bp");
499 pic14_emitcode("add","a,#0x%02x",
501 ((char)(sym->stack - _G.nRegsSaved )) :
502 ((char)sym->stack)) & 0xff);
505 pic14_emitcode ("mov","dpx1,#0x40");
506 pic14_emitcode ("mov","dph1,#0x00");
507 pic14_emitcode ("mov","dpl1, a");
511 pic14_emitcode("pop","acc");
513 sym->aop = aop = newAsmop(AOP_DPTR2);
514 aop->size = getSize(sym->type);
518 //DEBUGpic14_emitcode(";","%d",__LINE__);
519 /* if in bit space */
520 if (IN_BITSPACE(space)) {
521 sym->aop = aop = newAsmop (AOP_CRY);
522 aop->aopu.aop_dir = sym->rname ;
523 aop->size = getSize(sym->type);
524 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
527 /* if it is in direct space */
528 if (IN_DIRSPACE(space)) {
529 sym->aop = aop = newAsmop (AOP_DIR);
530 aop->aopu.aop_dir = sym->rname ;
531 aop->size = getSize(sym->type);
532 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
536 /* special case for a function */
537 if (IS_FUNC(sym->type)) {
539 sym->aop = aop = newAsmop(AOP_PCODE);
540 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
541 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542 PCOI(aop->aopu.pcop)->_function = 1;
543 PCOI(aop->aopu.pcop)->index = 0;
544 aop->size = FPTRSIZE;
546 sym->aop = aop = newAsmop(AOP_IMMD);
547 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548 strcpy(aop->aopu.aop_immd,sym->rname);
549 aop->size = FPTRSIZE;
551 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
556 /* only remaining is far space */
557 /* in which case DPTR gets the address */
558 sym->aop = aop = newAsmop(AOP_PCODE);
560 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
561 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
562 PCOI(aop->aopu.pcop)->index = 0;
564 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
565 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
567 allocDirReg (IC_LEFT(ic));
569 aop->size = FPTRSIZE;
571 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
572 sym->aop = aop = newAsmop(AOP_DPTR);
573 pic14_emitcode ("mov","dptr,#%s", sym->rname);
574 aop->size = getSize(sym->type);
576 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
579 /* if it is in code space */
580 if (IN_CODESPACE(space))
586 /*-----------------------------------------------------------------*/
587 /* aopForRemat - rematerialzes an object */
588 /*-----------------------------------------------------------------*/
589 static asmop *aopForRemat (operand *op) // x symbol *sym)
591 symbol *sym = OP_SYMBOL(op);
593 asmop *aop = newAsmop(AOP_PCODE);
597 ic = sym->rematiCode;
599 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
600 if(IS_OP_POINTER(op)) {
601 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
605 val += (int) operandLitValue(IC_RIGHT(ic));
606 } else if (ic->op == '-') {
607 val -= (int) operandLitValue(IC_RIGHT(ic));
611 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
614 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
615 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
616 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
617 PCOI(aop->aopu.pcop)->index = val;
619 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
620 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
621 val, IS_PTR_CONST(operandType(op)));
623 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
625 allocDirReg (IC_LEFT(ic));
630 int aopIdx (asmop *aop, int offset)
635 if(aop->type != AOP_REG)
638 return aop->aopu.aop_reg[offset]->rIdx;
641 /*-----------------------------------------------------------------*/
642 /* regsInCommon - two operands have some registers in common */
643 /*-----------------------------------------------------------------*/
644 static bool regsInCommon (operand *op1, operand *op2)
649 /* if they have registers in common */
650 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
653 sym1 = OP_SYMBOL(op1);
654 sym2 = OP_SYMBOL(op2);
656 if (sym1->nRegs == 0 || sym2->nRegs == 0)
659 for (i = 0 ; i < sym1->nRegs ; i++) {
664 for (j = 0 ; j < sym2->nRegs ;j++ ) {
668 if (sym2->regs[j] == sym1->regs[i])
676 /*-----------------------------------------------------------------*/
677 /* operandsEqu - equivalent */
678 /*-----------------------------------------------------------------*/
679 static bool operandsEqu ( operand *op1, operand *op2)
683 /* if they not symbols */
684 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
687 sym1 = OP_SYMBOL(op1);
688 sym2 = OP_SYMBOL(op2);
690 /* if both are itemps & one is spilt
691 and the other is not then false */
692 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
693 sym1->isspilt != sym2->isspilt )
696 /* if they are the same */
700 if (sym1->rname[0] && sym2->rname[0]
701 && strcmp (sym1->rname, sym2->rname) == 0)
705 /* if left is a tmp & right is not */
709 (sym1->usl.spillLoc == sym2))
716 (sym2->usl.spillLoc == sym1))
722 /*-----------------------------------------------------------------*/
723 /* pic14_sameRegs - two asmops have the same registers */
724 /*-----------------------------------------------------------------*/
725 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
732 if (aop1->type != AOP_REG ||
733 aop2->type != AOP_REG )
736 if (aop1->size != aop2->size )
739 for (i = 0 ; i < aop1->size ; i++ )
740 if (aop1->aopu.aop_reg[i] !=
741 aop2->aopu.aop_reg[i] )
747 /*-----------------------------------------------------------------*/
748 /* aopOp - allocates an asmop for an operand : */
749 /*-----------------------------------------------------------------*/
750 void aopOp (operand *op, iCode *ic, bool result)
759 // DEBUGpic14_emitcode(";","%d",__LINE__);
760 /* if this a literal */
761 if (IS_OP_LITERAL(op)) {
762 op->aop = aop = newAsmop(AOP_LIT);
763 aop->aopu.aop_lit = op->operand.valOperand;
764 aop->size = getSize(operandType(op));
769 sym_link *type = operandType(op);
770 if(IS_PTR_CONST(type))
771 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
774 /* if already has a asmop then continue */
778 /* if the underlying symbol has a aop */
779 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
780 DEBUGpic14_emitcode(";","%d",__LINE__);
781 op->aop = OP_SYMBOL(op)->aop;
785 /* if this is a true symbol */
786 if (IS_TRUE_SYMOP(op)) {
787 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
788 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
792 /* this is a temporary : this has
798 e) can be a return use only */
803 /* if the type is a conditional */
804 if (sym->regType == REG_CND) {
805 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
810 /* if it is spilt then two situations
812 b) has a spill location */
813 if (sym->isspilt || sym->nRegs == 0) {
815 DEBUGpic14_emitcode(";","%d",__LINE__);
816 /* rematerialize it NOW */
819 sym->aop = op->aop = aop = aopForRemat (op);
820 aop->size = getSize(sym->type);
821 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
827 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
828 aop->size = getSize(sym->type);
829 for ( i = 0 ; i < 2 ; i++ )
830 aop->aopu.aop_str[i] = accUse[i];
831 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
836 if(sym->isptr) { // && sym->uptr
837 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
838 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
840 //PCOI(aop->aopu.pcop)->_const = 0;
841 //PCOI(aop->aopu.pcop)->index = 0;
843 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
844 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
846 //allocDirReg (IC_LEFT(ic));
848 aop->size = getSize(sym->type);
849 DEBUGpic14_emitcode(";","%d",__LINE__);
856 aop = op->aop = sym->aop = newAsmop(AOP_STR);
857 aop->size = getSize(sym->type);
858 for ( i = 0 ; i < fReturnSizePic ; i++ )
859 aop->aopu.aop_str[i] = fReturn[i];
861 DEBUGpic14_emitcode(";","%d",__LINE__);
866 /* else spill location */
867 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
868 /* force a new aop if sizes differ */
869 sym->usl.spillLoc->aop = NULL;
871 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
872 __FUNCTION__,__LINE__,
873 sym->usl.spillLoc->rname,
874 sym->rname, sym->usl.spillLoc->offset);
876 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
877 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
878 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
880 sym->usl.spillLoc->offset);
881 aop->size = getSize(sym->type);
887 sym_link *type = operandType(op);
888 if(IS_PTR_CONST(type))
889 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
892 /* must be in a register */
893 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
894 sym->aop = op->aop = aop = newAsmop(AOP_REG);
895 aop->size = sym->nRegs;
896 for ( i = 0 ; i < sym->nRegs ;i++)
897 aop->aopu.aop_reg[i] = sym->regs[i];
900 /*-----------------------------------------------------------------*/
901 /* freeAsmop - free up the asmop given to an operand */
902 /*----------------------------------------------------------------*/
903 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
920 /* depending on the asmop type only three cases need work AOP_RO
921 , AOP_R1 && AOP_STK */
927 pic14_emitcode ("pop","ar0");
931 bitVectUnSetBit(ic->rUsed,R0_IDX);
937 pic14_emitcode ("pop","ar1");
941 bitVectUnSetBit(ic->rUsed,R1_IDX);
947 int stk = aop->aopu.aop_stk + aop->size;
948 bitVectUnSetBit(ic->rUsed,R0_IDX);
949 bitVectUnSetBit(ic->rUsed,R1_IDX);
951 getFreePtr(ic,&aop,FALSE);
953 if (options.stack10bit)
955 /* I'm not sure what to do here yet... */
958 "*** Warning: probably generating bad code for "
959 "10 bit stack mode.\n");
963 pic14_emitcode ("mov","a,_bp");
964 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
965 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
967 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
971 pic14_emitcode("pop","acc");
972 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
974 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
977 freeAsmop(op,NULL,ic,TRUE);
979 pic14_emitcode("pop","ar0");
984 pic14_emitcode("pop","ar1");
992 /* all other cases just dealloc */
996 OP_SYMBOL(op)->aop = NULL;
997 /* if the symbol has a spill */
999 SPIL_LOC(op)->aop = NULL;
1004 /*-----------------------------------------------------------------*/
1005 /* aopGet - for fetching value of the aop */
1006 /*-----------------------------------------------------------------*/
1007 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1012 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1013 /* offset is greater than
1015 if (offset > (aop->size - 1) &&
1016 aop->type != AOP_LIT)
1019 /* depending on type */
1020 switch (aop->type) {
1024 DEBUGpic14_emitcode(";","%d",__LINE__);
1025 /* if we need to increment it */
1026 while (offset > aop->coff) {
1027 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1031 while (offset < aop->coff) {
1032 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1036 aop->coff = offset ;
1038 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1039 return (dname ? "acc" : "a");
1041 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1042 rs = Safe_calloc(1,strlen(s)+1);
1048 DEBUGpic14_emitcode(";","%d",__LINE__);
1049 if (aop->type == AOP_DPTR2)
1054 while (offset > aop->coff) {
1055 pic14_emitcode ("inc","dptr");
1059 while (offset < aop->coff) {
1060 pic14_emitcode("lcall","__decdptr");
1066 pic14_emitcode("clr","a");
1067 pic14_emitcode("movc","a,@a+dptr");
1070 pic14_emitcode("movx","a,@dptr");
1073 if (aop->type == AOP_DPTR2)
1078 return (dname ? "acc" : "a");
1083 sprintf (s,"%s",aop->aopu.aop_immd);
1086 sprintf(s,"(%s >> %d)",
1091 aop->aopu.aop_immd);
1092 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1093 rs = Safe_calloc(1,strlen(s)+1);
1099 sprintf(s,"(%s + %d)",
1102 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1104 sprintf(s,"%s",aop->aopu.aop_dir);
1105 rs = Safe_calloc(1,strlen(s)+1);
1111 // return aop->aopu.aop_reg[offset]->dname;
1113 return aop->aopu.aop_reg[offset]->name;
1116 //pic14_emitcode(";","%d",__LINE__);
1117 return aop->aopu.aop_dir;
1120 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1121 return "AOP_accumulator_bug";
1124 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1125 rs = Safe_calloc(1,strlen(s)+1);
1130 aop->coff = offset ;
1131 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1134 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1136 return aop->aopu.aop_str[offset];
1140 pCodeOp *pcop = aop->aopu.pcop;
1141 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1143 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1144 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1145 sprintf(s,"%s", pcop->name);
1147 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1150 rs = Safe_calloc(1,strlen(s)+1);
1156 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1157 "aopget got unsupported aop->type");
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGetTempReg(void)
1170 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1171 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1172 PCOR(pcop)->r->wasUsed=1;
1173 PCOR(pcop)->r->isFree=0;
1179 /*-----------------------------------------------------------------*/
1180 /* popGetTempReg - create a new temporary pCodeOp */
1181 /*-----------------------------------------------------------------*/
1182 void popReleaseTempReg(pCodeOp *pcop)
1185 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1186 PCOR(pcop)->r->isFree = 1;
1189 /*-----------------------------------------------------------------*/
1190 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1191 /*-----------------------------------------------------------------*/
1192 pCodeOp *popGetLabel(unsigned int key)
1195 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1197 if(key>(unsigned int)max_key)
1200 return newpCodeOpLabel(NULL,key+100+labelOffset);
1203 /*-------------------------------------------------------------------*/
1204 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1205 /*-------------------------------------------------------------------*/
1206 pCodeOp *popGetHighLabel(unsigned int key)
1209 pcop = popGetLabel(key);
1210 PCOLAB(pcop)->offset = 1;
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1220 return newpCodeOpLit(lit);
1223 /*-----------------------------------------------------------------*/
1224 /* popGetImmd - asm operator to pcode immediate conversion */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1229 return newpCodeOpImmd(name, offset,index, 0, is_func);
1233 /*-----------------------------------------------------------------*/
1234 /* popGet - asm operator to pcode operator conversion */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetWithString(char *str, int isExtern)
1242 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1246 pcop = newpCodeOp(str,PO_STR);
1247 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString - */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1258 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259 pcop->type = PO_DIR;
1261 DEBUGpic14_emitcode(";","%d",__LINE__);
1266 pcop->name = Safe_calloc(1,strlen(str)+1);
1267 strcpy(pcop->name,str);
1269 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271 PCOR(pcop)->r = dirregWithName(pcop->name);
1272 if(PCOR(pcop)->r == NULL) {
1273 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1277 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1279 PCOR(pcop)->instance = offset;
1284 /*-----------------------------------------------------------------*/
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popRegFromIdx(int rIdx)
1290 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1291 __FUNCTION__,__LINE__,rIdx);
1293 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295 PCOR(pcop)->rIdx = rIdx;
1296 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1297 PCOR(pcop)->r->isFree = 0;
1298 PCOR(pcop)->r->wasUsed = 1;
1300 pcop->type = PCOR(pcop)->r->pc_type;
1306 /*-----------------------------------------------------------------*/
1307 /* popGet - asm operator to pcode operator conversion */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1311 //char *s = buffer ;
1316 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1317 /* offset is greater than
1320 if (offset > (aop->size - 1) &&
1321 aop->type != AOP_LIT)
1322 return NULL; //zero;
1324 /* depending on type */
1325 switch (aop->type) {
1332 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1336 DEBUGpic14_emitcode(";","%d",__LINE__);
1337 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1340 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1342 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1343 pcop->type = PO_DIR;
1345 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1346 strcpy(pcop->name,aop->aopu.aop_dir);
1347 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1348 if(PCOR(pcop)->r == NULL) {
1349 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1350 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1351 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1353 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1355 PCOR(pcop)->instance = offset;
1362 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1364 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365 PCOR(pcop)->rIdx = rIdx;
1366 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1367 PCOR(pcop)->r->wasUsed=1;
1368 PCOR(pcop)->r->isFree=0;
1370 PCOR(pcop)->instance = offset;
1371 pcop->type = PCOR(pcop)->r->pc_type;
1372 //rs = aop->aopu.aop_reg[offset]->name;
1373 DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1378 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1379 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1380 //if(PCOR(pcop)->r == NULL)
1381 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1385 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1388 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1389 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1391 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1392 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1393 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1394 pcop->type = PCOR(pcop)->r->pc_type;
1395 pcop->name = PCOR(pcop)->r->name;
1401 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1403 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1404 pcop = pCodeOpCopy(aop->aopu.pcop);
1405 PCOI(pcop)->offset = offset;
1409 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1410 "popGet got unsupported aop->type");
1413 /*-----------------------------------------------------------------*/
1414 /* aopPut - puts a string for a aop */
1415 /*-----------------------------------------------------------------*/
1416 void aopPut (asmop *aop, char *s, int offset)
1421 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1423 if (aop->size && offset > ( aop->size - 1)) {
1424 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1425 "aopPut got offset > aop->size");
1429 /* will assign value to value */
1430 /* depending on where it is ofcourse */
1431 switch (aop->type) {
1434 sprintf(d,"(%s + %d)",
1435 aop->aopu.aop_dir,offset);
1436 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1439 sprintf(d,"%s",aop->aopu.aop_dir);
1442 DEBUGpic14_emitcode(";","%d",__LINE__);
1444 pic14_emitcode("movf","%s,w",s);
1445 pic14_emitcode("movwf","%s",d);
1448 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1449 if(offset >= aop->size) {
1450 emitpcode(POC_CLRF,popGet(aop,offset));
1453 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1456 emitpcode(POC_MOVWF,popGet(aop,offset));
1463 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1464 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1467 strcmp(s,"r0") == 0 ||
1468 strcmp(s,"r1") == 0 ||
1469 strcmp(s,"r2") == 0 ||
1470 strcmp(s,"r3") == 0 ||
1471 strcmp(s,"r4") == 0 ||
1472 strcmp(s,"r5") == 0 ||
1473 strcmp(s,"r6") == 0 ||
1474 strcmp(s,"r7") == 0 )
1475 pic14_emitcode("mov","%s,%s ; %d",
1476 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1480 if(strcmp(s,"W")==0 )
1481 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1483 pic14_emitcode("movwf","%s",
1484 aop->aopu.aop_reg[offset]->name);
1486 if(strcmp(s,zero)==0) {
1487 emitpcode(POC_CLRF,popGet(aop,offset));
1489 } else if(strcmp(s,"W")==0) {
1490 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1491 pcop->type = PO_GPR_REGISTER;
1493 PCOR(pcop)->rIdx = -1;
1494 PCOR(pcop)->r = NULL;
1496 DEBUGpic14_emitcode(";","%d",__LINE__);
1497 pcop->name = Safe_strdup(s);
1498 emitpcode(POC_MOVFW,pcop);
1499 emitpcode(POC_MOVWF,popGet(aop,offset));
1500 } else if(strcmp(s,one)==0) {
1501 emitpcode(POC_CLRF,popGet(aop,offset));
1502 emitpcode(POC_INCF,popGet(aop,offset));
1504 emitpcode(POC_MOVWF,popGet(aop,offset));
1512 if (aop->type == AOP_DPTR2)
1518 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1519 "aopPut writting to code space");
1523 while (offset > aop->coff) {
1525 pic14_emitcode ("inc","dptr");
1528 while (offset < aop->coff) {
1530 pic14_emitcode("lcall","__decdptr");
1535 /* if not in accumulater */
1538 pic14_emitcode ("movx","@dptr,a");
1540 if (aop->type == AOP_DPTR2)
1548 while (offset > aop->coff) {
1550 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1552 while (offset < aop->coff) {
1554 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1560 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1565 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1567 if (strcmp(s,"r0") == 0 ||
1568 strcmp(s,"r1") == 0 ||
1569 strcmp(s,"r2") == 0 ||
1570 strcmp(s,"r3") == 0 ||
1571 strcmp(s,"r4") == 0 ||
1572 strcmp(s,"r5") == 0 ||
1573 strcmp(s,"r6") == 0 ||
1574 strcmp(s,"r7") == 0 ) {
1576 sprintf(buffer,"a%s",s);
1577 pic14_emitcode("mov","@%s,%s",
1578 aop->aopu.aop_ptr->name,buffer);
1580 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1585 if (strcmp(s,"a") == 0)
1586 pic14_emitcode("push","acc");
1588 pic14_emitcode("push","%s",s);
1593 /* if bit variable */
1594 if (!aop->aopu.aop_dir) {
1595 pic14_emitcode("clr","a");
1596 pic14_emitcode("rlc","a");
1599 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1602 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1605 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1607 lbl = newiTempLabel(NULL);
1609 if (strcmp(s,"a")) {
1612 pic14_emitcode("clr","c");
1613 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1614 pic14_emitcode("cpl","c");
1615 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1616 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1623 if (strcmp(aop->aopu.aop_str[offset],s))
1624 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1629 if (!offset && (strcmp(s,"acc") == 0))
1632 if (strcmp(aop->aopu.aop_str[offset],s))
1633 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1637 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1638 "aopPut got unsupported aop->type");
1644 /*-----------------------------------------------------------------*/
1645 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1646 /*-----------------------------------------------------------------*/
1647 void mov2w (asmop *aop, int offset)
1653 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1655 if ( aop->type == AOP_PCODE ||
1656 aop->type == AOP_LIT ||
1657 aop->type == AOP_IMMD )
1658 emitpcode(POC_MOVLW,popGet(aop,offset));
1660 emitpcode(POC_MOVFW,popGet(aop,offset));
1664 /*-----------------------------------------------------------------*/
1665 /* reAdjustPreg - points a register back to where it should */
1666 /*-----------------------------------------------------------------*/
1667 static void reAdjustPreg (asmop *aop)
1671 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1673 if ((size = aop->size) <= 1)
1676 switch (aop->type) {
1680 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1684 if (aop->type == AOP_DPTR2)
1690 pic14_emitcode("lcall","__decdptr");
1693 if (aop->type == AOP_DPTR2)
1705 /*-----------------------------------------------------------------*/
1706 /* opIsGptr: returns non-zero if the passed operand is */
1707 /* a generic pointer type. */
1708 /*-----------------------------------------------------------------*/
1709 static int opIsGptr(operand *op)
1711 sym_link *type = operandType(op);
1713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1714 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1722 /*-----------------------------------------------------------------*/
1723 /* pic14_getDataSize - get the operand data size */
1724 /*-----------------------------------------------------------------*/
1725 int pic14_getDataSize(operand *op)
1727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1730 return AOP_SIZE(op);
1732 // tsd- in the pic port, the genptr size is 1, so this code here
1733 // fails. ( in the 8051 port, the size was 4).
1736 size = AOP_SIZE(op);
1737 if (size == GPTRSIZE)
1739 sym_link *type = operandType(op);
1740 if (IS_GENPTR(type))
1742 /* generic pointer; arithmetic operations
1743 * should ignore the high byte (pointer type).
1746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1753 /*-----------------------------------------------------------------*/
1754 /* pic14_outAcc - output Acc */
1755 /*-----------------------------------------------------------------*/
1756 void pic14_outAcc(operand *result)
1759 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1760 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1763 size = pic14_getDataSize(result);
1765 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1768 /* unsigned or positive */
1770 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1775 /*-----------------------------------------------------------------*/
1776 /* pic14_outBitC - output a bit C */
1777 /*-----------------------------------------------------------------*/
1778 void pic14_outBitC(operand *result)
1781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1782 /* if the result is bit */
1783 if (AOP_TYPE(result) == AOP_CRY)
1784 aopPut(AOP(result),"c",0);
1786 pic14_emitcode("clr","a ; %d", __LINE__);
1787 pic14_emitcode("rlc","a");
1788 pic14_outAcc(result);
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_toBoolean(operand *oper)
1797 int size = AOP_SIZE(oper) - 1;
1800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1802 if ( AOP_TYPE(oper) != AOP_ACC) {
1803 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1806 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1811 /*-----------------------------------------------------------------*/
1812 /* genNot - generate code for ! operation */
1813 /*-----------------------------------------------------------------*/
1814 static void genNot (iCode *ic)
1819 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1820 /* assign asmOps to operand & result */
1821 aopOp (IC_LEFT(ic),ic,FALSE);
1822 aopOp (IC_RESULT(ic),ic,TRUE);
1824 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1825 /* if in bit space then a special case */
1826 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1827 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1828 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1829 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1831 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1832 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1833 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1838 size = AOP_SIZE(IC_LEFT(ic));
1840 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1841 emitpcode(POC_ANDLW,popGetLit(1));
1842 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1845 pic14_toBoolean(IC_LEFT(ic));
1847 tlbl = newiTempLabel(NULL);
1848 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1849 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1850 pic14_outBitC(IC_RESULT(ic));
1853 /* release the aops */
1854 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1855 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1859 /*-----------------------------------------------------------------*/
1860 /* genCpl - generate code for complement */
1861 /*-----------------------------------------------------------------*/
1862 static void genCpl (iCode *ic)
1864 operand *left, *result;
1868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1869 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1870 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1872 /* if both are in bit space then
1874 if (AOP_TYPE(result) == AOP_CRY &&
1875 AOP_TYPE(left) == AOP_CRY ) {
1877 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1878 pic14_emitcode("cpl","c");
1879 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1883 size = AOP_SIZE(result);
1886 if(AOP_TYPE(left) == AOP_ACC)
1887 emitpcode(POC_XORLW, popGetLit(0xff));
1889 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1891 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1897 /* release the aops */
1898 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899 freeAsmop(result,NULL,ic,TRUE);
1902 /*-----------------------------------------------------------------*/
1903 /* genUminusFloat - unary minus for floating points */
1904 /*-----------------------------------------------------------------*/
1905 static void genUminusFloat(operand *op,operand *result)
1907 int size ,offset =0 ;
1910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1911 /* for this we just need to flip the
1912 first it then copy the rest in place */
1913 size = AOP_SIZE(op) - 1;
1914 l = aopGet(AOP(op),3,FALSE,FALSE);
1918 pic14_emitcode("cpl","acc.7");
1919 aopPut(AOP(result),"a",3);
1923 aopGet(AOP(op),offset,FALSE,FALSE),
1929 /*-----------------------------------------------------------------*/
1930 /* genUminus - unary minus code generation */
1931 /*-----------------------------------------------------------------*/
1932 static void genUminus (iCode *ic)
1935 sym_link *optype, *rtype;
1938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1940 aopOp(IC_LEFT(ic),ic,FALSE);
1941 aopOp(IC_RESULT(ic),ic,TRUE);
1943 /* if both in bit space then special
1945 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1946 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1948 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1949 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1950 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1955 optype = operandType(IC_LEFT(ic));
1956 rtype = operandType(IC_RESULT(ic));
1958 /* if float then do float stuff */
1959 if (IS_FLOAT(optype)) {
1960 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1964 /* otherwise subtract from zero by taking the 2's complement */
1965 size = AOP_SIZE(IC_LEFT(ic));
1967 for(i=0; i<size; i++) {
1968 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1969 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1971 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1972 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1976 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1977 for(i=1; i<size; i++) {
1979 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1983 /* release the aops */
1984 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1985 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1988 /*-----------------------------------------------------------------*/
1989 /* saveRegisters - will look for a call and save the registers */
1990 /*-----------------------------------------------------------------*/
1991 static void saveRegisters(iCode *lic)
1998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2000 for (ic = lic ; ic ; ic = ic->next)
2001 if (ic->op == CALL || ic->op == PCALL)
2005 fprintf(stderr,"found parameter push with no function call\n");
2009 /* if the registers have been saved already then
2011 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2014 /* find the registers in use at this time
2015 and push them away to safety */
2016 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2020 if (options.useXstack) {
2021 if (bitVectBitValue(rsave,R0_IDX))
2022 pic14_emitcode("mov","b,r0");
2023 pic14_emitcode("mov","r0,%s",spname);
2024 for (i = 0 ; i < pic14_nRegs ; i++) {
2025 if (bitVectBitValue(rsave,i)) {
2027 pic14_emitcode("mov","a,b");
2029 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2030 pic14_emitcode("movx","@r0,a");
2031 pic14_emitcode("inc","r0");
2034 pic14_emitcode("mov","%s,r0",spname);
2035 if (bitVectBitValue(rsave,R0_IDX))
2036 pic14_emitcode("mov","r0,b");
2038 //for (i = 0 ; i < pic14_nRegs ; i++) {
2039 // if (bitVectBitValue(rsave,i))
2040 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2043 dtype = operandType(IC_LEFT(ic));
2044 if (currFunc && dtype &&
2045 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2046 IFFUNC_ISISR(currFunc->type) &&
2049 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2052 /*-----------------------------------------------------------------*/
2053 /* unsaveRegisters - pop the pushed registers */
2054 /*-----------------------------------------------------------------*/
2055 static void unsaveRegisters (iCode *ic)
2060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2061 /* find the registers in use at this time
2062 and push them away to safety */
2063 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2066 if (options.useXstack) {
2067 pic14_emitcode("mov","r0,%s",spname);
2068 for (i = pic14_nRegs ; i >= 0 ; i--) {
2069 if (bitVectBitValue(rsave,i)) {
2070 pic14_emitcode("dec","r0");
2071 pic14_emitcode("movx","a,@r0");
2073 pic14_emitcode("mov","b,a");
2075 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2079 pic14_emitcode("mov","%s,r0",spname);
2080 if (bitVectBitValue(rsave,R0_IDX))
2081 pic14_emitcode("mov","r0,b");
2083 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2084 // if (bitVectBitValue(rsave,i))
2085 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2091 /*-----------------------------------------------------------------*/
2093 /*-----------------------------------------------------------------*/
2094 static void pushSide(operand * oper, int size)
2098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2101 if (AOP_TYPE(oper) != AOP_REG &&
2102 AOP_TYPE(oper) != AOP_DIR &&
2104 pic14_emitcode("mov","a,%s",l);
2105 pic14_emitcode("push","acc");
2107 pic14_emitcode("push","%s",l);
2112 /*-----------------------------------------------------------------*/
2113 /* assignResultValue - */
2114 /*-----------------------------------------------------------------*/
2115 static void assignResultValue(operand * oper)
2117 int size = AOP_SIZE(oper);
2119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2121 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2124 if (GpsuedoStkPtr++)
2125 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2126 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2131 /*-----------------------------------------------------------------*/
2132 /* genIpush - genrate code for pushing this gets a little complex */
2133 /*-----------------------------------------------------------------*/
2134 static void genIpush (iCode *ic)
2137 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2139 int size, offset = 0 ;
2143 /* if this is not a parm push : ie. it is spill push
2144 and spill push is always done on the local stack */
2145 if (!ic->parmPush) {
2147 /* and the item is spilt then do nothing */
2148 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2151 aopOp(IC_LEFT(ic),ic,FALSE);
2152 size = AOP_SIZE(IC_LEFT(ic));
2153 /* push it on the stack */
2155 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2160 pic14_emitcode("push","%s",l);
2165 /* this is a paramter push: in this case we call
2166 the routine to find the call and save those
2167 registers that need to be saved */
2170 /* then do the push */
2171 aopOp(IC_LEFT(ic),ic,FALSE);
2174 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2175 size = AOP_SIZE(IC_LEFT(ic));
2178 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2179 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2180 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2182 pic14_emitcode("mov","a,%s",l);
2183 pic14_emitcode("push","acc");
2185 pic14_emitcode("push","%s",l);
2188 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2192 /*-----------------------------------------------------------------*/
2193 /* genIpop - recover the registers: can happen only for spilling */
2194 /*-----------------------------------------------------------------*/
2195 static void genIpop (iCode *ic)
2197 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2202 /* if the temp was not pushed then */
2203 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2206 aopOp(IC_LEFT(ic),ic,FALSE);
2207 size = AOP_SIZE(IC_LEFT(ic));
2210 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2213 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2217 /*-----------------------------------------------------------------*/
2218 /* unsaverbank - restores the resgister bank from stack */
2219 /*-----------------------------------------------------------------*/
2220 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2222 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2230 if (options.useXstack) {
2232 r = getFreePtr(ic,&aop,FALSE);
2235 pic14_emitcode("mov","%s,_spx",r->name);
2236 pic14_emitcode("movx","a,@%s",r->name);
2237 pic14_emitcode("mov","psw,a");
2238 pic14_emitcode("dec","%s",r->name);
2241 pic14_emitcode ("pop","psw");
2244 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2245 if (options.useXstack) {
2246 pic14_emitcode("movx","a,@%s",r->name);
2247 //pic14_emitcode("mov","(%s+%d),a",
2248 // regspic14[i].base,8*bank+regspic14[i].offset);
2249 pic14_emitcode("dec","%s",r->name);
2252 pic14_emitcode("pop",""); //"(%s+%d)",
2253 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2256 if (options.useXstack) {
2258 pic14_emitcode("mov","_spx,%s",r->name);
2259 freeAsmop(NULL,aop,ic,TRUE);
2265 /*-----------------------------------------------------------------*/
2266 /* saverbank - saves an entire register bank on the stack */
2267 /*-----------------------------------------------------------------*/
2268 static void saverbank (int bank, iCode *ic, bool pushPsw)
2270 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2277 if (options.useXstack) {
2280 r = getFreePtr(ic,&aop,FALSE);
2281 pic14_emitcode("mov","%s,_spx",r->name);
2285 for (i = 0 ; i < pic14_nRegs ;i++) {
2286 if (options.useXstack) {
2287 pic14_emitcode("inc","%s",r->name);
2288 //pic14_emitcode("mov","a,(%s+%d)",
2289 // regspic14[i].base,8*bank+regspic14[i].offset);
2290 pic14_emitcode("movx","@%s,a",r->name);
2292 pic14_emitcode("push","");// "(%s+%d)",
2293 //regspic14[i].base,8*bank+regspic14[i].offset);
2297 if (options.useXstack) {
2298 pic14_emitcode("mov","a,psw");
2299 pic14_emitcode("movx","@%s,a",r->name);
2300 pic14_emitcode("inc","%s",r->name);
2301 pic14_emitcode("mov","_spx,%s",r->name);
2302 freeAsmop (NULL,aop,ic,TRUE);
2305 pic14_emitcode("push","psw");
2307 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2313 /*-----------------------------------------------------------------*/
2314 /* genCall - generates a call statement */
2315 /*-----------------------------------------------------------------*/
2316 static void genCall (iCode *ic)
2320 unsigned char *name;
2323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2325 /* if caller saves & we have not saved then */
2329 /* if we are calling a function that is not using
2330 the same register bank then we need to save the
2331 destination registers on the stack */
2332 dtype = operandType(IC_LEFT(ic));
2333 if (currFunc && dtype &&
2334 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2335 IFFUNC_ISISR(currFunc->type) &&
2338 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2340 /* if send set is not empty the assign */
2343 /* For the Pic port, there is no data stack.
2344 * So parameters passed to functions are stored
2345 * in registers. (The pCode optimizer will get
2346 * rid of most of these :).
2348 int psuedoStkPtr=-1;
2349 int firstTimeThruLoop = 1;
2351 _G.sendSet = reverseSet(_G.sendSet);
2353 /* First figure how many parameters are getting passed */
2354 for (sic = setFirstItem(_G.sendSet) ; sic ;
2355 sic = setNextItem(_G.sendSet)) {
2357 aopOp(IC_LEFT(sic),sic,FALSE);
2358 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2359 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2362 for (sic = setFirstItem(_G.sendSet) ; sic ;
2363 sic = setNextItem(_G.sendSet)) {
2364 int size, offset = 0;
2366 aopOp(IC_LEFT(sic),sic,FALSE);
2367 size = AOP_SIZE(IC_LEFT(sic));
2370 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2371 AopType(AOP_TYPE(IC_LEFT(sic))));
2373 if(!firstTimeThruLoop) {
2374 /* If this is not the first time we've been through the loop
2375 * then we need to save the parameter in a temporary
2376 * register. The last byte of the last parameter is
2378 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2381 firstTimeThruLoop=0;
2383 mov2w (AOP(IC_LEFT(sic)), offset);
2386 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2391 sym = OP_SYMBOL(IC_LEFT(ic));
2392 name = sym->rname[0] ? sym->rname : sym->name;
2393 isExtern = IS_EXTERN(sym->etype);
2395 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2397 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2399 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2402 /* if we need assign a result value */
2403 if ((IS_ITEMP(IC_RESULT(ic)) &&
2404 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2405 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2406 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2409 aopOp(IC_RESULT(ic),ic,FALSE);
2412 assignResultValue(IC_RESULT(ic));
2414 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2415 AopType(AOP_TYPE(IC_RESULT(ic))));
2417 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2420 /* adjust the stack for parameters if
2422 if (ic->parmBytes) {
2424 if (ic->parmBytes > 3) {
2425 pic14_emitcode("mov","a,%s",spname);
2426 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2427 pic14_emitcode("mov","%s,a",spname);
2429 for ( i = 0 ; i < ic->parmBytes ;i++)
2430 pic14_emitcode("dec","%s",spname);
2434 /* if register bank was saved then pop them */
2436 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2438 /* if we hade saved some registers then unsave them */
2439 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2440 unsaveRegisters (ic);
2445 /*-----------------------------------------------------------------*/
2446 /* genPcall - generates a call by pointer statement */
2447 /*-----------------------------------------------------------------*/
2448 static void genPcall (iCode *ic)
2451 symbol *albl = newiTempLabel(NULL);
2452 symbol *blbl = newiTempLabel(NULL);
2457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2458 /* if caller saves & we have not saved then */
2462 /* if we are calling a function that is not using
2463 the same register bank then we need to save the
2464 destination registers on the stack */
2465 dtype = operandType(IC_LEFT(ic));
2466 if (currFunc && dtype &&
2467 IFFUNC_ISISR(currFunc->type) &&
2468 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2469 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2472 aopOp(left,ic,FALSE);
2473 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2475 pushSide(IC_LEFT(ic), FPTRSIZE);
2477 /* if send set is not empty, assign parameters */
2480 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2481 /* no way to pass args - W always gets used to make the call */
2483 /* first idea - factor out a common helper function and call it.
2484 But don't know how to get it generated only once in its own block
2486 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2489 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2490 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2491 buffer = Safe_calloc(1,strlen(rname)+16);
2492 sprintf(buffer, "%s_goto_helper", rname);
2493 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2497 emitpcode(POC_CALL,popGetLabel(albl->key));
2498 pcop = popGetLabel(blbl->key);
2499 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2500 emitpcode(POC_GOTO,pcop);
2501 emitpLabel(albl->key);
2503 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2505 emitpcode(poc,popGet(AOP(left),1));
2506 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2507 emitpcode(poc,popGet(AOP(left),0));
2508 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2510 emitpLabel(blbl->key);
2512 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2514 /* if we need to assign a result value */
2515 if ((IS_ITEMP(IC_RESULT(ic)) &&
2516 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2517 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2518 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2521 aopOp(IC_RESULT(ic),ic,FALSE);
2524 assignResultValue(IC_RESULT(ic));
2526 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2529 /* if register bank was saved then unsave them */
2530 if (currFunc && dtype &&
2531 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2534 /* if we hade saved some registers then
2537 unsaveRegisters (ic);
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result is rematerializable */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2546 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2547 if (SKIP_IC(ic) || ic->op == IFX)
2550 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552 if (sym->remat && !POINTER_SET(ic))
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2562 #define STRCASECMP strcasecmp
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2571 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2575 if (options.excludeRegs[i] &&
2576 STRCASECMP(options.excludeRegs[i],"none") == 0)
2579 for ( i = 0 ; options.excludeRegs[i]; i++) {
2580 if (options.excludeRegs[i] &&
2581 STRCASECMP(s,options.excludeRegs[i]) == 0)
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2596 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2598 labelOffset += (max_key+4);
2602 /* create the function header */
2603 pic14_emitcode(";","-----------------------------------------");
2604 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605 pic14_emitcode(";","-----------------------------------------");
2607 pic14_emitcode("","%s:",sym->rname);
2608 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2610 ftype = operandType(IC_LEFT(ic));
2612 /* if critical function then turn interrupts off */
2613 if (IFFUNC_ISCRITICAL(ftype))
2614 pic14_emitcode("clr","ea");
2616 /* here we need to generate the equates for the
2617 register bank if required */
2619 if (FUNC_REGBANK(ftype) != rbank) {
2622 rbank = FUNC_REGBANK(ftype);
2623 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624 if (strcmp(regspic14[i].base,"0") == 0)
2625 pic14_emitcode("","%s = 0x%02x",
2627 8*rbank+regspic14[i].offset);
2629 pic14_emitcode ("","%s = %s + 0x%02x",
2632 8*rbank+regspic14[i].offset);
2637 /* if this is an interrupt service routine */
2638 if (IFFUNC_ISISR(sym->type)) {
2639 /* already done in pic14createInterruptVect() - delete me
2640 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641 emitpcodeNULLop(POC_NOP);
2642 emitpcodeNULLop(POC_NOP);
2643 emitpcodeNULLop(POC_NOP);
2645 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2646 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2647 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2648 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2649 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2650 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2651 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2653 pBlockConvert2ISR(pb);
2655 if (!inExcludeList("acc"))
2656 pic14_emitcode ("push","acc");
2657 if (!inExcludeList("b"))
2658 pic14_emitcode ("push","b");
2659 if (!inExcludeList("dpl"))
2660 pic14_emitcode ("push","dpl");
2661 if (!inExcludeList("dph"))
2662 pic14_emitcode ("push","dph");
2663 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2665 pic14_emitcode ("push", "dpx");
2666 /* Make sure we're using standard DPTR */
2667 pic14_emitcode ("push", "dps");
2668 pic14_emitcode ("mov", "dps, #0x00");
2669 if (options.stack10bit)
2671 /* This ISR could conceivably use DPTR2. Better save it. */
2672 pic14_emitcode ("push", "dpl1");
2673 pic14_emitcode ("push", "dph1");
2674 pic14_emitcode ("push", "dpx1");
2677 /* if this isr has no bank i.e. is going to
2678 run with bank 0 , then we need to save more
2680 if (!FUNC_REGBANK(sym->type)) {
2682 /* if this function does not call any other
2683 function then we can be economical and
2684 save only those registers that are used */
2685 if (! IFFUNC_HASFCALL(sym->type)) {
2688 /* if any registers used */
2689 if (sym->regsUsed) {
2690 /* save the registers used */
2691 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2692 if (bitVectBitValue(sym->regsUsed,i) ||
2693 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2694 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2699 /* this function has a function call cannot
2700 determines register usage so we will have the
2702 saverbank(0,ic,FALSE);
2707 /* if callee-save to be used for this function
2708 then save the registers being used in this function */
2709 if (IFFUNC_CALLEESAVES(sym->type)) {
2712 /* if any registers used */
2713 if (sym->regsUsed) {
2714 /* save the registers used */
2715 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2716 if (bitVectBitValue(sym->regsUsed,i) ||
2717 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2718 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2726 /* set the register bank to the desired value */
2727 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2728 pic14_emitcode("push","psw");
2729 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2732 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2734 if (options.useXstack) {
2735 pic14_emitcode("mov","r0,%s",spname);
2736 pic14_emitcode("mov","a,_bp");
2737 pic14_emitcode("movx","@r0,a");
2738 pic14_emitcode("inc","%s",spname);
2742 /* set up the stack */
2743 pic14_emitcode ("push","_bp"); /* save the callers stack */
2745 pic14_emitcode ("mov","_bp,%s",spname);
2748 /* adjust the stack for the function */
2753 werror(W_STACK_OVERFLOW,sym->name);
2755 if (i > 3 && sym->recvSize < 4) {
2757 pic14_emitcode ("mov","a,sp");
2758 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2759 pic14_emitcode ("mov","sp,a");
2764 pic14_emitcode("inc","sp");
2769 pic14_emitcode ("mov","a,_spx");
2770 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2771 pic14_emitcode ("mov","_spx,a");
2776 /*-----------------------------------------------------------------*/
2777 /* genEndFunction - generates epilogue for functions */
2778 /*-----------------------------------------------------------------*/
2779 static void genEndFunction (iCode *ic)
2781 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2785 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2787 pic14_emitcode ("mov","%s,_bp",spname);
2790 /* if use external stack but some variables were
2791 added to the local stack then decrement the
2793 if (options.useXstack && sym->stack) {
2794 pic14_emitcode("mov","a,sp");
2795 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2796 pic14_emitcode("mov","sp,a");
2800 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2801 if (options.useXstack) {
2802 pic14_emitcode("mov","r0,%s",spname);
2803 pic14_emitcode("movx","a,@r0");
2804 pic14_emitcode("mov","_bp,a");
2805 pic14_emitcode("dec","%s",spname);
2809 pic14_emitcode ("pop","_bp");
2813 /* restore the register bank */
2814 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2815 pic14_emitcode ("pop","psw");
2817 if (IFFUNC_ISISR(sym->type)) {
2819 /* now we need to restore the registers */
2820 /* if this isr has no bank i.e. is going to
2821 run with bank 0 , then we need to save more
2823 if (!FUNC_REGBANK(sym->type)) {
2825 /* if this function does not call any other
2826 function then we can be economical and
2827 save only those registers that are used */
2828 if (! IFFUNC_HASFCALL(sym->type)) {
2831 /* if any registers used */
2832 if (sym->regsUsed) {
2833 /* save the registers used */
2834 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2835 if (bitVectBitValue(sym->regsUsed,i) ||
2836 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2837 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2842 /* this function has a function call cannot
2843 determines register usage so we will have the
2845 unsaverbank(0,ic,FALSE);
2849 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2851 if (options.stack10bit)
2853 pic14_emitcode ("pop", "dpx1");
2854 pic14_emitcode ("pop", "dph1");
2855 pic14_emitcode ("pop", "dpl1");
2857 pic14_emitcode ("pop", "dps");
2858 pic14_emitcode ("pop", "dpx");
2860 if (!inExcludeList("dph"))
2861 pic14_emitcode ("pop","dph");
2862 if (!inExcludeList("dpl"))
2863 pic14_emitcode ("pop","dpl");
2864 if (!inExcludeList("b"))
2865 pic14_emitcode ("pop","b");
2866 if (!inExcludeList("acc"))
2867 pic14_emitcode ("pop","acc");
2869 if (IFFUNC_ISCRITICAL(sym->type))
2870 pic14_emitcode("setb","ea");
2873 /* if debug then send end of function */
2874 /* if (options.debug && currFunc) { */
2876 debugFile->writeEndFunction (currFunc, ic, 1);
2879 pic14_emitcode ("reti","");
2880 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2881 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2882 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2883 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2884 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2885 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2886 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2887 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2888 emitpcodeNULLop(POC_RETFIE);
2891 if (IFFUNC_ISCRITICAL(sym->type))
2892 pic14_emitcode("setb","ea");
2894 if (IFFUNC_CALLEESAVES(sym->type)) {
2897 /* if any registers used */
2898 if (sym->regsUsed) {
2899 /* save the registers used */
2900 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2901 if (bitVectBitValue(sym->regsUsed,i) ||
2902 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2903 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2909 /* if debug then send end of function */
2911 debugFile->writeEndFunction (currFunc, ic, 1);
2914 pic14_emitcode ("return","");
2915 emitpcodeNULLop(POC_RETURN);
2917 /* Mark the end of a function */
2918 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2923 /*-----------------------------------------------------------------*/
2924 /* genRet - generate code for return statement */
2925 /*-----------------------------------------------------------------*/
2926 static void genRet (iCode *ic)
2928 int size, pushed = 0;
2930 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2931 /* if we have no return value then
2932 just generate the "ret" */
2936 /* we have something to return then
2937 move the return value into place */
2938 aopOp(IC_LEFT(ic),ic,FALSE);
2939 size = AOP_SIZE(IC_LEFT(ic));
2943 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2945 l = aopGet(AOP(IC_LEFT(ic)),size,FALSE,TRUE);
2946 pic14_emitcode("push","%s",l);
2949 l = aopGet(AOP(IC_LEFT(ic)),size,FALSE,FALSE);
2950 if (strcmp(fReturn[size],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)),size));
2957 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),size));
2960 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2969 if (strcmp(fReturn[pushed],"a"))
2970 pic14_emitcode("pop",fReturn[pushed]);
2972 pic14_emitcode("pop","acc");
2975 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2978 /* generate a jump to the return label
2979 if the next is not the return statement */
2980 if (!(ic->next && ic->next->op == LABEL &&
2981 IC_LABEL(ic->next) == returnLabel)) {
2983 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2984 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2989 /*-----------------------------------------------------------------*/
2990 /* genLabel - generates a label */
2991 /*-----------------------------------------------------------------*/
2992 static void genLabel (iCode *ic)
2994 /* special case never generate */
2995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2996 if (IC_LABEL(ic) == entryLabel)
2999 emitpLabel(IC_LABEL(ic)->key);
3000 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3003 /*-----------------------------------------------------------------*/
3004 /* genGoto - generates a goto */
3005 /*-----------------------------------------------------------------*/
3007 static void genGoto (iCode *ic)
3009 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3010 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3014 /*-----------------------------------------------------------------*/
3015 /* genMultbits :- multiplication of bits */
3016 /*-----------------------------------------------------------------*/
3017 static void genMultbits (operand *left,
3021 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3023 if(!pic14_sameRegs(AOP(result),AOP(right)))
3024 emitpcode(POC_BSF, popGet(AOP(result),0));
3026 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3027 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3028 emitpcode(POC_BCF, popGet(AOP(result),0));
3033 /*-----------------------------------------------------------------*/
3034 /* genMultOneByte : 8 bit multiplication & division */
3035 /*-----------------------------------------------------------------*/
3036 static void genMultOneByte (operand *left,
3040 sym_link *opetype = operandType(result);
3045 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3046 DEBUGpic14_AopType(__LINE__,left,right,result);
3047 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3049 /* (if two literals, the value is computed before) */
3050 /* if one literal, literal on the right */
3051 if (AOP_TYPE(left) == AOP_LIT){
3057 size = AOP_SIZE(result);
3060 if (AOP_TYPE(right) == AOP_LIT){
3061 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3062 aopGet(AOP(right),0,FALSE,FALSE),
3063 aopGet(AOP(left),0,FALSE,FALSE),
3064 aopGet(AOP(result),0,FALSE,FALSE));
3065 pic14_emitcode("call","genMultLit");
3067 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3068 aopGet(AOP(right),0,FALSE,FALSE),
3069 aopGet(AOP(left),0,FALSE,FALSE),
3070 aopGet(AOP(result),0,FALSE,FALSE));
3071 pic14_emitcode("call","genMult8X8_8");
3074 genMult8X8_8 (left, right,result);
3077 /* signed or unsigned */
3078 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3079 //l = aopGet(AOP(left),0,FALSE,FALSE);
3081 //pic14_emitcode("mul","ab");
3082 /* if result size = 1, mul signed = mul unsigned */
3083 //aopPut(AOP(result),"a",0);
3085 } else { // (size > 1)
3087 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3088 aopGet(AOP(right),0,FALSE,FALSE),
3089 aopGet(AOP(left),0,FALSE,FALSE),
3090 aopGet(AOP(result),0,FALSE,FALSE));
3092 if (SPEC_USIGN(opetype)){
3093 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3094 genUMult8X8_16 (left, right, result, NULL);
3097 /* for filling the MSBs */
3098 emitpcode(POC_CLRF, popGet(AOP(result),2));
3099 emitpcode(POC_CLRF, popGet(AOP(result),3));
3103 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3105 pic14_emitcode("mov","a,b");
3107 /* adjust the MSB if left or right neg */
3109 /* if one literal */
3110 if (AOP_TYPE(right) == AOP_LIT){
3111 pic14_emitcode("multiply ","right is a lit");
3112 /* AND literal negative */
3113 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3114 /* adjust MSB (c==0 after mul) */
3115 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3119 genSMult8X8_16 (left, right, result, NULL);
3123 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3125 pic14_emitcode("rlc","a");
3126 pic14_emitcode("subb","a,acc");
3134 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3135 //aopPut(AOP(result),"a",offset++);
3139 /*-----------------------------------------------------------------*/
3140 /* genMult - generates code for multiplication */
3141 /*-----------------------------------------------------------------*/
3142 static void genMult (iCode *ic)
3144 operand *left = IC_LEFT(ic);
3145 operand *right = IC_RIGHT(ic);
3146 operand *result= IC_RESULT(ic);
3148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3149 /* assign the amsops */
3150 aopOp (left,ic,FALSE);
3151 aopOp (right,ic,FALSE);
3152 aopOp (result,ic,TRUE);
3154 DEBUGpic14_AopType(__LINE__,left,right,result);
3156 /* special cases first */
3158 if (AOP_TYPE(left) == AOP_CRY &&
3159 AOP_TYPE(right)== AOP_CRY) {
3160 genMultbits(left,right,result);
3164 /* if both are of size == 1 */
3165 if (AOP_SIZE(left) == 1 &&
3166 AOP_SIZE(right) == 1 ) {
3167 genMultOneByte(left,right,result);
3171 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3173 /* should have been converted to function call */
3177 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3178 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3179 freeAsmop(result,NULL,ic,TRUE);
3182 /*-----------------------------------------------------------------*/
3183 /* genDivbits :- division of bits */
3184 /*-----------------------------------------------------------------*/
3185 static void genDivbits (operand *left,
3192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3193 /* the result must be bit */
3194 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3195 l = aopGet(AOP(left),0,FALSE,FALSE);
3199 pic14_emitcode("div","ab");
3200 pic14_emitcode("rrc","a");
3201 aopPut(AOP(result),"c",0);
3204 /*-----------------------------------------------------------------*/
3205 /* genDivOneByte : 8 bit division */
3206 /*-----------------------------------------------------------------*/
3207 static void genDivOneByte (operand *left,
3211 sym_link *opetype = operandType(result);
3216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3217 size = AOP_SIZE(result) - 1;
3219 /* signed or unsigned */
3220 if (SPEC_USIGN(opetype)) {
3221 /* unsigned is easy */
3222 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3223 l = aopGet(AOP(left),0,FALSE,FALSE);
3225 pic14_emitcode("div","ab");
3226 aopPut(AOP(result),"a",0);
3228 aopPut(AOP(result),zero,offset++);
3232 /* signed is a little bit more difficult */
3234 /* save the signs of the operands */
3235 l = aopGet(AOP(left),0,FALSE,FALSE);
3237 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3238 pic14_emitcode("push","acc"); /* save it on the stack */
3240 /* now sign adjust for both left & right */
3241 l = aopGet(AOP(right),0,FALSE,FALSE);
3243 lbl = newiTempLabel(NULL);
3244 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3245 pic14_emitcode("cpl","a");
3246 pic14_emitcode("inc","a");
3247 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3248 pic14_emitcode("mov","b,a");
3250 /* sign adjust left side */
3251 l = aopGet(AOP(left),0,FALSE,FALSE);
3254 lbl = newiTempLabel(NULL);
3255 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3256 pic14_emitcode("cpl","a");
3257 pic14_emitcode("inc","a");
3258 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3260 /* now the division */
3261 pic14_emitcode("div","ab");
3262 /* we are interested in the lower order
3264 pic14_emitcode("mov","b,a");
3265 lbl = newiTempLabel(NULL);
3266 pic14_emitcode("pop","acc");
3267 /* if there was an over flow we don't
3268 adjust the sign of the result */
3269 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3270 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3272 pic14_emitcode("clr","a");
3273 pic14_emitcode("subb","a,b");
3274 pic14_emitcode("mov","b,a");
3275 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3277 /* now we are done */
3278 aopPut(AOP(result),"b",0);
3280 pic14_emitcode("mov","c,b.7");
3281 pic14_emitcode("subb","a,acc");
3284 aopPut(AOP(result),"a",offset++);
3288 /*-----------------------------------------------------------------*/
3289 /* genDiv - generates code for division */
3290 /*-----------------------------------------------------------------*/
3291 static void genDiv (iCode *ic)
3293 operand *left = IC_LEFT(ic);
3294 operand *right = IC_RIGHT(ic);
3295 operand *result= IC_RESULT(ic);
3297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3298 /* assign the amsops */
3299 aopOp (left,ic,FALSE);
3300 aopOp (right,ic,FALSE);
3301 aopOp (result,ic,TRUE);
3303 /* special cases first */
3305 if (AOP_TYPE(left) == AOP_CRY &&
3306 AOP_TYPE(right)== AOP_CRY) {
3307 genDivbits(left,right,result);
3311 /* if both are of size == 1 */
3312 if (AOP_SIZE(left) == 1 &&
3313 AOP_SIZE(right) == 1 ) {
3314 genDivOneByte(left,right,result);
3318 /* should have been converted to function call */
3321 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3322 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3323 freeAsmop(result,NULL,ic,TRUE);
3326 /*-----------------------------------------------------------------*/
3327 /* genModbits :- modulus of bits */
3328 /*-----------------------------------------------------------------*/
3329 static void genModbits (operand *left,
3336 /* the result must be bit */
3337 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3338 l = aopGet(AOP(left),0,FALSE,FALSE);
3342 pic14_emitcode("div","ab");
3343 pic14_emitcode("mov","a,b");
3344 pic14_emitcode("rrc","a");
3345 aopPut(AOP(result),"c",0);
3348 /*-----------------------------------------------------------------*/
3349 /* genModOneByte : 8 bit modulus */
3350 /*-----------------------------------------------------------------*/
3351 static void genModOneByte (operand *left,
3355 sym_link *opetype = operandType(result);
3359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3360 /* signed or unsigned */
3361 if (SPEC_USIGN(opetype)) {
3362 /* unsigned is easy */
3363 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3364 l = aopGet(AOP(left),0,FALSE,FALSE);
3366 pic14_emitcode("div","ab");
3367 aopPut(AOP(result),"b",0);
3371 /* signed is a little bit more difficult */
3373 /* save the signs of the operands */
3374 l = aopGet(AOP(left),0,FALSE,FALSE);
3377 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3378 pic14_emitcode("push","acc"); /* save it on the stack */
3380 /* now sign adjust for both left & right */
3381 l = aopGet(AOP(right),0,FALSE,FALSE);
3384 lbl = newiTempLabel(NULL);
3385 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3386 pic14_emitcode("cpl","a");
3387 pic14_emitcode("inc","a");
3388 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3389 pic14_emitcode("mov","b,a");
3391 /* sign adjust left side */
3392 l = aopGet(AOP(left),0,FALSE,FALSE);
3395 lbl = newiTempLabel(NULL);
3396 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3397 pic14_emitcode("cpl","a");
3398 pic14_emitcode("inc","a");
3399 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3401 /* now the multiplication */
3402 pic14_emitcode("div","ab");
3403 /* we are interested in the lower order
3405 lbl = newiTempLabel(NULL);
3406 pic14_emitcode("pop","acc");
3407 /* if there was an over flow we don't
3408 adjust the sign of the result */
3409 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3410 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3412 pic14_emitcode("clr","a");
3413 pic14_emitcode("subb","a,b");
3414 pic14_emitcode("mov","b,a");
3415 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3417 /* now we are done */
3418 aopPut(AOP(result),"b",0);
3422 /*-----------------------------------------------------------------*/
3423 /* genMod - generates code for division */
3424 /*-----------------------------------------------------------------*/
3425 static void genMod (iCode *ic)
3427 operand *left = IC_LEFT(ic);
3428 operand *right = IC_RIGHT(ic);
3429 operand *result= IC_RESULT(ic);
3431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3432 /* assign the amsops */
3433 aopOp (left,ic,FALSE);
3434 aopOp (right,ic,FALSE);
3435 aopOp (result,ic,TRUE);
3437 /* special cases first */
3439 if (AOP_TYPE(left) == AOP_CRY &&
3440 AOP_TYPE(right)== AOP_CRY) {
3441 genModbits(left,right,result);
3445 /* if both are of size == 1 */
3446 if (AOP_SIZE(left) == 1 &&
3447 AOP_SIZE(right) == 1 ) {
3448 genModOneByte(left,right,result);
3452 /* should have been converted to function call */
3456 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3457 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3458 freeAsmop(result,NULL,ic,TRUE);
3461 /*-----------------------------------------------------------------*/
3462 /* genIfxJump :- will create a jump depending on the ifx */
3463 /*-----------------------------------------------------------------*/
3465 note: May need to add parameter to indicate when a variable is in bit space.
3467 static void genIfxJump (iCode *ic, char *jval)
3470 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3471 /* if true label then we jump if condition
3473 if ( IC_TRUE(ic) ) {
3475 if(strcmp(jval,"a") == 0)
3477 else if (strcmp(jval,"c") == 0)
3480 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3481 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3484 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3485 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3489 /* false label is present */
3490 if(strcmp(jval,"a") == 0)
3492 else if (strcmp(jval,"c") == 0)
3495 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3496 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3499 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3500 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3505 /* mark the icode as generated */
3509 /*-----------------------------------------------------------------*/
3511 /*-----------------------------------------------------------------*/
3512 static void genSkip(iCode *ifx,int status_bit)
3517 if ( IC_TRUE(ifx) ) {
3518 switch(status_bit) {
3533 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3534 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3538 switch(status_bit) {
3552 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3553 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3559 /*-----------------------------------------------------------------*/
3561 /*-----------------------------------------------------------------*/
3562 static void genSkipc(resolvedIfx *rifx)
3572 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3573 rifx->generated = 1;
3576 /*-----------------------------------------------------------------*/
3578 /*-----------------------------------------------------------------*/
3579 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3584 if( (rifx->condition ^ invert_condition) & 1)
3589 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3590 rifx->generated = 1;
3593 /*-----------------------------------------------------------------*/
3595 /*-----------------------------------------------------------------*/
3596 static void genSkipz(iCode *ifx, int condition)
3607 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3609 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3612 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3614 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3617 /*-----------------------------------------------------------------*/
3619 /*-----------------------------------------------------------------*/
3620 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3626 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3628 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3631 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3632 rifx->generated = 1;
3636 /*-----------------------------------------------------------------*/
3637 /* genChkZeroes :- greater or less than comparison */
3638 /* For each byte in a literal that is zero, inclusive or the */
3639 /* the corresponding byte in the operand with W */
3640 /* returns true if any of the bytes are zero */
3641 /*-----------------------------------------------------------------*/
3642 static int genChkZeroes(operand *op, int lit, int size)
3649 i = (lit >> (size*8)) & 0xff;
3653 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3655 emitpcode(POC_IORFW, popGet(AOP(op),size));
3664 /*-----------------------------------------------------------------*/
3665 /* genCmp :- greater or less than comparison */
3666 /*-----------------------------------------------------------------*/
3667 static void genCmp (operand *left,operand *right,
3668 operand *result, iCode *ifx, int sign)
3670 int size; //, offset = 0 ;
3671 unsigned long lit = 0L,i = 0;
3672 resolvedIfx rFalseIfx;
3673 // resolvedIfx rTrueIfx;
3675 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3678 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3679 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3683 resolveIfx(&rFalseIfx,ifx);
3684 truelbl = newiTempLabel(NULL);
3685 size = max(AOP_SIZE(left),AOP_SIZE(right));
3687 DEBUGpic14_AopType(__LINE__,left,right,result);
3691 /* if literal is on the right then swap with left */
3692 if ((AOP_TYPE(right) == AOP_LIT)) {
3693 operand *tmp = right ;
3694 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3695 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3698 lit = (lit - 1) & mask;
3701 rFalseIfx.condition ^= 1;
3704 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3705 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3709 //if(IC_TRUE(ifx) == NULL)
3710 /* if left & right are bit variables */
3711 if (AOP_TYPE(left) == AOP_CRY &&
3712 AOP_TYPE(right) == AOP_CRY ) {
3713 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3714 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3716 /* subtract right from left if at the
3717 end the carry flag is set then we know that
3718 left is greater than right */
3720 symbol *lbl = newiTempLabel(NULL);
3723 if(AOP_TYPE(right) == AOP_LIT) {
3725 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3727 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3734 genSkipCond(&rFalseIfx,left,size-1,7);
3736 /* no need to compare to 0...*/
3737 /* NOTE: this is a de-generate compare that most certainly
3738 * creates some dead code. */
3739 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3741 if(ifx) ifx->generated = 1;
3748 //i = (lit >> (size*8)) & 0xff;
3749 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3751 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3753 i = ((0-lit) & 0xff);
3756 /* lit is 0x7f, all signed chars are less than
3757 * this except for 0x7f itself */
3758 emitpcode(POC_XORLW, popGetLit(0x7f));
3759 genSkipz2(&rFalseIfx,0);
3761 emitpcode(POC_ADDLW, popGetLit(0x80));
3762 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3763 genSkipc(&rFalseIfx);
3768 genSkipz2(&rFalseIfx,1);
3770 emitpcode(POC_ADDLW, popGetLit(i));
3771 genSkipc(&rFalseIfx);
3775 if(ifx) ifx->generated = 1;
3779 /* chars are out of the way. now do ints and longs */
3782 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3789 genSkipCond(&rFalseIfx,left,size,7);
3790 if(ifx) ifx->generated = 1;
3795 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3797 //rFalseIfx.condition ^= 1;
3798 //genSkipCond(&rFalseIfx,left,size,7);
3799 //rFalseIfx.condition ^= 1;
3801 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3802 if(rFalseIfx.condition)
3803 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3805 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3807 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3808 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3809 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3812 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3814 if(rFalseIfx.condition) {
3816 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3822 genSkipc(&rFalseIfx);
3823 emitpLabel(truelbl->key);
3824 if(ifx) ifx->generated = 1;
3831 if( (lit & 0xff) == 0) {
3832 /* lower byte is zero */
3833 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3834 i = ((lit >> 8) & 0xff) ^0x80;
3835 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3836 emitpcode(POC_ADDLW, popGetLit( 0x80));
3837 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3838 genSkipc(&rFalseIfx);
3841 if(ifx) ifx->generated = 1;
3846 /* Special cases for signed longs */
3847 if( (lit & 0xffffff) == 0) {
3848 /* lower byte is zero */
3849 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3850 i = ((lit >> 8*3) & 0xff) ^0x80;
3851 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3852 emitpcode(POC_ADDLW, popGetLit( 0x80));
3853 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3854 genSkipc(&rFalseIfx);
3857 if(ifx) ifx->generated = 1;
3865 if(lit & (0x80 << (size*8))) {
3866 /* lit is negative */
3867 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3869 //genSkipCond(&rFalseIfx,left,size,7);
3871 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3873 if(rFalseIfx.condition)
3874 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3876 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3880 /* lit is positive */
3881 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3882 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3883 if(rFalseIfx.condition)
3884 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3886 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3890 /* There are no more special cases, so perform a general compare */
3892 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3893 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3897 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3899 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3901 //rFalseIfx.condition ^= 1;
3902 genSkipc(&rFalseIfx);
3904 emitpLabel(truelbl->key);
3906 if(ifx) ifx->generated = 1;
3913 /* sign is out of the way. So now do an unsigned compare */
3914 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3917 /* General case - compare to an unsigned literal on the right.*/
3919 i = (lit >> (size*8)) & 0xff;
3920 emitpcode(POC_MOVLW, popGetLit(i));
3921 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3923 i = (lit >> (size*8)) & 0xff;
3926 emitpcode(POC_MOVLW, popGetLit(i));
3928 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3930 /* this byte of the lit is zero,
3931 *if it's not the last then OR in the variable */
3933 emitpcode(POC_IORFW, popGet(AOP(left),size));
3938 emitpLabel(lbl->key);
3939 //if(emitFinalCheck)
3940 genSkipc(&rFalseIfx);
3942 emitpLabel(truelbl->key);
3944 if(ifx) ifx->generated = 1;
3951 if(AOP_TYPE(left) == AOP_LIT) {
3952 //symbol *lbl = newiTempLabel(NULL);
3954 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3957 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3960 if((lit == 0) && (sign == 0)){
3963 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3965 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3967 genSkipz2(&rFalseIfx,0);
3968 if(ifx) ifx->generated = 1;
3975 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3976 /* degenerate compare can never be true */
3977 if(rFalseIfx.condition == 0)
3978 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3980 if(ifx) ifx->generated = 1;
3985 /* signed comparisons to a literal byte */
3987 int lp1 = (lit+1) & 0xff;
3989 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3992 rFalseIfx.condition ^= 1;
3993 genSkipCond(&rFalseIfx,right,0,7);
3996 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3997 emitpcode(POC_XORLW, popGetLit(0x7f));
3998 genSkipz2(&rFalseIfx,1);
4001 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4002 emitpcode(POC_ADDLW, popGetLit(0x80));
4003 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4004 rFalseIfx.condition ^= 1;
4005 genSkipc(&rFalseIfx);
4008 if(ifx) ifx->generated = 1;
4010 /* unsigned comparisons to a literal byte */
4012 switch(lit & 0xff ) {
4014 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4015 genSkipz2(&rFalseIfx,0);
4016 if(ifx) ifx->generated = 1;
4019 genSkipCond(&rFalseIfx,right,0,7);
4020 if(ifx) ifx->generated = 1;
4024 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4025 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4027 rFalseIfx.condition ^= 1;
4028 if (AOP_TYPE(result) == AOP_CRY) {
4029 genSkipc(&rFalseIfx);
4030 if(ifx) ifx->generated = 1;
4032 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4033 emitpcode(POC_CLRF, popGet(AOP(result),0));
4034 emitpcode(POC_RLF, popGet(AOP(result),0));
4035 emitpcode(POC_MOVLW, popGetLit(0x01));
4036 emitpcode(POC_XORWF, popGet(AOP(result),0));
4047 /* Size is greater than 1 */
4055 /* this means lit = 0xffffffff, or -1 */
4058 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4059 rFalseIfx.condition ^= 1;
4060 genSkipCond(&rFalseIfx,right,size,7);
4061 if(ifx) ifx->generated = 1;
4068 if(rFalseIfx.condition) {
4069 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4070 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4073 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4075 emitpcode(POC_IORFW, popGet(AOP(right),size));
4079 if(rFalseIfx.condition) {
4080 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4081 emitpLabel(truelbl->key);
4083 rFalseIfx.condition ^= 1;
4084 genSkipCond(&rFalseIfx,right,s,7);
4087 if(ifx) ifx->generated = 1;
4091 if((size == 1) && (0 == (lp1&0xff))) {
4092 /* lower byte of signed word is zero */
4093 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4094 i = ((lp1 >> 8) & 0xff) ^0x80;
4095 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4096 emitpcode(POC_ADDLW, popGetLit( 0x80));
4097 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4098 rFalseIfx.condition ^= 1;
4099 genSkipc(&rFalseIfx);
4102 if(ifx) ifx->generated = 1;
4106 if(lit & (0x80 << (size*8))) {
4107 /* Lit is less than zero */
4108 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4109 //rFalseIfx.condition ^= 1;
4110 //genSkipCond(&rFalseIfx,left,size,7);
4111 //rFalseIfx.condition ^= 1;
4112 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4113 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4115 if(rFalseIfx.condition)
4116 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4118 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4122 /* Lit is greater than or equal to zero */
4123 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4124 //rFalseIfx.condition ^= 1;
4125 //genSkipCond(&rFalseIfx,right,size,7);
4126 //rFalseIfx.condition ^= 1;
4128 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4129 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4131 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132 if(rFalseIfx.condition)
4133 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4135 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4140 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4141 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4145 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4147 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4149 rFalseIfx.condition ^= 1;
4150 //rFalseIfx.condition = 1;
4151 genSkipc(&rFalseIfx);
4153 emitpLabel(truelbl->key);
4155 if(ifx) ifx->generated = 1;
4160 /* compare word or long to an unsigned literal on the right.*/
4165 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4168 break; /* handled above */
4171 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4173 emitpcode(POC_IORFW, popGet(AOP(right),size));
4174 genSkipz2(&rFalseIfx,0);
4178 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4180 emitpcode(POC_IORFW, popGet(AOP(right),size));
4183 if(rFalseIfx.condition)
4184 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4186 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4189 emitpcode(POC_MOVLW, popGetLit(lit+1));
4190 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4192 rFalseIfx.condition ^= 1;
4193 genSkipc(&rFalseIfx);
4196 emitpLabel(truelbl->key);
4198 if(ifx) ifx->generated = 1;
4204 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4205 i = (lit >> (size*8)) & 0xff;
4207 emitpcode(POC_MOVLW, popGetLit(i));
4208 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4211 i = (lit >> (size*8)) & 0xff;
4214 emitpcode(POC_MOVLW, popGetLit(i));
4216 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4218 /* this byte of the lit is zero,
4219 *if it's not the last then OR in the variable */
4221 emitpcode(POC_IORFW, popGet(AOP(right),size));
4226 emitpLabel(lbl->key);
4228 rFalseIfx.condition ^= 1;
4229 genSkipc(&rFalseIfx);
4233 emitpLabel(truelbl->key);
4234 if(ifx) ifx->generated = 1;
4238 /* Compare two variables */
4240 DEBUGpic14_emitcode(";sign","%d",sign);
4244 /* Sigh. thus sucks... */
4246 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4247 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4248 emitpcode(POC_MOVLW, popGetLit(0x80));
4249 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4250 emitpcode(POC_XORFW, popGet(AOP(right),size));
4251 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4253 /* Signed char comparison */
4254 /* Special thanks to Nikolai Golovchenko for this snippet */
4255 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4256 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4257 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4258 emitpcode(POC_XORFW, popGet(AOP(left),0));
4259 emitpcode(POC_XORFW, popGet(AOP(right),0));
4260 emitpcode(POC_ADDLW, popGetLit(0x80));
4262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4263 genSkipc(&rFalseIfx);
4265 if(ifx) ifx->generated = 1;
4271 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4272 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4276 /* The rest of the bytes of a multi-byte compare */
4280 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4283 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4284 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4289 emitpLabel(lbl->key);
4291 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4292 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4293 (AOP_TYPE(result) == AOP_REG)) {
4294 emitpcode(POC_CLRF, popGet(AOP(result),0));
4295 emitpcode(POC_RLF, popGet(AOP(result),0));
4297 genSkipc(&rFalseIfx);
4299 //genSkipc(&rFalseIfx);
4300 if(ifx) ifx->generated = 1;
4307 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4308 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4309 pic14_outBitC(result);
4311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4312 /* if the result is used in the next
4313 ifx conditional branch then generate
4314 code a little differently */
4316 genIfxJump (ifx,"c");
4318 pic14_outBitC(result);
4319 /* leave the result in acc */
4324 /*-----------------------------------------------------------------*/
4325 /* genCmpGt :- greater than comparison */
4326 /*-----------------------------------------------------------------*/
4327 static void genCmpGt (iCode *ic, iCode *ifx)
4329 operand *left, *right, *result;
4330 sym_link *letype , *retype;
4333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4335 right= IC_RIGHT(ic);
4336 result = IC_RESULT(ic);
4338 letype = getSpec(operandType(left));
4339 retype =getSpec(operandType(right));
4340 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4341 /* assign the amsops */
4342 aopOp (left,ic,FALSE);
4343 aopOp (right,ic,FALSE);
4344 aopOp (result,ic,TRUE);
4346 genCmp(right, left, result, ifx, sign);
4348 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4349 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4350 freeAsmop(result,NULL,ic,TRUE);
4353 /*-----------------------------------------------------------------*/
4354 /* genCmpLt - less than comparisons */
4355 /*-----------------------------------------------------------------*/
4356 static void genCmpLt (iCode *ic, iCode *ifx)
4358 operand *left, *right, *result;
4359 sym_link *letype , *retype;
4362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4364 right= IC_RIGHT(ic);
4365 result = IC_RESULT(ic);
4367 letype = getSpec(operandType(left));
4368 retype =getSpec(operandType(right));
4369 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4371 /* assign the amsops */
4372 aopOp (left,ic,FALSE);
4373 aopOp (right,ic,FALSE);
4374 aopOp (result,ic,TRUE);
4376 genCmp(left, right, result, ifx, sign);
4378 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4379 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380 freeAsmop(result,NULL,ic,TRUE);
4383 /*-----------------------------------------------------------------*/
4384 /* genc16bit2lit - compare a 16 bit value to a literal */
4385 /*-----------------------------------------------------------------*/
4386 static void genc16bit2lit(operand *op, int lit, int offset)
4390 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4391 if( (lit&0xff) == 0)
4396 switch( BYTEofLONG(lit,i)) {
4398 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4401 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4404 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4407 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4408 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4413 switch( BYTEofLONG(lit,i)) {
4415 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4419 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4423 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4426 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4428 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4434 /*-----------------------------------------------------------------*/
4435 /* gencjneshort - compare and jump if not equal */
4436 /*-----------------------------------------------------------------*/
4437 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4439 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4441 int res_offset = 0; /* the result may be a different size then left or right */
4442 int res_size = AOP_SIZE(result);
4446 unsigned long lit = 0L;
4447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4448 DEBUGpic14_AopType(__LINE__,left,right,result);
4450 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4451 resolveIfx(&rIfx,ifx);
4452 lbl = newiTempLabel(NULL);
4455 /* if the left side is a literal or
4456 if the right is in a pointer register and left
4458 if ((AOP_TYPE(left) == AOP_LIT) ||
4459 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4464 if(AOP_TYPE(right) == AOP_LIT)
4465 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4467 /* if the right side is a literal then anything goes */
4468 if (AOP_TYPE(right) == AOP_LIT &&
4469 AOP_TYPE(left) != AOP_DIR ) {
4472 genc16bit2lit(left, lit, 0);
4474 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4479 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4480 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4482 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4486 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4488 if(res_offset < res_size-1)
4496 /* if the right side is in a register or in direct space or
4497 if the left is a pointer register & right is not */
4498 else if (AOP_TYPE(right) == AOP_REG ||
4499 AOP_TYPE(right) == AOP_DIR ||
4500 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4501 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4502 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4503 int lbl_key = lbl->key;
4506 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4507 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4509 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4510 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4511 __FUNCTION__,__LINE__);
4515 /* switch(size) { */
4517 /* genc16bit2lit(left, lit, 0); */
4519 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4524 if((AOP_TYPE(left) == AOP_DIR) &&
4525 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4527 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4528 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4530 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4532 switch (lit & 0xff) {
4534 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4537 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4538 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4539 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4543 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4544 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4545 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4546 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4550 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4551 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4556 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4559 if(AOP_TYPE(result) == AOP_CRY) {
4560 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4565 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4567 /* fix me. probably need to check result size too */
4568 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4573 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4574 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4581 if(res_offset < res_size-1)
4586 } else if(AOP_TYPE(right) == AOP_REG &&
4587 AOP_TYPE(left) != AOP_DIR){
4590 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4591 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4592 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4597 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4599 if(res_offset < res_size-1)
4604 /* right is a pointer reg need both a & b */
4606 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4608 pic14_emitcode("mov","b,%s",l);
4609 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4610 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4615 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4617 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4619 emitpLabel(lbl->key);
4621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4628 /*-----------------------------------------------------------------*/
4629 /* gencjne - compare and jump if not equal */
4630 /*-----------------------------------------------------------------*/
4631 static void gencjne(operand *left, operand *right, iCode *ifx)
4633 symbol *tlbl = newiTempLabel(NULL);
4635 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4636 gencjneshort(left, right, lbl);
4638 pic14_emitcode("mov","a,%s",one);
4639 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4640 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4641 pic14_emitcode("clr","a");
4642 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4644 emitpLabel(lbl->key);
4645 emitpLabel(tlbl->key);
4650 /*-----------------------------------------------------------------*/
4651 /* genCmpEq - generates code for equal to */
4652 /*-----------------------------------------------------------------*/
4653 static void genCmpEq (iCode *ic, iCode *ifx)
4655 operand *left, *right, *result;
4656 unsigned long lit = 0L;
4659 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4662 DEBUGpic14_emitcode ("; ifx is non-null","");
4664 DEBUGpic14_emitcode ("; ifx is null","");
4666 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4667 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4668 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4670 size = max(AOP_SIZE(left),AOP_SIZE(right));
4672 DEBUGpic14_AopType(__LINE__,left,right,result);
4674 /* if literal, literal on the right or
4675 if the right is in a pointer register and left
4677 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4678 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4679 operand *tmp = right ;
4685 if(ifx && !AOP_SIZE(result)){
4687 /* if they are both bit variables */
4688 if (AOP_TYPE(left) == AOP_CRY &&
4689 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4690 if(AOP_TYPE(right) == AOP_LIT){
4691 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4693 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4694 pic14_emitcode("cpl","c");
4695 } else if(lit == 1L) {
4696 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4698 pic14_emitcode("clr","c");
4700 /* AOP_TYPE(right) == AOP_CRY */
4702 symbol *lbl = newiTempLabel(NULL);
4703 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4704 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4705 pic14_emitcode("cpl","c");
4706 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4708 /* if true label then we jump if condition
4710 tlbl = newiTempLabel(NULL);
4711 if ( IC_TRUE(ifx) ) {
4712 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4713 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4715 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4716 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4718 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4721 /* left and right are both bit variables, result is carry */
4724 resolveIfx(&rIfx,ifx);
4726 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4727 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4728 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4729 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4734 /* They're not both bit variables. Is the right a literal? */
4735 if(AOP_TYPE(right) == AOP_LIT) {
4736 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4741 switch(lit & 0xff) {
4743 if ( IC_TRUE(ifx) ) {
4744 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4746 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4748 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4749 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4753 if ( IC_TRUE(ifx) ) {
4754 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4756 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4758 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4759 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4763 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4765 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4770 /* end of size == 1 */
4774 genc16bit2lit(left,lit,offset);
4777 /* end of size == 2 */
4782 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4783 emitpcode(POC_IORFW,popGet(AOP(left),1));
4784 emitpcode(POC_IORFW,popGet(AOP(left),2));
4785 emitpcode(POC_IORFW,popGet(AOP(left),3));
4789 /* search for patterns that can be optimized */
4791 genc16bit2lit(left,lit,0);
4794 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4796 genc16bit2lit(left,lit,2);
4798 emitpcode(POC_IORFW,popGet(AOP(left),2));
4799 emitpcode(POC_IORFW,popGet(AOP(left),3));
4812 } else if(AOP_TYPE(right) == AOP_CRY ) {
4813 /* we know the left is not a bit, but that the right is */
4814 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4815 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4816 popGet(AOP(right),offset));
4817 emitpcode(POC_XORLW,popGetLit(1));
4819 /* if the two are equal, then W will be 0 and the Z bit is set
4820 * we could test Z now, or go ahead and check the high order bytes if
4821 * the variable we're comparing is larger than a byte. */
4824 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4826 if ( IC_TRUE(ifx) ) {
4828 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4829 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4832 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4833 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4837 /* They're both variables that are larger than bits */
4840 tlbl = newiTempLabel(NULL);
4843 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4844 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4846 if ( IC_TRUE(ifx) ) {
4849 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4850 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4853 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4854 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4858 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4859 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4863 if(s>1 && IC_TRUE(ifx)) {
4864 emitpLabel(tlbl->key);
4865 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4869 /* mark the icode as generated */
4874 /* if they are both bit variables */
4875 if (AOP_TYPE(left) == AOP_CRY &&
4876 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4877 if(AOP_TYPE(right) == AOP_LIT){
4878 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4880 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4881 pic14_emitcode("cpl","c");
4882 } else if(lit == 1L) {
4883 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4885 pic14_emitcode("clr","c");
4887 /* AOP_TYPE(right) == AOP_CRY */
4889 symbol *lbl = newiTempLabel(NULL);
4890 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4891 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4892 pic14_emitcode("cpl","c");
4893 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4896 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4897 pic14_outBitC(result);
4901 genIfxJump (ifx,"c");
4904 /* if the result is used in an arithmetic operation
4905 then put the result in place */
4906 pic14_outBitC(result);
4909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4910 gencjne(left,right,result,ifx);
4913 gencjne(left,right,newiTempLabel(NULL));
4915 if(IC_TRUE(ifx)->key)
4916 gencjne(left,right,IC_TRUE(ifx)->key);
4918 gencjne(left,right,IC_FALSE(ifx)->key);
4922 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4923 aopPut(AOP(result),"a",0);
4928 genIfxJump (ifx,"a");
4932 /* if the result is used in an arithmetic operation
4933 then put the result in place */
4935 if (AOP_TYPE(result) != AOP_CRY)
4936 pic14_outAcc(result);
4938 /* leave the result in acc */
4942 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4943 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4944 freeAsmop(result,NULL,ic,TRUE);
4947 /*-----------------------------------------------------------------*/
4948 /* ifxForOp - returns the icode containing the ifx for operand */
4949 /*-----------------------------------------------------------------*/
4950 static iCode *ifxForOp ( operand *op, iCode *ic )
4952 /* if true symbol then needs to be assigned */
4953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4954 if (IS_TRUE_SYMOP(op))
4957 /* if this has register type condition and
4958 the next instruction is ifx with the same operand
4959 and live to of the operand is upto the ifx only then */
4961 ic->next->op == IFX &&
4962 IC_COND(ic->next)->key == op->key &&
4963 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4967 ic->next->op == IFX &&
4968 IC_COND(ic->next)->key == op->key) {
4969 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4973 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4975 ic->next->op == IFX)
4976 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4979 ic->next->op == IFX &&
4980 IC_COND(ic->next)->key == op->key) {
4981 DEBUGpic14_emitcode ("; "," key is okay");
4982 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4983 OP_SYMBOL(op)->liveTo,
4990 /*-----------------------------------------------------------------*/
4991 /* genAndOp - for && operation */
4992 /*-----------------------------------------------------------------*/
4993 static void genAndOp (iCode *ic)
4995 operand *left,*right, *result;
4998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4999 /* note here that && operations that are in an
5000 if statement are taken away by backPatchLabels
5001 only those used in arthmetic operations remain */
5002 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5003 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5004 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5006 DEBUGpic14_AopType(__LINE__,left,right,result);
5008 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5009 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5010 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5012 /* if both are bit variables */
5013 /* if (AOP_TYPE(left) == AOP_CRY && */
5014 /* AOP_TYPE(right) == AOP_CRY ) { */
5015 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5016 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5017 /* pic14_outBitC(result); */
5019 /* tlbl = newiTempLabel(NULL); */
5020 /* pic14_toBoolean(left); */
5021 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5022 /* pic14_toBoolean(right); */
5023 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5024 /* pic14_outBitAcc(result); */
5027 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5028 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5029 freeAsmop(result,NULL,ic,TRUE);
5033 /*-----------------------------------------------------------------*/
5034 /* genOrOp - for || operation */
5035 /*-----------------------------------------------------------------*/
5038 modified this code, but it doesn't appear to ever get called
5041 static void genOrOp (iCode *ic)
5043 operand *left,*right, *result;
5046 /* note here that || operations that are in an
5047 if statement are taken away by backPatchLabels
5048 only those used in arthmetic operations remain */
5049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5050 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5051 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5052 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5054 DEBUGpic14_AopType(__LINE__,left,right,result);
5056 /* if both are bit variables */
5057 if (AOP_TYPE(left) == AOP_CRY &&
5058 AOP_TYPE(right) == AOP_CRY ) {
5059 pic14_emitcode("clrc","");
5060 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5061 AOP(left)->aopu.aop_dir,
5062 AOP(left)->aopu.aop_dir);
5063 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5064 AOP(right)->aopu.aop_dir,
5065 AOP(right)->aopu.aop_dir);
5066 pic14_emitcode("setc","");
5069 tlbl = newiTempLabel(NULL);
5070 pic14_toBoolean(left);
5072 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5073 pic14_toBoolean(right);
5074 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5076 pic14_outBitAcc(result);
5079 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5080 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5081 freeAsmop(result,NULL,ic,TRUE);
5084 /*-----------------------------------------------------------------*/
5085 /* isLiteralBit - test if lit == 2^n */
5086 /*-----------------------------------------------------------------*/
5087 static int isLiteralBit(unsigned long lit)
5089 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5090 0x100L,0x200L,0x400L,0x800L,
5091 0x1000L,0x2000L,0x4000L,0x8000L,
5092 0x10000L,0x20000L,0x40000L,0x80000L,
5093 0x100000L,0x200000L,0x400000L,0x800000L,
5094 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5095 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5099 for(idx = 0; idx < 32; idx++)
5105 /*-----------------------------------------------------------------*/
5106 /* continueIfTrue - */
5107 /*-----------------------------------------------------------------*/
5108 static void continueIfTrue (iCode *ic)
5110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5112 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5116 /*-----------------------------------------------------------------*/
5118 /*-----------------------------------------------------------------*/
5119 static void jumpIfTrue (iCode *ic)
5121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5123 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5127 /*-----------------------------------------------------------------*/
5128 /* jmpTrueOrFalse - */
5129 /*-----------------------------------------------------------------*/
5130 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5132 // ugly but optimized by peephole
5133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5135 symbol *nlbl = newiTempLabel(NULL);
5136 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5137 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5138 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5139 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5142 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5143 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5148 /*-----------------------------------------------------------------*/
5149 /* genAnd - code for and */
5150 /*-----------------------------------------------------------------*/
5151 static void genAnd (iCode *ic, iCode *ifx)
5153 operand *left, *right, *result;
5155 unsigned long lit = 0L;
5160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5161 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5162 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5163 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5165 resolveIfx(&rIfx,ifx);
5167 /* if left is a literal & right is not then exchange them */
5168 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5169 AOP_NEEDSACC(left)) {
5170 operand *tmp = right ;
5175 /* if result = right then exchange them */
5176 if(pic14_sameRegs(AOP(result),AOP(right))){
5177 operand *tmp = right ;
5182 /* if right is bit then exchange them */
5183 if (AOP_TYPE(right) == AOP_CRY &&
5184 AOP_TYPE(left) != AOP_CRY){
5185 operand *tmp = right ;
5189 if(AOP_TYPE(right) == AOP_LIT)
5190 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5192 size = AOP_SIZE(result);
5194 DEBUGpic14_AopType(__LINE__,left,right,result);
5197 // result = bit & yy;
5198 if (AOP_TYPE(left) == AOP_CRY){
5199 // c = bit & literal;
5200 if(AOP_TYPE(right) == AOP_LIT){
5202 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5205 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5208 if(size && (AOP_TYPE(result) == AOP_CRY)){
5209 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5212 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5216 pic14_emitcode("clr","c");
5219 if (AOP_TYPE(right) == AOP_CRY){
5221 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5222 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5225 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5227 pic14_emitcode("rrc","a");
5228 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5234 pic14_outBitC(result);
5236 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5237 genIfxJump(ifx, "c");
5241 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5242 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5243 if((AOP_TYPE(right) == AOP_LIT) &&
5244 (AOP_TYPE(result) == AOP_CRY) &&
5245 (AOP_TYPE(left) != AOP_CRY)){
5246 int posbit = isLiteralBit(lit);
5250 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5253 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5258 while (posbit > 7) {
5262 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5263 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5264 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5271 symbol *tlbl = newiTempLabel(NULL);
5272 int sizel = AOP_SIZE(left);
5274 pic14_emitcode("setb","c");
5276 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5277 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5279 if((posbit = isLiteralBit(bytelit)) != 0)
5280 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5282 if(bytelit != 0x0FFL)
5283 pic14_emitcode("anl","a,%s",
5284 aopGet(AOP(right),offset,FALSE,TRUE));
5285 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5290 // bit = left & literal
5292 pic14_emitcode("clr","c");
5293 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5295 // if(left & literal)
5298 jmpTrueOrFalse(ifx, tlbl);
5302 pic14_outBitC(result);
5306 /* if left is same as result */
5307 if(pic14_sameRegs(AOP(result),AOP(left))){
5309 for(;size--; offset++,lit>>=8) {
5310 if(AOP_TYPE(right) == AOP_LIT){
5311 switch(lit & 0xff) {
5313 /* and'ing with 0 has clears the result */
5314 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
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 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5327 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5330 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5331 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5332 if(know_W != (int)(lit&0xff))
5333 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5335 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5340 if (AOP_TYPE(left) == AOP_ACC) {
5341 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5343 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5344 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5351 // left & result in different registers
5352 if(AOP_TYPE(result) == AOP_CRY){
5354 // if(size), result in bit
5355 // if(!size && ifx), conditional oper: if(left & right)
5356 symbol *tlbl = newiTempLabel(NULL);
5357 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5359 pic14_emitcode("setb","c");
5361 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5362 pic14_emitcode("anl","a,%s",
5363 aopGet(AOP(left),offset,FALSE,FALSE));
5364 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5369 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5370 pic14_outBitC(result);
5372 jmpTrueOrFalse(ifx, tlbl);
5374 for(;(size--);offset++) {
5376 // result = left & right
5377 if(AOP_TYPE(right) == AOP_LIT){
5378 int t = (lit >> (offset*8)) & 0x0FFL;
5381 pic14_emitcode("clrf","%s",
5382 aopGet(AOP(result),offset,FALSE,FALSE));
5383 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5386 if(AOP_TYPE(left) != AOP_ACC) {
5387 pic14_emitcode("movf","%s,w",
5388 aopGet(AOP(left),offset,FALSE,FALSE));
5389 pic14_emitcode("movwf","%s",
5390 aopGet(AOP(result),offset,FALSE,FALSE));
5391 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5393 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5396 if(AOP_TYPE(left) == AOP_ACC) {
5397 emitpcode(POC_ANDLW, popGetLit(t));
5399 pic14_emitcode("movlw","0x%x",t);
5400 pic14_emitcode("andwf","%s,w",
5401 aopGet(AOP(left),offset,FALSE,FALSE));
5402 pic14_emitcode("movwf","%s",
5403 aopGet(AOP(result),offset,FALSE,FALSE));
5405 emitpcode(POC_MOVLW, popGetLit(t));
5406 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5408 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5413 if (AOP_TYPE(left) == AOP_ACC) {
5414 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5415 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5417 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5418 pic14_emitcode("andwf","%s,w",
5419 aopGet(AOP(left),offset,FALSE,FALSE));
5420 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5421 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5423 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5424 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5430 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5431 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5432 freeAsmop(result,NULL,ic,TRUE);
5435 /*-----------------------------------------------------------------*/
5436 /* genOr - code for or */
5437 /*-----------------------------------------------------------------*/
5438 static void genOr (iCode *ic, iCode *ifx)
5440 operand *left, *right, *result;
5442 unsigned long lit = 0L;
5444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5446 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5447 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5448 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5450 DEBUGpic14_AopType(__LINE__,left,right,result);
5452 /* if left is a literal & right is not then exchange them */
5453 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5454 AOP_NEEDSACC(left)) {
5455 operand *tmp = right ;
5460 /* if result = right then exchange them */
5461 if(pic14_sameRegs(AOP(result),AOP(right))){
5462 operand *tmp = right ;
5467 /* if right is bit then exchange them */
5468 if (AOP_TYPE(right) == AOP_CRY &&
5469 AOP_TYPE(left) != AOP_CRY){
5470 operand *tmp = right ;
5475 DEBUGpic14_AopType(__LINE__,left,right,result);
5477 if(AOP_TYPE(right) == AOP_LIT)
5478 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5480 size = AOP_SIZE(result);
5484 if (AOP_TYPE(left) == AOP_CRY){
5485 if(AOP_TYPE(right) == AOP_LIT){
5486 // c = bit & literal;
5488 // lit != 0 => result = 1
5489 if(AOP_TYPE(result) == AOP_CRY){
5491 emitpcode(POC_BSF, popGet(AOP(result),0));
5492 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5493 // AOP(result)->aopu.aop_dir,
5494 // AOP(result)->aopu.aop_dir);
5496 continueIfTrue(ifx);
5500 // lit == 0 => result = left
5501 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5503 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5506 if (AOP_TYPE(right) == AOP_CRY){
5507 if(pic14_sameRegs(AOP(result),AOP(left))){
5509 emitpcode(POC_BCF, popGet(AOP(result),0));
5510 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5511 emitpcode(POC_BSF, popGet(AOP(result),0));
5513 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5514 AOP(result)->aopu.aop_dir,
5515 AOP(result)->aopu.aop_dir);
5516 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5517 AOP(right)->aopu.aop_dir,
5518 AOP(right)->aopu.aop_dir);
5519 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5520 AOP(result)->aopu.aop_dir,
5521 AOP(result)->aopu.aop_dir);
5523 if( AOP_TYPE(result) == AOP_ACC) {
5524 emitpcode(POC_MOVLW, popGetLit(0));
5525 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5526 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5527 emitpcode(POC_MOVLW, popGetLit(1));
5531 emitpcode(POC_BCF, popGet(AOP(result),0));
5532 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5533 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5534 emitpcode(POC_BSF, popGet(AOP(result),0));
5536 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5537 AOP(result)->aopu.aop_dir,
5538 AOP(result)->aopu.aop_dir);
5539 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5540 AOP(right)->aopu.aop_dir,
5541 AOP(right)->aopu.aop_dir);
5542 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5543 AOP(left)->aopu.aop_dir,
5544 AOP(left)->aopu.aop_dir);
5545 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5546 AOP(result)->aopu.aop_dir,
5547 AOP(result)->aopu.aop_dir);
5552 symbol *tlbl = newiTempLabel(NULL);
5553 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5556 emitpcode(POC_BCF, popGet(AOP(result),0));
5557 if( AOP_TYPE(right) == AOP_ACC) {
5558 emitpcode(POC_IORLW, popGetLit(0));
5560 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5561 emitpcode(POC_BSF, popGet(AOP(result),0));
5566 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5567 pic14_emitcode(";XXX setb","c");
5568 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5569 AOP(left)->aopu.aop_dir,tlbl->key+100);
5570 pic14_toBoolean(right);
5571 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5572 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5573 jmpTrueOrFalse(ifx, tlbl);
5577 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5584 pic14_outBitC(result);
5586 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5587 genIfxJump(ifx, "c");
5591 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5592 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5593 if((AOP_TYPE(right) == AOP_LIT) &&
5594 (AOP_TYPE(result) == AOP_CRY) &&
5595 (AOP_TYPE(left) != AOP_CRY)){
5597 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5600 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5602 continueIfTrue(ifx);
5605 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5606 // lit = 0, result = boolean(left)
5608 pic14_emitcode(";XXX setb","c");
5609 pic14_toBoolean(right);
5611 symbol *tlbl = newiTempLabel(NULL);
5612 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5614 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5616 genIfxJump (ifx,"a");
5620 pic14_outBitC(result);
5624 /* if left is same as result */
5625 if(pic14_sameRegs(AOP(result),AOP(left))){
5627 for(;size--; offset++,lit>>=8) {
5628 if(AOP_TYPE(right) == AOP_LIT){
5629 if((lit & 0xff) == 0)
5630 /* or'ing with 0 has no effect */
5633 int p = my_powof2(lit & 0xff);
5635 /* only one bit is set in the literal, so use a bsf instruction */
5637 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5639 if(know_W != (int)(lit & 0xff))
5640 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5641 know_W = lit & 0xff;
5642 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5647 if (AOP_TYPE(left) == AOP_ACC) {
5648 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5649 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5651 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5652 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5654 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5655 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5661 // left & result in different registers
5662 if(AOP_TYPE(result) == AOP_CRY){
5664 // if(size), result in bit
5665 // if(!size && ifx), conditional oper: if(left | right)
5666 symbol *tlbl = newiTempLabel(NULL);
5667 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5668 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5672 pic14_emitcode(";XXX setb","c");
5674 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5675 pic14_emitcode(";XXX orl","a,%s",
5676 aopGet(AOP(left),offset,FALSE,FALSE));
5677 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5682 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5683 pic14_outBitC(result);
5685 jmpTrueOrFalse(ifx, tlbl);
5686 } else for(;(size--);offset++){
5688 // result = left & right
5689 if(AOP_TYPE(right) == AOP_LIT){
5690 int t = (lit >> (offset*8)) & 0x0FFL;
5693 if (AOP_TYPE(left) != AOP_ACC) {
5694 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5696 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5700 if (AOP_TYPE(left) == AOP_ACC) {
5701 emitpcode(POC_IORLW, popGetLit(t));
5703 emitpcode(POC_MOVLW, popGetLit(t));
5704 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5706 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5711 // faster than result <- left, anl result,right
5712 // and better if result is SFR
5713 if (AOP_TYPE(left) == AOP_ACC) {
5714 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5715 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5717 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5718 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5720 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5721 pic14_emitcode("iorwf","%s,w",
5722 aopGet(AOP(left),offset,FALSE,FALSE));
5724 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5725 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5730 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5731 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5732 freeAsmop(result,NULL,ic,TRUE);
5735 /*-----------------------------------------------------------------*/
5736 /* genXor - code for xclusive or */
5737 /*-----------------------------------------------------------------*/
5738 static void genXor (iCode *ic, iCode *ifx)
5740 operand *left, *right, *result;
5742 unsigned long lit = 0L;
5744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5746 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5747 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5748 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5750 /* if left is a literal & right is not ||
5751 if left needs acc & right does not */
5752 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5753 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5754 operand *tmp = right ;
5759 /* if result = right then exchange them */
5760 if(pic14_sameRegs(AOP(result),AOP(right))){
5761 operand *tmp = right ;
5766 /* if right is bit then exchange them */
5767 if (AOP_TYPE(right) == AOP_CRY &&
5768 AOP_TYPE(left) != AOP_CRY){
5769 operand *tmp = right ;
5773 if(AOP_TYPE(right) == AOP_LIT)
5774 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5776 size = AOP_SIZE(result);
5780 if (AOP_TYPE(left) == AOP_CRY){
5781 if(AOP_TYPE(right) == AOP_LIT){
5782 // c = bit & literal;
5784 // lit>>1 != 0 => result = 1
5785 if(AOP_TYPE(result) == AOP_CRY){
5787 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5788 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5790 continueIfTrue(ifx);
5793 pic14_emitcode("setb","c");
5797 // lit == 0, result = left
5798 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5800 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5802 // lit == 1, result = not(left)
5803 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5804 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5805 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5806 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5809 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5810 pic14_emitcode("cpl","c");
5817 symbol *tlbl = newiTempLabel(NULL);
5818 if (AOP_TYPE(right) == AOP_CRY){
5820 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5823 int sizer = AOP_SIZE(right);
5825 // if val>>1 != 0, result = 1
5826 pic14_emitcode("setb","c");
5828 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5830 // test the msb of the lsb
5831 pic14_emitcode("anl","a,#0xfe");
5832 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5836 pic14_emitcode("rrc","a");
5838 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5839 pic14_emitcode("cpl","c");
5840 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5845 pic14_outBitC(result);
5847 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5848 genIfxJump(ifx, "c");
5852 if(pic14_sameRegs(AOP(result),AOP(left))){
5853 /* if left is same as result */
5854 for(;size--; offset++) {
5855 if(AOP_TYPE(right) == AOP_LIT){
5856 int t = (lit >> (offset*8)) & 0x0FFL;
5860 if (IS_AOP_PREG(left)) {
5861 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5862 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5863 aopPut(AOP(result),"a",offset);
5865 emitpcode(POC_MOVLW, popGetLit(t));
5866 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5867 pic14_emitcode("xrl","%s,%s",
5868 aopGet(AOP(left),offset,FALSE,TRUE),
5869 aopGet(AOP(right),offset,FALSE,FALSE));
5872 if (AOP_TYPE(left) == AOP_ACC)
5873 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5875 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5876 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5878 if (IS_AOP_PREG(left)) {
5879 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5880 aopPut(AOP(result),"a",offset);
5882 pic14_emitcode("xrl","%s,a",
5883 aopGet(AOP(left),offset,FALSE,TRUE));
5889 // left & result in different registers
5890 if(AOP_TYPE(result) == AOP_CRY){
5892 // if(size), result in bit
5893 // if(!size && ifx), conditional oper: if(left ^ right)
5894 symbol *tlbl = newiTempLabel(NULL);
5895 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5897 pic14_emitcode("setb","c");
5899 if((AOP_TYPE(right) == AOP_LIT) &&
5900 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5901 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5903 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5904 pic14_emitcode("xrl","a,%s",
5905 aopGet(AOP(left),offset,FALSE,FALSE));
5907 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5912 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5913 pic14_outBitC(result);
5915 jmpTrueOrFalse(ifx, tlbl);
5916 } else for(;(size--);offset++){
5918 // result = left & right
5919 if(AOP_TYPE(right) == AOP_LIT){
5920 int t = (lit >> (offset*8)) & 0x0FFL;
5923 if (AOP_TYPE(left) != AOP_ACC) {
5924 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5926 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5927 pic14_emitcode("movf","%s,w",
5928 aopGet(AOP(left),offset,FALSE,FALSE));
5929 pic14_emitcode("movwf","%s",
5930 aopGet(AOP(result),offset,FALSE,FALSE));
5933 if (AOP_TYPE(left) == AOP_ACC) {
5934 emitpcode(POC_XORLW, popGetLit(t));
5936 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5938 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5941 if (AOP_TYPE(left) == AOP_ACC) {
5942 emitpcode(POC_XORLW, popGetLit(t));
5944 emitpcode(POC_MOVLW, popGetLit(t));
5945 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5947 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5948 pic14_emitcode("movlw","0x%x",t);
5949 pic14_emitcode("xorwf","%s,w",
5950 aopGet(AOP(left),offset,FALSE,FALSE));
5951 pic14_emitcode("movwf","%s",
5952 aopGet(AOP(result),offset,FALSE,FALSE));
5958 // faster than result <- left, anl result,right
5959 // and better if result is SFR
5960 if (AOP_TYPE(left) == AOP_ACC) {
5961 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5962 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5964 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5965 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5966 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5967 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5969 if ( AOP_TYPE(result) != AOP_ACC){
5970 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5971 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5977 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5978 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5979 freeAsmop(result,NULL,ic,TRUE);
5982 /*-----------------------------------------------------------------*/
5983 /* genInline - write the inline code out */
5984 /*-----------------------------------------------------------------*/
5985 static void genInline (iCode *ic)
5987 char *buffer, *bp, *bp1;
5989 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5991 _G.inLine += (!options.asmpeep);
5993 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5994 strcpy(buffer,IC_INLINE(ic));
5996 /* emit each line as a code */
6002 addpCode2pBlock(pb,AssembleLine(bp1));
6009 pic14_emitcode(bp1,"");
6015 if ((bp1 != bp) && *bp1)
6016 addpCode2pBlock(pb,AssembleLine(bp1));
6020 _G.inLine -= (!options.asmpeep);
6023 /*-----------------------------------------------------------------*/
6024 /* genRRC - rotate right with carry */
6025 /*-----------------------------------------------------------------*/
6026 static void genRRC (iCode *ic)
6028 operand *left , *result ;
6029 int size, offset = 0, same;
6031 /* rotate right with carry */
6033 result=IC_RESULT(ic);
6034 aopOp (left,ic,FALSE);
6035 aopOp (result,ic,FALSE);
6037 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6039 same = pic14_sameRegs(AOP(result),AOP(left));
6041 size = AOP_SIZE(result);
6043 /* get the lsb and put it into the carry */
6044 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6051 emitpcode(POC_RRF, popGet(AOP(left),offset));
6053 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6054 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6060 freeAsmop(left,NULL,ic,TRUE);
6061 freeAsmop(result,NULL,ic,TRUE);
6064 /*-----------------------------------------------------------------*/
6065 /* genRLC - generate code for rotate left with carry */
6066 /*-----------------------------------------------------------------*/
6067 static void genRLC (iCode *ic)
6069 operand *left , *result ;
6070 int size, offset = 0;
6073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6074 /* rotate right with carry */
6076 result=IC_RESULT(ic);
6077 aopOp (left,ic,FALSE);
6078 aopOp (result,ic,FALSE);
6080 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6082 same = pic14_sameRegs(AOP(result),AOP(left));
6084 /* move it to the result */
6085 size = AOP_SIZE(result);
6087 /* get the msb and put it into the carry */
6088 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6095 emitpcode(POC_RLF, popGet(AOP(left),offset));
6097 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6098 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6105 freeAsmop(left,NULL,ic,TRUE);
6106 freeAsmop(result,NULL,ic,TRUE);
6109 /*-----------------------------------------------------------------*/
6110 /* genGetHbit - generates code get highest order bit */
6111 /*-----------------------------------------------------------------*/
6112 static void genGetHbit (iCode *ic)
6114 operand *left, *result;
6116 result=IC_RESULT(ic);
6117 aopOp (left,ic,FALSE);
6118 aopOp (result,ic,FALSE);
6120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6121 /* get the highest order byte into a */
6122 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6123 if(AOP_TYPE(result) == AOP_CRY){
6124 pic14_emitcode("rlc","a");
6125 pic14_outBitC(result);
6128 pic14_emitcode("rl","a");
6129 pic14_emitcode("anl","a,#0x01");
6130 pic14_outAcc(result);
6134 freeAsmop(left,NULL,ic,TRUE);
6135 freeAsmop(result,NULL,ic,TRUE);
6138 /*-----------------------------------------------------------------*/
6139 /* AccRol - rotate left accumulator by known count */
6140 /*-----------------------------------------------------------------*/
6141 static void AccRol (int shCount)
6143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6144 shCount &= 0x0007; // shCount : 0..7
6149 pic14_emitcode("rl","a");
6152 pic14_emitcode("rl","a");
6153 pic14_emitcode("rl","a");
6156 pic14_emitcode("swap","a");
6157 pic14_emitcode("rr","a");
6160 pic14_emitcode("swap","a");
6163 pic14_emitcode("swap","a");
6164 pic14_emitcode("rl","a");
6167 pic14_emitcode("rr","a");
6168 pic14_emitcode("rr","a");
6171 pic14_emitcode("rr","a");
6176 /*-----------------------------------------------------------------*/
6177 /* AccLsh - left shift accumulator by known count */
6178 /*-----------------------------------------------------------------*/
6179 static void AccLsh (int shCount)
6181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6184 pic14_emitcode("add","a,acc");
6187 pic14_emitcode("add","a,acc");
6188 pic14_emitcode("add","a,acc");
6190 /* rotate left accumulator */
6192 /* and kill the lower order bits */
6193 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6198 /*-----------------------------------------------------------------*/
6199 /* AccRsh - right shift accumulator by known count */
6200 /*-----------------------------------------------------------------*/
6201 static void AccRsh (int shCount)
6203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6207 pic14_emitcode("rrc","a");
6209 /* rotate right accumulator */
6210 AccRol(8 - shCount);
6211 /* and kill the higher order bits */
6212 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6218 /*-----------------------------------------------------------------*/
6219 /* AccSRsh - signed right shift accumulator by known count */
6220 /*-----------------------------------------------------------------*/
6221 static void AccSRsh (int shCount)
6224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6227 pic14_emitcode("mov","c,acc.7");
6228 pic14_emitcode("rrc","a");
6229 } else if(shCount == 2){
6230 pic14_emitcode("mov","c,acc.7");
6231 pic14_emitcode("rrc","a");
6232 pic14_emitcode("mov","c,acc.7");
6233 pic14_emitcode("rrc","a");
6235 tlbl = newiTempLabel(NULL);
6236 /* rotate right accumulator */
6237 AccRol(8 - shCount);
6238 /* and kill the higher order bits */
6239 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6240 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6241 pic14_emitcode("orl","a,#0x%02x",
6242 (unsigned char)~SRMask[shCount]);
6243 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6248 /*-----------------------------------------------------------------*/
6249 /* shiftR1Left2Result - shift right one byte from left to result */
6250 /*-----------------------------------------------------------------*/
6251 static void shiftR1Left2ResultSigned (operand *left, int offl,
6252 operand *result, int offr,
6257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6259 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6263 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6265 emitpcode(POC_RRF, popGet(AOP(result),offr));
6267 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6268 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6274 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6276 emitpcode(POC_RRF, popGet(AOP(result),offr));
6278 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6279 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6281 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6282 emitpcode(POC_RRF, popGet(AOP(result),offr));
6288 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6290 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6291 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6294 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6295 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6296 emitpcode(POC_ANDLW, popGetLit(0x1f));
6298 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6299 emitpcode(POC_IORLW, popGetLit(0xe0));
6301 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6305 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6306 emitpcode(POC_ANDLW, popGetLit(0x0f));
6307 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6308 emitpcode(POC_IORLW, popGetLit(0xf0));
6309 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6313 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6315 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6316 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6318 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6319 emitpcode(POC_ANDLW, popGetLit(0x07));
6320 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6321 emitpcode(POC_IORLW, popGetLit(0xf8));
6322 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6327 emitpcode(POC_MOVLW, popGetLit(0x00));
6328 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6329 emitpcode(POC_MOVLW, popGetLit(0xfe));
6330 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6331 emitpcode(POC_IORLW, popGetLit(0x01));
6332 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6334 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6335 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6336 emitpcode(POC_DECF, popGet(AOP(result),offr));
6337 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6338 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6344 emitpcode(POC_MOVLW, popGetLit(0x00));
6345 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6346 emitpcode(POC_MOVLW, popGetLit(0xff));
6347 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6349 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6350 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6351 emitpcode(POC_DECF, popGet(AOP(result),offr));
6359 /*-----------------------------------------------------------------*/
6360 /* shiftR1Left2Result - shift right one byte from left to result */
6361 /*-----------------------------------------------------------------*/
6362 static void shiftR1Left2Result (operand *left, int offl,
6363 operand *result, int offr,
6364 int shCount, int sign)
6368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6370 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6372 /* Copy the msb into the carry if signed. */
6374 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6384 emitpcode(POC_RRF, popGet(AOP(result),offr));
6386 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6387 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6393 emitpcode(POC_RRF, popGet(AOP(result),offr));
6395 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6396 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6399 emitpcode(POC_RRF, popGet(AOP(result),offr));
6404 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6406 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6407 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6410 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6411 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6412 emitpcode(POC_ANDLW, popGetLit(0x1f));
6413 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6417 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6418 emitpcode(POC_ANDLW, popGetLit(0x0f));
6419 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6424 emitpcode(POC_ANDLW, popGetLit(0x0f));
6425 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427 emitpcode(POC_RRF, popGet(AOP(result),offr));
6432 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6433 emitpcode(POC_ANDLW, popGetLit(0x80));
6434 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6435 emitpcode(POC_RLF, popGet(AOP(result),offr));
6436 emitpcode(POC_RLF, popGet(AOP(result),offr));
6441 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6442 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6443 emitpcode(POC_RLF, popGet(AOP(result),offr));
6452 /*-----------------------------------------------------------------*/
6453 /* shiftL1Left2Result - shift left one byte from left to result */
6454 /*-----------------------------------------------------------------*/
6455 static void shiftL1Left2Result (operand *left, int offl,
6456 operand *result, int offr, int shCount)
6461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6463 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6464 DEBUGpic14_emitcode ("; ***","same = %d",same);
6465 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6467 /* shift left accumulator */
6468 //AccLsh(shCount); // don't comment out just yet...
6469 // aopPut(AOP(result),"a",offr);
6473 /* Shift left 1 bit position */
6474 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6476 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6478 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6479 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6484 emitpcode(POC_ANDLW,popGetLit(0x7e));
6485 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6486 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6489 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6490 emitpcode(POC_ANDLW,popGetLit(0x3e));
6491 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6492 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6493 emitpcode(POC_RLF, popGet(AOP(result),offr));
6496 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6497 emitpcode(POC_ANDLW, popGetLit(0xf0));
6498 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6501 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6502 emitpcode(POC_ANDLW, popGetLit(0xf0));
6503 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6504 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6507 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6508 emitpcode(POC_ANDLW, popGetLit(0x30));
6509 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6510 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6511 emitpcode(POC_RLF, popGet(AOP(result),offr));
6514 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6515 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6516 emitpcode(POC_RRF, popGet(AOP(result),offr));
6520 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6525 /*-----------------------------------------------------------------*/
6526 /* movLeft2Result - move byte from left to result */
6527 /*-----------------------------------------------------------------*/
6528 static void movLeft2Result (operand *left, int offl,
6529 operand *result, int offr)
6532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6533 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6534 l = aopGet(AOP(left),offl,FALSE,FALSE);
6536 if (*l == '@' && (IS_AOP_PREG(result))) {
6537 pic14_emitcode("mov","a,%s",l);
6538 aopPut(AOP(result),"a",offr);
6540 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6541 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6546 /*-----------------------------------------------------------------*/
6547 /* shiftL2Left2Result - shift left two bytes from left to result */
6548 /*-----------------------------------------------------------------*/
6549 static void shiftL2Left2Result (operand *left, int offl,
6550 operand *result, int offr, int shCount)
6554 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6556 if(pic14_sameRegs(AOP(result), AOP(left))) {
6564 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6565 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6566 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6570 emitpcode(POC_RLF, popGet(AOP(result),offr));
6571 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6577 emitpcode(POC_MOVLW, popGetLit(0x0f));
6578 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6579 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6580 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6581 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6582 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6583 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6585 emitpcode(POC_RLF, popGet(AOP(result),offr));
6586 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6590 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6591 emitpcode(POC_RRF, popGet(AOP(result),offr));
6592 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6593 emitpcode(POC_RRF, popGet(AOP(result),offr));
6594 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6595 emitpcode(POC_ANDLW,popGetLit(0xc0));
6596 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6597 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6598 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6599 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6602 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6603 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6604 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6606 emitpcode(POC_RRF, popGet(AOP(result),offr));
6616 /* note, use a mov/add for the shift since the mov has a
6617 chance of getting optimized out */
6618 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6619 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6620 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6621 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6622 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6626 emitpcode(POC_RLF, popGet(AOP(result),offr));
6627 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6633 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6634 emitpcode(POC_ANDLW, popGetLit(0xF0));
6635 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6636 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6637 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6638 emitpcode(POC_ANDLW, popGetLit(0xF0));
6639 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6640 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6644 emitpcode(POC_RLF, popGet(AOP(result),offr));
6645 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6650 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6651 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6652 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6654 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6655 emitpcode(POC_RRF, popGet(AOP(result),offr));
6656 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6657 emitpcode(POC_ANDLW,popGetLit(0xc0));
6658 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6659 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6660 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6661 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6665 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6666 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6668 emitpcode(POC_RRF, popGet(AOP(result),offr));
6673 /*-----------------------------------------------------------------*/
6674 /* shiftR2Left2Result - shift right two bytes from left to result */
6675 /*-----------------------------------------------------------------*/
6676 static void shiftR2Left2Result (operand *left, int offl,
6677 operand *result, int offr,
6678 int shCount, int sign)
6682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6683 same = pic14_sameRegs(AOP(result), AOP(left));
6685 if(same && ((offl + MSB16) == offr)){
6687 /* don't crash result[offr] */
6688 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6689 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6692 movLeft2Result(left,offl, result, offr);
6693 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6696 /* a:x >> shCount (x = lsb(result))*/
6699 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6701 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6710 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6716 emitpcode(POC_RRF,popGet(AOP(result),offr));
6718 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6719 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6720 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6721 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6726 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6729 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6730 emitpcode(POC_RRF,popGet(AOP(result),offr));
6737 emitpcode(POC_MOVLW, popGetLit(0xf0));
6738 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6739 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6741 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6746 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6747 emitpcode(POC_ANDLW, popGetLit(0x0f));
6748 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6750 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6751 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6752 emitpcode(POC_ANDLW, popGetLit(0xf0));
6753 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6754 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6758 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6759 emitpcode(POC_RRF, popGet(AOP(result),offr));
6763 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6764 emitpcode(POC_BTFSC,
6765 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6766 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6774 emitpcode(POC_RLF, popGet(AOP(result),offr));
6775 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6777 emitpcode(POC_RLF, popGet(AOP(result),offr));
6778 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6779 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6780 emitpcode(POC_ANDLW,popGetLit(0x03));
6782 emitpcode(POC_BTFSC,
6783 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6784 emitpcode(POC_IORLW,popGetLit(0xfc));
6786 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6787 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6788 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6789 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6791 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6792 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6793 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6794 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6795 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6796 emitpcode(POC_RLF, popGet(AOP(result),offr));
6797 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6798 emitpcode(POC_ANDLW,popGetLit(0x03));
6800 emitpcode(POC_BTFSC,
6801 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6802 emitpcode(POC_IORLW,popGetLit(0xfc));
6804 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6805 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6812 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6813 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6814 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6815 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6818 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6820 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6825 /*-----------------------------------------------------------------*/
6826 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6827 /*-----------------------------------------------------------------*/
6828 static void shiftLLeftOrResult (operand *left, int offl,
6829 operand *result, int offr, int shCount)
6831 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6832 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6833 /* shift left accumulator */
6835 /* or with result */
6836 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6837 /* back to result */
6838 aopPut(AOP(result),"a",offr);
6841 /*-----------------------------------------------------------------*/
6842 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6843 /*-----------------------------------------------------------------*/
6844 static void shiftRLeftOrResult (operand *left, int offl,
6845 operand *result, int offr, int shCount)
6847 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6848 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6849 /* shift right accumulator */
6851 /* or with result */
6852 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6853 /* back to result */
6854 aopPut(AOP(result),"a",offr);
6857 /*-----------------------------------------------------------------*/
6858 /* genlshOne - left shift a one byte quantity by known count */
6859 /*-----------------------------------------------------------------*/
6860 static void genlshOne (operand *result, operand *left, int shCount)
6862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6863 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6866 /*-----------------------------------------------------------------*/
6867 /* genlshTwo - left shift two bytes by known amount != 0 */
6868 /*-----------------------------------------------------------------*/
6869 static void genlshTwo (operand *result,operand *left, int shCount)
6873 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6874 size = pic14_getDataSize(result);
6876 /* if shCount >= 8 */
6882 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6884 movLeft2Result(left, LSB, result, MSB16);
6886 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6889 /* 1 <= shCount <= 7 */
6892 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6894 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6898 /*-----------------------------------------------------------------*/
6899 /* shiftLLong - shift left one long from left to result */
6900 /* offl = LSB or MSB16 */
6901 /*-----------------------------------------------------------------*/
6902 static void shiftLLong (operand *left, operand *result, int offr )
6905 int size = AOP_SIZE(result);
6907 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6908 if(size >= LSB+offr){
6909 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6911 pic14_emitcode("add","a,acc");
6912 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6913 size >= MSB16+offr && offr != LSB )
6914 pic14_emitcode("xch","a,%s",
6915 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6917 aopPut(AOP(result),"a",LSB+offr);
6920 if(size >= MSB16+offr){
6921 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6922 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6925 pic14_emitcode("rlc","a");
6926 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6927 size >= MSB24+offr && offr != LSB)
6928 pic14_emitcode("xch","a,%s",
6929 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6931 aopPut(AOP(result),"a",MSB16+offr);
6934 if(size >= MSB24+offr){
6935 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6936 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6939 pic14_emitcode("rlc","a");
6940 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6941 size >= MSB32+offr && offr != LSB )
6942 pic14_emitcode("xch","a,%s",
6943 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6945 aopPut(AOP(result),"a",MSB24+offr);
6948 if(size > MSB32+offr){
6949 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6950 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6953 pic14_emitcode("rlc","a");
6954 aopPut(AOP(result),"a",MSB32+offr);
6957 aopPut(AOP(result),zero,LSB);
6960 /*-----------------------------------------------------------------*/
6961 /* genlshFour - shift four byte by a known amount != 0 */
6962 /*-----------------------------------------------------------------*/
6963 static void genlshFour (operand *result, operand *left, int shCount)
6967 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6968 size = AOP_SIZE(result);
6970 /* if shifting more that 3 bytes */
6971 if (shCount >= 24 ) {
6974 /* lowest order of left goes to the highest
6975 order of the destination */
6976 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6978 movLeft2Result(left, LSB, result, MSB32);
6979 aopPut(AOP(result),zero,LSB);
6980 aopPut(AOP(result),zero,MSB16);
6981 aopPut(AOP(result),zero,MSB32);
6985 /* more than two bytes */
6986 else if ( shCount >= 16 ) {
6987 /* lower order two bytes goes to higher order two bytes */
6989 /* if some more remaining */
6991 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6993 movLeft2Result(left, MSB16, result, MSB32);
6994 movLeft2Result(left, LSB, result, MSB24);
6996 aopPut(AOP(result),zero,MSB16);
6997 aopPut(AOP(result),zero,LSB);
7001 /* if more than 1 byte */
7002 else if ( shCount >= 8 ) {
7003 /* lower order three bytes goes to higher order three bytes */
7007 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7009 movLeft2Result(left, LSB, result, MSB16);
7011 else{ /* size = 4 */
7013 movLeft2Result(left, MSB24, result, MSB32);
7014 movLeft2Result(left, MSB16, result, MSB24);
7015 movLeft2Result(left, LSB, result, MSB16);
7016 aopPut(AOP(result),zero,LSB);
7018 else if(shCount == 1)
7019 shiftLLong(left, result, MSB16);
7021 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7022 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7023 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7024 aopPut(AOP(result),zero,LSB);
7029 /* 1 <= shCount <= 7 */
7030 else if(shCount <= 2){
7031 shiftLLong(left, result, LSB);
7033 shiftLLong(result, result, LSB);
7035 /* 3 <= shCount <= 7, optimize */
7037 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7038 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7039 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7043 /*-----------------------------------------------------------------*/
7044 /* genLeftShiftLiteral - left shifting by known count */
7045 /*-----------------------------------------------------------------*/
7046 static void genLeftShiftLiteral (operand *left,
7051 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7055 freeAsmop(right,NULL,ic,TRUE);
7057 aopOp(left,ic,FALSE);
7058 aopOp(result,ic,FALSE);
7060 size = getSize(operandType(result));
7063 pic14_emitcode("; shift left ","result %d, left %d",size,
7067 /* I suppose that the left size >= result size */
7070 movLeft2Result(left, size, result, size);
7074 else if(shCount >= (size * 8))
7076 aopPut(AOP(result),zero,size);
7080 genlshOne (result,left,shCount);
7085 genlshTwo (result,left,shCount);
7089 genlshFour (result,left,shCount);
7093 freeAsmop(left,NULL,ic,TRUE);
7094 freeAsmop(result,NULL,ic,TRUE);
7097 /*-----------------------------------------------------------------*
7098 * genMultiAsm - repeat assembly instruction for size of register.
7099 * if endian == 1, then the high byte (i.e base address + size of
7100 * register) is used first else the low byte is used first;
7101 *-----------------------------------------------------------------*/
7102 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7107 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7120 emitpcode(poc, popGet(AOP(reg),offset));
7125 /*-----------------------------------------------------------------*/
7126 /* genLeftShift - generates code for left shifting */
7127 /*-----------------------------------------------------------------*/
7128 static void genLeftShift (iCode *ic)
7130 operand *left,*right, *result;
7133 symbol *tlbl , *tlbl1;
7136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7138 right = IC_RIGHT(ic);
7140 result = IC_RESULT(ic);
7142 aopOp(right,ic,FALSE);
7144 /* if the shift count is known then do it
7145 as efficiently as possible */
7146 if (AOP_TYPE(right) == AOP_LIT) {
7147 genLeftShiftLiteral (left,right,result,ic);
7151 /* shift count is unknown then we have to form
7152 a loop get the loop count in B : Note: we take
7153 only the lower order byte since shifting
7154 more that 32 bits make no sense anyway, ( the
7155 largest size of an object can be only 32 bits ) */
7158 aopOp(left,ic,FALSE);
7159 aopOp(result,ic,FALSE);
7161 /* now move the left to the result if they are not the
7163 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7164 AOP_SIZE(result) > 1) {
7166 size = AOP_SIZE(result);
7169 l = aopGet(AOP(left),offset,FALSE,TRUE);
7170 if (*l == '@' && (IS_AOP_PREG(result))) {
7172 pic14_emitcode("mov","a,%s",l);
7173 aopPut(AOP(result),"a",offset);
7175 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7176 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7177 //aopPut(AOP(result),l,offset);
7183 size = AOP_SIZE(result);
7185 /* if it is only one byte then */
7187 if(optimized_for_speed) {
7188 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7189 emitpcode(POC_ANDLW, popGetLit(0xf0));
7190 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7191 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7192 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7193 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7194 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7195 emitpcode(POC_RLFW, popGet(AOP(result),0));
7196 emitpcode(POC_ANDLW, popGetLit(0xfe));
7197 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7198 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7199 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7202 tlbl = newiTempLabel(NULL);
7203 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7204 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7205 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7208 emitpcode(POC_COMFW, popGet(AOP(right),0));
7209 emitpcode(POC_RRF, popGet(AOP(result),0));
7210 emitpLabel(tlbl->key);
7211 emitpcode(POC_RLF, popGet(AOP(result),0));
7212 emitpcode(POC_ADDLW, popGetLit(1));
7214 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7219 if (pic14_sameRegs(AOP(left),AOP(result))) {
7221 tlbl = newiTempLabel(NULL);
7222 emitpcode(POC_COMFW, popGet(AOP(right),0));
7223 genMultiAsm(POC_RRF, result, size,1);
7224 emitpLabel(tlbl->key);
7225 genMultiAsm(POC_RLF, result, size,0);
7226 emitpcode(POC_ADDLW, popGetLit(1));
7228 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7232 //tlbl = newiTempLabel(NULL);
7234 //tlbl1 = newiTempLabel(NULL);
7236 //reAdjustPreg(AOP(result));
7238 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7239 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7240 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7242 //pic14_emitcode("add","a,acc");
7243 //aopPut(AOP(result),"a",offset++);
7245 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7247 // pic14_emitcode("rlc","a");
7248 // aopPut(AOP(result),"a",offset++);
7250 //reAdjustPreg(AOP(result));
7252 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7253 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7256 tlbl = newiTempLabel(NULL);
7257 tlbl1= newiTempLabel(NULL);
7259 size = AOP_SIZE(result);
7262 pctemp = popGetTempReg(); /* grab a temporary working register. */
7264 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7266 /* offset should be 0, 1 or 3 */
7267 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7269 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7271 emitpcode(POC_MOVWF, pctemp);
7274 emitpLabel(tlbl->key);
7277 emitpcode(POC_RLF, popGet(AOP(result),0));
7279 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7281 emitpcode(POC_DECFSZ, pctemp);
7282 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7283 emitpLabel(tlbl1->key);
7285 popReleaseTempReg(pctemp);
7289 freeAsmop (right,NULL,ic,TRUE);
7290 freeAsmop(left,NULL,ic,TRUE);
7291 freeAsmop(result,NULL,ic,TRUE);
7294 /*-----------------------------------------------------------------*/
7295 /* genrshOne - right shift a one byte quantity by known count */
7296 /*-----------------------------------------------------------------*/
7297 static void genrshOne (operand *result, operand *left,
7298 int shCount, int sign)
7300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7301 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7304 /*-----------------------------------------------------------------*/
7305 /* genrshTwo - right shift two bytes by known amount != 0 */
7306 /*-----------------------------------------------------------------*/
7307 static void genrshTwo (operand *result,operand *left,
7308 int shCount, int sign)
7310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7311 /* if shCount >= 8 */
7315 shiftR1Left2Result(left, MSB16, result, LSB,
7318 movLeft2Result(left, MSB16, result, LSB);
7320 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7323 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7324 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7328 /* 1 <= shCount <= 7 */
7330 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7333 /*-----------------------------------------------------------------*/
7334 /* shiftRLong - shift right one long from left to result */
7335 /* offl = LSB or MSB16 */
7336 /*-----------------------------------------------------------------*/
7337 static void shiftRLong (operand *left, int offl,
7338 operand *result, int sign)
7340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7342 pic14_emitcode("clr","c");
7343 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7345 pic14_emitcode("mov","c,acc.7");
7346 pic14_emitcode("rrc","a");
7347 aopPut(AOP(result),"a",MSB32-offl);
7349 /* add sign of "a" */
7350 addSign(result, MSB32, sign);
7352 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7353 pic14_emitcode("rrc","a");
7354 aopPut(AOP(result),"a",MSB24-offl);
7356 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7357 pic14_emitcode("rrc","a");
7358 aopPut(AOP(result),"a",MSB16-offl);
7361 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7362 pic14_emitcode("rrc","a");
7363 aopPut(AOP(result),"a",LSB);
7367 /*-----------------------------------------------------------------*/
7368 /* genrshFour - shift four byte by a known amount != 0 */
7369 /*-----------------------------------------------------------------*/
7370 static void genrshFour (operand *result, operand *left,
7371 int shCount, int sign)
7373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7374 /* if shifting more that 3 bytes */
7375 if(shCount >= 24 ) {
7378 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7380 movLeft2Result(left, MSB32, result, LSB);
7382 addSign(result, MSB16, sign);
7384 else if(shCount >= 16){
7387 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7389 movLeft2Result(left, MSB24, result, LSB);
7390 movLeft2Result(left, MSB32, result, MSB16);
7392 addSign(result, MSB24, sign);
7394 else if(shCount >= 8){
7397 shiftRLong(left, MSB16, result, sign);
7398 else if(shCount == 0){
7399 movLeft2Result(left, MSB16, result, LSB);
7400 movLeft2Result(left, MSB24, result, MSB16);
7401 movLeft2Result(left, MSB32, result, MSB24);
7402 addSign(result, MSB32, sign);
7405 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7406 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7407 /* the last shift is signed */
7408 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7409 addSign(result, MSB32, sign);
7412 else{ /* 1 <= shCount <= 7 */
7414 shiftRLong(left, LSB, result, sign);
7416 shiftRLong(result, LSB, result, sign);
7419 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7420 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7421 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7426 /*-----------------------------------------------------------------*/
7427 /* genRightShiftLiteral - right shifting by known count */
7428 /*-----------------------------------------------------------------*/
7429 static void genRightShiftLiteral (operand *left,
7435 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7438 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7439 freeAsmop(right,NULL,ic,TRUE);
7441 aopOp(left,ic,FALSE);
7442 aopOp(result,ic,FALSE);
7445 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7449 lsize = pic14_getDataSize(left);
7450 res_size = pic14_getDataSize(result);
7451 /* test the LEFT size !!! */
7453 /* I suppose that the left size >= result size */
7456 movLeft2Result(left, lsize, result, res_size);
7459 else if(shCount >= (lsize * 8)){
7462 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7464 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7465 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7470 emitpcode(POC_MOVLW, popGetLit(0));
7471 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7472 emitpcode(POC_MOVLW, popGetLit(0xff));
7474 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7479 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7486 genrshOne (result,left,shCount,sign);
7490 genrshTwo (result,left,shCount,sign);
7494 genrshFour (result,left,shCount,sign);
7502 freeAsmop(left,NULL,ic,TRUE);
7503 freeAsmop(result,NULL,ic,TRUE);
7506 /*-----------------------------------------------------------------*/
7507 /* genSignedRightShift - right shift of signed number */
7508 /*-----------------------------------------------------------------*/
7509 static void genSignedRightShift (iCode *ic)
7511 operand *right, *left, *result;
7514 symbol *tlbl, *tlbl1 ;
7517 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7519 /* we do it the hard way put the shift count in b
7520 and loop thru preserving the sign */
7521 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7523 right = IC_RIGHT(ic);
7525 result = IC_RESULT(ic);
7527 aopOp(right,ic,FALSE);
7528 aopOp(left,ic,FALSE);
7529 aopOp(result,ic,FALSE);
7532 if ( AOP_TYPE(right) == AOP_LIT) {
7533 genRightShiftLiteral (left,right,result,ic,1);
7536 /* shift count is unknown then we have to form
7537 a loop get the loop count in B : Note: we take
7538 only the lower order byte since shifting
7539 more that 32 bits make no sense anyway, ( the
7540 largest size of an object can be only 32 bits ) */
7542 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7543 //pic14_emitcode("inc","b");
7544 //freeAsmop (right,NULL,ic,TRUE);
7545 //aopOp(left,ic,FALSE);
7546 //aopOp(result,ic,FALSE);
7548 /* now move the left to the result if they are not the
7550 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7551 AOP_SIZE(result) > 1) {
7553 size = AOP_SIZE(result);
7557 l = aopGet(AOP(left),offset,FALSE,TRUE);
7558 if (*l == '@' && IS_AOP_PREG(result)) {
7560 pic14_emitcode("mov","a,%s",l);
7561 aopPut(AOP(result),"a",offset);
7563 aopPut(AOP(result),l,offset);
7565 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7566 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7572 /* mov the highest order bit to OVR */
7573 tlbl = newiTempLabel(NULL);
7574 tlbl1= newiTempLabel(NULL);
7576 size = AOP_SIZE(result);
7579 pctemp = popGetTempReg(); /* grab a temporary working register. */
7581 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7583 /* offset should be 0, 1 or 3 */
7584 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7586 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7588 emitpcode(POC_MOVWF, pctemp);
7591 emitpLabel(tlbl->key);
7593 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7594 emitpcode(POC_RRF, popGet(AOP(result),offset));
7597 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7600 emitpcode(POC_DECFSZ, pctemp);
7601 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7602 emitpLabel(tlbl1->key);
7604 popReleaseTempReg(pctemp);
7606 size = AOP_SIZE(result);
7608 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7609 pic14_emitcode("rlc","a");
7610 pic14_emitcode("mov","ov,c");
7611 /* if it is only one byte then */
7613 l = aopGet(AOP(left),0,FALSE,FALSE);
7615 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7616 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7617 pic14_emitcode("mov","c,ov");
7618 pic14_emitcode("rrc","a");
7619 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7620 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7621 aopPut(AOP(result),"a",0);
7625 reAdjustPreg(AOP(result));
7626 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7627 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7628 pic14_emitcode("mov","c,ov");
7630 l = aopGet(AOP(result),offset,FALSE,FALSE);
7632 pic14_emitcode("rrc","a");
7633 aopPut(AOP(result),"a",offset--);
7635 reAdjustPreg(AOP(result));
7636 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7637 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7642 freeAsmop(left,NULL,ic,TRUE);
7643 freeAsmop(result,NULL,ic,TRUE);
7644 freeAsmop(right,NULL,ic,TRUE);
7647 /*-----------------------------------------------------------------*/
7648 /* genRightShift - generate code for right shifting */
7649 /*-----------------------------------------------------------------*/
7650 static void genRightShift (iCode *ic)
7652 operand *right, *left, *result;
7656 symbol *tlbl, *tlbl1 ;
7658 /* if signed then we do it the hard way preserve the
7659 sign bit moving it inwards */
7660 retype = getSpec(operandType(IC_RESULT(ic)));
7661 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7663 if (!SPEC_USIGN(retype)) {
7664 genSignedRightShift (ic);
7668 /* signed & unsigned types are treated the same : i.e. the
7669 signed is NOT propagated inwards : quoting from the
7670 ANSI - standard : "for E1 >> E2, is equivalent to division
7671 by 2**E2 if unsigned or if it has a non-negative value,
7672 otherwise the result is implementation defined ", MY definition
7673 is that the sign does not get propagated */
7675 right = IC_RIGHT(ic);
7677 result = IC_RESULT(ic);
7679 aopOp(right,ic,FALSE);
7681 /* if the shift count is known then do it
7682 as efficiently as possible */
7683 if (AOP_TYPE(right) == AOP_LIT) {
7684 genRightShiftLiteral (left,right,result,ic, 0);
7688 /* shift count is unknown then we have to form
7689 a loop get the loop count in B : Note: we take
7690 only the lower order byte since shifting
7691 more that 32 bits make no sense anyway, ( the
7692 largest size of an object can be only 32 bits ) */
7694 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7695 pic14_emitcode("inc","b");
7696 aopOp(left,ic,FALSE);
7697 aopOp(result,ic,FALSE);
7699 /* now move the left to the result if they are not the
7701 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7702 AOP_SIZE(result) > 1) {
7704 size = AOP_SIZE(result);
7707 l = aopGet(AOP(left),offset,FALSE,TRUE);
7708 if (*l == '@' && IS_AOP_PREG(result)) {
7710 pic14_emitcode("mov","a,%s",l);
7711 aopPut(AOP(result),"a",offset);
7713 aopPut(AOP(result),l,offset);
7718 tlbl = newiTempLabel(NULL);
7719 tlbl1= newiTempLabel(NULL);
7720 size = AOP_SIZE(result);
7723 /* if it is only one byte then */
7726 tlbl = newiTempLabel(NULL);
7727 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7728 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7729 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7732 emitpcode(POC_COMFW, popGet(AOP(right),0));
7733 emitpcode(POC_RLF, popGet(AOP(result),0));
7734 emitpLabel(tlbl->key);
7735 emitpcode(POC_RRF, popGet(AOP(result),0));
7736 emitpcode(POC_ADDLW, popGetLit(1));
7738 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7743 reAdjustPreg(AOP(result));
7744 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7745 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7748 l = aopGet(AOP(result),offset,FALSE,FALSE);
7750 pic14_emitcode("rrc","a");
7751 aopPut(AOP(result),"a",offset--);
7753 reAdjustPreg(AOP(result));
7755 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7756 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7759 freeAsmop(left,NULL,ic,TRUE);
7760 freeAsmop (right,NULL,ic,TRUE);
7761 freeAsmop(result,NULL,ic,TRUE);
7764 /*-----------------------------------------------------------------*/
7765 /* genUnpackBits - generates code for unpacking bits */
7766 /*-----------------------------------------------------------------*/
7767 static void genUnpackBits (operand *result, char *rname, int ptype)
7774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7775 etype = getSpec(operandType(result));
7777 /* read the first byte */
7782 pic14_emitcode("mov","a,@%s",rname);
7786 pic14_emitcode("movx","a,@%s",rname);
7790 pic14_emitcode("movx","a,@dptr");
7794 pic14_emitcode("clr","a");
7795 pic14_emitcode("movc","a","@a+dptr");
7799 pic14_emitcode("lcall","__gptrget");
7803 /* if we have bitdisplacement then it fits */
7804 /* into this byte completely or if length is */
7805 /* less than a byte */
7806 if ((shCnt = SPEC_BSTR(etype)) ||
7807 (SPEC_BLEN(etype) <= 8)) {
7809 /* shift right acc */
7812 pic14_emitcode("anl","a,#0x%02x",
7813 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7814 aopPut(AOP(result),"a",offset);
7818 /* bit field did not fit in a byte */
7819 rlen = SPEC_BLEN(etype) - 8;
7820 aopPut(AOP(result),"a",offset++);
7827 pic14_emitcode("inc","%s",rname);
7828 pic14_emitcode("mov","a,@%s",rname);
7832 pic14_emitcode("inc","%s",rname);
7833 pic14_emitcode("movx","a,@%s",rname);
7837 pic14_emitcode("inc","dptr");
7838 pic14_emitcode("movx","a,@dptr");
7842 pic14_emitcode("clr","a");
7843 pic14_emitcode("inc","dptr");
7844 pic14_emitcode("movc","a","@a+dptr");
7848 pic14_emitcode("inc","dptr");
7849 pic14_emitcode("lcall","__gptrget");
7854 /* if we are done */
7858 aopPut(AOP(result),"a",offset++);
7863 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7864 aopPut(AOP(result),"a",offset);
7871 /*-----------------------------------------------------------------*/
7872 /* genDataPointerGet - generates code when ptr offset is known */
7873 /*-----------------------------------------------------------------*/
7874 static void genDataPointerGet (operand *left,
7878 int size , offset = 0;
7881 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7884 /* optimization - most of the time, left and result are the same
7885 * address, but different types. for the pic code, we could omit
7889 aopOp(result,ic,TRUE);
7891 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7893 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7895 size = AOP_SIZE(result);
7898 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7902 freeAsmop(left,NULL,ic,TRUE);
7903 freeAsmop(result,NULL,ic,TRUE);
7906 /*-----------------------------------------------------------------*/
7907 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7908 /*-----------------------------------------------------------------*/
7909 static void genNearPointerGet (operand *left,
7914 //regs *preg = NULL ;
7916 sym_link *rtype, *retype;
7917 sym_link *ltype = operandType(left);
7920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7922 rtype = operandType(result);
7923 retype= getSpec(rtype);
7925 aopOp(left,ic,FALSE);
7927 /* if left is rematerialisable and
7928 result is not bit variable type and
7929 the left is pointer to data space i.e
7930 lower 128 bytes of space */
7931 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7932 !IS_BITVAR(retype) &&
7933 DCL_TYPE(ltype) == POINTER) {
7934 //genDataPointerGet (left,result,ic);
7938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7940 /* if the value is already in a pointer register
7941 then don't need anything more */
7942 if (!AOP_INPREG(AOP(left))) {
7943 /* otherwise get a free pointer register */
7944 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7947 preg = getFreePtr(ic,&aop,FALSE);
7948 pic14_emitcode("mov","%s,%s",
7950 aopGet(AOP(left),0,FALSE,TRUE));
7951 rname = preg->name ;
7955 rname = aopGet(AOP(left),0,FALSE,FALSE);
7957 aopOp (result,ic,FALSE);
7959 /* if bitfield then unpack the bits */
7960 if (IS_BITFIELD(retype))
7961 genUnpackBits (result,rname,POINTER);
7963 /* we have can just get the values */
7964 int size = AOP_SIZE(result);
7967 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7969 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7970 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7972 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7973 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7975 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7979 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7981 pic14_emitcode("mov","a,@%s",rname);
7982 aopPut(AOP(result),"a",offset);
7984 sprintf(buffer,"@%s",rname);
7985 aopPut(AOP(result),buffer,offset);
7989 pic14_emitcode("inc","%s",rname);
7994 /* now some housekeeping stuff */
7996 /* we had to allocate for this iCode */
7997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7998 freeAsmop(NULL,aop,ic,TRUE);
8000 /* we did not allocate which means left
8001 already in a pointer register, then
8002 if size > 0 && this could be used again
8003 we have to point it back to where it
8005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8006 if (AOP_SIZE(result) > 1 &&
8007 !OP_SYMBOL(left)->remat &&
8008 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8010 int size = AOP_SIZE(result) - 1;
8012 pic14_emitcode("dec","%s",rname);
8017 freeAsmop(left,NULL,ic,TRUE);
8018 freeAsmop(result,NULL,ic,TRUE);
8022 /*-----------------------------------------------------------------*/
8023 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8024 /*-----------------------------------------------------------------*/
8025 static void genPagedPointerGet (operand *left,
8032 sym_link *rtype, *retype;
8034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8036 rtype = operandType(result);
8037 retype= getSpec(rtype);
8039 aopOp(left,ic,FALSE);
8041 /* if the value is already in a pointer register
8042 then don't need anything more */
8043 if (!AOP_INPREG(AOP(left))) {
8044 /* otherwise get a free pointer register */
8046 preg = getFreePtr(ic,&aop,FALSE);
8047 pic14_emitcode("mov","%s,%s",
8049 aopGet(AOP(left),0,FALSE,TRUE));
8050 rname = preg->name ;
8052 rname = aopGet(AOP(left),0,FALSE,FALSE);
8054 freeAsmop(left,NULL,ic,TRUE);
8055 aopOp (result,ic,FALSE);
8057 /* if bitfield then unpack the bits */
8058 if (IS_BITFIELD(retype))
8059 genUnpackBits (result,rname,PPOINTER);
8061 /* we have can just get the values */
8062 int size = AOP_SIZE(result);
8067 pic14_emitcode("movx","a,@%s",rname);
8068 aopPut(AOP(result),"a",offset);
8073 pic14_emitcode("inc","%s",rname);
8077 /* now some housekeeping stuff */
8079 /* we had to allocate for this iCode */
8080 freeAsmop(NULL,aop,ic,TRUE);
8082 /* we did not allocate which means left
8083 already in a pointer register, then
8084 if size > 0 && this could be used again
8085 we have to point it back to where it
8087 if (AOP_SIZE(result) > 1 &&
8088 !OP_SYMBOL(left)->remat &&
8089 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8091 int size = AOP_SIZE(result) - 1;
8093 pic14_emitcode("dec","%s",rname);
8098 freeAsmop(result,NULL,ic,TRUE);
8103 /*-----------------------------------------------------------------*/
8104 /* genFarPointerGet - gget value from far space */
8105 /*-----------------------------------------------------------------*/
8106 static void genFarPointerGet (operand *left,
8107 operand *result, iCode *ic)
8110 sym_link *retype = getSpec(operandType(result));
8112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8114 aopOp(left,ic,FALSE);
8116 /* if the operand is already in dptr
8117 then we do nothing else we move the value to dptr */
8118 if (AOP_TYPE(left) != AOP_STR) {
8119 /* if this is remateriazable */
8120 if (AOP_TYPE(left) == AOP_IMMD)
8121 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8122 else { /* we need to get it byte by byte */
8123 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8124 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8125 if (options.model == MODEL_FLAT24)
8127 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8131 /* so dptr know contains the address */
8132 freeAsmop(left,NULL,ic,TRUE);
8133 aopOp(result,ic,FALSE);
8135 /* if bit then unpack */
8136 if (IS_BITFIELD(retype))
8137 genUnpackBits(result,"dptr",FPOINTER);
8139 size = AOP_SIZE(result);
8143 pic14_emitcode("movx","a,@dptr");
8144 aopPut(AOP(result),"a",offset++);
8146 pic14_emitcode("inc","dptr");
8150 freeAsmop(result,NULL,ic,TRUE);
8153 /*-----------------------------------------------------------------*/
8154 /* genCodePointerGet - get value from code space */
8155 /*-----------------------------------------------------------------*/
8156 static void genCodePointerGet (operand *left,
8157 operand *result, iCode *ic)
8160 sym_link *retype = getSpec(operandType(result));
8162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8164 aopOp(left,ic,FALSE);
8166 /* if the operand is already in dptr
8167 then we do nothing else we move the value to dptr */
8168 if (AOP_TYPE(left) != AOP_STR) {
8169 /* if this is remateriazable */
8170 if (AOP_TYPE(left) == AOP_IMMD)
8171 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8172 else { /* we need to get it byte by byte */
8173 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8174 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8175 if (options.model == MODEL_FLAT24)
8177 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8181 /* so dptr know contains the address */
8182 freeAsmop(left,NULL,ic,TRUE);
8183 aopOp(result,ic,FALSE);
8185 /* if bit then unpack */
8186 if (IS_BITFIELD(retype))
8187 genUnpackBits(result,"dptr",CPOINTER);
8189 size = AOP_SIZE(result);
8193 pic14_emitcode("clr","a");
8194 pic14_emitcode("movc","a,@a+dptr");
8195 aopPut(AOP(result),"a",offset++);
8197 pic14_emitcode("inc","dptr");
8201 freeAsmop(result,NULL,ic,TRUE);
8204 /*-----------------------------------------------------------------*/
8205 /* genGenPointerGet - gget value from generic pointer space */
8206 /*-----------------------------------------------------------------*/
8207 static void genGenPointerGet (operand *left,
8208 operand *result, iCode *ic)
8211 sym_link *retype = getSpec(operandType(result));
8213 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8214 aopOp(left,ic,FALSE);
8215 aopOp(result,ic,FALSE);
8218 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8220 /* if the operand is already in dptr
8221 then we do nothing else we move the value to dptr */
8222 // if (AOP_TYPE(left) != AOP_STR) {
8223 /* if this is remateriazable */
8224 if (AOP_TYPE(left) == AOP_IMMD) {
8225 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8226 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8228 else { /* we need to get it byte by byte */
8230 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8231 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8233 size = AOP_SIZE(result);
8237 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8238 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8240 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8245 /* so dptr know contains the address */
8247 /* if bit then unpack */
8248 //if (IS_BITFIELD(retype))
8249 // genUnpackBits(result,"dptr",GPOINTER);
8252 freeAsmop(left,NULL,ic,TRUE);
8253 freeAsmop(result,NULL,ic,TRUE);
8257 /*-----------------------------------------------------------------*/
8258 /* genConstPointerGet - get value from const generic pointer space */
8259 /*-----------------------------------------------------------------*/
8260 static void genConstPointerGet (operand *left,
8261 operand *result, iCode *ic)
8263 //sym_link *retype = getSpec(operandType(result));
8264 symbol *albl = newiTempLabel(NULL);
8265 symbol *blbl = newiTempLabel(NULL);
8269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8270 aopOp(left,ic,FALSE);
8271 aopOp(result,ic,FALSE);
8274 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8276 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8278 emitpcode(POC_CALL,popGetLabel(albl->key));
8279 pcop = popGetLabel(blbl->key);
8280 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8281 emitpcode(POC_GOTO,pcop);
8282 emitpLabel(albl->key);
8284 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8286 emitpcode(poc,popGet(AOP(left),1));
8287 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8288 emitpcode(poc,popGet(AOP(left),0));
8289 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8291 emitpLabel(blbl->key);
8293 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8296 freeAsmop(left,NULL,ic,TRUE);
8297 freeAsmop(result,NULL,ic,TRUE);
8300 /*-----------------------------------------------------------------*/
8301 /* genPointerGet - generate code for pointer get */
8302 /*-----------------------------------------------------------------*/
8303 static void genPointerGet (iCode *ic)
8305 operand *left, *result ;
8306 sym_link *type, *etype;
8309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8312 result = IC_RESULT(ic) ;
8314 /* depending on the type of pointer we need to
8315 move it to the correct pointer register */
8316 type = operandType(left);
8317 etype = getSpec(type);
8319 if (IS_PTR_CONST(type))
8320 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8322 /* if left is of type of pointer then it is simple */
8323 if (IS_PTR(type) && !IS_FUNC(type->next))
8324 p_type = DCL_TYPE(type);
8326 /* we have to go by the storage class */
8327 p_type = PTR_TYPE(SPEC_OCLS(etype));
8329 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8331 if (SPEC_OCLS(etype)->codesp ) {
8332 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8333 //p_type = CPOINTER ;
8336 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8337 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8338 /*p_type = FPOINTER ;*/
8340 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8341 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8342 /* p_type = PPOINTER; */
8344 if (SPEC_OCLS(etype) == idata )
8345 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8346 /* p_type = IPOINTER; */
8348 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8349 /* p_type = POINTER ; */
8352 /* now that we have the pointer type we assign
8353 the pointer values */
8358 genNearPointerGet (left,result,ic);
8362 genPagedPointerGet(left,result,ic);
8366 genFarPointerGet (left,result,ic);
8370 genConstPointerGet (left,result,ic);
8371 //pic14_emitcodePointerGet (left,result,ic);
8375 if (IS_PTR_CONST(type))
8376 genConstPointerGet (left,result,ic);
8378 genGenPointerGet (left,result,ic);
8384 /*-----------------------------------------------------------------*/
8385 /* genPackBits - generates code for packed bit storage */
8386 /*-----------------------------------------------------------------*/
8387 static void genPackBits (sym_link *etype ,
8389 char *rname, int p_type)
8397 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8398 blen = SPEC_BLEN(etype);
8399 bstr = SPEC_BSTR(etype);
8401 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8404 /* if the bit lenth is less than or */
8405 /* it exactly fits a byte then */
8406 if (SPEC_BLEN(etype) <= 8 ) {
8407 shCount = SPEC_BSTR(etype) ;
8409 /* shift left acc */
8412 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8417 pic14_emitcode ("mov","b,a");
8418 pic14_emitcode("mov","a,@%s",rname);
8422 pic14_emitcode ("mov","b,a");
8423 pic14_emitcode("movx","a,@dptr");
8427 pic14_emitcode ("push","b");
8428 pic14_emitcode ("push","acc");
8429 pic14_emitcode ("lcall","__gptrget");
8430 pic14_emitcode ("pop","b");
8434 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8435 ((unsigned char)(0xFF << (blen+bstr)) |
8436 (unsigned char)(0xFF >> (8-bstr)) ) );
8437 pic14_emitcode ("orl","a,b");
8438 if (p_type == GPOINTER)
8439 pic14_emitcode("pop","b");
8445 pic14_emitcode("mov","@%s,a",rname);
8449 pic14_emitcode("movx","@dptr,a");
8453 DEBUGpic14_emitcode(";lcall","__gptrput");
8458 if ( SPEC_BLEN(etype) <= 8 )
8461 pic14_emitcode("inc","%s",rname);
8462 rLen = SPEC_BLEN(etype) ;
8464 /* now generate for lengths greater than one byte */
8467 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8477 pic14_emitcode("mov","@%s,a",rname);
8479 pic14_emitcode("mov","@%s,%s",rname,l);
8484 pic14_emitcode("movx","@dptr,a");
8489 DEBUGpic14_emitcode(";lcall","__gptrput");
8492 pic14_emitcode ("inc","%s",rname);
8497 /* last last was not complete */
8499 /* save the byte & read byte */
8502 pic14_emitcode ("mov","b,a");
8503 pic14_emitcode("mov","a,@%s",rname);
8507 pic14_emitcode ("mov","b,a");
8508 pic14_emitcode("movx","a,@dptr");
8512 pic14_emitcode ("push","b");
8513 pic14_emitcode ("push","acc");
8514 pic14_emitcode ("lcall","__gptrget");
8515 pic14_emitcode ("pop","b");
8519 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8520 pic14_emitcode ("orl","a,b");
8523 if (p_type == GPOINTER)
8524 pic14_emitcode("pop","b");
8529 pic14_emitcode("mov","@%s,a",rname);
8533 pic14_emitcode("movx","@dptr,a");
8537 DEBUGpic14_emitcode(";lcall","__gptrput");
8541 /*-----------------------------------------------------------------*/
8542 /* genDataPointerSet - remat pointer to data space */
8543 /*-----------------------------------------------------------------*/
8544 static void genDataPointerSet(operand *right,
8548 int size, offset = 0 ;
8549 char *l, buffer[256];
8551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8552 aopOp(right,ic,FALSE);
8554 l = aopGet(AOP(result),0,FALSE,TRUE);
8555 size = AOP_SIZE(right);
8557 if ( AOP_TYPE(result) == AOP_PCODE) {
8558 fprintf(stderr,"genDataPointerSet %s, %d\n",
8559 AOP(result)->aopu.pcop->name,
8560 PCOI(AOP(result)->aopu.pcop)->offset);
8564 // tsd, was l+1 - the underline `_' prefix was being stripped
8567 sprintf(buffer,"(%s + %d)",l,offset);
8568 fprintf(stderr,"oops %s\n",buffer);
8570 sprintf(buffer,"%s",l);
8572 if (AOP_TYPE(right) == AOP_LIT) {
8573 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8574 lit = lit >> (8*offset);
8576 pic14_emitcode("movlw","%d",lit);
8577 pic14_emitcode("movwf","%s",buffer);
8579 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8580 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8581 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8584 pic14_emitcode("clrf","%s",buffer);
8585 //emitpcode(POC_CLRF, popRegFromString(buffer));
8586 emitpcode(POC_CLRF, popGet(AOP(result),0));
8589 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8590 pic14_emitcode("movwf","%s",buffer);
8592 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8593 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8594 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8601 freeAsmop(right,NULL,ic,TRUE);
8602 freeAsmop(result,NULL,ic,TRUE);
8605 /*-----------------------------------------------------------------*/
8606 /* genNearPointerSet - pic14_emitcode for near pointer put */
8607 /*-----------------------------------------------------------------*/
8608 static void genNearPointerSet (operand *right,
8615 sym_link *ptype = operandType(result);
8618 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8619 retype= getSpec(operandType(right));
8621 aopOp(result,ic,FALSE);
8624 /* if the result is rematerializable &
8625 in data space & not a bit variable */
8626 //if (AOP_TYPE(result) == AOP_IMMD &&
8627 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8628 DCL_TYPE(ptype) == POINTER &&
8629 !IS_BITFIELD(retype)) {
8630 genDataPointerSet (right,result,ic);
8631 freeAsmop(result,NULL,ic,TRUE);
8635 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8636 aopOp(right,ic,FALSE);
8637 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8639 /* if the value is already in a pointer register
8640 then don't need anything more */
8641 if (!AOP_INPREG(AOP(result))) {
8642 /* otherwise get a free pointer register */
8643 //aop = newAsmop(0);
8644 //preg = getFreePtr(ic,&aop,FALSE);
8645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8646 //pic14_emitcode("mov","%s,%s",
8648 // aopGet(AOP(result),0,FALSE,TRUE));
8649 //rname = preg->name ;
8650 //pic14_emitcode("movwf","fsr");
8651 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8652 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8653 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8654 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8658 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8661 /* if bitfield then unpack the bits */
8662 if (IS_BITFIELD(retype)) {
8663 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8664 "The programmer is obviously confused");
8665 //genPackBits (retype,right,rname,POINTER);
8669 /* we have can just get the values */
8670 int size = AOP_SIZE(right);
8673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8675 l = aopGet(AOP(right),offset,FALSE,TRUE);
8678 //pic14_emitcode("mov","@%s,a",rname);
8679 pic14_emitcode("movf","indf,w ;1");
8682 if (AOP_TYPE(right) == AOP_LIT) {
8683 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8685 pic14_emitcode("movlw","%s",l);
8686 pic14_emitcode("movwf","indf ;2");
8688 pic14_emitcode("clrf","indf");
8690 pic14_emitcode("movf","%s,w",l);
8691 pic14_emitcode("movwf","indf ;2");
8693 //pic14_emitcode("mov","@%s,%s",rname,l);
8696 pic14_emitcode("incf","fsr,f ;3");
8697 //pic14_emitcode("inc","%s",rname);
8702 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8703 /* now some housekeeping stuff */
8705 /* we had to allocate for this iCode */
8706 freeAsmop(NULL,aop,ic,TRUE);
8708 /* we did not allocate which means left
8709 already in a pointer register, then
8710 if size > 0 && this could be used again
8711 we have to point it back to where it
8713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8714 if (AOP_SIZE(right) > 1 &&
8715 !OP_SYMBOL(result)->remat &&
8716 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8718 int size = AOP_SIZE(right) - 1;
8720 pic14_emitcode("decf","fsr,f");
8721 //pic14_emitcode("dec","%s",rname);
8725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8728 freeAsmop(right,NULL,ic,TRUE);
8729 freeAsmop(result,NULL,ic,TRUE);
8732 /*-----------------------------------------------------------------*/
8733 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8734 /*-----------------------------------------------------------------*/
8735 static void genPagedPointerSet (operand *right,
8744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8746 retype= getSpec(operandType(right));
8748 aopOp(result,ic,FALSE);
8750 /* if the value is already in a pointer register
8751 then don't need anything more */
8752 if (!AOP_INPREG(AOP(result))) {
8753 /* otherwise get a free pointer register */
8755 preg = getFreePtr(ic,&aop,FALSE);
8756 pic14_emitcode("mov","%s,%s",
8758 aopGet(AOP(result),0,FALSE,TRUE));
8759 rname = preg->name ;
8761 rname = aopGet(AOP(result),0,FALSE,FALSE);
8763 freeAsmop(result,NULL,ic,TRUE);
8764 aopOp (right,ic,FALSE);
8766 /* if bitfield then unpack the bits */
8767 if (IS_BITFIELD(retype))
8768 genPackBits (retype,right,rname,PPOINTER);
8770 /* we have can just get the values */
8771 int size = AOP_SIZE(right);
8775 l = aopGet(AOP(right),offset,FALSE,TRUE);
8778 pic14_emitcode("movx","@%s,a",rname);
8781 pic14_emitcode("inc","%s",rname);
8787 /* now some housekeeping stuff */
8789 /* we had to allocate for this iCode */
8790 freeAsmop(NULL,aop,ic,TRUE);
8792 /* we did not allocate which means left
8793 already in a pointer register, then
8794 if size > 0 && this could be used again
8795 we have to point it back to where it
8797 if (AOP_SIZE(right) > 1 &&
8798 !OP_SYMBOL(result)->remat &&
8799 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8801 int size = AOP_SIZE(right) - 1;
8803 pic14_emitcode("dec","%s",rname);
8808 freeAsmop(right,NULL,ic,TRUE);
8813 /*-----------------------------------------------------------------*/
8814 /* genFarPointerSet - set value from far space */
8815 /*-----------------------------------------------------------------*/
8816 static void genFarPointerSet (operand *right,
8817 operand *result, iCode *ic)
8820 sym_link *retype = getSpec(operandType(right));
8822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8823 aopOp(result,ic,FALSE);
8825 /* if the operand is already in dptr
8826 then we do nothing else we move the value to dptr */
8827 if (AOP_TYPE(result) != AOP_STR) {
8828 /* if this is remateriazable */
8829 if (AOP_TYPE(result) == AOP_IMMD)
8830 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8831 else { /* we need to get it byte by byte */
8832 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8833 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8834 if (options.model == MODEL_FLAT24)
8836 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8840 /* so dptr know contains the address */
8841 freeAsmop(result,NULL,ic,TRUE);
8842 aopOp(right,ic,FALSE);
8844 /* if bit then unpack */
8845 if (IS_BITFIELD(retype))
8846 genPackBits(retype,right,"dptr",FPOINTER);
8848 size = AOP_SIZE(right);
8852 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8854 pic14_emitcode("movx","@dptr,a");
8856 pic14_emitcode("inc","dptr");
8860 freeAsmop(right,NULL,ic,TRUE);
8863 /*-----------------------------------------------------------------*/
8864 /* genGenPointerSet - set value from generic pointer space */
8865 /*-----------------------------------------------------------------*/
8866 static void genGenPointerSet (operand *right,
8867 operand *result, iCode *ic)
8870 sym_link *retype = getSpec(operandType(right));
8872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8874 aopOp(result,ic,FALSE);
8875 aopOp(right,ic,FALSE);
8876 size = AOP_SIZE(right);
8878 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8880 /* if the operand is already in dptr
8881 then we do nothing else we move the value to dptr */
8882 if (AOP_TYPE(result) != AOP_STR) {
8883 /* if this is remateriazable */
8884 if (AOP_TYPE(result) == AOP_IMMD) {
8885 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8886 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8888 else { /* we need to get it byte by byte */
8889 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8890 size = AOP_SIZE(right);
8893 /* hack hack! see if this the FSR. If so don't load W */
8894 if(AOP_TYPE(right) != AOP_ACC) {
8897 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8898 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8900 if(AOP_SIZE(result) > 1) {
8901 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8902 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8903 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8908 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8910 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8911 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8915 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8916 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8919 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8926 if(aopIdx(AOP(result),0) != 4) {
8928 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8932 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8937 /* so dptr know contains the address */
8940 /* if bit then unpack */
8941 if (IS_BITFIELD(retype))
8942 genPackBits(retype,right,"dptr",GPOINTER);
8944 size = AOP_SIZE(right);
8947 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8951 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8952 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8954 if (AOP_TYPE(right) == AOP_LIT)
8955 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8957 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8959 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8966 freeAsmop(right,NULL,ic,TRUE);
8967 freeAsmop(result,NULL,ic,TRUE);
8970 /*-----------------------------------------------------------------*/
8971 /* genPointerSet - stores the value into a pointer location */
8972 /*-----------------------------------------------------------------*/
8973 static void genPointerSet (iCode *ic)
8975 operand *right, *result ;
8976 sym_link *type, *etype;
8979 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8981 right = IC_RIGHT(ic);
8982 result = IC_RESULT(ic) ;
8984 /* depending on the type of pointer we need to
8985 move it to the correct pointer register */
8986 type = operandType(result);
8987 etype = getSpec(type);
8988 /* if left is of type of pointer then it is simple */
8989 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8990 p_type = DCL_TYPE(type);
8993 /* we have to go by the storage class */
8994 p_type = PTR_TYPE(SPEC_OCLS(etype));
8996 /* if (SPEC_OCLS(etype)->codesp ) { */
8997 /* p_type = CPOINTER ; */
9000 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9001 /* p_type = FPOINTER ; */
9003 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9004 /* p_type = PPOINTER ; */
9006 /* if (SPEC_OCLS(etype) == idata ) */
9007 /* p_type = IPOINTER ; */
9009 /* p_type = POINTER ; */
9012 /* now that we have the pointer type we assign
9013 the pointer values */
9018 genNearPointerSet (right,result,ic);
9022 genPagedPointerSet (right,result,ic);
9026 genFarPointerSet (right,result,ic);
9030 genGenPointerSet (right,result,ic);
9034 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9035 "genPointerSet: illegal pointer type");
9039 /*-----------------------------------------------------------------*/
9040 /* genIfx - generate code for Ifx statement */
9041 /*-----------------------------------------------------------------*/
9042 static void genIfx (iCode *ic, iCode *popIc)
9044 operand *cond = IC_COND(ic);
9047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9049 aopOp(cond,ic,FALSE);
9051 /* get the value into acc */
9052 if (AOP_TYPE(cond) != AOP_CRY)
9053 pic14_toBoolean(cond);
9056 /* the result is now in the accumulator */
9057 freeAsmop(cond,NULL,ic,TRUE);
9059 /* if there was something to be popped then do it */
9063 /* if the condition is a bit variable */
9064 if (isbit && IS_ITEMP(cond) &&
9066 genIfxJump(ic,SPIL_LOC(cond)->rname);
9067 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9070 if (isbit && !IS_ITEMP(cond))
9071 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9079 /*-----------------------------------------------------------------*/
9080 /* genAddrOf - generates code for address of */
9081 /*-----------------------------------------------------------------*/
9082 static void genAddrOf (iCode *ic)
9084 operand *right, *result, *left;
9087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9090 //aopOp(IC_RESULT(ic),ic,FALSE);
9092 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9093 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9094 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9096 DEBUGpic14_AopType(__LINE__,left,right,result);
9098 size = AOP_SIZE(IC_RESULT(ic));
9102 /* fixing bug #863624, reported from (errolv) */
9103 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9104 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9107 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9108 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9113 freeAsmop(left,NULL,ic,FALSE);
9114 freeAsmop(result,NULL,ic,TRUE);
9119 /*-----------------------------------------------------------------*/
9120 /* genFarFarAssign - assignment when both are in far space */
9121 /*-----------------------------------------------------------------*/
9122 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9124 int size = AOP_SIZE(right);
9127 /* first push the right side on to the stack */
9129 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9131 pic14_emitcode ("push","acc");
9134 freeAsmop(right,NULL,ic,FALSE);
9135 /* now assign DPTR to result */
9136 aopOp(result,ic,FALSE);
9137 size = AOP_SIZE(result);
9139 pic14_emitcode ("pop","acc");
9140 aopPut(AOP(result),"a",--offset);
9142 freeAsmop(result,NULL,ic,FALSE);
9147 /*-----------------------------------------------------------------*/
9148 /* genAssign - generate code for assignment */
9149 /*-----------------------------------------------------------------*/
9150 static void genAssign (iCode *ic)
9152 operand *result, *right;
9153 int size, offset,know_W;
9154 unsigned long lit = 0L;
9156 result = IC_RESULT(ic);
9157 right = IC_RIGHT(ic) ;
9159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9161 /* if they are the same */
9162 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9165 aopOp(right,ic,FALSE);
9166 aopOp(result,ic,TRUE);
9168 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9170 /* if they are the same registers */
9171 if (pic14_sameRegs(AOP(right),AOP(result)))
9174 /* if the result is a bit */
9175 if (AOP_TYPE(result) == AOP_CRY) {
9177 /* if the right size is a literal then
9178 we know what the value is */
9179 if (AOP_TYPE(right) == AOP_LIT) {
9181 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9182 popGet(AOP(result),0));
9184 if (((int) operandLitValue(right)))
9185 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9186 AOP(result)->aopu.aop_dir,
9187 AOP(result)->aopu.aop_dir);
9189 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9190 AOP(result)->aopu.aop_dir,
9191 AOP(result)->aopu.aop_dir);
9195 /* the right is also a bit variable */
9196 if (AOP_TYPE(right) == AOP_CRY) {
9197 emitpcode(POC_BCF, popGet(AOP(result),0));
9198 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9199 emitpcode(POC_BSF, popGet(AOP(result),0));
9201 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9202 AOP(result)->aopu.aop_dir,
9203 AOP(result)->aopu.aop_dir);
9204 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9205 AOP(right)->aopu.aop_dir,
9206 AOP(right)->aopu.aop_dir);
9207 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9208 AOP(result)->aopu.aop_dir,
9209 AOP(result)->aopu.aop_dir);
9214 emitpcode(POC_BCF, popGet(AOP(result),0));
9215 pic14_toBoolean(right);
9217 emitpcode(POC_BSF, popGet(AOP(result),0));
9218 //aopPut(AOP(result),"a",0);
9222 /* bit variables done */
9224 size = AOP_SIZE(result);
9226 if(AOP_TYPE(right) == AOP_LIT)
9227 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9229 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9231 if(aopIdx(AOP(result),0) == 4) {
9232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9233 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9234 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9237 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9243 if(AOP_TYPE(right) == AOP_LIT) {
9245 if(know_W != (int)(lit&0xff))
9246 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9248 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9250 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9254 } else if (AOP_TYPE(right) == AOP_CRY) {
9255 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9257 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9258 emitpcode(POC_INCF, popGet(AOP(result),0));
9261 mov2w (AOP(right), offset);
9262 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9270 freeAsmop (right,NULL,ic,FALSE);
9271 freeAsmop (result,NULL,ic,TRUE);
9274 /*-----------------------------------------------------------------*/
9275 /* genJumpTab - genrates code for jump table */
9276 /*-----------------------------------------------------------------*/
9277 static void genJumpTab (iCode *ic)
9282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9284 aopOp(IC_JTCOND(ic),ic,FALSE);
9285 /* get the condition into accumulator */
9286 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9288 /* multiply by three */
9289 pic14_emitcode("add","a,acc");
9290 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9292 jtab = newiTempLabel(NULL);
9293 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9294 pic14_emitcode("jmp","@a+dptr");
9295 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9297 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9298 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9299 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9300 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9302 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9303 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9304 emitpLabel(jtab->key);
9306 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9308 /* now generate the jump labels */
9309 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9310 jtab = setNextItem(IC_JTLABELS(ic))) {
9311 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9312 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9318 /*-----------------------------------------------------------------*/
9319 /* genMixedOperation - gen code for operators between mixed types */
9320 /*-----------------------------------------------------------------*/
9322 TSD - Written for the PIC port - but this unfortunately is buggy.
9323 This routine is good in that it is able to efficiently promote
9324 types to different (larger) sizes. Unfortunately, the temporary
9325 variables that are optimized out by this routine are sometimes
9326 used in other places. So until I know how to really parse the
9327 iCode tree, I'm going to not be using this routine :(.
9329 static int genMixedOperation (iCode *ic)
9332 operand *result = IC_RESULT(ic);
9333 sym_link *ctype = operandType(IC_LEFT(ic));
9334 operand *right = IC_RIGHT(ic);
9340 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9342 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9348 nextright = IC_RIGHT(nextic);
9349 nextleft = IC_LEFT(nextic);
9350 nextresult = IC_RESULT(nextic);
9352 aopOp(right,ic,FALSE);
9353 aopOp(result,ic,FALSE);
9354 aopOp(nextright, nextic, FALSE);
9355 aopOp(nextleft, nextic, FALSE);
9356 aopOp(nextresult, nextic, FALSE);
9358 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9364 pic14_emitcode(";remove right +","");
9366 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9372 pic14_emitcode(";remove left +","");
9376 big = AOP_SIZE(nextleft);
9377 small = AOP_SIZE(nextright);
9379 switch(nextic->op) {
9382 pic14_emitcode(";optimize a +","");
9383 /* if unsigned or not an integral type */
9384 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9385 pic14_emitcode(";add a bit to something","");
9388 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9390 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9391 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9392 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9394 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9402 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9403 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9404 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9407 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9409 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9410 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9411 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9412 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9413 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9416 pic14_emitcode("rlf","known_zero,w");
9423 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9424 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9425 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9427 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9437 freeAsmop(right,NULL,ic,TRUE);
9438 freeAsmop(result,NULL,ic,TRUE);
9439 freeAsmop(nextright,NULL,ic,TRUE);
9440 freeAsmop(nextleft,NULL,ic,TRUE);
9442 nextic->generated = 1;
9449 /*-----------------------------------------------------------------*/
9450 /* genCast - gen code for casting */
9451 /*-----------------------------------------------------------------*/
9452 static void genCast (iCode *ic)
9454 operand *result = IC_RESULT(ic);
9455 sym_link *ctype = operandType(IC_LEFT(ic));
9456 sym_link *rtype = operandType(IC_RIGHT(ic));
9457 operand *right = IC_RIGHT(ic);
9460 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9461 /* if they are equivalent then do nothing */
9462 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9465 aopOp(right,ic,FALSE) ;
9466 aopOp(result,ic,FALSE);
9468 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9470 /* if the result is a bit */
9471 if (AOP_TYPE(result) == AOP_CRY) {
9472 /* if the right size is a literal then
9473 we know what the value is */
9474 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9475 if (AOP_TYPE(right) == AOP_LIT) {
9477 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9478 popGet(AOP(result),0));
9480 if (((int) operandLitValue(right)))
9481 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9482 AOP(result)->aopu.aop_dir,
9483 AOP(result)->aopu.aop_dir);
9485 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9486 AOP(result)->aopu.aop_dir,
9487 AOP(result)->aopu.aop_dir);
9492 /* the right is also a bit variable */
9493 if (AOP_TYPE(right) == AOP_CRY) {
9496 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9498 pic14_emitcode("clrc","");
9499 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9500 AOP(right)->aopu.aop_dir,
9501 AOP(right)->aopu.aop_dir);
9502 aopPut(AOP(result),"c",0);
9507 if (AOP_TYPE(right) == AOP_REG) {
9508 emitpcode(POC_BCF, popGet(AOP(result),0));
9509 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9510 emitpcode(POC_BSF, popGet(AOP(result),0));
9512 pic14_toBoolean(right);
9513 aopPut(AOP(result),"a",0);
9517 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9519 size = AOP_SIZE(result);
9521 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9523 emitpcode(POC_CLRF, popGet(AOP(result),0));
9524 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9525 emitpcode(POC_INCF, popGet(AOP(result),0));
9528 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9533 /* if they are the same size : or less */
9534 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9536 /* if they are in the same place */
9537 if (pic14_sameRegs(AOP(right),AOP(result)))
9540 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9541 if (IS_PTR_CONST(rtype))
9542 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9543 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9544 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9546 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9547 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9548 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9549 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9550 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9551 if(AOP_SIZE(result) <2)
9552 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9556 /* if they in different places then copy */
9557 size = AOP_SIZE(result);
9560 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9561 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9563 //aopPut(AOP(result),
9564 // aopGet(AOP(right),offset,FALSE,FALSE),
9574 /* if the result is of type pointer */
9575 if (IS_PTR(ctype)) {
9578 sym_link *type = operandType(right);
9579 sym_link *etype = getSpec(type);
9580 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9582 /* pointer to generic pointer */
9583 if (IS_GENPTR(ctype)) {
9587 p_type = DCL_TYPE(type);
9589 /* we have to go by the storage class */
9590 p_type = PTR_TYPE(SPEC_OCLS(etype));
9592 /* if (SPEC_OCLS(etype)->codesp ) */
9593 /* p_type = CPOINTER ; */
9595 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9596 /* p_type = FPOINTER ; */
9598 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9599 /* p_type = PPOINTER; */
9601 /* if (SPEC_OCLS(etype) == idata ) */
9602 /* p_type = IPOINTER ; */
9604 /* p_type = POINTER ; */
9607 /* the first two bytes are known */
9608 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9609 size = GPTRSIZE - 1;
9612 if(offset < AOP_SIZE(right)) {
9613 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9614 if ((AOP_TYPE(right) == AOP_PCODE) &&
9615 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9616 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9617 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9620 aopGet(AOP(right),offset,FALSE,FALSE),
9624 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9627 /* the last byte depending on type */
9631 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9634 pic14_emitcode(";BUG!? ","%d",__LINE__);
9638 pic14_emitcode(";BUG!? ","%d",__LINE__);
9642 pic14_emitcode(";BUG!? ","%d",__LINE__);
9647 /* this should never happen */
9648 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9649 "got unknown pointer type");
9652 //aopPut(AOP(result),l, GPTRSIZE - 1);
9656 /* just copy the pointers */
9657 size = AOP_SIZE(result);
9661 aopGet(AOP(right),offset,FALSE,FALSE),
9670 /* so we now know that the size of destination is greater
9671 than the size of the source.
9672 Now, if the next iCode is an operator then we might be
9673 able to optimize the operation without performing a cast.
9675 if(genMixedOperation(ic))
9678 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9680 /* we move to result for the size of source */
9681 size = AOP_SIZE(right);
9684 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9685 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9689 /* now depending on the sign of the destination */
9690 size = AOP_SIZE(result) - AOP_SIZE(right);
9691 /* if unsigned or not an integral type */
9692 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9694 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9696 /* we need to extend the sign :{ */
9699 /* Save one instruction of casting char to int */
9700 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9701 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9702 emitpcode(POC_DECF, popGet(AOP(result),offset));
9704 emitpcodeNULLop(POC_CLRW);
9707 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9709 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9711 emitpcode(POC_MOVLW, popGetLit(0xff));
9714 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9719 freeAsmop(right,NULL,ic,TRUE);
9720 freeAsmop(result,NULL,ic,TRUE);
9724 /*-----------------------------------------------------------------*/
9725 /* genDjnz - generate decrement & jump if not zero instrucion */
9726 /*-----------------------------------------------------------------*/
9727 static int genDjnz (iCode *ic, iCode *ifx)
9730 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9735 /* if the if condition has a false label
9736 then we cannot save */
9740 /* if the minus is not of the form
9742 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9743 !IS_OP_LITERAL(IC_RIGHT(ic)))
9746 if (operandLitValue(IC_RIGHT(ic)) != 1)
9749 /* if the size of this greater than one then no
9751 if (getSize(operandType(IC_RESULT(ic))) > 1)
9754 /* otherwise we can save BIG */
9755 lbl = newiTempLabel(NULL);
9756 lbl1= newiTempLabel(NULL);
9758 aopOp(IC_RESULT(ic),ic,FALSE);
9760 if (IS_AOP_PREG(IC_RESULT(ic))) {
9761 pic14_emitcode("dec","%s",
9762 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9763 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9764 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9768 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9769 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9771 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9772 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9775 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9776 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9777 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9778 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9781 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9786 /*-----------------------------------------------------------------*/
9787 /* genReceive - generate code for a receive iCode */
9788 /*-----------------------------------------------------------------*/
9789 static void genReceive (iCode *ic)
9791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9793 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9794 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9795 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9797 int size = getSize(operandType(IC_RESULT(ic)));
9798 int offset = fReturnSizePic - size;
9800 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9801 fReturn[fReturnSizePic - offset - 1] : "acc"));
9804 aopOp(IC_RESULT(ic),ic,FALSE);
9805 size = AOP_SIZE(IC_RESULT(ic));
9808 pic14_emitcode ("pop","acc");
9809 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9814 aopOp(IC_RESULT(ic),ic,FALSE);
9816 assignResultValue(IC_RESULT(ic));
9819 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9822 /*-----------------------------------------------------------------*/
9823 /* genDummyRead - generate code for dummy read of volatiles */
9824 /*-----------------------------------------------------------------*/
9826 genDummyRead (iCode * ic)
9828 pic14_emitcode ("; genDummyRead","");
9829 pic14_emitcode ("; not implemented","");
9834 /*-----------------------------------------------------------------*/
9835 /* genpic14Code - generate code for pic14 based controllers */
9836 /*-----------------------------------------------------------------*/
9838 * At this point, ralloc.c has gone through the iCode and attempted
9839 * to optimize in a way suitable for a PIC. Now we've got to generate
9840 * PIC instructions that correspond to the iCode.
9842 * Once the instructions are generated, we'll pass through both the
9843 * peep hole optimizer and the pCode optimizer.
9844 *-----------------------------------------------------------------*/
9846 void genpic14Code (iCode *lic)
9851 lineHead = lineCurr = NULL;
9853 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9856 /* if debug information required */
9857 if (options.debug && currFunc) {
9859 debugFile->writeFunction (currFunc, lic);
9864 for (ic = lic ; ic ; ic = ic->next ) {
9866 DEBUGpic14_emitcode(";ic","");
9867 if ( cln != ic->lineno ) {
9868 if ( options.debug ) {
9869 debugFile->writeCLine (ic);
9872 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9873 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9874 printCLine(ic->filename, ic->lineno));
9876 if (!options.noCcodeInAsm) {
9878 newpCodeCSource(ic->lineno,
9880 printCLine(ic->filename, ic->lineno)));
9886 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9888 /* if the result is marked as
9889 spilt and rematerializable or code for
9890 this has already been generated then
9892 if (resultRemat(ic) || ic->generated )
9895 /* depending on the operation */
9914 /* IPOP happens only when trying to restore a
9915 spilt live range, if there is an ifx statement
9916 following this pop then the if statement might
9917 be using some of the registers being popped which
9918 would destory the contents of the register so
9919 we need to check for this condition and handle it */
9921 ic->next->op == IFX &&
9922 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9923 genIfx (ic->next,ic);
9941 genEndFunction (ic);
9961 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9978 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9982 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9989 /* note these two are xlated by algebraic equivalence
9990 during parsing SDCC.y */
9991 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9992 "got '>=' or '<=' shouldn't have come here");
9996 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10008 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10012 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10016 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10040 genRightShift (ic);
10043 case GET_VALUE_AT_ADDRESS:
10048 if (POINTER_SET(ic))
10075 addSet(&_G.sendSet,ic);
10078 case DUMMY_READ_VOLATILE:
10088 /* now we are ready to call the
10089 peep hole optimizer */
10090 if (!options.nopeep) {
10091 peepHole (&lineHead);
10093 /* now do the actual printing */
10094 printLine (lineHead,codeOutFile);
10097 DFPRINTF((stderr,"printing pBlock\n\n"));
10098 printpBlock(stdout,pb);