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;
1347 sprintf(s,"(%s + %d)",
1351 sprintf(s,"%s",aop->aopu.aop_dir);
1352 pcop->name = Safe_calloc(1,strlen(s)+1);
1353 strcpy(pcop->name,s);
1355 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1356 strcpy(pcop->name,aop->aopu.aop_dir);
1357 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1358 if(PCOR(pcop)->r == NULL) {
1359 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1360 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1361 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1363 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1365 PCOR(pcop)->instance = offset;
1372 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1374 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1375 PCOR(pcop)->rIdx = rIdx;
1376 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1377 PCOR(pcop)->r->wasUsed=1;
1378 PCOR(pcop)->r->isFree=0;
1380 PCOR(pcop)->instance = offset;
1381 pcop->type = PCOR(pcop)->r->pc_type;
1382 //rs = aop->aopu.aop_reg[offset]->name;
1383 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1388 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1389 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1390 //if(PCOR(pcop)->r == NULL)
1391 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1395 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1398 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1399 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1401 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1402 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1403 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1404 pcop->type = PCOR(pcop)->r->pc_type;
1405 pcop->name = PCOR(pcop)->r->name;
1411 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1413 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1414 pcop = pCodeOpCopy(aop->aopu.pcop);
1415 PCOI(pcop)->offset = offset;
1419 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1420 "popGet got unsupported aop->type");
1423 /*-----------------------------------------------------------------*/
1424 /* aopPut - puts a string for a aop */
1425 /*-----------------------------------------------------------------*/
1426 void aopPut (asmop *aop, char *s, int offset)
1431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1433 if (aop->size && offset > ( aop->size - 1)) {
1434 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1435 "aopPut got offset > aop->size");
1439 /* will assign value to value */
1440 /* depending on where it is ofcourse */
1441 switch (aop->type) {
1444 sprintf(d,"(%s + %d)",
1445 aop->aopu.aop_dir,offset);
1446 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1449 sprintf(d,"%s",aop->aopu.aop_dir);
1452 DEBUGpic14_emitcode(";","%d",__LINE__);
1454 pic14_emitcode("movf","%s,w",s);
1455 pic14_emitcode("movwf","%s",d);
1458 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1459 if(offset >= aop->size) {
1460 emitpcode(POC_CLRF,popGet(aop,offset));
1463 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1466 emitpcode(POC_MOVWF,popGet(aop,offset));
1473 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1474 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1477 strcmp(s,"r0") == 0 ||
1478 strcmp(s,"r1") == 0 ||
1479 strcmp(s,"r2") == 0 ||
1480 strcmp(s,"r3") == 0 ||
1481 strcmp(s,"r4") == 0 ||
1482 strcmp(s,"r5") == 0 ||
1483 strcmp(s,"r6") == 0 ||
1484 strcmp(s,"r7") == 0 )
1485 pic14_emitcode("mov","%s,%s ; %d",
1486 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1490 if(strcmp(s,"W")==0 )
1491 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1493 pic14_emitcode("movwf","%s",
1494 aop->aopu.aop_reg[offset]->name);
1496 if(strcmp(s,zero)==0) {
1497 emitpcode(POC_CLRF,popGet(aop,offset));
1499 } else if(strcmp(s,"W")==0) {
1500 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1501 pcop->type = PO_GPR_REGISTER;
1503 PCOR(pcop)->rIdx = -1;
1504 PCOR(pcop)->r = NULL;
1506 DEBUGpic14_emitcode(";","%d",__LINE__);
1507 pcop->name = Safe_strdup(s);
1508 emitpcode(POC_MOVFW,pcop);
1509 emitpcode(POC_MOVWF,popGet(aop,offset));
1510 } else if(strcmp(s,one)==0) {
1511 emitpcode(POC_CLRF,popGet(aop,offset));
1512 emitpcode(POC_INCF,popGet(aop,offset));
1514 emitpcode(POC_MOVWF,popGet(aop,offset));
1522 if (aop->type == AOP_DPTR2)
1528 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1529 "aopPut writting to code space");
1533 while (offset > aop->coff) {
1535 pic14_emitcode ("inc","dptr");
1538 while (offset < aop->coff) {
1540 pic14_emitcode("lcall","__decdptr");
1545 /* if not in accumulater */
1548 pic14_emitcode ("movx","@dptr,a");
1550 if (aop->type == AOP_DPTR2)
1558 while (offset > aop->coff) {
1560 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1562 while (offset < aop->coff) {
1564 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1570 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1575 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1577 if (strcmp(s,"r0") == 0 ||
1578 strcmp(s,"r1") == 0 ||
1579 strcmp(s,"r2") == 0 ||
1580 strcmp(s,"r3") == 0 ||
1581 strcmp(s,"r4") == 0 ||
1582 strcmp(s,"r5") == 0 ||
1583 strcmp(s,"r6") == 0 ||
1584 strcmp(s,"r7") == 0 ) {
1586 sprintf(buffer,"a%s",s);
1587 pic14_emitcode("mov","@%s,%s",
1588 aop->aopu.aop_ptr->name,buffer);
1590 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1595 if (strcmp(s,"a") == 0)
1596 pic14_emitcode("push","acc");
1598 pic14_emitcode("push","%s",s);
1603 /* if bit variable */
1604 if (!aop->aopu.aop_dir) {
1605 pic14_emitcode("clr","a");
1606 pic14_emitcode("rlc","a");
1609 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1612 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1615 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1617 lbl = newiTempLabel(NULL);
1619 if (strcmp(s,"a")) {
1622 pic14_emitcode("clr","c");
1623 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1624 pic14_emitcode("cpl","c");
1625 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1626 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1633 if (strcmp(aop->aopu.aop_str[offset],s))
1634 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1639 if (!offset && (strcmp(s,"acc") == 0))
1642 if (strcmp(aop->aopu.aop_str[offset],s))
1643 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1647 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1648 "aopPut got unsupported aop->type");
1654 /*-----------------------------------------------------------------*/
1655 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1656 /*-----------------------------------------------------------------*/
1657 void mov2w (asmop *aop, int offset)
1663 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1665 if ( aop->type == AOP_PCODE ||
1666 aop->type == AOP_LIT ||
1667 aop->type == AOP_IMMD )
1668 emitpcode(POC_MOVLW,popGet(aop,offset));
1670 emitpcode(POC_MOVFW,popGet(aop,offset));
1674 /*-----------------------------------------------------------------*/
1675 /* reAdjustPreg - points a register back to where it should */
1676 /*-----------------------------------------------------------------*/
1677 static void reAdjustPreg (asmop *aop)
1681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1683 if ((size = aop->size) <= 1)
1686 switch (aop->type) {
1690 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1694 if (aop->type == AOP_DPTR2)
1700 pic14_emitcode("lcall","__decdptr");
1703 if (aop->type == AOP_DPTR2)
1715 /*-----------------------------------------------------------------*/
1716 /* opIsGptr: returns non-zero if the passed operand is */
1717 /* a generic pointer type. */
1718 /*-----------------------------------------------------------------*/
1719 static int opIsGptr(operand *op)
1721 sym_link *type = operandType(op);
1723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1724 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1732 /*-----------------------------------------------------------------*/
1733 /* pic14_getDataSize - get the operand data size */
1734 /*-----------------------------------------------------------------*/
1735 int pic14_getDataSize(operand *op)
1737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1740 return AOP_SIZE(op);
1742 // tsd- in the pic port, the genptr size is 1, so this code here
1743 // fails. ( in the 8051 port, the size was 4).
1746 size = AOP_SIZE(op);
1747 if (size == GPTRSIZE)
1749 sym_link *type = operandType(op);
1750 if (IS_GENPTR(type))
1752 /* generic pointer; arithmetic operations
1753 * should ignore the high byte (pointer type).
1756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1763 /*-----------------------------------------------------------------*/
1764 /* pic14_outAcc - output Acc */
1765 /*-----------------------------------------------------------------*/
1766 void pic14_outAcc(operand *result)
1769 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1770 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1773 size = pic14_getDataSize(result);
1775 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1778 /* unsigned or positive */
1780 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1785 /*-----------------------------------------------------------------*/
1786 /* pic14_outBitC - output a bit C */
1787 /*-----------------------------------------------------------------*/
1788 void pic14_outBitC(operand *result)
1791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1792 /* if the result is bit */
1793 if (AOP_TYPE(result) == AOP_CRY)
1794 aopPut(AOP(result),"c",0);
1796 pic14_emitcode("clr","a ; %d", __LINE__);
1797 pic14_emitcode("rlc","a");
1798 pic14_outAcc(result);
1802 /*-----------------------------------------------------------------*/
1803 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1804 /*-----------------------------------------------------------------*/
1805 void pic14_toBoolean(operand *oper)
1807 int size = AOP_SIZE(oper) - 1;
1810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1812 if ( AOP_TYPE(oper) != AOP_ACC) {
1813 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1816 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1821 /*-----------------------------------------------------------------*/
1822 /* genNot - generate code for ! operation */
1823 /*-----------------------------------------------------------------*/
1824 static void genNot (iCode *ic)
1829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1830 /* assign asmOps to operand & result */
1831 aopOp (IC_LEFT(ic),ic,FALSE);
1832 aopOp (IC_RESULT(ic),ic,TRUE);
1834 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1835 /* if in bit space then a special case */
1836 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1837 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1838 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1839 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1841 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1842 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1843 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1848 size = AOP_SIZE(IC_LEFT(ic));
1850 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1851 emitpcode(POC_ANDLW,popGetLit(1));
1852 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1855 pic14_toBoolean(IC_LEFT(ic));
1857 tlbl = newiTempLabel(NULL);
1858 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1859 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1860 pic14_outBitC(IC_RESULT(ic));
1863 /* release the aops */
1864 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1865 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1869 /*-----------------------------------------------------------------*/
1870 /* genCpl - generate code for complement */
1871 /*-----------------------------------------------------------------*/
1872 static void genCpl (iCode *ic)
1874 operand *left, *result;
1878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1879 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1880 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1882 /* if both are in bit space then
1884 if (AOP_TYPE(result) == AOP_CRY &&
1885 AOP_TYPE(left) == AOP_CRY ) {
1887 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1888 pic14_emitcode("cpl","c");
1889 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1893 size = AOP_SIZE(result);
1896 if(AOP_TYPE(left) == AOP_ACC)
1897 emitpcode(POC_XORLW, popGetLit(0xff));
1899 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1901 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1907 /* release the aops */
1908 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1909 freeAsmop(result,NULL,ic,TRUE);
1912 /*-----------------------------------------------------------------*/
1913 /* genUminusFloat - unary minus for floating points */
1914 /*-----------------------------------------------------------------*/
1915 static void genUminusFloat(operand *op,operand *result)
1917 int size ,offset =0 ;
1920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1921 /* for this we just need to flip the
1922 first it then copy the rest in place */
1923 size = AOP_SIZE(op) - 1;
1924 l = aopGet(AOP(op),3,FALSE,FALSE);
1928 pic14_emitcode("cpl","acc.7");
1929 aopPut(AOP(result),"a",3);
1933 aopGet(AOP(op),offset,FALSE,FALSE),
1939 /*-----------------------------------------------------------------*/
1940 /* genUminus - unary minus code generation */
1941 /*-----------------------------------------------------------------*/
1942 static void genUminus (iCode *ic)
1945 sym_link *optype, *rtype;
1948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1950 aopOp(IC_LEFT(ic),ic,FALSE);
1951 aopOp(IC_RESULT(ic),ic,TRUE);
1953 /* if both in bit space then special
1955 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1956 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1958 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1959 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1960 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1965 optype = operandType(IC_LEFT(ic));
1966 rtype = operandType(IC_RESULT(ic));
1968 /* if float then do float stuff */
1969 if (IS_FLOAT(optype)) {
1970 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1974 /* otherwise subtract from zero by taking the 2's complement */
1975 size = AOP_SIZE(IC_LEFT(ic));
1977 for(i=0; i<size; i++) {
1978 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1979 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1981 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1982 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1986 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1987 for(i=1; i<size; i++) {
1989 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1993 /* release the aops */
1994 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1995 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1998 /*-----------------------------------------------------------------*/
1999 /* saveRegisters - will look for a call and save the registers */
2000 /*-----------------------------------------------------------------*/
2001 static void saveRegisters(iCode *lic)
2008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2010 for (ic = lic ; ic ; ic = ic->next)
2011 if (ic->op == CALL || ic->op == PCALL)
2015 fprintf(stderr,"found parameter push with no function call\n");
2019 /* if the registers have been saved already then
2021 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2024 /* find the registers in use at this time
2025 and push them away to safety */
2026 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2030 if (options.useXstack) {
2031 if (bitVectBitValue(rsave,R0_IDX))
2032 pic14_emitcode("mov","b,r0");
2033 pic14_emitcode("mov","r0,%s",spname);
2034 for (i = 0 ; i < pic14_nRegs ; i++) {
2035 if (bitVectBitValue(rsave,i)) {
2037 pic14_emitcode("mov","a,b");
2039 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2040 pic14_emitcode("movx","@r0,a");
2041 pic14_emitcode("inc","r0");
2044 pic14_emitcode("mov","%s,r0",spname);
2045 if (bitVectBitValue(rsave,R0_IDX))
2046 pic14_emitcode("mov","r0,b");
2048 //for (i = 0 ; i < pic14_nRegs ; i++) {
2049 // if (bitVectBitValue(rsave,i))
2050 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2053 dtype = operandType(IC_LEFT(ic));
2054 if (currFunc && dtype &&
2055 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2056 IFFUNC_ISISR(currFunc->type) &&
2059 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2062 /*-----------------------------------------------------------------*/
2063 /* unsaveRegisters - pop the pushed registers */
2064 /*-----------------------------------------------------------------*/
2065 static void unsaveRegisters (iCode *ic)
2070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2071 /* find the registers in use at this time
2072 and push them away to safety */
2073 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2076 if (options.useXstack) {
2077 pic14_emitcode("mov","r0,%s",spname);
2078 for (i = pic14_nRegs ; i >= 0 ; i--) {
2079 if (bitVectBitValue(rsave,i)) {
2080 pic14_emitcode("dec","r0");
2081 pic14_emitcode("movx","a,@r0");
2083 pic14_emitcode("mov","b,a");
2085 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2089 pic14_emitcode("mov","%s,r0",spname);
2090 if (bitVectBitValue(rsave,R0_IDX))
2091 pic14_emitcode("mov","r0,b");
2093 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2094 // if (bitVectBitValue(rsave,i))
2095 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2101 /*-----------------------------------------------------------------*/
2103 /*-----------------------------------------------------------------*/
2104 static void pushSide(operand * oper, int size)
2108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2110 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2111 if (AOP_TYPE(oper) != AOP_REG &&
2112 AOP_TYPE(oper) != AOP_DIR &&
2114 pic14_emitcode("mov","a,%s",l);
2115 pic14_emitcode("push","acc");
2117 pic14_emitcode("push","%s",l);
2122 /*-----------------------------------------------------------------*/
2123 /* assignResultValue - */
2124 /*-----------------------------------------------------------------*/
2125 static void assignResultValue(operand * oper)
2127 int size = AOP_SIZE(oper);
2129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2131 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2134 if (GpsuedoStkPtr++)
2135 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2136 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2141 /*-----------------------------------------------------------------*/
2142 /* genIpush - genrate code for pushing this gets a little complex */
2143 /*-----------------------------------------------------------------*/
2144 static void genIpush (iCode *ic)
2147 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2149 int size, offset = 0 ;
2153 /* if this is not a parm push : ie. it is spill push
2154 and spill push is always done on the local stack */
2155 if (!ic->parmPush) {
2157 /* and the item is spilt then do nothing */
2158 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2161 aopOp(IC_LEFT(ic),ic,FALSE);
2162 size = AOP_SIZE(IC_LEFT(ic));
2163 /* push it on the stack */
2165 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2170 pic14_emitcode("push","%s",l);
2175 /* this is a paramter push: in this case we call
2176 the routine to find the call and save those
2177 registers that need to be saved */
2180 /* then do the push */
2181 aopOp(IC_LEFT(ic),ic,FALSE);
2184 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2185 size = AOP_SIZE(IC_LEFT(ic));
2188 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2189 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2190 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2192 pic14_emitcode("mov","a,%s",l);
2193 pic14_emitcode("push","acc");
2195 pic14_emitcode("push","%s",l);
2198 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2202 /*-----------------------------------------------------------------*/
2203 /* genIpop - recover the registers: can happen only for spilling */
2204 /*-----------------------------------------------------------------*/
2205 static void genIpop (iCode *ic)
2207 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2212 /* if the temp was not pushed then */
2213 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2216 aopOp(IC_LEFT(ic),ic,FALSE);
2217 size = AOP_SIZE(IC_LEFT(ic));
2220 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2223 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2227 /*-----------------------------------------------------------------*/
2228 /* unsaverbank - restores the resgister bank from stack */
2229 /*-----------------------------------------------------------------*/
2230 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2232 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2240 if (options.useXstack) {
2242 r = getFreePtr(ic,&aop,FALSE);
2245 pic14_emitcode("mov","%s,_spx",r->name);
2246 pic14_emitcode("movx","a,@%s",r->name);
2247 pic14_emitcode("mov","psw,a");
2248 pic14_emitcode("dec","%s",r->name);
2251 pic14_emitcode ("pop","psw");
2254 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2255 if (options.useXstack) {
2256 pic14_emitcode("movx","a,@%s",r->name);
2257 //pic14_emitcode("mov","(%s+%d),a",
2258 // regspic14[i].base,8*bank+regspic14[i].offset);
2259 pic14_emitcode("dec","%s",r->name);
2262 pic14_emitcode("pop",""); //"(%s+%d)",
2263 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2266 if (options.useXstack) {
2268 pic14_emitcode("mov","_spx,%s",r->name);
2269 freeAsmop(NULL,aop,ic,TRUE);
2275 /*-----------------------------------------------------------------*/
2276 /* saverbank - saves an entire register bank on the stack */
2277 /*-----------------------------------------------------------------*/
2278 static void saverbank (int bank, iCode *ic, bool pushPsw)
2280 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2287 if (options.useXstack) {
2290 r = getFreePtr(ic,&aop,FALSE);
2291 pic14_emitcode("mov","%s,_spx",r->name);
2295 for (i = 0 ; i < pic14_nRegs ;i++) {
2296 if (options.useXstack) {
2297 pic14_emitcode("inc","%s",r->name);
2298 //pic14_emitcode("mov","a,(%s+%d)",
2299 // regspic14[i].base,8*bank+regspic14[i].offset);
2300 pic14_emitcode("movx","@%s,a",r->name);
2302 pic14_emitcode("push","");// "(%s+%d)",
2303 //regspic14[i].base,8*bank+regspic14[i].offset);
2307 if (options.useXstack) {
2308 pic14_emitcode("mov","a,psw");
2309 pic14_emitcode("movx","@%s,a",r->name);
2310 pic14_emitcode("inc","%s",r->name);
2311 pic14_emitcode("mov","_spx,%s",r->name);
2312 freeAsmop (NULL,aop,ic,TRUE);
2315 pic14_emitcode("push","psw");
2317 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2323 /*-----------------------------------------------------------------*/
2324 /* genCall - generates a call statement */
2325 /*-----------------------------------------------------------------*/
2326 static void genCall (iCode *ic)
2330 unsigned char *name;
2333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2335 /* if caller saves & we have not saved then */
2339 /* if we are calling a function that is not using
2340 the same register bank then we need to save the
2341 destination registers on the stack */
2342 dtype = operandType(IC_LEFT(ic));
2343 if (currFunc && dtype &&
2344 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2345 IFFUNC_ISISR(currFunc->type) &&
2348 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2350 /* if send set is not empty the assign */
2353 /* For the Pic port, there is no data stack.
2354 * So parameters passed to functions are stored
2355 * in registers. (The pCode optimizer will get
2356 * rid of most of these :).
2358 int psuedoStkPtr=-1;
2359 int firstTimeThruLoop = 1;
2361 _G.sendSet = reverseSet(_G.sendSet);
2363 /* First figure how many parameters are getting passed */
2364 for (sic = setFirstItem(_G.sendSet) ; sic ;
2365 sic = setNextItem(_G.sendSet)) {
2367 aopOp(IC_LEFT(sic),sic,FALSE);
2368 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2369 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2372 for (sic = setFirstItem(_G.sendSet) ; sic ;
2373 sic = setNextItem(_G.sendSet)) {
2374 int size, offset = 0;
2376 aopOp(IC_LEFT(sic),sic,FALSE);
2377 size = AOP_SIZE(IC_LEFT(sic));
2380 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2381 AopType(AOP_TYPE(IC_LEFT(sic))));
2383 if(!firstTimeThruLoop) {
2384 /* If this is not the first time we've been through the loop
2385 * then we need to save the parameter in a temporary
2386 * register. The last byte of the last parameter is
2388 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2391 firstTimeThruLoop=0;
2393 mov2w (AOP(IC_LEFT(sic)), offset);
2396 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2401 sym = OP_SYMBOL(IC_LEFT(ic));
2402 name = sym->rname[0] ? sym->rname : sym->name;
2403 isExtern = IS_EXTERN(sym->etype);
2405 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2407 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2409 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2412 /* if we need assign a result value */
2413 if ((IS_ITEMP(IC_RESULT(ic)) &&
2414 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2415 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2416 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2419 aopOp(IC_RESULT(ic),ic,FALSE);
2422 assignResultValue(IC_RESULT(ic));
2424 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2425 AopType(AOP_TYPE(IC_RESULT(ic))));
2427 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2430 /* adjust the stack for parameters if
2432 if (ic->parmBytes) {
2434 if (ic->parmBytes > 3) {
2435 pic14_emitcode("mov","a,%s",spname);
2436 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2437 pic14_emitcode("mov","%s,a",spname);
2439 for ( i = 0 ; i < ic->parmBytes ;i++)
2440 pic14_emitcode("dec","%s",spname);
2444 /* if register bank was saved then pop them */
2446 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2448 /* if we hade saved some registers then unsave them */
2449 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2450 unsaveRegisters (ic);
2455 /*-----------------------------------------------------------------*/
2456 /* genPcall - generates a call by pointer statement */
2457 /*-----------------------------------------------------------------*/
2458 static void genPcall (iCode *ic)
2461 symbol *albl = newiTempLabel(NULL);
2462 symbol *blbl = newiTempLabel(NULL);
2467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2468 /* if caller saves & we have not saved then */
2472 /* if we are calling a function that is not using
2473 the same register bank then we need to save the
2474 destination registers on the stack */
2475 dtype = operandType(IC_LEFT(ic));
2476 if (currFunc && dtype &&
2477 IFFUNC_ISISR(currFunc->type) &&
2478 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2479 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2482 aopOp(left,ic,FALSE);
2483 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2485 pushSide(IC_LEFT(ic), FPTRSIZE);
2487 /* if send set is not empty, assign parameters */
2490 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2491 /* no way to pass args - W always gets used to make the call */
2493 /* first idea - factor out a common helper function and call it.
2494 But don't know how to get it generated only once in its own block
2496 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2499 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2500 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2501 buffer = Safe_calloc(1,strlen(rname)+16);
2502 sprintf(buffer, "%s_goto_helper", rname);
2503 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2507 emitpcode(POC_CALL,popGetLabel(albl->key));
2508 pcop = popGetLabel(blbl->key);
2509 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2510 emitpcode(POC_GOTO,pcop);
2511 emitpLabel(albl->key);
2513 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2515 emitpcode(poc,popGet(AOP(left),1));
2516 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2517 emitpcode(poc,popGet(AOP(left),0));
2518 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2520 emitpLabel(blbl->key);
2522 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2524 /* if we need to assign a result value */
2525 if ((IS_ITEMP(IC_RESULT(ic)) &&
2526 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2527 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2528 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2531 aopOp(IC_RESULT(ic),ic,FALSE);
2534 assignResultValue(IC_RESULT(ic));
2536 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2539 /* if register bank was saved then unsave them */
2540 if (currFunc && dtype &&
2541 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2542 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2544 /* if we hade saved some registers then
2547 unsaveRegisters (ic);
2551 /*-----------------------------------------------------------------*/
2552 /* resultRemat - result is rematerializable */
2553 /*-----------------------------------------------------------------*/
2554 static int resultRemat (iCode *ic)
2556 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2557 if (SKIP_IC(ic) || ic->op == IFX)
2560 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2561 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2562 if (sym->remat && !POINTER_SET(ic))
2569 #if defined(__BORLANDC__) || defined(_MSC_VER)
2570 #define STRCASECMP stricmp
2572 #define STRCASECMP strcasecmp
2576 /*-----------------------------------------------------------------*/
2577 /* inExcludeList - return 1 if the string is in exclude Reg list */
2578 /*-----------------------------------------------------------------*/
2579 static bool inExcludeList(char *s)
2581 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2584 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2585 if (options.excludeRegs[i] &&
2586 STRCASECMP(options.excludeRegs[i],"none") == 0)
2589 for ( i = 0 ; options.excludeRegs[i]; i++) {
2590 if (options.excludeRegs[i] &&
2591 STRCASECMP(s,options.excludeRegs[i]) == 0)
2598 /*-----------------------------------------------------------------*/
2599 /* genFunction - generated code for function entry */
2600 /*-----------------------------------------------------------------*/
2601 static void genFunction (iCode *ic)
2606 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2608 labelOffset += (max_key+4);
2612 /* create the function header */
2613 pic14_emitcode(";","-----------------------------------------");
2614 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2615 pic14_emitcode(";","-----------------------------------------");
2617 pic14_emitcode("","%s:",sym->rname);
2618 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2620 ftype = operandType(IC_LEFT(ic));
2622 /* if critical function then turn interrupts off */
2623 if (IFFUNC_ISCRITICAL(ftype))
2624 pic14_emitcode("clr","ea");
2626 /* here we need to generate the equates for the
2627 register bank if required */
2629 if (FUNC_REGBANK(ftype) != rbank) {
2632 rbank = FUNC_REGBANK(ftype);
2633 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2634 if (strcmp(regspic14[i].base,"0") == 0)
2635 pic14_emitcode("","%s = 0x%02x",
2637 8*rbank+regspic14[i].offset);
2639 pic14_emitcode ("","%s = %s + 0x%02x",
2642 8*rbank+regspic14[i].offset);
2647 /* if this is an interrupt service routine */
2648 if (IFFUNC_ISISR(sym->type)) {
2649 /* already done in pic14createInterruptVect() - delete me
2650 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2651 emitpcodeNULLop(POC_NOP);
2652 emitpcodeNULLop(POC_NOP);
2653 emitpcodeNULLop(POC_NOP);
2655 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2656 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2657 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2658 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2659 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2660 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2661 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2663 pBlockConvert2ISR(pb);
2665 if (!inExcludeList("acc"))
2666 pic14_emitcode ("push","acc");
2667 if (!inExcludeList("b"))
2668 pic14_emitcode ("push","b");
2669 if (!inExcludeList("dpl"))
2670 pic14_emitcode ("push","dpl");
2671 if (!inExcludeList("dph"))
2672 pic14_emitcode ("push","dph");
2673 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2675 pic14_emitcode ("push", "dpx");
2676 /* Make sure we're using standard DPTR */
2677 pic14_emitcode ("push", "dps");
2678 pic14_emitcode ("mov", "dps, #0x00");
2679 if (options.stack10bit)
2681 /* This ISR could conceivably use DPTR2. Better save it. */
2682 pic14_emitcode ("push", "dpl1");
2683 pic14_emitcode ("push", "dph1");
2684 pic14_emitcode ("push", "dpx1");
2687 /* if this isr has no bank i.e. is going to
2688 run with bank 0 , then we need to save more
2690 if (!FUNC_REGBANK(sym->type)) {
2692 /* if this function does not call any other
2693 function then we can be economical and
2694 save only those registers that are used */
2695 if (! IFFUNC_HASFCALL(sym->type)) {
2698 /* if any registers used */
2699 if (sym->regsUsed) {
2700 /* save the registers used */
2701 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2702 if (bitVectBitValue(sym->regsUsed,i) ||
2703 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2704 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2709 /* this function has a function call cannot
2710 determines register usage so we will have the
2712 saverbank(0,ic,FALSE);
2717 /* if callee-save to be used for this function
2718 then save the registers being used in this function */
2719 if (IFFUNC_CALLEESAVES(sym->type)) {
2722 /* if any registers used */
2723 if (sym->regsUsed) {
2724 /* save the registers used */
2725 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2726 if (bitVectBitValue(sym->regsUsed,i) ||
2727 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2728 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2736 /* set the register bank to the desired value */
2737 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2738 pic14_emitcode("push","psw");
2739 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2742 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2744 if (options.useXstack) {
2745 pic14_emitcode("mov","r0,%s",spname);
2746 pic14_emitcode("mov","a,_bp");
2747 pic14_emitcode("movx","@r0,a");
2748 pic14_emitcode("inc","%s",spname);
2752 /* set up the stack */
2753 pic14_emitcode ("push","_bp"); /* save the callers stack */
2755 pic14_emitcode ("mov","_bp,%s",spname);
2758 /* adjust the stack for the function */
2763 werror(W_STACK_OVERFLOW,sym->name);
2765 if (i > 3 && sym->recvSize < 4) {
2767 pic14_emitcode ("mov","a,sp");
2768 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2769 pic14_emitcode ("mov","sp,a");
2774 pic14_emitcode("inc","sp");
2779 pic14_emitcode ("mov","a,_spx");
2780 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2781 pic14_emitcode ("mov","_spx,a");
2786 /*-----------------------------------------------------------------*/
2787 /* genEndFunction - generates epilogue for functions */
2788 /*-----------------------------------------------------------------*/
2789 static void genEndFunction (iCode *ic)
2791 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2795 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2797 pic14_emitcode ("mov","%s,_bp",spname);
2800 /* if use external stack but some variables were
2801 added to the local stack then decrement the
2803 if (options.useXstack && sym->stack) {
2804 pic14_emitcode("mov","a,sp");
2805 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2806 pic14_emitcode("mov","sp,a");
2810 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2811 if (options.useXstack) {
2812 pic14_emitcode("mov","r0,%s",spname);
2813 pic14_emitcode("movx","a,@r0");
2814 pic14_emitcode("mov","_bp,a");
2815 pic14_emitcode("dec","%s",spname);
2819 pic14_emitcode ("pop","_bp");
2823 /* restore the register bank */
2824 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2825 pic14_emitcode ("pop","psw");
2827 if (IFFUNC_ISISR(sym->type)) {
2829 /* now we need to restore the registers */
2830 /* if this isr has no bank i.e. is going to
2831 run with bank 0 , then we need to save more
2833 if (!FUNC_REGBANK(sym->type)) {
2835 /* if this function does not call any other
2836 function then we can be economical and
2837 save only those registers that are used */
2838 if (! IFFUNC_HASFCALL(sym->type)) {
2841 /* if any registers used */
2842 if (sym->regsUsed) {
2843 /* save the registers used */
2844 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2845 if (bitVectBitValue(sym->regsUsed,i) ||
2846 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2847 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2852 /* this function has a function call cannot
2853 determines register usage so we will have the
2855 unsaverbank(0,ic,FALSE);
2859 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2861 if (options.stack10bit)
2863 pic14_emitcode ("pop", "dpx1");
2864 pic14_emitcode ("pop", "dph1");
2865 pic14_emitcode ("pop", "dpl1");
2867 pic14_emitcode ("pop", "dps");
2868 pic14_emitcode ("pop", "dpx");
2870 if (!inExcludeList("dph"))
2871 pic14_emitcode ("pop","dph");
2872 if (!inExcludeList("dpl"))
2873 pic14_emitcode ("pop","dpl");
2874 if (!inExcludeList("b"))
2875 pic14_emitcode ("pop","b");
2876 if (!inExcludeList("acc"))
2877 pic14_emitcode ("pop","acc");
2879 if (IFFUNC_ISCRITICAL(sym->type))
2880 pic14_emitcode("setb","ea");
2883 /* if debug then send end of function */
2884 /* if (options.debug && currFunc) { */
2886 debugFile->writeEndFunction (currFunc, ic, 1);
2889 pic14_emitcode ("reti","");
2890 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2891 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2892 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2893 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2894 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2895 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2896 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2897 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2898 emitpcodeNULLop(POC_RETFIE);
2901 if (IFFUNC_ISCRITICAL(sym->type))
2902 pic14_emitcode("setb","ea");
2904 if (IFFUNC_CALLEESAVES(sym->type)) {
2907 /* if any registers used */
2908 if (sym->regsUsed) {
2909 /* save the registers used */
2910 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2911 if (bitVectBitValue(sym->regsUsed,i) ||
2912 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2913 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2919 /* if debug then send end of function */
2921 debugFile->writeEndFunction (currFunc, ic, 1);
2924 pic14_emitcode ("return","");
2925 emitpcodeNULLop(POC_RETURN);
2927 /* Mark the end of a function */
2928 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2933 /*-----------------------------------------------------------------*/
2934 /* genRet - generate code for return statement */
2935 /*-----------------------------------------------------------------*/
2936 static void genRet (iCode *ic)
2938 int size,offset = 0 , pushed = 0;
2940 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2941 /* if we have no return value then
2942 just generate the "ret" */
2946 /* we have something to return then
2947 move the return value into place */
2948 aopOp(IC_LEFT(ic),ic,FALSE);
2949 size = AOP_SIZE(IC_LEFT(ic));
2953 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2955 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2957 pic14_emitcode("push","%s",l);
2960 l = aopGet(AOP(IC_LEFT(ic)),offset,
2962 if (strcmp(fReturn[offset],l)) {
2963 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2964 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2965 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2966 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2967 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2969 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2972 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2982 if (strcmp(fReturn[pushed],"a"))
2983 pic14_emitcode("pop",fReturn[pushed]);
2985 pic14_emitcode("pop","acc");
2988 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2991 /* generate a jump to the return label
2992 if the next is not the return statement */
2993 if (!(ic->next && ic->next->op == LABEL &&
2994 IC_LABEL(ic->next) == returnLabel)) {
2996 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2997 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3002 /*-----------------------------------------------------------------*/
3003 /* genLabel - generates a label */
3004 /*-----------------------------------------------------------------*/
3005 static void genLabel (iCode *ic)
3007 /* special case never generate */
3008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3009 if (IC_LABEL(ic) == entryLabel)
3012 emitpLabel(IC_LABEL(ic)->key);
3013 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3016 /*-----------------------------------------------------------------*/
3017 /* genGoto - generates a goto */
3018 /*-----------------------------------------------------------------*/
3020 static void genGoto (iCode *ic)
3022 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3023 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3027 /*-----------------------------------------------------------------*/
3028 /* genMultbits :- multiplication of bits */
3029 /*-----------------------------------------------------------------*/
3030 static void genMultbits (operand *left,
3034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3036 if(!pic14_sameRegs(AOP(result),AOP(right)))
3037 emitpcode(POC_BSF, popGet(AOP(result),0));
3039 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3040 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3041 emitpcode(POC_BCF, popGet(AOP(result),0));
3046 /*-----------------------------------------------------------------*/
3047 /* genMultOneByte : 8 bit multiplication & division */
3048 /*-----------------------------------------------------------------*/
3049 static void genMultOneByte (operand *left,
3053 sym_link *opetype = operandType(result);
3058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3059 DEBUGpic14_AopType(__LINE__,left,right,result);
3060 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3062 /* (if two literals, the value is computed before) */
3063 /* if one literal, literal on the right */
3064 if (AOP_TYPE(left) == AOP_LIT){
3070 size = AOP_SIZE(result);
3073 if (AOP_TYPE(right) == AOP_LIT){
3074 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3075 aopGet(AOP(right),0,FALSE,FALSE),
3076 aopGet(AOP(left),0,FALSE,FALSE),
3077 aopGet(AOP(result),0,FALSE,FALSE));
3078 pic14_emitcode("call","genMultLit");
3080 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3081 aopGet(AOP(right),0,FALSE,FALSE),
3082 aopGet(AOP(left),0,FALSE,FALSE),
3083 aopGet(AOP(result),0,FALSE,FALSE));
3084 pic14_emitcode("call","genMult8X8_8");
3087 genMult8X8_8 (left, right,result);
3090 /* signed or unsigned */
3091 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3092 //l = aopGet(AOP(left),0,FALSE,FALSE);
3094 //pic14_emitcode("mul","ab");
3095 /* if result size = 1, mul signed = mul unsigned */
3096 //aopPut(AOP(result),"a",0);
3098 } else { // (size > 1)
3100 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3101 aopGet(AOP(right),0,FALSE,FALSE),
3102 aopGet(AOP(left),0,FALSE,FALSE),
3103 aopGet(AOP(result),0,FALSE,FALSE));
3105 if (SPEC_USIGN(opetype)){
3106 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3107 genUMult8X8_16 (left, right, result, NULL);
3110 /* for filling the MSBs */
3111 emitpcode(POC_CLRF, popGet(AOP(result),2));
3112 emitpcode(POC_CLRF, popGet(AOP(result),3));
3116 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3118 pic14_emitcode("mov","a,b");
3120 /* adjust the MSB if left or right neg */
3122 /* if one literal */
3123 if (AOP_TYPE(right) == AOP_LIT){
3124 pic14_emitcode("multiply ","right is a lit");
3125 /* AND literal negative */
3126 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3127 /* adjust MSB (c==0 after mul) */
3128 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3132 genSMult8X8_16 (left, right, result, NULL);
3136 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3138 pic14_emitcode("rlc","a");
3139 pic14_emitcode("subb","a,acc");
3147 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3148 //aopPut(AOP(result),"a",offset++);
3152 /*-----------------------------------------------------------------*/
3153 /* genMult - generates code for multiplication */
3154 /*-----------------------------------------------------------------*/
3155 static void genMult (iCode *ic)
3157 operand *left = IC_LEFT(ic);
3158 operand *right = IC_RIGHT(ic);
3159 operand *result= IC_RESULT(ic);
3161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3162 /* assign the amsops */
3163 aopOp (left,ic,FALSE);
3164 aopOp (right,ic,FALSE);
3165 aopOp (result,ic,TRUE);
3167 DEBUGpic14_AopType(__LINE__,left,right,result);
3169 /* special cases first */
3171 if (AOP_TYPE(left) == AOP_CRY &&
3172 AOP_TYPE(right)== AOP_CRY) {
3173 genMultbits(left,right,result);
3177 /* if both are of size == 1 */
3178 if (AOP_SIZE(left) == 1 &&
3179 AOP_SIZE(right) == 1 ) {
3180 genMultOneByte(left,right,result);
3184 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3186 /* should have been converted to function call */
3190 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3191 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3192 freeAsmop(result,NULL,ic,TRUE);
3195 /*-----------------------------------------------------------------*/
3196 /* genDivbits :- division of bits */
3197 /*-----------------------------------------------------------------*/
3198 static void genDivbits (operand *left,
3205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3206 /* the result must be bit */
3207 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3208 l = aopGet(AOP(left),0,FALSE,FALSE);
3212 pic14_emitcode("div","ab");
3213 pic14_emitcode("rrc","a");
3214 aopPut(AOP(result),"c",0);
3217 /*-----------------------------------------------------------------*/
3218 /* genDivOneByte : 8 bit division */
3219 /*-----------------------------------------------------------------*/
3220 static void genDivOneByte (operand *left,
3224 sym_link *opetype = operandType(result);
3229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3230 size = AOP_SIZE(result) - 1;
3232 /* signed or unsigned */
3233 if (SPEC_USIGN(opetype)) {
3234 /* unsigned is easy */
3235 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3236 l = aopGet(AOP(left),0,FALSE,FALSE);
3238 pic14_emitcode("div","ab");
3239 aopPut(AOP(result),"a",0);
3241 aopPut(AOP(result),zero,offset++);
3245 /* signed is a little bit more difficult */
3247 /* save the signs of the operands */
3248 l = aopGet(AOP(left),0,FALSE,FALSE);
3250 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3251 pic14_emitcode("push","acc"); /* save it on the stack */
3253 /* now sign adjust for both left & right */
3254 l = aopGet(AOP(right),0,FALSE,FALSE);
3256 lbl = newiTempLabel(NULL);
3257 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3258 pic14_emitcode("cpl","a");
3259 pic14_emitcode("inc","a");
3260 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3261 pic14_emitcode("mov","b,a");
3263 /* sign adjust left side */
3264 l = aopGet(AOP(left),0,FALSE,FALSE);
3267 lbl = newiTempLabel(NULL);
3268 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3269 pic14_emitcode("cpl","a");
3270 pic14_emitcode("inc","a");
3271 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3273 /* now the division */
3274 pic14_emitcode("div","ab");
3275 /* we are interested in the lower order
3277 pic14_emitcode("mov","b,a");
3278 lbl = newiTempLabel(NULL);
3279 pic14_emitcode("pop","acc");
3280 /* if there was an over flow we don't
3281 adjust the sign of the result */
3282 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3283 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3285 pic14_emitcode("clr","a");
3286 pic14_emitcode("subb","a,b");
3287 pic14_emitcode("mov","b,a");
3288 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3290 /* now we are done */
3291 aopPut(AOP(result),"b",0);
3293 pic14_emitcode("mov","c,b.7");
3294 pic14_emitcode("subb","a,acc");
3297 aopPut(AOP(result),"a",offset++);
3301 /*-----------------------------------------------------------------*/
3302 /* genDiv - generates code for division */
3303 /*-----------------------------------------------------------------*/
3304 static void genDiv (iCode *ic)
3306 operand *left = IC_LEFT(ic);
3307 operand *right = IC_RIGHT(ic);
3308 operand *result= IC_RESULT(ic);
3310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3311 /* assign the amsops */
3312 aopOp (left,ic,FALSE);
3313 aopOp (right,ic,FALSE);
3314 aopOp (result,ic,TRUE);
3316 /* special cases first */
3318 if (AOP_TYPE(left) == AOP_CRY &&
3319 AOP_TYPE(right)== AOP_CRY) {
3320 genDivbits(left,right,result);
3324 /* if both are of size == 1 */
3325 if (AOP_SIZE(left) == 1 &&
3326 AOP_SIZE(right) == 1 ) {
3327 genDivOneByte(left,right,result);
3331 /* should have been converted to function call */
3334 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3335 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3336 freeAsmop(result,NULL,ic,TRUE);
3339 /*-----------------------------------------------------------------*/
3340 /* genModbits :- modulus of bits */
3341 /*-----------------------------------------------------------------*/
3342 static void genModbits (operand *left,
3349 /* the result must be bit */
3350 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3351 l = aopGet(AOP(left),0,FALSE,FALSE);
3355 pic14_emitcode("div","ab");
3356 pic14_emitcode("mov","a,b");
3357 pic14_emitcode("rrc","a");
3358 aopPut(AOP(result),"c",0);
3361 /*-----------------------------------------------------------------*/
3362 /* genModOneByte : 8 bit modulus */
3363 /*-----------------------------------------------------------------*/
3364 static void genModOneByte (operand *left,
3368 sym_link *opetype = operandType(result);
3372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3373 /* signed or unsigned */
3374 if (SPEC_USIGN(opetype)) {
3375 /* unsigned is easy */
3376 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3377 l = aopGet(AOP(left),0,FALSE,FALSE);
3379 pic14_emitcode("div","ab");
3380 aopPut(AOP(result),"b",0);
3384 /* signed is a little bit more difficult */
3386 /* save the signs of the operands */
3387 l = aopGet(AOP(left),0,FALSE,FALSE);
3390 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3391 pic14_emitcode("push","acc"); /* save it on the stack */
3393 /* now sign adjust for both left & right */
3394 l = aopGet(AOP(right),0,FALSE,FALSE);
3397 lbl = newiTempLabel(NULL);
3398 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3399 pic14_emitcode("cpl","a");
3400 pic14_emitcode("inc","a");
3401 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3402 pic14_emitcode("mov","b,a");
3404 /* sign adjust left side */
3405 l = aopGet(AOP(left),0,FALSE,FALSE);
3408 lbl = newiTempLabel(NULL);
3409 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3410 pic14_emitcode("cpl","a");
3411 pic14_emitcode("inc","a");
3412 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3414 /* now the multiplication */
3415 pic14_emitcode("div","ab");
3416 /* we are interested in the lower order
3418 lbl = newiTempLabel(NULL);
3419 pic14_emitcode("pop","acc");
3420 /* if there was an over flow we don't
3421 adjust the sign of the result */
3422 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3423 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3425 pic14_emitcode("clr","a");
3426 pic14_emitcode("subb","a,b");
3427 pic14_emitcode("mov","b,a");
3428 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3430 /* now we are done */
3431 aopPut(AOP(result),"b",0);
3435 /*-----------------------------------------------------------------*/
3436 /* genMod - generates code for division */
3437 /*-----------------------------------------------------------------*/
3438 static void genMod (iCode *ic)
3440 operand *left = IC_LEFT(ic);
3441 operand *right = IC_RIGHT(ic);
3442 operand *result= IC_RESULT(ic);
3444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3445 /* assign the amsops */
3446 aopOp (left,ic,FALSE);
3447 aopOp (right,ic,FALSE);
3448 aopOp (result,ic,TRUE);
3450 /* special cases first */
3452 if (AOP_TYPE(left) == AOP_CRY &&
3453 AOP_TYPE(right)== AOP_CRY) {
3454 genModbits(left,right,result);
3458 /* if both are of size == 1 */
3459 if (AOP_SIZE(left) == 1 &&
3460 AOP_SIZE(right) == 1 ) {
3461 genModOneByte(left,right,result);
3465 /* should have been converted to function call */
3469 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3470 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3471 freeAsmop(result,NULL,ic,TRUE);
3474 /*-----------------------------------------------------------------*/
3475 /* genIfxJump :- will create a jump depending on the ifx */
3476 /*-----------------------------------------------------------------*/
3478 note: May need to add parameter to indicate when a variable is in bit space.
3480 static void genIfxJump (iCode *ic, char *jval)
3483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3484 /* if true label then we jump if condition
3486 if ( IC_TRUE(ic) ) {
3488 if(strcmp(jval,"a") == 0)
3490 else if (strcmp(jval,"c") == 0)
3493 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3494 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3497 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3498 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3502 /* false label is present */
3503 if(strcmp(jval,"a") == 0)
3505 else if (strcmp(jval,"c") == 0)
3508 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3509 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3512 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3513 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3518 /* mark the icode as generated */
3522 /*-----------------------------------------------------------------*/
3524 /*-----------------------------------------------------------------*/
3525 static void genSkip(iCode *ifx,int status_bit)
3530 if ( IC_TRUE(ifx) ) {
3531 switch(status_bit) {
3546 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3547 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3551 switch(status_bit) {
3565 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3566 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3572 /*-----------------------------------------------------------------*/
3574 /*-----------------------------------------------------------------*/
3575 static void genSkipc(resolvedIfx *rifx)
3585 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3586 rifx->generated = 1;
3589 /*-----------------------------------------------------------------*/
3591 /*-----------------------------------------------------------------*/
3592 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3597 if( (rifx->condition ^ invert_condition) & 1)
3602 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3603 rifx->generated = 1;
3606 /*-----------------------------------------------------------------*/
3608 /*-----------------------------------------------------------------*/
3609 static void genSkipz(iCode *ifx, int condition)
3620 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3622 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3625 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3627 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3630 /*-----------------------------------------------------------------*/
3632 /*-----------------------------------------------------------------*/
3633 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3639 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3641 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3644 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3645 rifx->generated = 1;
3649 /*-----------------------------------------------------------------*/
3650 /* genChkZeroes :- greater or less than comparison */
3651 /* For each byte in a literal that is zero, inclusive or the */
3652 /* the corresponding byte in the operand with W */
3653 /* returns true if any of the bytes are zero */
3654 /*-----------------------------------------------------------------*/
3655 static int genChkZeroes(operand *op, int lit, int size)
3662 i = (lit >> (size*8)) & 0xff;
3666 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3668 emitpcode(POC_IORFW, popGet(AOP(op),size));
3677 /*-----------------------------------------------------------------*/
3678 /* genCmp :- greater or less than comparison */
3679 /*-----------------------------------------------------------------*/
3680 static void genCmp (operand *left,operand *right,
3681 operand *result, iCode *ifx, int sign)
3683 int size; //, offset = 0 ;
3684 unsigned long lit = 0L,i = 0;
3685 resolvedIfx rFalseIfx;
3686 // resolvedIfx rTrueIfx;
3688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3691 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3692 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3696 resolveIfx(&rFalseIfx,ifx);
3697 truelbl = newiTempLabel(NULL);
3698 size = max(AOP_SIZE(left),AOP_SIZE(right));
3700 DEBUGpic14_AopType(__LINE__,left,right,result);
3704 /* if literal is on the right then swap with left */
3705 if ((AOP_TYPE(right) == AOP_LIT)) {
3706 operand *tmp = right ;
3707 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3708 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3711 lit = (lit - 1) & mask;
3714 rFalseIfx.condition ^= 1;
3717 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3718 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3722 //if(IC_TRUE(ifx) == NULL)
3723 /* if left & right are bit variables */
3724 if (AOP_TYPE(left) == AOP_CRY &&
3725 AOP_TYPE(right) == AOP_CRY ) {
3726 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3727 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3729 /* subtract right from left if at the
3730 end the carry flag is set then we know that
3731 left is greater than right */
3733 symbol *lbl = newiTempLabel(NULL);
3736 if(AOP_TYPE(right) == AOP_LIT) {
3738 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3740 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3747 genSkipCond(&rFalseIfx,left,size-1,7);
3749 /* no need to compare to 0...*/
3750 /* NOTE: this is a de-generate compare that most certainly
3751 * creates some dead code. */
3752 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3754 if(ifx) ifx->generated = 1;
3761 //i = (lit >> (size*8)) & 0xff;
3762 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3764 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3766 i = ((0-lit) & 0xff);
3769 /* lit is 0x7f, all signed chars are less than
3770 * this except for 0x7f itself */
3771 emitpcode(POC_XORLW, popGetLit(0x7f));
3772 genSkipz2(&rFalseIfx,0);
3774 emitpcode(POC_ADDLW, popGetLit(0x80));
3775 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3776 genSkipc(&rFalseIfx);
3781 genSkipz2(&rFalseIfx,1);
3783 emitpcode(POC_ADDLW, popGetLit(i));
3784 genSkipc(&rFalseIfx);
3788 if(ifx) ifx->generated = 1;
3792 /* chars are out of the way. now do ints and longs */
3795 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3802 genSkipCond(&rFalseIfx,left,size,7);
3803 if(ifx) ifx->generated = 1;
3808 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3810 //rFalseIfx.condition ^= 1;
3811 //genSkipCond(&rFalseIfx,left,size,7);
3812 //rFalseIfx.condition ^= 1;
3814 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3815 if(rFalseIfx.condition)
3816 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3818 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3820 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3821 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3822 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3825 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3827 if(rFalseIfx.condition) {
3829 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3835 genSkipc(&rFalseIfx);
3836 emitpLabel(truelbl->key);
3837 if(ifx) ifx->generated = 1;
3844 if( (lit & 0xff) == 0) {
3845 /* lower byte is zero */
3846 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3847 i = ((lit >> 8) & 0xff) ^0x80;
3848 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3849 emitpcode(POC_ADDLW, popGetLit( 0x80));
3850 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3851 genSkipc(&rFalseIfx);
3854 if(ifx) ifx->generated = 1;
3859 /* Special cases for signed longs */
3860 if( (lit & 0xffffff) == 0) {
3861 /* lower byte is zero */
3862 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3863 i = ((lit >> 8*3) & 0xff) ^0x80;
3864 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3865 emitpcode(POC_ADDLW, popGetLit( 0x80));
3866 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3867 genSkipc(&rFalseIfx);
3870 if(ifx) ifx->generated = 1;
3878 if(lit & (0x80 << (size*8))) {
3879 /* lit is negative */
3880 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3882 //genSkipCond(&rFalseIfx,left,size,7);
3884 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3886 if(rFalseIfx.condition)
3887 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3889 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3893 /* lit is positive */
3894 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3895 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3896 if(rFalseIfx.condition)
3897 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3899 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3903 /* There are no more special cases, so perform a general compare */
3905 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3906 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3910 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3912 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3914 //rFalseIfx.condition ^= 1;
3915 genSkipc(&rFalseIfx);
3917 emitpLabel(truelbl->key);
3919 if(ifx) ifx->generated = 1;
3926 /* sign is out of the way. So now do an unsigned compare */
3927 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3930 /* General case - compare to an unsigned literal on the right.*/
3932 i = (lit >> (size*8)) & 0xff;
3933 emitpcode(POC_MOVLW, popGetLit(i));
3934 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3936 i = (lit >> (size*8)) & 0xff;
3939 emitpcode(POC_MOVLW, popGetLit(i));
3941 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3943 /* this byte of the lit is zero,
3944 *if it's not the last then OR in the variable */
3946 emitpcode(POC_IORFW, popGet(AOP(left),size));
3951 emitpLabel(lbl->key);
3952 //if(emitFinalCheck)
3953 genSkipc(&rFalseIfx);
3955 emitpLabel(truelbl->key);
3957 if(ifx) ifx->generated = 1;
3964 if(AOP_TYPE(left) == AOP_LIT) {
3965 //symbol *lbl = newiTempLabel(NULL);
3967 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3970 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3973 if((lit == 0) && (sign == 0)){
3976 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3978 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3980 genSkipz2(&rFalseIfx,0);
3981 if(ifx) ifx->generated = 1;
3988 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3989 /* degenerate compare can never be true */
3990 if(rFalseIfx.condition == 0)
3991 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3993 if(ifx) ifx->generated = 1;
3998 /* signed comparisons to a literal byte */
4000 int lp1 = (lit+1) & 0xff;
4002 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4005 rFalseIfx.condition ^= 1;
4006 genSkipCond(&rFalseIfx,right,0,7);
4009 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4010 emitpcode(POC_XORLW, popGetLit(0x7f));
4011 genSkipz2(&rFalseIfx,1);
4014 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4015 emitpcode(POC_ADDLW, popGetLit(0x80));
4016 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4017 rFalseIfx.condition ^= 1;
4018 genSkipc(&rFalseIfx);
4021 if(ifx) ifx->generated = 1;
4023 /* unsigned comparisons to a literal byte */
4025 switch(lit & 0xff ) {
4027 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4028 genSkipz2(&rFalseIfx,0);
4029 if(ifx) ifx->generated = 1;
4032 genSkipCond(&rFalseIfx,right,0,7);
4033 if(ifx) ifx->generated = 1;
4037 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4038 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4040 rFalseIfx.condition ^= 1;
4041 if (AOP_TYPE(result) == AOP_CRY) {
4042 genSkipc(&rFalseIfx);
4043 if(ifx) ifx->generated = 1;
4045 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4046 emitpcode(POC_CLRF, popGet(AOP(result),0));
4047 emitpcode(POC_RLF, popGet(AOP(result),0));
4048 emitpcode(POC_MOVLW, popGetLit(0x01));
4049 emitpcode(POC_XORWF, popGet(AOP(result),0));
4060 /* Size is greater than 1 */
4068 /* this means lit = 0xffffffff, or -1 */
4071 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4072 rFalseIfx.condition ^= 1;
4073 genSkipCond(&rFalseIfx,right,size,7);
4074 if(ifx) ifx->generated = 1;
4081 if(rFalseIfx.condition) {
4082 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4083 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4086 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4088 emitpcode(POC_IORFW, popGet(AOP(right),size));
4092 if(rFalseIfx.condition) {
4093 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4094 emitpLabel(truelbl->key);
4096 rFalseIfx.condition ^= 1;
4097 genSkipCond(&rFalseIfx,right,s,7);
4100 if(ifx) ifx->generated = 1;
4104 if((size == 1) && (0 == (lp1&0xff))) {
4105 /* lower byte of signed word is zero */
4106 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4107 i = ((lp1 >> 8) & 0xff) ^0x80;
4108 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4109 emitpcode(POC_ADDLW, popGetLit( 0x80));
4110 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4111 rFalseIfx.condition ^= 1;
4112 genSkipc(&rFalseIfx);
4115 if(ifx) ifx->generated = 1;
4119 if(lit & (0x80 << (size*8))) {
4120 /* Lit is less than zero */
4121 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4122 //rFalseIfx.condition ^= 1;
4123 //genSkipCond(&rFalseIfx,left,size,7);
4124 //rFalseIfx.condition ^= 1;
4125 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4126 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4128 if(rFalseIfx.condition)
4129 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4131 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4135 /* Lit is greater than or equal to zero */
4136 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4137 //rFalseIfx.condition ^= 1;
4138 //genSkipCond(&rFalseIfx,right,size,7);
4139 //rFalseIfx.condition ^= 1;
4141 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4142 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4144 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4145 if(rFalseIfx.condition)
4146 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4148 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4153 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4154 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4158 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4160 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4162 rFalseIfx.condition ^= 1;
4163 //rFalseIfx.condition = 1;
4164 genSkipc(&rFalseIfx);
4166 emitpLabel(truelbl->key);
4168 if(ifx) ifx->generated = 1;
4173 /* compare word or long to an unsigned literal on the right.*/
4178 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4181 break; /* handled above */
4184 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4186 emitpcode(POC_IORFW, popGet(AOP(right),size));
4187 genSkipz2(&rFalseIfx,0);
4191 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4193 emitpcode(POC_IORFW, popGet(AOP(right),size));
4196 if(rFalseIfx.condition)
4197 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4199 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4202 emitpcode(POC_MOVLW, popGetLit(lit+1));
4203 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4205 rFalseIfx.condition ^= 1;
4206 genSkipc(&rFalseIfx);
4209 emitpLabel(truelbl->key);
4211 if(ifx) ifx->generated = 1;
4217 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4218 i = (lit >> (size*8)) & 0xff;
4220 emitpcode(POC_MOVLW, popGetLit(i));
4221 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4224 i = (lit >> (size*8)) & 0xff;
4227 emitpcode(POC_MOVLW, popGetLit(i));
4229 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4231 /* this byte of the lit is zero,
4232 *if it's not the last then OR in the variable */
4234 emitpcode(POC_IORFW, popGet(AOP(right),size));
4239 emitpLabel(lbl->key);
4241 rFalseIfx.condition ^= 1;
4242 genSkipc(&rFalseIfx);
4246 emitpLabel(truelbl->key);
4247 if(ifx) ifx->generated = 1;
4251 /* Compare two variables */
4253 DEBUGpic14_emitcode(";sign","%d",sign);
4257 /* Sigh. thus sucks... */
4259 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4260 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4261 emitpcode(POC_MOVLW, popGetLit(0x80));
4262 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4263 emitpcode(POC_XORFW, popGet(AOP(right),size));
4264 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4266 /* Signed char comparison */
4267 /* Special thanks to Nikolai Golovchenko for this snippet */
4268 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4269 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4270 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4271 emitpcode(POC_XORFW, popGet(AOP(left),0));
4272 emitpcode(POC_XORFW, popGet(AOP(right),0));
4273 emitpcode(POC_ADDLW, popGetLit(0x80));
4275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4276 genSkipc(&rFalseIfx);
4278 if(ifx) ifx->generated = 1;
4284 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4285 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4289 /* The rest of the bytes of a multi-byte compare */
4293 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4296 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4297 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4302 emitpLabel(lbl->key);
4304 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4305 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4306 (AOP_TYPE(result) == AOP_REG)) {
4307 emitpcode(POC_CLRF, popGet(AOP(result),0));
4308 emitpcode(POC_RLF, popGet(AOP(result),0));
4310 genSkipc(&rFalseIfx);
4312 //genSkipc(&rFalseIfx);
4313 if(ifx) ifx->generated = 1;
4320 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4322 pic14_outBitC(result);
4324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4325 /* if the result is used in the next
4326 ifx conditional branch then generate
4327 code a little differently */
4329 genIfxJump (ifx,"c");
4331 pic14_outBitC(result);
4332 /* leave the result in acc */
4337 /*-----------------------------------------------------------------*/
4338 /* genCmpGt :- greater than comparison */
4339 /*-----------------------------------------------------------------*/
4340 static void genCmpGt (iCode *ic, iCode *ifx)
4342 operand *left, *right, *result;
4343 sym_link *letype , *retype;
4346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4348 right= IC_RIGHT(ic);
4349 result = IC_RESULT(ic);
4351 letype = getSpec(operandType(left));
4352 retype =getSpec(operandType(right));
4353 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4354 /* assign the amsops */
4355 aopOp (left,ic,FALSE);
4356 aopOp (right,ic,FALSE);
4357 aopOp (result,ic,TRUE);
4359 genCmp(right, left, result, ifx, sign);
4361 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4362 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4363 freeAsmop(result,NULL,ic,TRUE);
4366 /*-----------------------------------------------------------------*/
4367 /* genCmpLt - less than comparisons */
4368 /*-----------------------------------------------------------------*/
4369 static void genCmpLt (iCode *ic, iCode *ifx)
4371 operand *left, *right, *result;
4372 sym_link *letype , *retype;
4375 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4377 right= IC_RIGHT(ic);
4378 result = IC_RESULT(ic);
4380 letype = getSpec(operandType(left));
4381 retype =getSpec(operandType(right));
4382 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4384 /* assign the amsops */
4385 aopOp (left,ic,FALSE);
4386 aopOp (right,ic,FALSE);
4387 aopOp (result,ic,TRUE);
4389 genCmp(left, right, result, ifx, sign);
4391 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4392 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4393 freeAsmop(result,NULL,ic,TRUE);
4396 /*-----------------------------------------------------------------*/
4397 /* genc16bit2lit - compare a 16 bit value to a literal */
4398 /*-----------------------------------------------------------------*/
4399 static void genc16bit2lit(operand *op, int lit, int offset)
4403 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4404 if( (lit&0xff) == 0)
4409 switch( BYTEofLONG(lit,i)) {
4411 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4414 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4417 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4420 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4421 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4426 switch( BYTEofLONG(lit,i)) {
4428 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4432 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4436 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4439 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4441 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4447 /*-----------------------------------------------------------------*/
4448 /* gencjneshort - compare and jump if not equal */
4449 /*-----------------------------------------------------------------*/
4450 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4452 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4454 int res_offset = 0; /* the result may be a different size then left or right */
4455 int res_size = AOP_SIZE(result);
4459 unsigned long lit = 0L;
4460 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4461 DEBUGpic14_AopType(__LINE__,left,right,result);
4463 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4464 resolveIfx(&rIfx,ifx);
4465 lbl = newiTempLabel(NULL);
4468 /* if the left side is a literal or
4469 if the right is in a pointer register and left
4471 if ((AOP_TYPE(left) == AOP_LIT) ||
4472 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4477 if(AOP_TYPE(right) == AOP_LIT)
4478 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4480 /* if the right side is a literal then anything goes */
4481 if (AOP_TYPE(right) == AOP_LIT &&
4482 AOP_TYPE(left) != AOP_DIR ) {
4485 genc16bit2lit(left, lit, 0);
4487 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4492 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4493 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4495 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4499 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4501 if(res_offset < res_size-1)
4509 /* if the right side is in a register or in direct space or
4510 if the left is a pointer register & right is not */
4511 else if (AOP_TYPE(right) == AOP_REG ||
4512 AOP_TYPE(right) == AOP_DIR ||
4513 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4514 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4515 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4516 int lbl_key = lbl->key;
4519 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4520 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4522 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4523 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4524 __FUNCTION__,__LINE__);
4528 /* switch(size) { */
4530 /* genc16bit2lit(left, lit, 0); */
4532 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4537 if((AOP_TYPE(left) == AOP_DIR) &&
4538 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4540 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4541 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4543 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4545 switch (lit & 0xff) {
4547 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4550 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4551 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4552 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4556 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4557 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4558 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4559 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4563 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4564 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4569 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4572 if(AOP_TYPE(result) == AOP_CRY) {
4573 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4578 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4580 /* fix me. probably need to check result size too */
4581 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4586 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4587 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4594 if(res_offset < res_size-1)
4599 } else if(AOP_TYPE(right) == AOP_REG &&
4600 AOP_TYPE(left) != AOP_DIR){
4603 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4604 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4605 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4610 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4612 if(res_offset < res_size-1)
4617 /* right is a pointer reg need both a & b */
4619 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4621 pic14_emitcode("mov","b,%s",l);
4622 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4623 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4628 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4632 emitpLabel(lbl->key);
4634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4641 /*-----------------------------------------------------------------*/
4642 /* gencjne - compare and jump if not equal */
4643 /*-----------------------------------------------------------------*/
4644 static void gencjne(operand *left, operand *right, iCode *ifx)
4646 symbol *tlbl = newiTempLabel(NULL);
4648 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4649 gencjneshort(left, right, lbl);
4651 pic14_emitcode("mov","a,%s",one);
4652 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4653 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4654 pic14_emitcode("clr","a");
4655 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4657 emitpLabel(lbl->key);
4658 emitpLabel(tlbl->key);
4663 /*-----------------------------------------------------------------*/
4664 /* genCmpEq - generates code for equal to */
4665 /*-----------------------------------------------------------------*/
4666 static void genCmpEq (iCode *ic, iCode *ifx)
4668 operand *left, *right, *result;
4669 unsigned long lit = 0L;
4672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4675 DEBUGpic14_emitcode ("; ifx is non-null","");
4677 DEBUGpic14_emitcode ("; ifx is null","");
4679 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4680 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4681 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4683 size = max(AOP_SIZE(left),AOP_SIZE(right));
4685 DEBUGpic14_AopType(__LINE__,left,right,result);
4687 /* if literal, literal on the right or
4688 if the right is in a pointer register and left
4690 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4691 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4692 operand *tmp = right ;
4698 if(ifx && !AOP_SIZE(result)){
4700 /* if they are both bit variables */
4701 if (AOP_TYPE(left) == AOP_CRY &&
4702 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4703 if(AOP_TYPE(right) == AOP_LIT){
4704 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4706 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4707 pic14_emitcode("cpl","c");
4708 } else if(lit == 1L) {
4709 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4711 pic14_emitcode("clr","c");
4713 /* AOP_TYPE(right) == AOP_CRY */
4715 symbol *lbl = newiTempLabel(NULL);
4716 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4717 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4718 pic14_emitcode("cpl","c");
4719 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4721 /* if true label then we jump if condition
4723 tlbl = newiTempLabel(NULL);
4724 if ( IC_TRUE(ifx) ) {
4725 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4726 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4728 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4729 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4731 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4734 /* left and right are both bit variables, result is carry */
4737 resolveIfx(&rIfx,ifx);
4739 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4740 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4741 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4742 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4747 /* They're not both bit variables. Is the right a literal? */
4748 if(AOP_TYPE(right) == AOP_LIT) {
4749 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4754 switch(lit & 0xff) {
4756 if ( IC_TRUE(ifx) ) {
4757 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4759 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4761 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4762 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4766 if ( IC_TRUE(ifx) ) {
4767 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4769 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4771 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4772 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4776 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4778 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4783 /* end of size == 1 */
4787 genc16bit2lit(left,lit,offset);
4790 /* end of size == 2 */
4795 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4796 emitpcode(POC_IORFW,popGet(AOP(left),1));
4797 emitpcode(POC_IORFW,popGet(AOP(left),2));
4798 emitpcode(POC_IORFW,popGet(AOP(left),3));
4802 /* search for patterns that can be optimized */
4804 genc16bit2lit(left,lit,0);
4807 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4809 genc16bit2lit(left,lit,2);
4811 emitpcode(POC_IORFW,popGet(AOP(left),2));
4812 emitpcode(POC_IORFW,popGet(AOP(left),3));
4825 } else if(AOP_TYPE(right) == AOP_CRY ) {
4826 /* we know the left is not a bit, but that the right is */
4827 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4828 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4829 popGet(AOP(right),offset));
4830 emitpcode(POC_XORLW,popGetLit(1));
4832 /* if the two are equal, then W will be 0 and the Z bit is set
4833 * we could test Z now, or go ahead and check the high order bytes if
4834 * the variable we're comparing is larger than a byte. */
4837 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4839 if ( IC_TRUE(ifx) ) {
4841 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4842 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4845 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4846 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4850 /* They're both variables that are larger than bits */
4853 tlbl = newiTempLabel(NULL);
4856 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4857 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4859 if ( IC_TRUE(ifx) ) {
4862 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4863 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4866 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4867 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4871 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4872 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4876 if(s>1 && IC_TRUE(ifx)) {
4877 emitpLabel(tlbl->key);
4878 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4882 /* mark the icode as generated */
4887 /* if they are both bit variables */
4888 if (AOP_TYPE(left) == AOP_CRY &&
4889 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4890 if(AOP_TYPE(right) == AOP_LIT){
4891 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4893 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4894 pic14_emitcode("cpl","c");
4895 } else if(lit == 1L) {
4896 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4898 pic14_emitcode("clr","c");
4900 /* AOP_TYPE(right) == AOP_CRY */
4902 symbol *lbl = newiTempLabel(NULL);
4903 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4904 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4905 pic14_emitcode("cpl","c");
4906 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4909 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4910 pic14_outBitC(result);
4914 genIfxJump (ifx,"c");
4917 /* if the result is used in an arithmetic operation
4918 then put the result in place */
4919 pic14_outBitC(result);
4922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4923 gencjne(left,right,result,ifx);
4926 gencjne(left,right,newiTempLabel(NULL));
4928 if(IC_TRUE(ifx)->key)
4929 gencjne(left,right,IC_TRUE(ifx)->key);
4931 gencjne(left,right,IC_FALSE(ifx)->key);
4935 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4936 aopPut(AOP(result),"a",0);
4941 genIfxJump (ifx,"a");
4945 /* if the result is used in an arithmetic operation
4946 then put the result in place */
4948 if (AOP_TYPE(result) != AOP_CRY)
4949 pic14_outAcc(result);
4951 /* leave the result in acc */
4955 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4956 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4957 freeAsmop(result,NULL,ic,TRUE);
4960 /*-----------------------------------------------------------------*/
4961 /* ifxForOp - returns the icode containing the ifx for operand */
4962 /*-----------------------------------------------------------------*/
4963 static iCode *ifxForOp ( operand *op, iCode *ic )
4965 /* if true symbol then needs to be assigned */
4966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4967 if (IS_TRUE_SYMOP(op))
4970 /* if this has register type condition and
4971 the next instruction is ifx with the same operand
4972 and live to of the operand is upto the ifx only then */
4974 ic->next->op == IFX &&
4975 IC_COND(ic->next)->key == op->key &&
4976 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4980 ic->next->op == IFX &&
4981 IC_COND(ic->next)->key == op->key) {
4982 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4986 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4988 ic->next->op == IFX)
4989 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4992 ic->next->op == IFX &&
4993 IC_COND(ic->next)->key == op->key) {
4994 DEBUGpic14_emitcode ("; "," key is okay");
4995 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4996 OP_SYMBOL(op)->liveTo,
5003 /*-----------------------------------------------------------------*/
5004 /* genAndOp - for && operation */
5005 /*-----------------------------------------------------------------*/
5006 static void genAndOp (iCode *ic)
5008 operand *left,*right, *result;
5011 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5012 /* note here that && operations that are in an
5013 if statement are taken away by backPatchLabels
5014 only those used in arthmetic operations remain */
5015 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5016 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5017 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5019 DEBUGpic14_AopType(__LINE__,left,right,result);
5021 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5022 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5023 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5025 /* if both are bit variables */
5026 /* if (AOP_TYPE(left) == AOP_CRY && */
5027 /* AOP_TYPE(right) == AOP_CRY ) { */
5028 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5029 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5030 /* pic14_outBitC(result); */
5032 /* tlbl = newiTempLabel(NULL); */
5033 /* pic14_toBoolean(left); */
5034 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5035 /* pic14_toBoolean(right); */
5036 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5037 /* pic14_outBitAcc(result); */
5040 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5041 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5042 freeAsmop(result,NULL,ic,TRUE);
5046 /*-----------------------------------------------------------------*/
5047 /* genOrOp - for || operation */
5048 /*-----------------------------------------------------------------*/
5051 modified this code, but it doesn't appear to ever get called
5054 static void genOrOp (iCode *ic)
5056 operand *left,*right, *result;
5059 /* note here that || operations that are in an
5060 if statement are taken away by backPatchLabels
5061 only those used in arthmetic operations remain */
5062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5063 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5064 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5065 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5067 DEBUGpic14_AopType(__LINE__,left,right,result);
5069 /* if both are bit variables */
5070 if (AOP_TYPE(left) == AOP_CRY &&
5071 AOP_TYPE(right) == AOP_CRY ) {
5072 pic14_emitcode("clrc","");
5073 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5074 AOP(left)->aopu.aop_dir,
5075 AOP(left)->aopu.aop_dir);
5076 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5077 AOP(right)->aopu.aop_dir,
5078 AOP(right)->aopu.aop_dir);
5079 pic14_emitcode("setc","");
5082 tlbl = newiTempLabel(NULL);
5083 pic14_toBoolean(left);
5085 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5086 pic14_toBoolean(right);
5087 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5089 pic14_outBitAcc(result);
5092 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5093 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5094 freeAsmop(result,NULL,ic,TRUE);
5097 /*-----------------------------------------------------------------*/
5098 /* isLiteralBit - test if lit == 2^n */
5099 /*-----------------------------------------------------------------*/
5100 static int isLiteralBit(unsigned long lit)
5102 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5103 0x100L,0x200L,0x400L,0x800L,
5104 0x1000L,0x2000L,0x4000L,0x8000L,
5105 0x10000L,0x20000L,0x40000L,0x80000L,
5106 0x100000L,0x200000L,0x400000L,0x800000L,
5107 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5108 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5112 for(idx = 0; idx < 32; idx++)
5118 /*-----------------------------------------------------------------*/
5119 /* continueIfTrue - */
5120 /*-----------------------------------------------------------------*/
5121 static void continueIfTrue (iCode *ic)
5123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5125 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5129 /*-----------------------------------------------------------------*/
5131 /*-----------------------------------------------------------------*/
5132 static void jumpIfTrue (iCode *ic)
5134 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5136 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5140 /*-----------------------------------------------------------------*/
5141 /* jmpTrueOrFalse - */
5142 /*-----------------------------------------------------------------*/
5143 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5145 // ugly but optimized by peephole
5146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5148 symbol *nlbl = newiTempLabel(NULL);
5149 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5150 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5151 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5152 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5155 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5156 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5161 /*-----------------------------------------------------------------*/
5162 /* genAnd - code for and */
5163 /*-----------------------------------------------------------------*/
5164 static void genAnd (iCode *ic, iCode *ifx)
5166 operand *left, *right, *result;
5168 unsigned long lit = 0L;
5173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5174 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5175 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5176 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5178 resolveIfx(&rIfx,ifx);
5180 /* if left is a literal & right is not then exchange them */
5181 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5182 AOP_NEEDSACC(left)) {
5183 operand *tmp = right ;
5188 /* if result = right then exchange them */
5189 if(pic14_sameRegs(AOP(result),AOP(right))){
5190 operand *tmp = right ;
5195 /* if right is bit then exchange them */
5196 if (AOP_TYPE(right) == AOP_CRY &&
5197 AOP_TYPE(left) != AOP_CRY){
5198 operand *tmp = right ;
5202 if(AOP_TYPE(right) == AOP_LIT)
5203 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5205 size = AOP_SIZE(result);
5207 DEBUGpic14_AopType(__LINE__,left,right,result);
5210 // result = bit & yy;
5211 if (AOP_TYPE(left) == AOP_CRY){
5212 // c = bit & literal;
5213 if(AOP_TYPE(right) == AOP_LIT){
5215 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5218 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5221 if(size && (AOP_TYPE(result) == AOP_CRY)){
5222 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5225 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5229 pic14_emitcode("clr","c");
5232 if (AOP_TYPE(right) == AOP_CRY){
5234 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5235 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5238 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5240 pic14_emitcode("rrc","a");
5241 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5247 pic14_outBitC(result);
5249 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5250 genIfxJump(ifx, "c");
5254 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5255 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5256 if((AOP_TYPE(right) == AOP_LIT) &&
5257 (AOP_TYPE(result) == AOP_CRY) &&
5258 (AOP_TYPE(left) != AOP_CRY)){
5259 int posbit = isLiteralBit(lit);
5263 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5266 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5271 while (posbit > 7) {
5275 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5276 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5277 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5284 symbol *tlbl = newiTempLabel(NULL);
5285 int sizel = AOP_SIZE(left);
5287 pic14_emitcode("setb","c");
5289 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5290 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5292 if((posbit = isLiteralBit(bytelit)) != 0)
5293 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5295 if(bytelit != 0x0FFL)
5296 pic14_emitcode("anl","a,%s",
5297 aopGet(AOP(right),offset,FALSE,TRUE));
5298 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5303 // bit = left & literal
5305 pic14_emitcode("clr","c");
5306 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5308 // if(left & literal)
5311 jmpTrueOrFalse(ifx, tlbl);
5315 pic14_outBitC(result);
5319 /* if left is same as result */
5320 if(pic14_sameRegs(AOP(result),AOP(left))){
5322 for(;size--; offset++,lit>>=8) {
5323 if(AOP_TYPE(right) == AOP_LIT){
5324 switch(lit & 0xff) {
5326 /* and'ing with 0 has clears the result */
5327 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5328 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5331 /* and'ing with 0xff is a nop when the result and left are the same */
5336 int p = my_powof2( (~lit) & 0xff );
5338 /* only one bit is set in the literal, so use a bcf instruction */
5339 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5340 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5343 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5344 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5345 if(know_W != (int)(lit&0xff))
5346 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5348 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5353 if (AOP_TYPE(left) == AOP_ACC) {
5354 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5356 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5357 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5364 // left & result in different registers
5365 if(AOP_TYPE(result) == AOP_CRY){
5367 // if(size), result in bit
5368 // if(!size && ifx), conditional oper: if(left & right)
5369 symbol *tlbl = newiTempLabel(NULL);
5370 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5372 pic14_emitcode("setb","c");
5374 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5375 pic14_emitcode("anl","a,%s",
5376 aopGet(AOP(left),offset,FALSE,FALSE));
5377 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5382 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5383 pic14_outBitC(result);
5385 jmpTrueOrFalse(ifx, tlbl);
5387 for(;(size--);offset++) {
5389 // result = left & right
5390 if(AOP_TYPE(right) == AOP_LIT){
5391 int t = (lit >> (offset*8)) & 0x0FFL;
5394 pic14_emitcode("clrf","%s",
5395 aopGet(AOP(result),offset,FALSE,FALSE));
5396 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5399 if(AOP_TYPE(left) != AOP_ACC) {
5400 pic14_emitcode("movf","%s,w",
5401 aopGet(AOP(left),offset,FALSE,FALSE));
5402 pic14_emitcode("movwf","%s",
5403 aopGet(AOP(result),offset,FALSE,FALSE));
5404 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5406 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5409 if(AOP_TYPE(left) == AOP_ACC) {
5410 emitpcode(POC_ANDLW, popGetLit(t));
5412 pic14_emitcode("movlw","0x%x",t);
5413 pic14_emitcode("andwf","%s,w",
5414 aopGet(AOP(left),offset,FALSE,FALSE));
5415 pic14_emitcode("movwf","%s",
5416 aopGet(AOP(result),offset,FALSE,FALSE));
5418 emitpcode(POC_MOVLW, popGetLit(t));
5419 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5421 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5426 if (AOP_TYPE(left) == AOP_ACC) {
5427 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5428 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5430 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5431 pic14_emitcode("andwf","%s,w",
5432 aopGet(AOP(left),offset,FALSE,FALSE));
5433 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5434 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5436 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5437 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5443 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5444 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5445 freeAsmop(result,NULL,ic,TRUE);
5448 /*-----------------------------------------------------------------*/
5449 /* genOr - code for or */
5450 /*-----------------------------------------------------------------*/
5451 static void genOr (iCode *ic, iCode *ifx)
5453 operand *left, *right, *result;
5455 unsigned long lit = 0L;
5457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5459 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5460 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5461 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5463 DEBUGpic14_AopType(__LINE__,left,right,result);
5465 /* if left is a literal & right is not then exchange them */
5466 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5467 AOP_NEEDSACC(left)) {
5468 operand *tmp = right ;
5473 /* if result = right then exchange them */
5474 if(pic14_sameRegs(AOP(result),AOP(right))){
5475 operand *tmp = right ;
5480 /* if right is bit then exchange them */
5481 if (AOP_TYPE(right) == AOP_CRY &&
5482 AOP_TYPE(left) != AOP_CRY){
5483 operand *tmp = right ;
5488 DEBUGpic14_AopType(__LINE__,left,right,result);
5490 if(AOP_TYPE(right) == AOP_LIT)
5491 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5493 size = AOP_SIZE(result);
5497 if (AOP_TYPE(left) == AOP_CRY){
5498 if(AOP_TYPE(right) == AOP_LIT){
5499 // c = bit & literal;
5501 // lit != 0 => result = 1
5502 if(AOP_TYPE(result) == AOP_CRY){
5504 emitpcode(POC_BSF, popGet(AOP(result),0));
5505 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5506 // AOP(result)->aopu.aop_dir,
5507 // AOP(result)->aopu.aop_dir);
5509 continueIfTrue(ifx);
5513 // lit == 0 => result = left
5514 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5516 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5519 if (AOP_TYPE(right) == AOP_CRY){
5520 if(pic14_sameRegs(AOP(result),AOP(left))){
5522 emitpcode(POC_BCF, popGet(AOP(result),0));
5523 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5524 emitpcode(POC_BSF, popGet(AOP(result),0));
5526 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5527 AOP(result)->aopu.aop_dir,
5528 AOP(result)->aopu.aop_dir);
5529 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5530 AOP(right)->aopu.aop_dir,
5531 AOP(right)->aopu.aop_dir);
5532 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5533 AOP(result)->aopu.aop_dir,
5534 AOP(result)->aopu.aop_dir);
5536 if( AOP_TYPE(result) == AOP_ACC) {
5537 emitpcode(POC_MOVLW, popGetLit(0));
5538 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5539 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5540 emitpcode(POC_MOVLW, popGetLit(1));
5544 emitpcode(POC_BCF, popGet(AOP(result),0));
5545 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5546 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5547 emitpcode(POC_BSF, popGet(AOP(result),0));
5549 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5550 AOP(result)->aopu.aop_dir,
5551 AOP(result)->aopu.aop_dir);
5552 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5553 AOP(right)->aopu.aop_dir,
5554 AOP(right)->aopu.aop_dir);
5555 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5556 AOP(left)->aopu.aop_dir,
5557 AOP(left)->aopu.aop_dir);
5558 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5559 AOP(result)->aopu.aop_dir,
5560 AOP(result)->aopu.aop_dir);
5565 symbol *tlbl = newiTempLabel(NULL);
5566 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5569 emitpcode(POC_BCF, popGet(AOP(result),0));
5570 if( AOP_TYPE(right) == AOP_ACC) {
5571 emitpcode(POC_IORLW, popGetLit(0));
5573 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5574 emitpcode(POC_BSF, popGet(AOP(result),0));
5579 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5580 pic14_emitcode(";XXX setb","c");
5581 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5582 AOP(left)->aopu.aop_dir,tlbl->key+100);
5583 pic14_toBoolean(right);
5584 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5585 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5586 jmpTrueOrFalse(ifx, tlbl);
5590 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5597 pic14_outBitC(result);
5599 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5600 genIfxJump(ifx, "c");
5604 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5605 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5606 if((AOP_TYPE(right) == AOP_LIT) &&
5607 (AOP_TYPE(result) == AOP_CRY) &&
5608 (AOP_TYPE(left) != AOP_CRY)){
5610 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5613 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5615 continueIfTrue(ifx);
5618 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5619 // lit = 0, result = boolean(left)
5621 pic14_emitcode(";XXX setb","c");
5622 pic14_toBoolean(right);
5624 symbol *tlbl = newiTempLabel(NULL);
5625 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5627 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5629 genIfxJump (ifx,"a");
5633 pic14_outBitC(result);
5637 /* if left is same as result */
5638 if(pic14_sameRegs(AOP(result),AOP(left))){
5640 for(;size--; offset++,lit>>=8) {
5641 if(AOP_TYPE(right) == AOP_LIT){
5642 if((lit & 0xff) == 0)
5643 /* or'ing with 0 has no effect */
5646 int p = my_powof2(lit & 0xff);
5648 /* only one bit is set in the literal, so use a bsf instruction */
5650 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5652 if(know_W != (int)(lit & 0xff))
5653 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5654 know_W = lit & 0xff;
5655 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5660 if (AOP_TYPE(left) == AOP_ACC) {
5661 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5662 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5664 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5665 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5667 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5668 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5674 // left & result in different registers
5675 if(AOP_TYPE(result) == AOP_CRY){
5677 // if(size), result in bit
5678 // if(!size && ifx), conditional oper: if(left | right)
5679 symbol *tlbl = newiTempLabel(NULL);
5680 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5681 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5685 pic14_emitcode(";XXX setb","c");
5687 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5688 pic14_emitcode(";XXX orl","a,%s",
5689 aopGet(AOP(left),offset,FALSE,FALSE));
5690 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5695 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5696 pic14_outBitC(result);
5698 jmpTrueOrFalse(ifx, tlbl);
5699 } else for(;(size--);offset++){
5701 // result = left & right
5702 if(AOP_TYPE(right) == AOP_LIT){
5703 int t = (lit >> (offset*8)) & 0x0FFL;
5706 if (AOP_TYPE(left) != AOP_ACC) {
5707 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5709 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5713 if (AOP_TYPE(left) == AOP_ACC) {
5714 emitpcode(POC_IORLW, popGetLit(t));
5716 emitpcode(POC_MOVLW, popGetLit(t));
5717 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5719 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5724 // faster than result <- left, anl result,right
5725 // and better if result is SFR
5726 if (AOP_TYPE(left) == AOP_ACC) {
5727 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5728 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5730 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5731 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5733 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5734 pic14_emitcode("iorwf","%s,w",
5735 aopGet(AOP(left),offset,FALSE,FALSE));
5737 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5738 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5743 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5744 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5745 freeAsmop(result,NULL,ic,TRUE);
5748 /*-----------------------------------------------------------------*/
5749 /* genXor - code for xclusive or */
5750 /*-----------------------------------------------------------------*/
5751 static void genXor (iCode *ic, iCode *ifx)
5753 operand *left, *right, *result;
5755 unsigned long lit = 0L;
5757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5759 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5760 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5761 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5763 /* if left is a literal & right is not ||
5764 if left needs acc & right does not */
5765 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5766 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5767 operand *tmp = right ;
5772 /* if result = right then exchange them */
5773 if(pic14_sameRegs(AOP(result),AOP(right))){
5774 operand *tmp = right ;
5779 /* if right is bit then exchange them */
5780 if (AOP_TYPE(right) == AOP_CRY &&
5781 AOP_TYPE(left) != AOP_CRY){
5782 operand *tmp = right ;
5786 if(AOP_TYPE(right) == AOP_LIT)
5787 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5789 size = AOP_SIZE(result);
5793 if (AOP_TYPE(left) == AOP_CRY){
5794 if(AOP_TYPE(right) == AOP_LIT){
5795 // c = bit & literal;
5797 // lit>>1 != 0 => result = 1
5798 if(AOP_TYPE(result) == AOP_CRY){
5800 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5801 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5803 continueIfTrue(ifx);
5806 pic14_emitcode("setb","c");
5810 // lit == 0, result = left
5811 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5813 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5815 // lit == 1, result = not(left)
5816 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5817 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5818 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5819 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5822 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5823 pic14_emitcode("cpl","c");
5830 symbol *tlbl = newiTempLabel(NULL);
5831 if (AOP_TYPE(right) == AOP_CRY){
5833 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5836 int sizer = AOP_SIZE(right);
5838 // if val>>1 != 0, result = 1
5839 pic14_emitcode("setb","c");
5841 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5843 // test the msb of the lsb
5844 pic14_emitcode("anl","a,#0xfe");
5845 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5849 pic14_emitcode("rrc","a");
5851 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5852 pic14_emitcode("cpl","c");
5853 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5858 pic14_outBitC(result);
5860 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5861 genIfxJump(ifx, "c");
5865 if(pic14_sameRegs(AOP(result),AOP(left))){
5866 /* if left is same as result */
5867 for(;size--; offset++) {
5868 if(AOP_TYPE(right) == AOP_LIT){
5869 int t = (lit >> (offset*8)) & 0x0FFL;
5873 if (IS_AOP_PREG(left)) {
5874 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5875 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5876 aopPut(AOP(result),"a",offset);
5878 emitpcode(POC_MOVLW, popGetLit(t));
5879 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5880 pic14_emitcode("xrl","%s,%s",
5881 aopGet(AOP(left),offset,FALSE,TRUE),
5882 aopGet(AOP(right),offset,FALSE,FALSE));
5885 if (AOP_TYPE(left) == AOP_ACC)
5886 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5888 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5889 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5891 if (IS_AOP_PREG(left)) {
5892 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5893 aopPut(AOP(result),"a",offset);
5895 pic14_emitcode("xrl","%s,a",
5896 aopGet(AOP(left),offset,FALSE,TRUE));
5902 // left & result in different registers
5903 if(AOP_TYPE(result) == AOP_CRY){
5905 // if(size), result in bit
5906 // if(!size && ifx), conditional oper: if(left ^ right)
5907 symbol *tlbl = newiTempLabel(NULL);
5908 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5910 pic14_emitcode("setb","c");
5912 if((AOP_TYPE(right) == AOP_LIT) &&
5913 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5914 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5916 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5917 pic14_emitcode("xrl","a,%s",
5918 aopGet(AOP(left),offset,FALSE,FALSE));
5920 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5925 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5926 pic14_outBitC(result);
5928 jmpTrueOrFalse(ifx, tlbl);
5929 } else for(;(size--);offset++){
5931 // result = left & right
5932 if(AOP_TYPE(right) == AOP_LIT){
5933 int t = (lit >> (offset*8)) & 0x0FFL;
5936 if (AOP_TYPE(left) != AOP_ACC) {
5937 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5939 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5940 pic14_emitcode("movf","%s,w",
5941 aopGet(AOP(left),offset,FALSE,FALSE));
5942 pic14_emitcode("movwf","%s",
5943 aopGet(AOP(result),offset,FALSE,FALSE));
5946 if (AOP_TYPE(left) == AOP_ACC) {
5947 emitpcode(POC_XORLW, popGetLit(t));
5949 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5951 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5954 if (AOP_TYPE(left) == AOP_ACC) {
5955 emitpcode(POC_XORLW, popGetLit(t));
5957 emitpcode(POC_MOVLW, popGetLit(t));
5958 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5960 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5961 pic14_emitcode("movlw","0x%x",t);
5962 pic14_emitcode("xorwf","%s,w",
5963 aopGet(AOP(left),offset,FALSE,FALSE));
5964 pic14_emitcode("movwf","%s",
5965 aopGet(AOP(result),offset,FALSE,FALSE));
5971 // faster than result <- left, anl result,right
5972 // and better if result is SFR
5973 if (AOP_TYPE(left) == AOP_ACC) {
5974 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5975 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5977 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5978 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5979 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5980 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5982 if ( AOP_TYPE(result) != AOP_ACC){
5983 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5984 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5990 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5991 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5992 freeAsmop(result,NULL,ic,TRUE);
5995 /*-----------------------------------------------------------------*/
5996 /* genInline - write the inline code out */
5997 /*-----------------------------------------------------------------*/
5998 static void genInline (iCode *ic)
6000 char *buffer, *bp, *bp1;
6002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6004 _G.inLine += (!options.asmpeep);
6006 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6007 strcpy(buffer,IC_INLINE(ic));
6009 /* emit each line as a code */
6015 addpCode2pBlock(pb,AssembleLine(bp1));
6022 pic14_emitcode(bp1,"");
6028 if ((bp1 != bp) && *bp1)
6029 addpCode2pBlock(pb,AssembleLine(bp1));
6033 _G.inLine -= (!options.asmpeep);
6036 /*-----------------------------------------------------------------*/
6037 /* genRRC - rotate right with carry */
6038 /*-----------------------------------------------------------------*/
6039 static void genRRC (iCode *ic)
6041 operand *left , *result ;
6042 int size, offset = 0, same;
6044 /* rotate right with carry */
6046 result=IC_RESULT(ic);
6047 aopOp (left,ic,FALSE);
6048 aopOp (result,ic,FALSE);
6050 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6052 same = pic14_sameRegs(AOP(result),AOP(left));
6054 size = AOP_SIZE(result);
6056 /* get the lsb and put it into the carry */
6057 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6064 emitpcode(POC_RRF, popGet(AOP(left),offset));
6066 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6067 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6073 freeAsmop(left,NULL,ic,TRUE);
6074 freeAsmop(result,NULL,ic,TRUE);
6077 /*-----------------------------------------------------------------*/
6078 /* genRLC - generate code for rotate left with carry */
6079 /*-----------------------------------------------------------------*/
6080 static void genRLC (iCode *ic)
6082 operand *left , *result ;
6083 int size, offset = 0;
6086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6087 /* rotate right with carry */
6089 result=IC_RESULT(ic);
6090 aopOp (left,ic,FALSE);
6091 aopOp (result,ic,FALSE);
6093 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6095 same = pic14_sameRegs(AOP(result),AOP(left));
6097 /* move it to the result */
6098 size = AOP_SIZE(result);
6100 /* get the msb and put it into the carry */
6101 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6108 emitpcode(POC_RLF, popGet(AOP(left),offset));
6110 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6111 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6118 freeAsmop(left,NULL,ic,TRUE);
6119 freeAsmop(result,NULL,ic,TRUE);
6122 /*-----------------------------------------------------------------*/
6123 /* genGetHbit - generates code get highest order bit */
6124 /*-----------------------------------------------------------------*/
6125 static void genGetHbit (iCode *ic)
6127 operand *left, *result;
6129 result=IC_RESULT(ic);
6130 aopOp (left,ic,FALSE);
6131 aopOp (result,ic,FALSE);
6133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6134 /* get the highest order byte into a */
6135 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6136 if(AOP_TYPE(result) == AOP_CRY){
6137 pic14_emitcode("rlc","a");
6138 pic14_outBitC(result);
6141 pic14_emitcode("rl","a");
6142 pic14_emitcode("anl","a,#0x01");
6143 pic14_outAcc(result);
6147 freeAsmop(left,NULL,ic,TRUE);
6148 freeAsmop(result,NULL,ic,TRUE);
6151 /*-----------------------------------------------------------------*/
6152 /* AccRol - rotate left accumulator by known count */
6153 /*-----------------------------------------------------------------*/
6154 static void AccRol (int shCount)
6156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6157 shCount &= 0x0007; // shCount : 0..7
6162 pic14_emitcode("rl","a");
6165 pic14_emitcode("rl","a");
6166 pic14_emitcode("rl","a");
6169 pic14_emitcode("swap","a");
6170 pic14_emitcode("rr","a");
6173 pic14_emitcode("swap","a");
6176 pic14_emitcode("swap","a");
6177 pic14_emitcode("rl","a");
6180 pic14_emitcode("rr","a");
6181 pic14_emitcode("rr","a");
6184 pic14_emitcode("rr","a");
6189 /*-----------------------------------------------------------------*/
6190 /* AccLsh - left shift accumulator by known count */
6191 /*-----------------------------------------------------------------*/
6192 static void AccLsh (int shCount)
6194 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 pic14_emitcode("add","a,acc");
6200 pic14_emitcode("add","a,acc");
6201 pic14_emitcode("add","a,acc");
6203 /* rotate left accumulator */
6205 /* and kill the lower order bits */
6206 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6211 /*-----------------------------------------------------------------*/
6212 /* AccRsh - right shift accumulator by known count */
6213 /*-----------------------------------------------------------------*/
6214 static void AccRsh (int shCount)
6216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6220 pic14_emitcode("rrc","a");
6222 /* rotate right accumulator */
6223 AccRol(8 - shCount);
6224 /* and kill the higher order bits */
6225 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6231 /*-----------------------------------------------------------------*/
6232 /* AccSRsh - signed right shift accumulator by known count */
6233 /*-----------------------------------------------------------------*/
6234 static void AccSRsh (int shCount)
6237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6240 pic14_emitcode("mov","c,acc.7");
6241 pic14_emitcode("rrc","a");
6242 } else if(shCount == 2){
6243 pic14_emitcode("mov","c,acc.7");
6244 pic14_emitcode("rrc","a");
6245 pic14_emitcode("mov","c,acc.7");
6246 pic14_emitcode("rrc","a");
6248 tlbl = newiTempLabel(NULL);
6249 /* rotate right accumulator */
6250 AccRol(8 - shCount);
6251 /* and kill the higher order bits */
6252 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6253 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6254 pic14_emitcode("orl","a,#0x%02x",
6255 (unsigned char)~SRMask[shCount]);
6256 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6261 /*-----------------------------------------------------------------*/
6262 /* shiftR1Left2Result - shift right one byte from left to result */
6263 /*-----------------------------------------------------------------*/
6264 static void shiftR1Left2ResultSigned (operand *left, int offl,
6265 operand *result, int offr,
6270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6272 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6276 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6278 emitpcode(POC_RRF, popGet(AOP(result),offr));
6280 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6281 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6287 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6289 emitpcode(POC_RRF, popGet(AOP(result),offr));
6291 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6292 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6294 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6295 emitpcode(POC_RRF, popGet(AOP(result),offr));
6301 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6303 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6304 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6307 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6308 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6309 emitpcode(POC_ANDLW, popGetLit(0x1f));
6311 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6312 emitpcode(POC_IORLW, popGetLit(0xe0));
6314 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6318 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6319 emitpcode(POC_ANDLW, popGetLit(0x0f));
6320 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6321 emitpcode(POC_IORLW, popGetLit(0xf0));
6322 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6326 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6328 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6329 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6331 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6332 emitpcode(POC_ANDLW, popGetLit(0x07));
6333 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6334 emitpcode(POC_IORLW, popGetLit(0xf8));
6335 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6340 emitpcode(POC_MOVLW, popGetLit(0x00));
6341 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6342 emitpcode(POC_MOVLW, popGetLit(0xfe));
6343 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6344 emitpcode(POC_IORLW, popGetLit(0x01));
6345 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6347 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6348 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6349 emitpcode(POC_DECF, popGet(AOP(result),offr));
6350 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6351 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6357 emitpcode(POC_MOVLW, popGetLit(0x00));
6358 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6359 emitpcode(POC_MOVLW, popGetLit(0xff));
6360 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6362 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6363 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6364 emitpcode(POC_DECF, popGet(AOP(result),offr));
6372 /*-----------------------------------------------------------------*/
6373 /* shiftR1Left2Result - shift right one byte from left to result */
6374 /*-----------------------------------------------------------------*/
6375 static void shiftR1Left2Result (operand *left, int offl,
6376 operand *result, int offr,
6377 int shCount, int sign)
6381 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6383 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6385 /* Copy the msb into the carry if signed. */
6387 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6397 emitpcode(POC_RRF, popGet(AOP(result),offr));
6399 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6400 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406 emitpcode(POC_RRF, popGet(AOP(result),offr));
6408 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6409 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6412 emitpcode(POC_RRF, popGet(AOP(result),offr));
6417 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6419 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6420 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6424 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6425 emitpcode(POC_ANDLW, popGetLit(0x1f));
6426 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6430 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6431 emitpcode(POC_ANDLW, popGetLit(0x0f));
6432 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6436 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6437 emitpcode(POC_ANDLW, popGetLit(0x0f));
6438 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6440 emitpcode(POC_RRF, popGet(AOP(result),offr));
6445 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6446 emitpcode(POC_ANDLW, popGetLit(0x80));
6447 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6448 emitpcode(POC_RLF, popGet(AOP(result),offr));
6449 emitpcode(POC_RLF, popGet(AOP(result),offr));
6454 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6455 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6456 emitpcode(POC_RLF, popGet(AOP(result),offr));
6465 /*-----------------------------------------------------------------*/
6466 /* shiftL1Left2Result - shift left one byte from left to result */
6467 /*-----------------------------------------------------------------*/
6468 static void shiftL1Left2Result (operand *left, int offl,
6469 operand *result, int offr, int shCount)
6474 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6476 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6477 DEBUGpic14_emitcode ("; ***","same = %d",same);
6478 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6480 /* shift left accumulator */
6481 //AccLsh(shCount); // don't comment out just yet...
6482 // aopPut(AOP(result),"a",offr);
6486 /* Shift left 1 bit position */
6487 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6489 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6491 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6492 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6496 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6497 emitpcode(POC_ANDLW,popGetLit(0x7e));
6498 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6499 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6502 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6503 emitpcode(POC_ANDLW,popGetLit(0x3e));
6504 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6505 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6506 emitpcode(POC_RLF, popGet(AOP(result),offr));
6509 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6510 emitpcode(POC_ANDLW, popGetLit(0xf0));
6511 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6514 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6515 emitpcode(POC_ANDLW, popGetLit(0xf0));
6516 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6517 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6520 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6521 emitpcode(POC_ANDLW, popGetLit(0x30));
6522 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6523 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6524 emitpcode(POC_RLF, popGet(AOP(result),offr));
6527 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6528 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6529 emitpcode(POC_RRF, popGet(AOP(result),offr));
6533 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6538 /*-----------------------------------------------------------------*/
6539 /* movLeft2Result - move byte from left to result */
6540 /*-----------------------------------------------------------------*/
6541 static void movLeft2Result (operand *left, int offl,
6542 operand *result, int offr)
6545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6546 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6547 l = aopGet(AOP(left),offl,FALSE,FALSE);
6549 if (*l == '@' && (IS_AOP_PREG(result))) {
6550 pic14_emitcode("mov","a,%s",l);
6551 aopPut(AOP(result),"a",offr);
6553 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6554 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6559 /*-----------------------------------------------------------------*/
6560 /* shiftL2Left2Result - shift left two bytes from left to result */
6561 /*-----------------------------------------------------------------*/
6562 static void shiftL2Left2Result (operand *left, int offl,
6563 operand *result, int offr, int shCount)
6567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6569 if(pic14_sameRegs(AOP(result), AOP(left))) {
6577 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6578 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6579 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_RLF, popGet(AOP(result),offr));
6584 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6590 emitpcode(POC_MOVLW, popGetLit(0x0f));
6591 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6592 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6593 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6594 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6595 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6596 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6598 emitpcode(POC_RLF, popGet(AOP(result),offr));
6599 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6603 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6604 emitpcode(POC_RRF, popGet(AOP(result),offr));
6605 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RRF, popGet(AOP(result),offr));
6607 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_ANDLW,popGetLit(0xc0));
6609 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6610 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6611 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6612 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6615 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6616 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6617 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6619 emitpcode(POC_RRF, popGet(AOP(result),offr));
6629 /* note, use a mov/add for the shift since the mov has a
6630 chance of getting optimized out */
6631 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6632 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6633 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6634 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6635 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6639 emitpcode(POC_RLF, popGet(AOP(result),offr));
6640 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6646 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6647 emitpcode(POC_ANDLW, popGetLit(0xF0));
6648 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6650 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6651 emitpcode(POC_ANDLW, popGetLit(0xF0));
6652 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6653 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6657 emitpcode(POC_RLF, popGet(AOP(result),offr));
6658 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6662 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6663 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6665 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6667 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_RRF, popGet(AOP(result),offr));
6669 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_ANDLW,popGetLit(0xc0));
6671 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6672 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6673 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6674 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6677 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6678 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6679 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6681 emitpcode(POC_RRF, popGet(AOP(result),offr));
6686 /*-----------------------------------------------------------------*/
6687 /* shiftR2Left2Result - shift right two bytes from left to result */
6688 /*-----------------------------------------------------------------*/
6689 static void shiftR2Left2Result (operand *left, int offl,
6690 operand *result, int offr,
6691 int shCount, int sign)
6695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6696 same = pic14_sameRegs(AOP(result), AOP(left));
6698 if(same && ((offl + MSB16) == offr)){
6700 /* don't crash result[offr] */
6701 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6702 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6705 movLeft2Result(left,offl, result, offr);
6706 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6709 /* a:x >> shCount (x = lsb(result))*/
6712 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6714 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6723 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6728 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6729 emitpcode(POC_RRF,popGet(AOP(result),offr));
6731 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6732 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6733 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6734 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6739 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_RRF,popGet(AOP(result),offr));
6750 emitpcode(POC_MOVLW, popGetLit(0xf0));
6751 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6752 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6754 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6756 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6757 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6759 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6760 emitpcode(POC_ANDLW, popGetLit(0x0f));
6761 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6763 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6764 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6765 emitpcode(POC_ANDLW, popGetLit(0xf0));
6766 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6767 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6771 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6772 emitpcode(POC_RRF, popGet(AOP(result),offr));
6776 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6777 emitpcode(POC_BTFSC,
6778 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6779 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6787 emitpcode(POC_RLF, popGet(AOP(result),offr));
6788 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6790 emitpcode(POC_RLF, popGet(AOP(result),offr));
6791 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6792 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6793 emitpcode(POC_ANDLW,popGetLit(0x03));
6795 emitpcode(POC_BTFSC,
6796 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6797 emitpcode(POC_IORLW,popGetLit(0xfc));
6799 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6801 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6804 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6805 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6806 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6807 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6808 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_RLF, popGet(AOP(result),offr));
6810 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6811 emitpcode(POC_ANDLW,popGetLit(0x03));
6813 emitpcode(POC_BTFSC,
6814 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6815 emitpcode(POC_IORLW,popGetLit(0xfc));
6817 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6818 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6825 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6826 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6827 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6828 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6838 /*-----------------------------------------------------------------*/
6839 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6840 /*-----------------------------------------------------------------*/
6841 static void shiftLLeftOrResult (operand *left, int offl,
6842 operand *result, int offr, int shCount)
6844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6845 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6846 /* shift left accumulator */
6848 /* or with result */
6849 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6850 /* back to result */
6851 aopPut(AOP(result),"a",offr);
6854 /*-----------------------------------------------------------------*/
6855 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6856 /*-----------------------------------------------------------------*/
6857 static void shiftRLeftOrResult (operand *left, int offl,
6858 operand *result, int offr, int shCount)
6860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6861 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6862 /* shift right accumulator */
6864 /* or with result */
6865 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6866 /* back to result */
6867 aopPut(AOP(result),"a",offr);
6870 /*-----------------------------------------------------------------*/
6871 /* genlshOne - left shift a one byte quantity by known count */
6872 /*-----------------------------------------------------------------*/
6873 static void genlshOne (operand *result, operand *left, int shCount)
6875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6876 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6879 /*-----------------------------------------------------------------*/
6880 /* genlshTwo - left shift two bytes by known amount != 0 */
6881 /*-----------------------------------------------------------------*/
6882 static void genlshTwo (operand *result,operand *left, int shCount)
6886 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6887 size = pic14_getDataSize(result);
6889 /* if shCount >= 8 */
6895 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6897 movLeft2Result(left, LSB, result, MSB16);
6899 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6902 /* 1 <= shCount <= 7 */
6905 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6907 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6911 /*-----------------------------------------------------------------*/
6912 /* shiftLLong - shift left one long from left to result */
6913 /* offl = LSB or MSB16 */
6914 /*-----------------------------------------------------------------*/
6915 static void shiftLLong (operand *left, operand *result, int offr )
6918 int size = AOP_SIZE(result);
6920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6921 if(size >= LSB+offr){
6922 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6924 pic14_emitcode("add","a,acc");
6925 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6926 size >= MSB16+offr && offr != LSB )
6927 pic14_emitcode("xch","a,%s",
6928 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6930 aopPut(AOP(result),"a",LSB+offr);
6933 if(size >= MSB16+offr){
6934 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6935 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6938 pic14_emitcode("rlc","a");
6939 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6940 size >= MSB24+offr && offr != LSB)
6941 pic14_emitcode("xch","a,%s",
6942 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6944 aopPut(AOP(result),"a",MSB16+offr);
6947 if(size >= MSB24+offr){
6948 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6949 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6952 pic14_emitcode("rlc","a");
6953 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6954 size >= MSB32+offr && offr != LSB )
6955 pic14_emitcode("xch","a,%s",
6956 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6958 aopPut(AOP(result),"a",MSB24+offr);
6961 if(size > MSB32+offr){
6962 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6963 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6966 pic14_emitcode("rlc","a");
6967 aopPut(AOP(result),"a",MSB32+offr);
6970 aopPut(AOP(result),zero,LSB);
6973 /*-----------------------------------------------------------------*/
6974 /* genlshFour - shift four byte by a known amount != 0 */
6975 /*-----------------------------------------------------------------*/
6976 static void genlshFour (operand *result, operand *left, int shCount)
6980 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6981 size = AOP_SIZE(result);
6983 /* if shifting more that 3 bytes */
6984 if (shCount >= 24 ) {
6987 /* lowest order of left goes to the highest
6988 order of the destination */
6989 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6991 movLeft2Result(left, LSB, result, MSB32);
6992 aopPut(AOP(result),zero,LSB);
6993 aopPut(AOP(result),zero,MSB16);
6994 aopPut(AOP(result),zero,MSB32);
6998 /* more than two bytes */
6999 else if ( shCount >= 16 ) {
7000 /* lower order two bytes goes to higher order two bytes */
7002 /* if some more remaining */
7004 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7006 movLeft2Result(left, MSB16, result, MSB32);
7007 movLeft2Result(left, LSB, result, MSB24);
7009 aopPut(AOP(result),zero,MSB16);
7010 aopPut(AOP(result),zero,LSB);
7014 /* if more than 1 byte */
7015 else if ( shCount >= 8 ) {
7016 /* lower order three bytes goes to higher order three bytes */
7020 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7022 movLeft2Result(left, LSB, result, MSB16);
7024 else{ /* size = 4 */
7026 movLeft2Result(left, MSB24, result, MSB32);
7027 movLeft2Result(left, MSB16, result, MSB24);
7028 movLeft2Result(left, LSB, result, MSB16);
7029 aopPut(AOP(result),zero,LSB);
7031 else if(shCount == 1)
7032 shiftLLong(left, result, MSB16);
7034 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7035 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7036 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7037 aopPut(AOP(result),zero,LSB);
7042 /* 1 <= shCount <= 7 */
7043 else if(shCount <= 2){
7044 shiftLLong(left, result, LSB);
7046 shiftLLong(result, result, LSB);
7048 /* 3 <= shCount <= 7, optimize */
7050 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7051 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7052 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7056 /*-----------------------------------------------------------------*/
7057 /* genLeftShiftLiteral - left shifting by known count */
7058 /*-----------------------------------------------------------------*/
7059 static void genLeftShiftLiteral (operand *left,
7064 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7067 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7068 freeAsmop(right,NULL,ic,TRUE);
7070 aopOp(left,ic,FALSE);
7071 aopOp(result,ic,FALSE);
7073 size = getSize(operandType(result));
7076 pic14_emitcode("; shift left ","result %d, left %d",size,
7080 /* I suppose that the left size >= result size */
7083 movLeft2Result(left, size, result, size);
7087 else if(shCount >= (size * 8))
7089 aopPut(AOP(result),zero,size);
7093 genlshOne (result,left,shCount);
7098 genlshTwo (result,left,shCount);
7102 genlshFour (result,left,shCount);
7106 freeAsmop(left,NULL,ic,TRUE);
7107 freeAsmop(result,NULL,ic,TRUE);
7110 /*-----------------------------------------------------------------*
7111 * genMultiAsm - repeat assembly instruction for size of register.
7112 * if endian == 1, then the high byte (i.e base address + size of
7113 * register) is used first else the low byte is used first;
7114 *-----------------------------------------------------------------*/
7115 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7133 emitpcode(poc, popGet(AOP(reg),offset));
7138 /*-----------------------------------------------------------------*/
7139 /* genLeftShift - generates code for left shifting */
7140 /*-----------------------------------------------------------------*/
7141 static void genLeftShift (iCode *ic)
7143 operand *left,*right, *result;
7146 symbol *tlbl , *tlbl1;
7149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7151 right = IC_RIGHT(ic);
7153 result = IC_RESULT(ic);
7155 aopOp(right,ic,FALSE);
7157 /* if the shift count is known then do it
7158 as efficiently as possible */
7159 if (AOP_TYPE(right) == AOP_LIT) {
7160 genLeftShiftLiteral (left,right,result,ic);
7164 /* shift count is unknown then we have to form
7165 a loop get the loop count in B : Note: we take
7166 only the lower order byte since shifting
7167 more that 32 bits make no sense anyway, ( the
7168 largest size of an object can be only 32 bits ) */
7171 aopOp(left,ic,FALSE);
7172 aopOp(result,ic,FALSE);
7174 /* now move the left to the result if they are not the
7176 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7177 AOP_SIZE(result) > 1) {
7179 size = AOP_SIZE(result);
7182 l = aopGet(AOP(left),offset,FALSE,TRUE);
7183 if (*l == '@' && (IS_AOP_PREG(result))) {
7185 pic14_emitcode("mov","a,%s",l);
7186 aopPut(AOP(result),"a",offset);
7188 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7189 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7190 //aopPut(AOP(result),l,offset);
7196 size = AOP_SIZE(result);
7198 /* if it is only one byte then */
7200 if(optimized_for_speed) {
7201 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7202 emitpcode(POC_ANDLW, popGetLit(0xf0));
7203 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7204 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7205 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7206 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7207 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7208 emitpcode(POC_RLFW, popGet(AOP(result),0));
7209 emitpcode(POC_ANDLW, popGetLit(0xfe));
7210 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7211 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7212 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7215 tlbl = newiTempLabel(NULL);
7216 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7217 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7218 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7221 emitpcode(POC_COMFW, popGet(AOP(right),0));
7222 emitpcode(POC_RRF, popGet(AOP(result),0));
7223 emitpLabel(tlbl->key);
7224 emitpcode(POC_RLF, popGet(AOP(result),0));
7225 emitpcode(POC_ADDLW, popGetLit(1));
7227 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7232 if (pic14_sameRegs(AOP(left),AOP(result))) {
7234 tlbl = newiTempLabel(NULL);
7235 emitpcode(POC_COMFW, popGet(AOP(right),0));
7236 genMultiAsm(POC_RRF, result, size,1);
7237 emitpLabel(tlbl->key);
7238 genMultiAsm(POC_RLF, result, size,0);
7239 emitpcode(POC_ADDLW, popGetLit(1));
7241 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7245 //tlbl = newiTempLabel(NULL);
7247 //tlbl1 = newiTempLabel(NULL);
7249 //reAdjustPreg(AOP(result));
7251 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7252 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7253 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7255 //pic14_emitcode("add","a,acc");
7256 //aopPut(AOP(result),"a",offset++);
7258 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7260 // pic14_emitcode("rlc","a");
7261 // aopPut(AOP(result),"a",offset++);
7263 //reAdjustPreg(AOP(result));
7265 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7266 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7269 tlbl = newiTempLabel(NULL);
7270 tlbl1= newiTempLabel(NULL);
7272 size = AOP_SIZE(result);
7275 pctemp = popGetTempReg(); /* grab a temporary working register. */
7277 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7279 /* offset should be 0, 1 or 3 */
7280 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7282 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7284 emitpcode(POC_MOVWF, pctemp);
7287 emitpLabel(tlbl->key);
7290 emitpcode(POC_RLF, popGet(AOP(result),0));
7292 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7294 emitpcode(POC_DECFSZ, pctemp);
7295 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7296 emitpLabel(tlbl1->key);
7298 popReleaseTempReg(pctemp);
7302 freeAsmop (right,NULL,ic,TRUE);
7303 freeAsmop(left,NULL,ic,TRUE);
7304 freeAsmop(result,NULL,ic,TRUE);
7307 /*-----------------------------------------------------------------*/
7308 /* genrshOne - right shift a one byte quantity by known count */
7309 /*-----------------------------------------------------------------*/
7310 static void genrshOne (operand *result, operand *left,
7311 int shCount, int sign)
7313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7314 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7317 /*-----------------------------------------------------------------*/
7318 /* genrshTwo - right shift two bytes by known amount != 0 */
7319 /*-----------------------------------------------------------------*/
7320 static void genrshTwo (operand *result,operand *left,
7321 int shCount, int sign)
7323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7324 /* if shCount >= 8 */
7328 shiftR1Left2Result(left, MSB16, result, LSB,
7331 movLeft2Result(left, MSB16, result, LSB);
7333 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7336 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7337 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7341 /* 1 <= shCount <= 7 */
7343 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7346 /*-----------------------------------------------------------------*/
7347 /* shiftRLong - shift right one long from left to result */
7348 /* offl = LSB or MSB16 */
7349 /*-----------------------------------------------------------------*/
7350 static void shiftRLong (operand *left, int offl,
7351 operand *result, int sign)
7353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7355 pic14_emitcode("clr","c");
7356 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7358 pic14_emitcode("mov","c,acc.7");
7359 pic14_emitcode("rrc","a");
7360 aopPut(AOP(result),"a",MSB32-offl);
7362 /* add sign of "a" */
7363 addSign(result, MSB32, sign);
7365 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7366 pic14_emitcode("rrc","a");
7367 aopPut(AOP(result),"a",MSB24-offl);
7369 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7370 pic14_emitcode("rrc","a");
7371 aopPut(AOP(result),"a",MSB16-offl);
7374 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7375 pic14_emitcode("rrc","a");
7376 aopPut(AOP(result),"a",LSB);
7380 /*-----------------------------------------------------------------*/
7381 /* genrshFour - shift four byte by a known amount != 0 */
7382 /*-----------------------------------------------------------------*/
7383 static void genrshFour (operand *result, operand *left,
7384 int shCount, int sign)
7386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7387 /* if shifting more that 3 bytes */
7388 if(shCount >= 24 ) {
7391 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7393 movLeft2Result(left, MSB32, result, LSB);
7395 addSign(result, MSB16, sign);
7397 else if(shCount >= 16){
7400 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7402 movLeft2Result(left, MSB24, result, LSB);
7403 movLeft2Result(left, MSB32, result, MSB16);
7405 addSign(result, MSB24, sign);
7407 else if(shCount >= 8){
7410 shiftRLong(left, MSB16, result, sign);
7411 else if(shCount == 0){
7412 movLeft2Result(left, MSB16, result, LSB);
7413 movLeft2Result(left, MSB24, result, MSB16);
7414 movLeft2Result(left, MSB32, result, MSB24);
7415 addSign(result, MSB32, sign);
7418 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7419 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7420 /* the last shift is signed */
7421 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7422 addSign(result, MSB32, sign);
7425 else{ /* 1 <= shCount <= 7 */
7427 shiftRLong(left, LSB, result, sign);
7429 shiftRLong(result, LSB, result, sign);
7432 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7433 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7434 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7439 /*-----------------------------------------------------------------*/
7440 /* genRightShiftLiteral - right shifting by known count */
7441 /*-----------------------------------------------------------------*/
7442 static void genRightShiftLiteral (operand *left,
7448 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7452 freeAsmop(right,NULL,ic,TRUE);
7454 aopOp(left,ic,FALSE);
7455 aopOp(result,ic,FALSE);
7458 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7462 lsize = pic14_getDataSize(left);
7463 res_size = pic14_getDataSize(result);
7464 /* test the LEFT size !!! */
7466 /* I suppose that the left size >= result size */
7469 movLeft2Result(left, lsize, result, res_size);
7472 else if(shCount >= (lsize * 8)){
7475 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7477 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7478 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7483 emitpcode(POC_MOVLW, popGetLit(0));
7484 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7485 emitpcode(POC_MOVLW, popGetLit(0xff));
7487 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7492 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7499 genrshOne (result,left,shCount,sign);
7503 genrshTwo (result,left,shCount,sign);
7507 genrshFour (result,left,shCount,sign);
7515 freeAsmop(left,NULL,ic,TRUE);
7516 freeAsmop(result,NULL,ic,TRUE);
7519 /*-----------------------------------------------------------------*/
7520 /* genSignedRightShift - right shift of signed number */
7521 /*-----------------------------------------------------------------*/
7522 static void genSignedRightShift (iCode *ic)
7524 operand *right, *left, *result;
7527 symbol *tlbl, *tlbl1 ;
7530 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7532 /* we do it the hard way put the shift count in b
7533 and loop thru preserving the sign */
7534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7536 right = IC_RIGHT(ic);
7538 result = IC_RESULT(ic);
7540 aopOp(right,ic,FALSE);
7541 aopOp(left,ic,FALSE);
7542 aopOp(result,ic,FALSE);
7545 if ( AOP_TYPE(right) == AOP_LIT) {
7546 genRightShiftLiteral (left,right,result,ic,1);
7549 /* shift count is unknown then we have to form
7550 a loop get the loop count in B : Note: we take
7551 only the lower order byte since shifting
7552 more that 32 bits make no sense anyway, ( the
7553 largest size of an object can be only 32 bits ) */
7555 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7556 //pic14_emitcode("inc","b");
7557 //freeAsmop (right,NULL,ic,TRUE);
7558 //aopOp(left,ic,FALSE);
7559 //aopOp(result,ic,FALSE);
7561 /* now move the left to the result if they are not the
7563 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7564 AOP_SIZE(result) > 1) {
7566 size = AOP_SIZE(result);
7570 l = aopGet(AOP(left),offset,FALSE,TRUE);
7571 if (*l == '@' && IS_AOP_PREG(result)) {
7573 pic14_emitcode("mov","a,%s",l);
7574 aopPut(AOP(result),"a",offset);
7576 aopPut(AOP(result),l,offset);
7578 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7579 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7585 /* mov the highest order bit to OVR */
7586 tlbl = newiTempLabel(NULL);
7587 tlbl1= newiTempLabel(NULL);
7589 size = AOP_SIZE(result);
7592 pctemp = popGetTempReg(); /* grab a temporary working register. */
7594 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7596 /* offset should be 0, 1 or 3 */
7597 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7599 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7601 emitpcode(POC_MOVWF, pctemp);
7604 emitpLabel(tlbl->key);
7606 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7607 emitpcode(POC_RRF, popGet(AOP(result),offset));
7610 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7613 emitpcode(POC_DECFSZ, pctemp);
7614 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7615 emitpLabel(tlbl1->key);
7617 popReleaseTempReg(pctemp);
7619 size = AOP_SIZE(result);
7621 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7622 pic14_emitcode("rlc","a");
7623 pic14_emitcode("mov","ov,c");
7624 /* if it is only one byte then */
7626 l = aopGet(AOP(left),0,FALSE,FALSE);
7628 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7629 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7630 pic14_emitcode("mov","c,ov");
7631 pic14_emitcode("rrc","a");
7632 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7633 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7634 aopPut(AOP(result),"a",0);
7638 reAdjustPreg(AOP(result));
7639 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7640 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7641 pic14_emitcode("mov","c,ov");
7643 l = aopGet(AOP(result),offset,FALSE,FALSE);
7645 pic14_emitcode("rrc","a");
7646 aopPut(AOP(result),"a",offset--);
7648 reAdjustPreg(AOP(result));
7649 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7650 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7655 freeAsmop(left,NULL,ic,TRUE);
7656 freeAsmop(result,NULL,ic,TRUE);
7657 freeAsmop(right,NULL,ic,TRUE);
7660 /*-----------------------------------------------------------------*/
7661 /* genRightShift - generate code for right shifting */
7662 /*-----------------------------------------------------------------*/
7663 static void genRightShift (iCode *ic)
7665 operand *right, *left, *result;
7669 symbol *tlbl, *tlbl1 ;
7671 /* if signed then we do it the hard way preserve the
7672 sign bit moving it inwards */
7673 retype = getSpec(operandType(IC_RESULT(ic)));
7674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7676 if (!SPEC_USIGN(retype)) {
7677 genSignedRightShift (ic);
7681 /* signed & unsigned types are treated the same : i.e. the
7682 signed is NOT propagated inwards : quoting from the
7683 ANSI - standard : "for E1 >> E2, is equivalent to division
7684 by 2**E2 if unsigned or if it has a non-negative value,
7685 otherwise the result is implementation defined ", MY definition
7686 is that the sign does not get propagated */
7688 right = IC_RIGHT(ic);
7690 result = IC_RESULT(ic);
7692 aopOp(right,ic,FALSE);
7694 /* if the shift count is known then do it
7695 as efficiently as possible */
7696 if (AOP_TYPE(right) == AOP_LIT) {
7697 genRightShiftLiteral (left,right,result,ic, 0);
7701 /* shift count is unknown then we have to form
7702 a loop get the loop count in B : Note: we take
7703 only the lower order byte since shifting
7704 more that 32 bits make no sense anyway, ( the
7705 largest size of an object can be only 32 bits ) */
7707 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7708 pic14_emitcode("inc","b");
7709 aopOp(left,ic,FALSE);
7710 aopOp(result,ic,FALSE);
7712 /* now move the left to the result if they are not the
7714 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7715 AOP_SIZE(result) > 1) {
7717 size = AOP_SIZE(result);
7720 l = aopGet(AOP(left),offset,FALSE,TRUE);
7721 if (*l == '@' && IS_AOP_PREG(result)) {
7723 pic14_emitcode("mov","a,%s",l);
7724 aopPut(AOP(result),"a",offset);
7726 aopPut(AOP(result),l,offset);
7731 tlbl = newiTempLabel(NULL);
7732 tlbl1= newiTempLabel(NULL);
7733 size = AOP_SIZE(result);
7736 /* if it is only one byte then */
7739 tlbl = newiTempLabel(NULL);
7740 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7741 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7742 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7745 emitpcode(POC_COMFW, popGet(AOP(right),0));
7746 emitpcode(POC_RLF, popGet(AOP(result),0));
7747 emitpLabel(tlbl->key);
7748 emitpcode(POC_RRF, popGet(AOP(result),0));
7749 emitpcode(POC_ADDLW, popGetLit(1));
7751 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7756 reAdjustPreg(AOP(result));
7757 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7758 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7761 l = aopGet(AOP(result),offset,FALSE,FALSE);
7763 pic14_emitcode("rrc","a");
7764 aopPut(AOP(result),"a",offset--);
7766 reAdjustPreg(AOP(result));
7768 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7769 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7772 freeAsmop(left,NULL,ic,TRUE);
7773 freeAsmop (right,NULL,ic,TRUE);
7774 freeAsmop(result,NULL,ic,TRUE);
7777 /*-----------------------------------------------------------------*/
7778 /* genUnpackBits - generates code for unpacking bits */
7779 /*-----------------------------------------------------------------*/
7780 static void genUnpackBits (operand *result, char *rname, int ptype)
7787 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7788 etype = getSpec(operandType(result));
7790 /* read the first byte */
7795 pic14_emitcode("mov","a,@%s",rname);
7799 pic14_emitcode("movx","a,@%s",rname);
7803 pic14_emitcode("movx","a,@dptr");
7807 pic14_emitcode("clr","a");
7808 pic14_emitcode("movc","a","@a+dptr");
7812 pic14_emitcode("lcall","__gptrget");
7816 /* if we have bitdisplacement then it fits */
7817 /* into this byte completely or if length is */
7818 /* less than a byte */
7819 if ((shCnt = SPEC_BSTR(etype)) ||
7820 (SPEC_BLEN(etype) <= 8)) {
7822 /* shift right acc */
7825 pic14_emitcode("anl","a,#0x%02x",
7826 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7827 aopPut(AOP(result),"a",offset);
7831 /* bit field did not fit in a byte */
7832 rlen = SPEC_BLEN(etype) - 8;
7833 aopPut(AOP(result),"a",offset++);
7840 pic14_emitcode("inc","%s",rname);
7841 pic14_emitcode("mov","a,@%s",rname);
7845 pic14_emitcode("inc","%s",rname);
7846 pic14_emitcode("movx","a,@%s",rname);
7850 pic14_emitcode("inc","dptr");
7851 pic14_emitcode("movx","a,@dptr");
7855 pic14_emitcode("clr","a");
7856 pic14_emitcode("inc","dptr");
7857 pic14_emitcode("movc","a","@a+dptr");
7861 pic14_emitcode("inc","dptr");
7862 pic14_emitcode("lcall","__gptrget");
7867 /* if we are done */
7871 aopPut(AOP(result),"a",offset++);
7876 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7877 aopPut(AOP(result),"a",offset);
7884 /*-----------------------------------------------------------------*/
7885 /* genDataPointerGet - generates code when ptr offset is known */
7886 /*-----------------------------------------------------------------*/
7887 static void genDataPointerGet (operand *left,
7891 int size , offset = 0;
7894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7897 /* optimization - most of the time, left and result are the same
7898 * address, but different types. for the pic code, we could omit
7902 aopOp(result,ic,TRUE);
7904 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7906 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7908 size = AOP_SIZE(result);
7911 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7915 freeAsmop(left,NULL,ic,TRUE);
7916 freeAsmop(result,NULL,ic,TRUE);
7919 /*-----------------------------------------------------------------*/
7920 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7921 /*-----------------------------------------------------------------*/
7922 static void genNearPointerGet (operand *left,
7927 //regs *preg = NULL ;
7929 sym_link *rtype, *retype;
7930 sym_link *ltype = operandType(left);
7933 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7935 rtype = operandType(result);
7936 retype= getSpec(rtype);
7938 aopOp(left,ic,FALSE);
7940 /* if left is rematerialisable and
7941 result is not bit variable type and
7942 the left is pointer to data space i.e
7943 lower 128 bytes of space */
7944 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7945 !IS_BITVAR(retype) &&
7946 DCL_TYPE(ltype) == POINTER) {
7947 //genDataPointerGet (left,result,ic);
7951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7953 /* if the value is already in a pointer register
7954 then don't need anything more */
7955 if (!AOP_INPREG(AOP(left))) {
7956 /* otherwise get a free pointer register */
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7960 preg = getFreePtr(ic,&aop,FALSE);
7961 pic14_emitcode("mov","%s,%s",
7963 aopGet(AOP(left),0,FALSE,TRUE));
7964 rname = preg->name ;
7968 rname = aopGet(AOP(left),0,FALSE,FALSE);
7970 aopOp (result,ic,FALSE);
7972 /* if bitfield then unpack the bits */
7973 if (IS_BITFIELD(retype))
7974 genUnpackBits (result,rname,POINTER);
7976 /* we have can just get the values */
7977 int size = AOP_SIZE(result);
7980 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7982 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7983 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7985 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7986 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7988 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7992 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7994 pic14_emitcode("mov","a,@%s",rname);
7995 aopPut(AOP(result),"a",offset);
7997 sprintf(buffer,"@%s",rname);
7998 aopPut(AOP(result),buffer,offset);
8002 pic14_emitcode("inc","%s",rname);
8007 /* now some housekeeping stuff */
8009 /* we had to allocate for this iCode */
8010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8011 freeAsmop(NULL,aop,ic,TRUE);
8013 /* we did not allocate which means left
8014 already in a pointer register, then
8015 if size > 0 && this could be used again
8016 we have to point it back to where it
8018 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 if (AOP_SIZE(result) > 1 &&
8020 !OP_SYMBOL(left)->remat &&
8021 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8023 int size = AOP_SIZE(result) - 1;
8025 pic14_emitcode("dec","%s",rname);
8030 freeAsmop(left,NULL,ic,TRUE);
8031 freeAsmop(result,NULL,ic,TRUE);
8035 /*-----------------------------------------------------------------*/
8036 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8037 /*-----------------------------------------------------------------*/
8038 static void genPagedPointerGet (operand *left,
8045 sym_link *rtype, *retype;
8047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8049 rtype = operandType(result);
8050 retype= getSpec(rtype);
8052 aopOp(left,ic,FALSE);
8054 /* if the value is already in a pointer register
8055 then don't need anything more */
8056 if (!AOP_INPREG(AOP(left))) {
8057 /* otherwise get a free pointer register */
8059 preg = getFreePtr(ic,&aop,FALSE);
8060 pic14_emitcode("mov","%s,%s",
8062 aopGet(AOP(left),0,FALSE,TRUE));
8063 rname = preg->name ;
8065 rname = aopGet(AOP(left),0,FALSE,FALSE);
8067 freeAsmop(left,NULL,ic,TRUE);
8068 aopOp (result,ic,FALSE);
8070 /* if bitfield then unpack the bits */
8071 if (IS_BITFIELD(retype))
8072 genUnpackBits (result,rname,PPOINTER);
8074 /* we have can just get the values */
8075 int size = AOP_SIZE(result);
8080 pic14_emitcode("movx","a,@%s",rname);
8081 aopPut(AOP(result),"a",offset);
8086 pic14_emitcode("inc","%s",rname);
8090 /* now some housekeeping stuff */
8092 /* we had to allocate for this iCode */
8093 freeAsmop(NULL,aop,ic,TRUE);
8095 /* we did not allocate which means left
8096 already in a pointer register, then
8097 if size > 0 && this could be used again
8098 we have to point it back to where it
8100 if (AOP_SIZE(result) > 1 &&
8101 !OP_SYMBOL(left)->remat &&
8102 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8104 int size = AOP_SIZE(result) - 1;
8106 pic14_emitcode("dec","%s",rname);
8111 freeAsmop(result,NULL,ic,TRUE);
8116 /*-----------------------------------------------------------------*/
8117 /* genFarPointerGet - gget value from far space */
8118 /*-----------------------------------------------------------------*/
8119 static void genFarPointerGet (operand *left,
8120 operand *result, iCode *ic)
8123 sym_link *retype = getSpec(operandType(result));
8125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8127 aopOp(left,ic,FALSE);
8129 /* if the operand is already in dptr
8130 then we do nothing else we move the value to dptr */
8131 if (AOP_TYPE(left) != AOP_STR) {
8132 /* if this is remateriazable */
8133 if (AOP_TYPE(left) == AOP_IMMD)
8134 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8135 else { /* we need to get it byte by byte */
8136 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8137 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8138 if (options.model == MODEL_FLAT24)
8140 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8144 /* so dptr know contains the address */
8145 freeAsmop(left,NULL,ic,TRUE);
8146 aopOp(result,ic,FALSE);
8148 /* if bit then unpack */
8149 if (IS_BITFIELD(retype))
8150 genUnpackBits(result,"dptr",FPOINTER);
8152 size = AOP_SIZE(result);
8156 pic14_emitcode("movx","a,@dptr");
8157 aopPut(AOP(result),"a",offset++);
8159 pic14_emitcode("inc","dptr");
8163 freeAsmop(result,NULL,ic,TRUE);
8166 /*-----------------------------------------------------------------*/
8167 /* genCodePointerGet - get value from code space */
8168 /*-----------------------------------------------------------------*/
8169 static void genCodePointerGet (operand *left,
8170 operand *result, iCode *ic)
8173 sym_link *retype = getSpec(operandType(result));
8175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8177 aopOp(left,ic,FALSE);
8179 /* if the operand is already in dptr
8180 then we do nothing else we move the value to dptr */
8181 if (AOP_TYPE(left) != AOP_STR) {
8182 /* if this is remateriazable */
8183 if (AOP_TYPE(left) == AOP_IMMD)
8184 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8185 else { /* we need to get it byte by byte */
8186 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8187 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8188 if (options.model == MODEL_FLAT24)
8190 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8194 /* so dptr know contains the address */
8195 freeAsmop(left,NULL,ic,TRUE);
8196 aopOp(result,ic,FALSE);
8198 /* if bit then unpack */
8199 if (IS_BITFIELD(retype))
8200 genUnpackBits(result,"dptr",CPOINTER);
8202 size = AOP_SIZE(result);
8206 pic14_emitcode("clr","a");
8207 pic14_emitcode("movc","a,@a+dptr");
8208 aopPut(AOP(result),"a",offset++);
8210 pic14_emitcode("inc","dptr");
8214 freeAsmop(result,NULL,ic,TRUE);
8217 /*-----------------------------------------------------------------*/
8218 /* genGenPointerGet - gget value from generic pointer space */
8219 /*-----------------------------------------------------------------*/
8220 static void genGenPointerGet (operand *left,
8221 operand *result, iCode *ic)
8224 sym_link *retype = getSpec(operandType(result));
8226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8227 aopOp(left,ic,FALSE);
8228 aopOp(result,ic,FALSE);
8231 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8233 /* if the operand is already in dptr
8234 then we do nothing else we move the value to dptr */
8235 // if (AOP_TYPE(left) != AOP_STR) {
8236 /* if this is remateriazable */
8237 if (AOP_TYPE(left) == AOP_IMMD) {
8238 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8239 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8241 else { /* we need to get it byte by byte */
8243 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8244 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8246 size = AOP_SIZE(result);
8250 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8251 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8253 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8258 /* so dptr know contains the address */
8260 /* if bit then unpack */
8261 //if (IS_BITFIELD(retype))
8262 // genUnpackBits(result,"dptr",GPOINTER);
8265 freeAsmop(left,NULL,ic,TRUE);
8266 freeAsmop(result,NULL,ic,TRUE);
8270 /*-----------------------------------------------------------------*/
8271 /* genConstPointerGet - get value from const generic pointer space */
8272 /*-----------------------------------------------------------------*/
8273 static void genConstPointerGet (operand *left,
8274 operand *result, iCode *ic)
8276 //sym_link *retype = getSpec(operandType(result));
8277 symbol *albl = newiTempLabel(NULL);
8278 symbol *blbl = newiTempLabel(NULL);
8282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8283 aopOp(left,ic,FALSE);
8284 aopOp(result,ic,FALSE);
8287 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8289 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8291 emitpcode(POC_CALL,popGetLabel(albl->key));
8292 pcop = popGetLabel(blbl->key);
8293 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8294 emitpcode(POC_GOTO,pcop);
8295 emitpLabel(albl->key);
8297 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8299 emitpcode(poc,popGet(AOP(left),1));
8300 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8301 emitpcode(poc,popGet(AOP(left),0));
8302 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8304 emitpLabel(blbl->key);
8306 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8309 freeAsmop(left,NULL,ic,TRUE);
8310 freeAsmop(result,NULL,ic,TRUE);
8313 /*-----------------------------------------------------------------*/
8314 /* genPointerGet - generate code for pointer get */
8315 /*-----------------------------------------------------------------*/
8316 static void genPointerGet (iCode *ic)
8318 operand *left, *result ;
8319 sym_link *type, *etype;
8322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8325 result = IC_RESULT(ic) ;
8327 /* depending on the type of pointer we need to
8328 move it to the correct pointer register */
8329 type = operandType(left);
8330 etype = getSpec(type);
8332 if (IS_PTR_CONST(type))
8333 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8335 /* if left is of type of pointer then it is simple */
8336 if (IS_PTR(type) && !IS_FUNC(type->next))
8337 p_type = DCL_TYPE(type);
8339 /* we have to go by the storage class */
8340 p_type = PTR_TYPE(SPEC_OCLS(etype));
8342 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8344 if (SPEC_OCLS(etype)->codesp ) {
8345 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8346 //p_type = CPOINTER ;
8349 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8350 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8351 /*p_type = FPOINTER ;*/
8353 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8354 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8355 /* p_type = PPOINTER; */
8357 if (SPEC_OCLS(etype) == idata )
8358 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8359 /* p_type = IPOINTER; */
8361 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8362 /* p_type = POINTER ; */
8365 /* now that we have the pointer type we assign
8366 the pointer values */
8371 genNearPointerGet (left,result,ic);
8375 genPagedPointerGet(left,result,ic);
8379 genFarPointerGet (left,result,ic);
8383 genConstPointerGet (left,result,ic);
8384 //pic14_emitcodePointerGet (left,result,ic);
8388 if (IS_PTR_CONST(type))
8389 genConstPointerGet (left,result,ic);
8391 genGenPointerGet (left,result,ic);
8397 /*-----------------------------------------------------------------*/
8398 /* genPackBits - generates code for packed bit storage */
8399 /*-----------------------------------------------------------------*/
8400 static void genPackBits (sym_link *etype ,
8402 char *rname, int p_type)
8410 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8411 blen = SPEC_BLEN(etype);
8412 bstr = SPEC_BSTR(etype);
8414 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8417 /* if the bit lenth is less than or */
8418 /* it exactly fits a byte then */
8419 if (SPEC_BLEN(etype) <= 8 ) {
8420 shCount = SPEC_BSTR(etype) ;
8422 /* shift left acc */
8425 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8430 pic14_emitcode ("mov","b,a");
8431 pic14_emitcode("mov","a,@%s",rname);
8435 pic14_emitcode ("mov","b,a");
8436 pic14_emitcode("movx","a,@dptr");
8440 pic14_emitcode ("push","b");
8441 pic14_emitcode ("push","acc");
8442 pic14_emitcode ("lcall","__gptrget");
8443 pic14_emitcode ("pop","b");
8447 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8448 ((unsigned char)(0xFF << (blen+bstr)) |
8449 (unsigned char)(0xFF >> (8-bstr)) ) );
8450 pic14_emitcode ("orl","a,b");
8451 if (p_type == GPOINTER)
8452 pic14_emitcode("pop","b");
8458 pic14_emitcode("mov","@%s,a",rname);
8462 pic14_emitcode("movx","@dptr,a");
8466 DEBUGpic14_emitcode(";lcall","__gptrput");
8471 if ( SPEC_BLEN(etype) <= 8 )
8474 pic14_emitcode("inc","%s",rname);
8475 rLen = SPEC_BLEN(etype) ;
8477 /* now generate for lengths greater than one byte */
8480 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8490 pic14_emitcode("mov","@%s,a",rname);
8492 pic14_emitcode("mov","@%s,%s",rname,l);
8497 pic14_emitcode("movx","@dptr,a");
8502 DEBUGpic14_emitcode(";lcall","__gptrput");
8505 pic14_emitcode ("inc","%s",rname);
8510 /* last last was not complete */
8512 /* save the byte & read byte */
8515 pic14_emitcode ("mov","b,a");
8516 pic14_emitcode("mov","a,@%s",rname);
8520 pic14_emitcode ("mov","b,a");
8521 pic14_emitcode("movx","a,@dptr");
8525 pic14_emitcode ("push","b");
8526 pic14_emitcode ("push","acc");
8527 pic14_emitcode ("lcall","__gptrget");
8528 pic14_emitcode ("pop","b");
8532 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8533 pic14_emitcode ("orl","a,b");
8536 if (p_type == GPOINTER)
8537 pic14_emitcode("pop","b");
8542 pic14_emitcode("mov","@%s,a",rname);
8546 pic14_emitcode("movx","@dptr,a");
8550 DEBUGpic14_emitcode(";lcall","__gptrput");
8554 /*-----------------------------------------------------------------*/
8555 /* genDataPointerSet - remat pointer to data space */
8556 /*-----------------------------------------------------------------*/
8557 static void genDataPointerSet(operand *right,
8561 int size, offset = 0 ;
8562 char *l, buffer[256];
8564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8565 aopOp(right,ic,FALSE);
8567 l = aopGet(AOP(result),0,FALSE,TRUE);
8568 size = AOP_SIZE(right);
8570 if ( AOP_TYPE(result) == AOP_PCODE) {
8571 fprintf(stderr,"genDataPointerSet %s, %d\n",
8572 AOP(result)->aopu.pcop->name,
8573 PCOI(AOP(result)->aopu.pcop)->offset);
8577 // tsd, was l+1 - the underline `_' prefix was being stripped
8580 sprintf(buffer,"(%s + %d)",l,offset);
8581 fprintf(stderr,"oops %s\n",buffer);
8583 sprintf(buffer,"%s",l);
8585 if (AOP_TYPE(right) == AOP_LIT) {
8586 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8587 lit = lit >> (8*offset);
8589 pic14_emitcode("movlw","%d",lit);
8590 pic14_emitcode("movwf","%s",buffer);
8592 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8593 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8594 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8597 pic14_emitcode("clrf","%s",buffer);
8598 //emitpcode(POC_CLRF, popRegFromString(buffer));
8599 emitpcode(POC_CLRF, popGet(AOP(result),0));
8602 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8603 pic14_emitcode("movwf","%s",buffer);
8605 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8606 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8607 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8614 freeAsmop(right,NULL,ic,TRUE);
8615 freeAsmop(result,NULL,ic,TRUE);
8618 /*-----------------------------------------------------------------*/
8619 /* genNearPointerSet - pic14_emitcode for near pointer put */
8620 /*-----------------------------------------------------------------*/
8621 static void genNearPointerSet (operand *right,
8628 sym_link *ptype = operandType(result);
8631 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8632 retype= getSpec(operandType(right));
8634 aopOp(result,ic,FALSE);
8637 /* if the result is rematerializable &
8638 in data space & not a bit variable */
8639 //if (AOP_TYPE(result) == AOP_IMMD &&
8640 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8641 DCL_TYPE(ptype) == POINTER &&
8642 !IS_BITFIELD(retype)) {
8643 genDataPointerSet (right,result,ic);
8644 freeAsmop(result,NULL,ic,TRUE);
8648 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8649 aopOp(right,ic,FALSE);
8650 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8652 /* if the value is already in a pointer register
8653 then don't need anything more */
8654 if (!AOP_INPREG(AOP(result))) {
8655 /* otherwise get a free pointer register */
8656 //aop = newAsmop(0);
8657 //preg = getFreePtr(ic,&aop,FALSE);
8658 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8659 //pic14_emitcode("mov","%s,%s",
8661 // aopGet(AOP(result),0,FALSE,TRUE));
8662 //rname = preg->name ;
8663 //pic14_emitcode("movwf","fsr");
8664 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8665 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8666 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8667 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8671 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8674 /* if bitfield then unpack the bits */
8675 if (IS_BITFIELD(retype)) {
8676 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8677 "The programmer is obviously confused");
8678 //genPackBits (retype,right,rname,POINTER);
8682 /* we have can just get the values */
8683 int size = AOP_SIZE(right);
8686 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8688 l = aopGet(AOP(right),offset,FALSE,TRUE);
8691 //pic14_emitcode("mov","@%s,a",rname);
8692 pic14_emitcode("movf","indf,w ;1");
8695 if (AOP_TYPE(right) == AOP_LIT) {
8696 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8698 pic14_emitcode("movlw","%s",l);
8699 pic14_emitcode("movwf","indf ;2");
8701 pic14_emitcode("clrf","indf");
8703 pic14_emitcode("movf","%s,w",l);
8704 pic14_emitcode("movwf","indf ;2");
8706 //pic14_emitcode("mov","@%s,%s",rname,l);
8709 pic14_emitcode("incf","fsr,f ;3");
8710 //pic14_emitcode("inc","%s",rname);
8715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8716 /* now some housekeeping stuff */
8718 /* we had to allocate for this iCode */
8719 freeAsmop(NULL,aop,ic,TRUE);
8721 /* we did not allocate which means left
8722 already in a pointer register, then
8723 if size > 0 && this could be used again
8724 we have to point it back to where it
8726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8727 if (AOP_SIZE(right) > 1 &&
8728 !OP_SYMBOL(result)->remat &&
8729 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8731 int size = AOP_SIZE(right) - 1;
8733 pic14_emitcode("decf","fsr,f");
8734 //pic14_emitcode("dec","%s",rname);
8738 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8741 freeAsmop(right,NULL,ic,TRUE);
8742 freeAsmop(result,NULL,ic,TRUE);
8745 /*-----------------------------------------------------------------*/
8746 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8747 /*-----------------------------------------------------------------*/
8748 static void genPagedPointerSet (operand *right,
8757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8759 retype= getSpec(operandType(right));
8761 aopOp(result,ic,FALSE);
8763 /* if the value is already in a pointer register
8764 then don't need anything more */
8765 if (!AOP_INPREG(AOP(result))) {
8766 /* otherwise get a free pointer register */
8768 preg = getFreePtr(ic,&aop,FALSE);
8769 pic14_emitcode("mov","%s,%s",
8771 aopGet(AOP(result),0,FALSE,TRUE));
8772 rname = preg->name ;
8774 rname = aopGet(AOP(result),0,FALSE,FALSE);
8776 freeAsmop(result,NULL,ic,TRUE);
8777 aopOp (right,ic,FALSE);
8779 /* if bitfield then unpack the bits */
8780 if (IS_BITFIELD(retype))
8781 genPackBits (retype,right,rname,PPOINTER);
8783 /* we have can just get the values */
8784 int size = AOP_SIZE(right);
8788 l = aopGet(AOP(right),offset,FALSE,TRUE);
8791 pic14_emitcode("movx","@%s,a",rname);
8794 pic14_emitcode("inc","%s",rname);
8800 /* now some housekeeping stuff */
8802 /* we had to allocate for this iCode */
8803 freeAsmop(NULL,aop,ic,TRUE);
8805 /* we did not allocate which means left
8806 already in a pointer register, then
8807 if size > 0 && this could be used again
8808 we have to point it back to where it
8810 if (AOP_SIZE(right) > 1 &&
8811 !OP_SYMBOL(result)->remat &&
8812 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8814 int size = AOP_SIZE(right) - 1;
8816 pic14_emitcode("dec","%s",rname);
8821 freeAsmop(right,NULL,ic,TRUE);
8826 /*-----------------------------------------------------------------*/
8827 /* genFarPointerSet - set value from far space */
8828 /*-----------------------------------------------------------------*/
8829 static void genFarPointerSet (operand *right,
8830 operand *result, iCode *ic)
8833 sym_link *retype = getSpec(operandType(right));
8835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8836 aopOp(result,ic,FALSE);
8838 /* if the operand is already in dptr
8839 then we do nothing else we move the value to dptr */
8840 if (AOP_TYPE(result) != AOP_STR) {
8841 /* if this is remateriazable */
8842 if (AOP_TYPE(result) == AOP_IMMD)
8843 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8844 else { /* we need to get it byte by byte */
8845 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8846 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8847 if (options.model == MODEL_FLAT24)
8849 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8853 /* so dptr know contains the address */
8854 freeAsmop(result,NULL,ic,TRUE);
8855 aopOp(right,ic,FALSE);
8857 /* if bit then unpack */
8858 if (IS_BITFIELD(retype))
8859 genPackBits(retype,right,"dptr",FPOINTER);
8861 size = AOP_SIZE(right);
8865 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8867 pic14_emitcode("movx","@dptr,a");
8869 pic14_emitcode("inc","dptr");
8873 freeAsmop(right,NULL,ic,TRUE);
8876 /*-----------------------------------------------------------------*/
8877 /* genGenPointerSet - set value from generic pointer space */
8878 /*-----------------------------------------------------------------*/
8879 static void genGenPointerSet (operand *right,
8880 operand *result, iCode *ic)
8883 sym_link *retype = getSpec(operandType(right));
8885 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8887 aopOp(result,ic,FALSE);
8888 aopOp(right,ic,FALSE);
8889 size = AOP_SIZE(right);
8891 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8893 /* if the operand is already in dptr
8894 then we do nothing else we move the value to dptr */
8895 if (AOP_TYPE(result) != AOP_STR) {
8896 /* if this is remateriazable */
8897 if (AOP_TYPE(result) == AOP_IMMD) {
8898 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8899 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8901 else { /* we need to get it byte by byte */
8902 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8903 size = AOP_SIZE(right);
8906 /* hack hack! see if this the FSR. If so don't load W */
8907 if(AOP_TYPE(right) != AOP_ACC) {
8910 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8911 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8913 if(AOP_SIZE(result) > 1) {
8914 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8915 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8916 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8921 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8923 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8924 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8928 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8929 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8932 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8939 if(aopIdx(AOP(result),0) != 4) {
8941 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8945 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8950 /* so dptr know contains the address */
8953 /* if bit then unpack */
8954 if (IS_BITFIELD(retype))
8955 genPackBits(retype,right,"dptr",GPOINTER);
8957 size = AOP_SIZE(right);
8960 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8964 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8965 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8967 if (AOP_TYPE(right) == AOP_LIT)
8968 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8970 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8972 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8979 freeAsmop(right,NULL,ic,TRUE);
8980 freeAsmop(result,NULL,ic,TRUE);
8983 /*-----------------------------------------------------------------*/
8984 /* genPointerSet - stores the value into a pointer location */
8985 /*-----------------------------------------------------------------*/
8986 static void genPointerSet (iCode *ic)
8988 operand *right, *result ;
8989 sym_link *type, *etype;
8992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8994 right = IC_RIGHT(ic);
8995 result = IC_RESULT(ic) ;
8997 /* depending on the type of pointer we need to
8998 move it to the correct pointer register */
8999 type = operandType(result);
9000 etype = getSpec(type);
9001 /* if left is of type of pointer then it is simple */
9002 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9003 p_type = DCL_TYPE(type);
9006 /* we have to go by the storage class */
9007 p_type = PTR_TYPE(SPEC_OCLS(etype));
9009 /* if (SPEC_OCLS(etype)->codesp ) { */
9010 /* p_type = CPOINTER ; */
9013 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9014 /* p_type = FPOINTER ; */
9016 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9017 /* p_type = PPOINTER ; */
9019 /* if (SPEC_OCLS(etype) == idata ) */
9020 /* p_type = IPOINTER ; */
9022 /* p_type = POINTER ; */
9025 /* now that we have the pointer type we assign
9026 the pointer values */
9031 genNearPointerSet (right,result,ic);
9035 genPagedPointerSet (right,result,ic);
9039 genFarPointerSet (right,result,ic);
9043 genGenPointerSet (right,result,ic);
9047 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9048 "genPointerSet: illegal pointer type");
9052 /*-----------------------------------------------------------------*/
9053 /* genIfx - generate code for Ifx statement */
9054 /*-----------------------------------------------------------------*/
9055 static void genIfx (iCode *ic, iCode *popIc)
9057 operand *cond = IC_COND(ic);
9060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9062 aopOp(cond,ic,FALSE);
9064 /* get the value into acc */
9065 if (AOP_TYPE(cond) != AOP_CRY)
9066 pic14_toBoolean(cond);
9069 /* the result is now in the accumulator */
9070 freeAsmop(cond,NULL,ic,TRUE);
9072 /* if there was something to be popped then do it */
9076 /* if the condition is a bit variable */
9077 if (isbit && IS_ITEMP(cond) &&
9079 genIfxJump(ic,SPIL_LOC(cond)->rname);
9080 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9083 if (isbit && !IS_ITEMP(cond))
9084 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9092 /*-----------------------------------------------------------------*/
9093 /* genAddrOf - generates code for address of */
9094 /*-----------------------------------------------------------------*/
9095 static void genAddrOf (iCode *ic)
9097 operand *right, *result, *left;
9100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9103 //aopOp(IC_RESULT(ic),ic,FALSE);
9105 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9106 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9107 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9109 DEBUGpic14_AopType(__LINE__,left,right,result);
9111 size = AOP_SIZE(IC_RESULT(ic));
9115 /* fixing bug #863624, reported from (errolv) */
9116 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9117 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9120 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9121 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9126 freeAsmop(left,NULL,ic,FALSE);
9127 freeAsmop(result,NULL,ic,TRUE);
9132 /*-----------------------------------------------------------------*/
9133 /* genFarFarAssign - assignment when both are in far space */
9134 /*-----------------------------------------------------------------*/
9135 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9137 int size = AOP_SIZE(right);
9140 /* first push the right side on to the stack */
9142 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9144 pic14_emitcode ("push","acc");
9147 freeAsmop(right,NULL,ic,FALSE);
9148 /* now assign DPTR to result */
9149 aopOp(result,ic,FALSE);
9150 size = AOP_SIZE(result);
9152 pic14_emitcode ("pop","acc");
9153 aopPut(AOP(result),"a",--offset);
9155 freeAsmop(result,NULL,ic,FALSE);
9160 /*-----------------------------------------------------------------*/
9161 /* genAssign - generate code for assignment */
9162 /*-----------------------------------------------------------------*/
9163 static void genAssign (iCode *ic)
9165 operand *result, *right;
9166 int size, offset,know_W;
9167 unsigned long lit = 0L;
9169 result = IC_RESULT(ic);
9170 right = IC_RIGHT(ic) ;
9172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9174 /* if they are the same */
9175 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9178 aopOp(right,ic,FALSE);
9179 aopOp(result,ic,TRUE);
9181 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9183 /* if they are the same registers */
9184 if (pic14_sameRegs(AOP(right),AOP(result)))
9187 /* if the result is a bit */
9188 if (AOP_TYPE(result) == AOP_CRY) {
9190 /* if the right size is a literal then
9191 we know what the value is */
9192 if (AOP_TYPE(right) == AOP_LIT) {
9194 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9195 popGet(AOP(result),0));
9197 if (((int) operandLitValue(right)))
9198 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9199 AOP(result)->aopu.aop_dir,
9200 AOP(result)->aopu.aop_dir);
9202 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9203 AOP(result)->aopu.aop_dir,
9204 AOP(result)->aopu.aop_dir);
9208 /* the right is also a bit variable */
9209 if (AOP_TYPE(right) == AOP_CRY) {
9210 emitpcode(POC_BCF, popGet(AOP(result),0));
9211 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9212 emitpcode(POC_BSF, popGet(AOP(result),0));
9214 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9215 AOP(result)->aopu.aop_dir,
9216 AOP(result)->aopu.aop_dir);
9217 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9218 AOP(right)->aopu.aop_dir,
9219 AOP(right)->aopu.aop_dir);
9220 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9221 AOP(result)->aopu.aop_dir,
9222 AOP(result)->aopu.aop_dir);
9227 emitpcode(POC_BCF, popGet(AOP(result),0));
9228 pic14_toBoolean(right);
9230 emitpcode(POC_BSF, popGet(AOP(result),0));
9231 //aopPut(AOP(result),"a",0);
9235 /* bit variables done */
9237 size = AOP_SIZE(result);
9239 if(AOP_TYPE(right) == AOP_LIT)
9240 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9242 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9244 if(aopIdx(AOP(result),0) == 4) {
9245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9246 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9247 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9250 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9255 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9256 if(AOP_TYPE(right) == AOP_LIT) {
9258 if(know_W != (int)(lit&0xff))
9259 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9261 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9263 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9267 } else if (AOP_TYPE(right) == AOP_CRY) {
9268 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9270 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9271 emitpcode(POC_INCF, popGet(AOP(result),0));
9274 mov2w (AOP(right), offset);
9275 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9283 freeAsmop (right,NULL,ic,FALSE);
9284 freeAsmop (result,NULL,ic,TRUE);
9287 /*-----------------------------------------------------------------*/
9288 /* genJumpTab - genrates code for jump table */
9289 /*-----------------------------------------------------------------*/
9290 static void genJumpTab (iCode *ic)
9295 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9297 aopOp(IC_JTCOND(ic),ic,FALSE);
9298 /* get the condition into accumulator */
9299 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9301 /* multiply by three */
9302 pic14_emitcode("add","a,acc");
9303 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9305 jtab = newiTempLabel(NULL);
9306 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9307 pic14_emitcode("jmp","@a+dptr");
9308 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9310 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9311 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9312 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9313 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9315 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9316 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9317 emitpLabel(jtab->key);
9319 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9321 /* now generate the jump labels */
9322 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9323 jtab = setNextItem(IC_JTLABELS(ic))) {
9324 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9325 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9331 /*-----------------------------------------------------------------*/
9332 /* genMixedOperation - gen code for operators between mixed types */
9333 /*-----------------------------------------------------------------*/
9335 TSD - Written for the PIC port - but this unfortunately is buggy.
9336 This routine is good in that it is able to efficiently promote
9337 types to different (larger) sizes. Unfortunately, the temporary
9338 variables that are optimized out by this routine are sometimes
9339 used in other places. So until I know how to really parse the
9340 iCode tree, I'm going to not be using this routine :(.
9342 static int genMixedOperation (iCode *ic)
9345 operand *result = IC_RESULT(ic);
9346 sym_link *ctype = operandType(IC_LEFT(ic));
9347 operand *right = IC_RIGHT(ic);
9353 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9355 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9361 nextright = IC_RIGHT(nextic);
9362 nextleft = IC_LEFT(nextic);
9363 nextresult = IC_RESULT(nextic);
9365 aopOp(right,ic,FALSE);
9366 aopOp(result,ic,FALSE);
9367 aopOp(nextright, nextic, FALSE);
9368 aopOp(nextleft, nextic, FALSE);
9369 aopOp(nextresult, nextic, FALSE);
9371 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9377 pic14_emitcode(";remove right +","");
9379 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9385 pic14_emitcode(";remove left +","");
9389 big = AOP_SIZE(nextleft);
9390 small = AOP_SIZE(nextright);
9392 switch(nextic->op) {
9395 pic14_emitcode(";optimize a +","");
9396 /* if unsigned or not an integral type */
9397 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9398 pic14_emitcode(";add a bit to something","");
9401 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9403 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9404 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9405 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9407 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9415 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9416 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9417 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9420 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9422 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9423 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9424 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9425 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9426 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9429 pic14_emitcode("rlf","known_zero,w");
9436 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9437 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9438 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9440 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9450 freeAsmop(right,NULL,ic,TRUE);
9451 freeAsmop(result,NULL,ic,TRUE);
9452 freeAsmop(nextright,NULL,ic,TRUE);
9453 freeAsmop(nextleft,NULL,ic,TRUE);
9455 nextic->generated = 1;
9462 /*-----------------------------------------------------------------*/
9463 /* genCast - gen code for casting */
9464 /*-----------------------------------------------------------------*/
9465 static void genCast (iCode *ic)
9467 operand *result = IC_RESULT(ic);
9468 sym_link *ctype = operandType(IC_LEFT(ic));
9469 sym_link *rtype = operandType(IC_RIGHT(ic));
9470 operand *right = IC_RIGHT(ic);
9473 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9474 /* if they are equivalent then do nothing */
9475 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9478 aopOp(right,ic,FALSE) ;
9479 aopOp(result,ic,FALSE);
9481 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9483 /* if the result is a bit */
9484 if (AOP_TYPE(result) == AOP_CRY) {
9485 /* if the right size is a literal then
9486 we know what the value is */
9487 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9488 if (AOP_TYPE(right) == AOP_LIT) {
9490 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9491 popGet(AOP(result),0));
9493 if (((int) operandLitValue(right)))
9494 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9495 AOP(result)->aopu.aop_dir,
9496 AOP(result)->aopu.aop_dir);
9498 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9499 AOP(result)->aopu.aop_dir,
9500 AOP(result)->aopu.aop_dir);
9505 /* the right is also a bit variable */
9506 if (AOP_TYPE(right) == AOP_CRY) {
9509 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9511 pic14_emitcode("clrc","");
9512 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9513 AOP(right)->aopu.aop_dir,
9514 AOP(right)->aopu.aop_dir);
9515 aopPut(AOP(result),"c",0);
9520 if (AOP_TYPE(right) == AOP_REG) {
9521 emitpcode(POC_BCF, popGet(AOP(result),0));
9522 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9523 emitpcode(POC_BSF, popGet(AOP(result),0));
9525 pic14_toBoolean(right);
9526 aopPut(AOP(result),"a",0);
9530 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9532 size = AOP_SIZE(result);
9534 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9536 emitpcode(POC_CLRF, popGet(AOP(result),0));
9537 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9538 emitpcode(POC_INCF, popGet(AOP(result),0));
9541 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9546 /* if they are the same size : or less */
9547 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9549 /* if they are in the same place */
9550 if (pic14_sameRegs(AOP(right),AOP(result)))
9553 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9554 if (IS_PTR_CONST(rtype))
9555 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9556 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9557 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9559 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9560 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9561 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9562 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9563 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9564 if(AOP_SIZE(result) <2)
9565 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9569 /* if they in different places then copy */
9570 size = AOP_SIZE(result);
9573 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9574 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9576 //aopPut(AOP(result),
9577 // aopGet(AOP(right),offset,FALSE,FALSE),
9587 /* if the result is of type pointer */
9588 if (IS_PTR(ctype)) {
9591 sym_link *type = operandType(right);
9592 sym_link *etype = getSpec(type);
9593 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9595 /* pointer to generic pointer */
9596 if (IS_GENPTR(ctype)) {
9600 p_type = DCL_TYPE(type);
9602 /* we have to go by the storage class */
9603 p_type = PTR_TYPE(SPEC_OCLS(etype));
9605 /* if (SPEC_OCLS(etype)->codesp ) */
9606 /* p_type = CPOINTER ; */
9608 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9609 /* p_type = FPOINTER ; */
9611 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9612 /* p_type = PPOINTER; */
9614 /* if (SPEC_OCLS(etype) == idata ) */
9615 /* p_type = IPOINTER ; */
9617 /* p_type = POINTER ; */
9620 /* the first two bytes are known */
9621 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9622 size = GPTRSIZE - 1;
9625 if(offset < AOP_SIZE(right)) {
9626 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9627 if ((AOP_TYPE(right) == AOP_PCODE) &&
9628 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9629 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9630 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9633 aopGet(AOP(right),offset,FALSE,FALSE),
9637 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9640 /* the last byte depending on type */
9644 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9647 pic14_emitcode(";BUG!? ","%d",__LINE__);
9651 pic14_emitcode(";BUG!? ","%d",__LINE__);
9655 pic14_emitcode(";BUG!? ","%d",__LINE__);
9660 /* this should never happen */
9661 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9662 "got unknown pointer type");
9665 //aopPut(AOP(result),l, GPTRSIZE - 1);
9669 /* just copy the pointers */
9670 size = AOP_SIZE(result);
9674 aopGet(AOP(right),offset,FALSE,FALSE),
9683 /* so we now know that the size of destination is greater
9684 than the size of the source.
9685 Now, if the next iCode is an operator then we might be
9686 able to optimize the operation without performing a cast.
9688 if(genMixedOperation(ic))
9691 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9693 /* we move to result for the size of source */
9694 size = AOP_SIZE(right);
9697 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9698 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9702 /* now depending on the sign of the destination */
9703 size = AOP_SIZE(result) - AOP_SIZE(right);
9704 /* if unsigned or not an integral type */
9705 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9707 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9709 /* we need to extend the sign :{ */
9712 /* Save one instruction of casting char to int */
9713 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9714 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9715 emitpcode(POC_DECF, popGet(AOP(result),offset));
9717 emitpcodeNULLop(POC_CLRW);
9720 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9722 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9724 emitpcode(POC_MOVLW, popGetLit(0xff));
9727 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9732 freeAsmop(right,NULL,ic,TRUE);
9733 freeAsmop(result,NULL,ic,TRUE);
9737 /*-----------------------------------------------------------------*/
9738 /* genDjnz - generate decrement & jump if not zero instrucion */
9739 /*-----------------------------------------------------------------*/
9740 static int genDjnz (iCode *ic, iCode *ifx)
9743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9748 /* if the if condition has a false label
9749 then we cannot save */
9753 /* if the minus is not of the form
9755 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9756 !IS_OP_LITERAL(IC_RIGHT(ic)))
9759 if (operandLitValue(IC_RIGHT(ic)) != 1)
9762 /* if the size of this greater than one then no
9764 if (getSize(operandType(IC_RESULT(ic))) > 1)
9767 /* otherwise we can save BIG */
9768 lbl = newiTempLabel(NULL);
9769 lbl1= newiTempLabel(NULL);
9771 aopOp(IC_RESULT(ic),ic,FALSE);
9773 if (IS_AOP_PREG(IC_RESULT(ic))) {
9774 pic14_emitcode("dec","%s",
9775 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9776 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9777 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9781 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9782 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9784 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9785 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9788 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9789 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9790 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9791 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9794 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9799 /*-----------------------------------------------------------------*/
9800 /* genReceive - generate code for a receive iCode */
9801 /*-----------------------------------------------------------------*/
9802 static void genReceive (iCode *ic)
9804 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9806 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9807 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9808 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9810 int size = getSize(operandType(IC_RESULT(ic)));
9811 int offset = fReturnSizePic - size;
9813 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9814 fReturn[fReturnSizePic - offset - 1] : "acc"));
9817 aopOp(IC_RESULT(ic),ic,FALSE);
9818 size = AOP_SIZE(IC_RESULT(ic));
9821 pic14_emitcode ("pop","acc");
9822 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9827 aopOp(IC_RESULT(ic),ic,FALSE);
9829 assignResultValue(IC_RESULT(ic));
9832 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9835 /*-----------------------------------------------------------------*/
9836 /* genDummyRead - generate code for dummy read of volatiles */
9837 /*-----------------------------------------------------------------*/
9839 genDummyRead (iCode * ic)
9841 pic14_emitcode ("; genDummyRead","");
9842 pic14_emitcode ("; not implemented","");
9847 /*-----------------------------------------------------------------*/
9848 /* genpic14Code - generate code for pic14 based controllers */
9849 /*-----------------------------------------------------------------*/
9851 * At this point, ralloc.c has gone through the iCode and attempted
9852 * to optimize in a way suitable for a PIC. Now we've got to generate
9853 * PIC instructions that correspond to the iCode.
9855 * Once the instructions are generated, we'll pass through both the
9856 * peep hole optimizer and the pCode optimizer.
9857 *-----------------------------------------------------------------*/
9859 void genpic14Code (iCode *lic)
9864 lineHead = lineCurr = NULL;
9866 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9869 /* if debug information required */
9870 if (options.debug && currFunc) {
9872 debugFile->writeFunction (currFunc, lic);
9877 for (ic = lic ; ic ; ic = ic->next ) {
9879 DEBUGpic14_emitcode(";ic","");
9880 if ( cln != ic->lineno ) {
9881 if ( options.debug ) {
9882 debugFile->writeCLine (ic);
9885 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9886 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9887 printCLine(ic->filename, ic->lineno));
9889 if (!options.noCcodeInAsm) {
9891 newpCodeCSource(ic->lineno,
9893 printCLine(ic->filename, ic->lineno)));
9899 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9901 /* if the result is marked as
9902 spilt and rematerializable or code for
9903 this has already been generated then
9905 if (resultRemat(ic) || ic->generated )
9908 /* depending on the operation */
9927 /* IPOP happens only when trying to restore a
9928 spilt live range, if there is an ifx statement
9929 following this pop then the if statement might
9930 be using some of the registers being popped which
9931 would destory the contents of the register so
9932 we need to check for this condition and handle it */
9934 ic->next->op == IFX &&
9935 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9936 genIfx (ic->next,ic);
9954 genEndFunction (ic);
9974 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9991 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9995 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10002 /* note these two are xlated by algebraic equivalence
10003 during parsing SDCC.y */
10004 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10005 "got '>=' or '<=' shouldn't have come here");
10009 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10021 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10025 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10029 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10053 genRightShift (ic);
10056 case GET_VALUE_AT_ADDRESS:
10061 if (POINTER_SET(ic))
10088 addSet(&_G.sendSet,ic);
10091 case DUMMY_READ_VOLATILE:
10101 /* now we are ready to call the
10102 peep hole optimizer */
10103 if (!options.nopeep) {
10104 peepHole (&lineHead);
10106 /* now do the actual printing */
10107 printLine (lineHead,codeOutFile);
10110 DFPRINTF((stderr,"printing pBlock\n\n"));
10111 printpBlock(stdout,pb);