1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
220 addpCode2pBlock(pb,newpCode(poc,pcop));
222 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
225 void emitpcodeNULLop(PIC_OPCODE poc)
228 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
268 /*-----------------------------------------------------------------*/
269 /* pic14_emitDebuggerSymbol - associate the current code location */
270 /* with a debugger symbol */
271 /*-----------------------------------------------------------------*/
273 pic14_emitDebuggerSymbol (char * debugSym)
276 pic14_emitcode ("", ";%s ==.", debugSym);
281 /*-----------------------------------------------------------------*/
282 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
283 /*-----------------------------------------------------------------*/
284 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
286 bool r0iu = FALSE , r1iu = FALSE;
287 bool r0ou = FALSE , r1ou = FALSE;
289 /* the logic: if r0 & r1 used in the instruction
290 then we are in trouble otherwise */
292 /* first check if r0 & r1 are used by this
293 instruction, in which case we are in trouble */
294 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
295 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
300 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
301 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
303 /* if no usage of r0 then return it */
304 if (!r0iu && !r0ou) {
305 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
306 (*aopp)->type = AOP_R0;
308 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
311 /* if no usage of r1 then return it */
312 if (!r1iu && !r1ou) {
313 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
314 (*aopp)->type = AOP_R1;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
319 /* now we know they both have usage */
320 /* if r0 not used in this instruction */
322 /* push it if not already pushed */
324 //pic14_emitcode ("push","%s",
325 // pic14_regWithIdx(R0_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
330 (*aopp)->type = AOP_R0;
332 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
335 /* if r1 not used then */
338 /* push it if not already pushed */
340 //pic14_emitcode ("push","%s",
341 // pic14_regWithIdx(R1_IDX)->dname);
345 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
346 (*aopp)->type = AOP_R1;
347 return pic14_regWithIdx(R1_IDX);
351 /* I said end of world but not quite end of world yet */
352 /* if this is a result then we can push it on the stack*/
354 (*aopp)->type = AOP_STK;
358 /* other wise this is true end of the world */
359 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
360 "getFreePtr should never reach here");
364 /*-----------------------------------------------------------------*/
365 /* newAsmop - creates a new asmOp */
366 /*-----------------------------------------------------------------*/
367 asmop *newAsmop (short type)
371 aop = Safe_calloc(1,sizeof(asmop));
376 static void genSetDPTR(int n)
380 pic14_emitcode(";", "Select standard DPTR");
381 pic14_emitcode("mov", "dps, #0x00");
385 pic14_emitcode(";", "Select alternate DPTR");
386 pic14_emitcode("mov", "dps, #0x01");
390 /*-----------------------------------------------------------------*/
391 /* resolveIfx - converts an iCode ifx into a form more useful for */
392 /* generating code */
393 /*-----------------------------------------------------------------*/
394 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
399 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
401 resIfx->condition = 1; /* assume that the ifx is true */
402 resIfx->generated = 0; /* indicate that the ifx has not been used */
405 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
407 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
408 __FUNCTION__,__LINE__,resIfx->lbl->key);
412 resIfx->lbl = IC_TRUE(ifx);
414 resIfx->lbl = IC_FALSE(ifx);
415 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
425 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
428 /*-----------------------------------------------------------------*/
429 /* pointerCode - returns the code for a pointer type */
430 /*-----------------------------------------------------------------*/
431 static int pointerCode (sym_link *etype)
434 return PTR_TYPE(SPEC_OCLS(etype));
438 /*-----------------------------------------------------------------*/
439 /* aopForSym - for a true symbol */
440 /*-----------------------------------------------------------------*/
441 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
444 memmap *space= SPEC_OCLS(sym->etype);
446 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
447 /* if already has one */
451 /* assign depending on the storage class */
452 /* if it is on the stack or indirectly addressable */
453 /* space we need to assign either r0 or r1 to it */
454 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
455 sym->aop = aop = newAsmop(0);
456 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
457 aop->size = getSize(sym->type);
459 /* now assign the address of the variable to
460 the pointer register */
461 if (aop->type != AOP_STK) {
465 pic14_emitcode("push","acc");
467 pic14_emitcode("mov","a,_bp");
468 pic14_emitcode("add","a,#0x%02x",
470 ((char)(sym->stack - _G.nRegsSaved )) :
471 ((char)sym->stack)) & 0xff);
472 pic14_emitcode("mov","%s,a",
473 aop->aopu.aop_ptr->name);
476 pic14_emitcode("pop","acc");
478 pic14_emitcode("mov","%s,#%s",
479 aop->aopu.aop_ptr->name,
481 aop->paged = space->paged;
483 aop->aopu.aop_stk = sym->stack;
487 if (sym->onStack && options.stack10bit)
489 /* It's on the 10 bit stack, which is located in
493 //DEBUGpic14_emitcode(";","%d",__LINE__);
496 pic14_emitcode("push","acc");
498 pic14_emitcode("mov","a,_bp");
499 pic14_emitcode("add","a,#0x%02x",
501 ((char)(sym->stack - _G.nRegsSaved )) :
502 ((char)sym->stack)) & 0xff);
505 pic14_emitcode ("mov","dpx1,#0x40");
506 pic14_emitcode ("mov","dph1,#0x00");
507 pic14_emitcode ("mov","dpl1, a");
511 pic14_emitcode("pop","acc");
513 sym->aop = aop = newAsmop(AOP_DPTR2);
514 aop->size = getSize(sym->type);
518 //DEBUGpic14_emitcode(";","%d",__LINE__);
519 /* if in bit space */
520 if (IN_BITSPACE(space)) {
521 sym->aop = aop = newAsmop (AOP_CRY);
522 aop->aopu.aop_dir = sym->rname ;
523 aop->size = getSize(sym->type);
524 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
527 /* if it is in direct space */
528 if (IN_DIRSPACE(space)) {
529 sym->aop = aop = newAsmop (AOP_DIR);
530 aop->aopu.aop_dir = sym->rname ;
531 aop->size = getSize(sym->type);
532 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
536 /* special case for a function */
537 if (IS_FUNC(sym->type)) {
539 sym->aop = aop = newAsmop(AOP_PCODE);
540 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
541 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542 PCOI(aop->aopu.pcop)->_function = 1;
543 PCOI(aop->aopu.pcop)->index = 0;
544 aop->size = FPTRSIZE;
546 sym->aop = aop = newAsmop(AOP_IMMD);
547 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548 strcpy(aop->aopu.aop_immd,sym->rname);
549 aop->size = FPTRSIZE;
551 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
556 /* only remaining is far space */
557 /* in which case DPTR gets the address */
558 sym->aop = aop = newAsmop(AOP_PCODE);
560 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
561 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
562 PCOI(aop->aopu.pcop)->index = 0;
564 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
565 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
567 allocDirReg (IC_LEFT(ic));
569 aop->size = FPTRSIZE;
571 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
572 sym->aop = aop = newAsmop(AOP_DPTR);
573 pic14_emitcode ("mov","dptr,#%s", sym->rname);
574 aop->size = getSize(sym->type);
576 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
579 /* if it is in code space */
580 if (IN_CODESPACE(space))
586 /*-----------------------------------------------------------------*/
587 /* aopForRemat - rematerialzes an object */
588 /*-----------------------------------------------------------------*/
589 static asmop *aopForRemat (operand *op) // x symbol *sym)
591 symbol *sym = OP_SYMBOL(op);
593 asmop *aop = newAsmop(AOP_PCODE);
597 ic = sym->rematiCode;
599 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
600 if(IS_OP_POINTER(op)) {
601 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
605 val += (int) operandLitValue(IC_RIGHT(ic));
606 } else if (ic->op == '-') {
607 val -= (int) operandLitValue(IC_RIGHT(ic));
611 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
614 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
615 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
616 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
617 PCOI(aop->aopu.pcop)->index = val;
619 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
620 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
621 val, IS_PTR_CONST(operandType(op)));
623 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
625 allocDirReg (IC_LEFT(ic));
630 int aopIdx (asmop *aop, int offset)
635 if(aop->type != AOP_REG)
638 return aop->aopu.aop_reg[offset]->rIdx;
641 /*-----------------------------------------------------------------*/
642 /* regsInCommon - two operands have some registers in common */
643 /*-----------------------------------------------------------------*/
644 static bool regsInCommon (operand *op1, operand *op2)
649 /* if they have registers in common */
650 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
653 sym1 = OP_SYMBOL(op1);
654 sym2 = OP_SYMBOL(op2);
656 if (sym1->nRegs == 0 || sym2->nRegs == 0)
659 for (i = 0 ; i < sym1->nRegs ; i++) {
664 for (j = 0 ; j < sym2->nRegs ;j++ ) {
668 if (sym2->regs[j] == sym1->regs[i])
676 /*-----------------------------------------------------------------*/
677 /* operandsEqu - equivalent */
678 /*-----------------------------------------------------------------*/
679 static bool operandsEqu ( operand *op1, operand *op2)
683 /* if they not symbols */
684 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
687 sym1 = OP_SYMBOL(op1);
688 sym2 = OP_SYMBOL(op2);
690 /* if both are itemps & one is spilt
691 and the other is not then false */
692 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
693 sym1->isspilt != sym2->isspilt )
696 /* if they are the same */
700 if (sym1->rname[0] && sym2->rname[0]
701 && strcmp (sym1->rname, sym2->rname) == 0)
705 /* if left is a tmp & right is not */
709 (sym1->usl.spillLoc == sym2))
716 (sym2->usl.spillLoc == sym1))
722 /*-----------------------------------------------------------------*/
723 /* pic14_sameRegs - two asmops have the same registers */
724 /*-----------------------------------------------------------------*/
725 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
732 if (aop1->type != AOP_REG ||
733 aop2->type != AOP_REG )
736 if (aop1->size != aop2->size )
739 for (i = 0 ; i < aop1->size ; i++ )
740 if (aop1->aopu.aop_reg[i] !=
741 aop2->aopu.aop_reg[i] )
747 /*-----------------------------------------------------------------*/
748 /* aopOp - allocates an asmop for an operand : */
749 /*-----------------------------------------------------------------*/
750 void aopOp (operand *op, iCode *ic, bool result)
759 // DEBUGpic14_emitcode(";","%d",__LINE__);
760 /* if this a literal */
761 if (IS_OP_LITERAL(op)) {
762 op->aop = aop = newAsmop(AOP_LIT);
763 aop->aopu.aop_lit = op->operand.valOperand;
764 aop->size = getSize(operandType(op));
769 sym_link *type = operandType(op);
770 if(IS_PTR_CONST(type))
771 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
774 /* if already has a asmop then continue */
778 /* if the underlying symbol has a aop */
779 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
780 DEBUGpic14_emitcode(";","%d",__LINE__);
781 op->aop = OP_SYMBOL(op)->aop;
785 /* if this is a true symbol */
786 if (IS_TRUE_SYMOP(op)) {
787 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
788 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
792 /* this is a temporary : this has
798 e) can be a return use only */
803 /* if the type is a conditional */
804 if (sym->regType == REG_CND) {
805 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
810 /* if it is spilt then two situations
812 b) has a spill location */
813 if (sym->isspilt || sym->nRegs == 0) {
815 DEBUGpic14_emitcode(";","%d",__LINE__);
816 /* rematerialize it NOW */
819 sym->aop = op->aop = aop = aopForRemat (op);
820 aop->size = getSize(sym->type);
821 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
827 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
828 aop->size = getSize(sym->type);
829 for ( i = 0 ; i < 2 ; i++ )
830 aop->aopu.aop_str[i] = accUse[i];
831 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
836 if(sym->isptr) { // && sym->uptr
837 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
838 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
840 //PCOI(aop->aopu.pcop)->_const = 0;
841 //PCOI(aop->aopu.pcop)->index = 0;
843 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
844 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
846 //allocDirReg (IC_LEFT(ic));
848 aop->size = getSize(sym->type);
849 DEBUGpic14_emitcode(";","%d",__LINE__);
856 aop = op->aop = sym->aop = newAsmop(AOP_STR);
857 aop->size = getSize(sym->type);
858 for ( i = 0 ; i < fReturnSizePic ; i++ )
859 aop->aopu.aop_str[i] = fReturn[i];
861 DEBUGpic14_emitcode(";","%d",__LINE__);
866 /* else spill location */
867 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
868 /* force a new aop if sizes differ */
869 sym->usl.spillLoc->aop = NULL;
871 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
872 __FUNCTION__,__LINE__,
873 sym->usl.spillLoc->rname,
874 sym->rname, sym->usl.spillLoc->offset);
876 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
877 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
878 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
880 sym->usl.spillLoc->offset);
881 aop->size = getSize(sym->type);
887 sym_link *type = operandType(op);
888 if(IS_PTR_CONST(type))
889 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
892 /* must be in a register */
893 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
894 sym->aop = op->aop = aop = newAsmop(AOP_REG);
895 aop->size = sym->nRegs;
896 for ( i = 0 ; i < sym->nRegs ;i++)
897 aop->aopu.aop_reg[i] = sym->regs[i];
900 /*-----------------------------------------------------------------*/
901 /* freeAsmop - free up the asmop given to an operand */
902 /*----------------------------------------------------------------*/
903 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
920 /* depending on the asmop type only three cases need work AOP_RO
921 , AOP_R1 && AOP_STK */
927 pic14_emitcode ("pop","ar0");
931 bitVectUnSetBit(ic->rUsed,R0_IDX);
937 pic14_emitcode ("pop","ar1");
941 bitVectUnSetBit(ic->rUsed,R1_IDX);
947 int stk = aop->aopu.aop_stk + aop->size;
948 bitVectUnSetBit(ic->rUsed,R0_IDX);
949 bitVectUnSetBit(ic->rUsed,R1_IDX);
951 getFreePtr(ic,&aop,FALSE);
953 if (options.stack10bit)
955 /* I'm not sure what to do here yet... */
958 "*** Warning: probably generating bad code for "
959 "10 bit stack mode.\n");
963 pic14_emitcode ("mov","a,_bp");
964 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
965 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
967 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
971 pic14_emitcode("pop","acc");
972 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
974 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
977 freeAsmop(op,NULL,ic,TRUE);
979 pic14_emitcode("pop","ar0");
984 pic14_emitcode("pop","ar1");
992 /* all other cases just dealloc */
996 OP_SYMBOL(op)->aop = NULL;
997 /* if the symbol has a spill */
999 SPIL_LOC(op)->aop = NULL;
1004 /*-----------------------------------------------------------------*/
1005 /* aopGet - for fetching value of the aop */
1006 /*-----------------------------------------------------------------*/
1007 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1012 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1013 /* offset is greater than
1015 if (offset > (aop->size - 1) &&
1016 aop->type != AOP_LIT)
1019 /* depending on type */
1020 switch (aop->type) {
1024 DEBUGpic14_emitcode(";","%d",__LINE__);
1025 /* if we need to increment it */
1026 while (offset > aop->coff) {
1027 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1031 while (offset < aop->coff) {
1032 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1036 aop->coff = offset ;
1038 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1039 return (dname ? "acc" : "a");
1041 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1042 rs = Safe_calloc(1,strlen(s)+1);
1048 DEBUGpic14_emitcode(";","%d",__LINE__);
1049 if (aop->type == AOP_DPTR2)
1054 while (offset > aop->coff) {
1055 pic14_emitcode ("inc","dptr");
1059 while (offset < aop->coff) {
1060 pic14_emitcode("lcall","__decdptr");
1066 pic14_emitcode("clr","a");
1067 pic14_emitcode("movc","a,@a+dptr");
1070 pic14_emitcode("movx","a,@dptr");
1073 if (aop->type == AOP_DPTR2)
1078 return (dname ? "acc" : "a");
1083 sprintf (s,"%s",aop->aopu.aop_immd);
1086 sprintf(s,"(%s >> %d)",
1091 aop->aopu.aop_immd);
1092 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1093 rs = Safe_calloc(1,strlen(s)+1);
1099 sprintf(s,"(%s + %d)",
1102 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1104 sprintf(s,"%s",aop->aopu.aop_dir);
1105 rs = Safe_calloc(1,strlen(s)+1);
1111 // return aop->aopu.aop_reg[offset]->dname;
1113 return aop->aopu.aop_reg[offset]->name;
1116 //pic14_emitcode(";","%d",__LINE__);
1117 return aop->aopu.aop_dir;
1120 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1121 return "AOP_accumulator_bug";
1124 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1125 rs = Safe_calloc(1,strlen(s)+1);
1130 aop->coff = offset ;
1131 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1134 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1136 return aop->aopu.aop_str[offset];
1140 pCodeOp *pcop = aop->aopu.pcop;
1141 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1143 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1144 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1145 sprintf(s,"%s", pcop->name);
1147 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1150 rs = Safe_calloc(1,strlen(s)+1);
1156 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1157 "aopget got unsupported aop->type");
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGetTempReg(void)
1170 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1171 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1172 PCOR(pcop)->r->wasUsed=1;
1173 PCOR(pcop)->r->isFree=0;
1179 /*-----------------------------------------------------------------*/
1180 /* popGetTempReg - create a new temporary pCodeOp */
1181 /*-----------------------------------------------------------------*/
1182 void popReleaseTempReg(pCodeOp *pcop)
1185 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1186 PCOR(pcop)->r->isFree = 1;
1189 /*-----------------------------------------------------------------*/
1190 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1191 /*-----------------------------------------------------------------*/
1192 pCodeOp *popGetLabel(unsigned int key)
1195 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1197 if(key>(unsigned int)max_key)
1200 return newpCodeOpLabel(NULL,key+100+labelOffset);
1203 /*-------------------------------------------------------------------*/
1204 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1205 /*-------------------------------------------------------------------*/
1206 pCodeOp *popGetHighLabel(unsigned int key)
1209 pcop = popGetLabel(key);
1210 PCOLAB(pcop)->offset = 1;
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1220 return newpCodeOpLit(lit);
1223 /*-----------------------------------------------------------------*/
1224 /* popGetImmd - asm operator to pcode immediate conversion */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1229 return newpCodeOpImmd(name, offset,index, 0, is_func);
1233 /*-----------------------------------------------------------------*/
1234 /* popGet - asm operator to pcode operator conversion */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetWithString(char *str, int isExtern)
1242 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1246 pcop = newpCodeOp(str,PO_STR);
1247 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString - */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1258 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259 pcop->type = PO_DIR;
1261 DEBUGpic14_emitcode(";","%d",__LINE__);
1266 pcop->name = Safe_calloc(1,strlen(str)+1);
1267 strcpy(pcop->name,str);
1269 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271 PCOR(pcop)->r = dirregWithName(pcop->name);
1272 if(PCOR(pcop)->r == NULL) {
1273 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1277 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1279 PCOR(pcop)->instance = offset;
1284 /*-----------------------------------------------------------------*/
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popRegFromIdx(int rIdx)
1290 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1291 __FUNCTION__,__LINE__,rIdx);
1293 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295 PCOR(pcop)->rIdx = rIdx;
1296 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1297 PCOR(pcop)->r->isFree = 0;
1298 PCOR(pcop)->r->wasUsed = 1;
1300 pcop->type = PCOR(pcop)->r->pc_type;
1306 /*-----------------------------------------------------------------*/
1307 /* popGet - asm operator to pcode operator conversion */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1311 //char *s = buffer ;
1316 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1317 /* offset is greater than
1320 if (offset > (aop->size - 1) &&
1321 aop->type != AOP_LIT)
1322 return NULL; //zero;
1324 /* depending on type */
1325 switch (aop->type) {
1332 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1336 DEBUGpic14_emitcode(";","%d",__LINE__);
1337 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1340 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1342 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1343 pcop->type = PO_DIR;
1345 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1346 strcpy(pcop->name,aop->aopu.aop_dir);
1347 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1348 if(PCOR(pcop)->r == NULL) {
1349 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1350 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1351 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1353 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1355 PCOR(pcop)->instance = offset;
1362 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1364 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365 PCOR(pcop)->rIdx = rIdx;
1366 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1367 PCOR(pcop)->r->wasUsed=1;
1368 PCOR(pcop)->r->isFree=0;
1370 PCOR(pcop)->instance = offset;
1371 pcop->type = PCOR(pcop)->r->pc_type;
1372 //rs = aop->aopu.aop_reg[offset]->name;
1373 DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1378 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1379 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1380 //if(PCOR(pcop)->r == NULL)
1381 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1385 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1388 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1389 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1391 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1392 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1393 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1394 pcop->type = PCOR(pcop)->r->pc_type;
1395 pcop->name = PCOR(pcop)->r->name;
1401 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1403 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1404 pcop = pCodeOpCopy(aop->aopu.pcop);
1405 PCOI(pcop)->offset = offset;
1409 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1410 "popGet got unsupported aop->type");
1413 /*-----------------------------------------------------------------*/
1414 /* aopPut - puts a string for a aop */
1415 /*-----------------------------------------------------------------*/
1416 void aopPut (asmop *aop, char *s, int offset)
1421 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1423 if (aop->size && offset > ( aop->size - 1)) {
1424 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1425 "aopPut got offset > aop->size");
1429 /* will assign value to value */
1430 /* depending on where it is ofcourse */
1431 switch (aop->type) {
1434 sprintf(d,"(%s + %d)",
1435 aop->aopu.aop_dir,offset);
1436 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1439 sprintf(d,"%s",aop->aopu.aop_dir);
1442 DEBUGpic14_emitcode(";","%d",__LINE__);
1444 pic14_emitcode("movf","%s,w",s);
1445 pic14_emitcode("movwf","%s",d);
1448 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1449 if(offset >= aop->size) {
1450 emitpcode(POC_CLRF,popGet(aop,offset));
1453 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1456 emitpcode(POC_MOVWF,popGet(aop,offset));
1463 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1464 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1467 strcmp(s,"r0") == 0 ||
1468 strcmp(s,"r1") == 0 ||
1469 strcmp(s,"r2") == 0 ||
1470 strcmp(s,"r3") == 0 ||
1471 strcmp(s,"r4") == 0 ||
1472 strcmp(s,"r5") == 0 ||
1473 strcmp(s,"r6") == 0 ||
1474 strcmp(s,"r7") == 0 )
1475 pic14_emitcode("mov","%s,%s ; %d",
1476 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1480 if(strcmp(s,"W")==0 )
1481 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1483 pic14_emitcode("movwf","%s",
1484 aop->aopu.aop_reg[offset]->name);
1486 if(strcmp(s,zero)==0) {
1487 emitpcode(POC_CLRF,popGet(aop,offset));
1489 } else if(strcmp(s,"W")==0) {
1490 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1491 pcop->type = PO_GPR_REGISTER;
1493 PCOR(pcop)->rIdx = -1;
1494 PCOR(pcop)->r = NULL;
1496 DEBUGpic14_emitcode(";","%d",__LINE__);
1497 pcop->name = Safe_strdup(s);
1498 emitpcode(POC_MOVFW,pcop);
1499 emitpcode(POC_MOVWF,popGet(aop,offset));
1500 } else if(strcmp(s,one)==0) {
1501 emitpcode(POC_CLRF,popGet(aop,offset));
1502 emitpcode(POC_INCF,popGet(aop,offset));
1504 emitpcode(POC_MOVWF,popGet(aop,offset));
1512 if (aop->type == AOP_DPTR2)
1518 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1519 "aopPut writting to code space");
1523 while (offset > aop->coff) {
1525 pic14_emitcode ("inc","dptr");
1528 while (offset < aop->coff) {
1530 pic14_emitcode("lcall","__decdptr");
1535 /* if not in accumulater */
1538 pic14_emitcode ("movx","@dptr,a");
1540 if (aop->type == AOP_DPTR2)
1548 while (offset > aop->coff) {
1550 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1552 while (offset < aop->coff) {
1554 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1560 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1565 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1567 if (strcmp(s,"r0") == 0 ||
1568 strcmp(s,"r1") == 0 ||
1569 strcmp(s,"r2") == 0 ||
1570 strcmp(s,"r3") == 0 ||
1571 strcmp(s,"r4") == 0 ||
1572 strcmp(s,"r5") == 0 ||
1573 strcmp(s,"r6") == 0 ||
1574 strcmp(s,"r7") == 0 ) {
1576 sprintf(buffer,"a%s",s);
1577 pic14_emitcode("mov","@%s,%s",
1578 aop->aopu.aop_ptr->name,buffer);
1580 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1585 if (strcmp(s,"a") == 0)
1586 pic14_emitcode("push","acc");
1588 pic14_emitcode("push","%s",s);
1593 /* if bit variable */
1594 if (!aop->aopu.aop_dir) {
1595 pic14_emitcode("clr","a");
1596 pic14_emitcode("rlc","a");
1599 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1602 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1605 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1607 lbl = newiTempLabel(NULL);
1609 if (strcmp(s,"a")) {
1612 pic14_emitcode("clr","c");
1613 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1614 pic14_emitcode("cpl","c");
1615 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1616 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1623 if (strcmp(aop->aopu.aop_str[offset],s))
1624 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1629 if (!offset && (strcmp(s,"acc") == 0))
1632 if (strcmp(aop->aopu.aop_str[offset],s))
1633 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1637 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1638 "aopPut got unsupported aop->type");
1644 /*-----------------------------------------------------------------*/
1645 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1646 /*-----------------------------------------------------------------*/
1647 void mov2w (asmop *aop, int offset)
1653 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1655 if ( aop->type == AOP_PCODE ||
1656 aop->type == AOP_LIT ||
1657 aop->type == AOP_IMMD )
1658 emitpcode(POC_MOVLW,popGet(aop,offset));
1660 emitpcode(POC_MOVFW,popGet(aop,offset));
1664 /*-----------------------------------------------------------------*/
1665 /* reAdjustPreg - points a register back to where it should */
1666 /*-----------------------------------------------------------------*/
1667 static void reAdjustPreg (asmop *aop)
1671 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1673 if ((size = aop->size) <= 1)
1676 switch (aop->type) {
1680 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1684 if (aop->type == AOP_DPTR2)
1690 pic14_emitcode("lcall","__decdptr");
1693 if (aop->type == AOP_DPTR2)
1705 /*-----------------------------------------------------------------*/
1706 /* opIsGptr: returns non-zero if the passed operand is */
1707 /* a generic pointer type. */
1708 /*-----------------------------------------------------------------*/
1709 static int opIsGptr(operand *op)
1711 sym_link *type = operandType(op);
1713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1714 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1722 /*-----------------------------------------------------------------*/
1723 /* pic14_getDataSize - get the operand data size */
1724 /*-----------------------------------------------------------------*/
1725 int pic14_getDataSize(operand *op)
1727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1730 return AOP_SIZE(op);
1732 // tsd- in the pic port, the genptr size is 1, so this code here
1733 // fails. ( in the 8051 port, the size was 4).
1736 size = AOP_SIZE(op);
1737 if (size == GPTRSIZE)
1739 sym_link *type = operandType(op);
1740 if (IS_GENPTR(type))
1742 /* generic pointer; arithmetic operations
1743 * should ignore the high byte (pointer type).
1746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1753 /*-----------------------------------------------------------------*/
1754 /* pic14_outAcc - output Acc */
1755 /*-----------------------------------------------------------------*/
1756 void pic14_outAcc(operand *result)
1759 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1760 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1763 size = pic14_getDataSize(result);
1765 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1768 /* unsigned or positive */
1770 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1775 /*-----------------------------------------------------------------*/
1776 /* pic14_outBitC - output a bit C */
1777 /*-----------------------------------------------------------------*/
1778 void pic14_outBitC(operand *result)
1781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1782 /* if the result is bit */
1783 if (AOP_TYPE(result) == AOP_CRY)
1784 aopPut(AOP(result),"c",0);
1786 pic14_emitcode("clr","a ; %d", __LINE__);
1787 pic14_emitcode("rlc","a");
1788 pic14_outAcc(result);
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_toBoolean(operand *oper)
1797 int size = AOP_SIZE(oper) - 1;
1800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1802 if ( AOP_TYPE(oper) != AOP_ACC) {
1803 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1806 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1811 /*-----------------------------------------------------------------*/
1812 /* genNot - generate code for ! operation */
1813 /*-----------------------------------------------------------------*/
1814 static void genNot (iCode *ic)
1819 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1820 /* assign asmOps to operand & result */
1821 aopOp (IC_LEFT(ic),ic,FALSE);
1822 aopOp (IC_RESULT(ic),ic,TRUE);
1824 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1825 /* if in bit space then a special case */
1826 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1827 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1828 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1829 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1831 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1832 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1833 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1838 size = AOP_SIZE(IC_LEFT(ic));
1840 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1841 emitpcode(POC_ANDLW,popGetLit(1));
1842 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1845 pic14_toBoolean(IC_LEFT(ic));
1847 tlbl = newiTempLabel(NULL);
1848 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1849 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1850 pic14_outBitC(IC_RESULT(ic));
1853 /* release the aops */
1854 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1855 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1859 /*-----------------------------------------------------------------*/
1860 /* genCpl - generate code for complement */
1861 /*-----------------------------------------------------------------*/
1862 static void genCpl (iCode *ic)
1864 operand *left, *result;
1868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1869 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1870 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1872 /* if both are in bit space then
1874 if (AOP_TYPE(result) == AOP_CRY &&
1875 AOP_TYPE(left) == AOP_CRY ) {
1877 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1878 pic14_emitcode("cpl","c");
1879 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1883 size = AOP_SIZE(result);
1886 if(AOP_TYPE(left) == AOP_ACC)
1887 emitpcode(POC_XORLW, popGetLit(0xff));
1889 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1891 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1897 /* release the aops */
1898 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899 freeAsmop(result,NULL,ic,TRUE);
1902 /*-----------------------------------------------------------------*/
1903 /* genUminusFloat - unary minus for floating points */
1904 /*-----------------------------------------------------------------*/
1905 static void genUminusFloat(operand *op,operand *result)
1907 int size ,offset =0 ;
1910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1911 /* for this we just need to flip the
1912 first it then copy the rest in place */
1913 size = AOP_SIZE(op) - 1;
1914 l = aopGet(AOP(op),3,FALSE,FALSE);
1918 pic14_emitcode("cpl","acc.7");
1919 aopPut(AOP(result),"a",3);
1923 aopGet(AOP(op),offset,FALSE,FALSE),
1929 /*-----------------------------------------------------------------*/
1930 /* genUminus - unary minus code generation */
1931 /*-----------------------------------------------------------------*/
1932 static void genUminus (iCode *ic)
1935 sym_link *optype, *rtype;
1938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1940 aopOp(IC_LEFT(ic),ic,FALSE);
1941 aopOp(IC_RESULT(ic),ic,TRUE);
1943 /* if both in bit space then special
1945 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1946 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1948 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1949 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1950 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1955 optype = operandType(IC_LEFT(ic));
1956 rtype = operandType(IC_RESULT(ic));
1958 /* if float then do float stuff */
1959 if (IS_FLOAT(optype)) {
1960 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1964 /* otherwise subtract from zero by taking the 2's complement */
1965 size = AOP_SIZE(IC_LEFT(ic));
1967 for(i=0; i<size; i++) {
1968 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1969 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1971 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1972 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1976 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1977 for(i=1; i<size; i++) {
1979 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1983 /* release the aops */
1984 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1985 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1988 /*-----------------------------------------------------------------*/
1989 /* saveRegisters - will look for a call and save the registers */
1990 /*-----------------------------------------------------------------*/
1991 static void saveRegisters(iCode *lic)
1998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2000 for (ic = lic ; ic ; ic = ic->next)
2001 if (ic->op == CALL || ic->op == PCALL)
2005 fprintf(stderr,"found parameter push with no function call\n");
2009 /* if the registers have been saved already then
2011 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2014 /* find the registers in use at this time
2015 and push them away to safety */
2016 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2020 if (options.useXstack) {
2021 if (bitVectBitValue(rsave,R0_IDX))
2022 pic14_emitcode("mov","b,r0");
2023 pic14_emitcode("mov","r0,%s",spname);
2024 for (i = 0 ; i < pic14_nRegs ; i++) {
2025 if (bitVectBitValue(rsave,i)) {
2027 pic14_emitcode("mov","a,b");
2029 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2030 pic14_emitcode("movx","@r0,a");
2031 pic14_emitcode("inc","r0");
2034 pic14_emitcode("mov","%s,r0",spname);
2035 if (bitVectBitValue(rsave,R0_IDX))
2036 pic14_emitcode("mov","r0,b");
2038 //for (i = 0 ; i < pic14_nRegs ; i++) {
2039 // if (bitVectBitValue(rsave,i))
2040 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2043 dtype = operandType(IC_LEFT(ic));
2044 if (currFunc && dtype &&
2045 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2046 IFFUNC_ISISR(currFunc->type) &&
2049 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2052 /*-----------------------------------------------------------------*/
2053 /* unsaveRegisters - pop the pushed registers */
2054 /*-----------------------------------------------------------------*/
2055 static void unsaveRegisters (iCode *ic)
2060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2061 /* find the registers in use at this time
2062 and push them away to safety */
2063 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2066 if (options.useXstack) {
2067 pic14_emitcode("mov","r0,%s",spname);
2068 for (i = pic14_nRegs ; i >= 0 ; i--) {
2069 if (bitVectBitValue(rsave,i)) {
2070 pic14_emitcode("dec","r0");
2071 pic14_emitcode("movx","a,@r0");
2073 pic14_emitcode("mov","b,a");
2075 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2079 pic14_emitcode("mov","%s,r0",spname);
2080 if (bitVectBitValue(rsave,R0_IDX))
2081 pic14_emitcode("mov","r0,b");
2083 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2084 // if (bitVectBitValue(rsave,i))
2085 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2091 /*-----------------------------------------------------------------*/
2093 /*-----------------------------------------------------------------*/
2094 static void pushSide(operand * oper, int size)
2098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2101 if (AOP_TYPE(oper) != AOP_REG &&
2102 AOP_TYPE(oper) != AOP_DIR &&
2104 pic14_emitcode("mov","a,%s",l);
2105 pic14_emitcode("push","acc");
2107 pic14_emitcode("push","%s",l);
2112 /*-----------------------------------------------------------------*/
2113 /* assignResultValue - */
2114 /*-----------------------------------------------------------------*/
2115 static void assignResultValue(operand * oper)
2117 int size = AOP_SIZE(oper);
2119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2121 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2124 if (GpsuedoStkPtr++)
2125 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2126 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2131 /*-----------------------------------------------------------------*/
2132 /* genIpush - genrate code for pushing this gets a little complex */
2133 /*-----------------------------------------------------------------*/
2134 static void genIpush (iCode *ic)
2137 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2139 int size, offset = 0 ;
2143 /* if this is not a parm push : ie. it is spill push
2144 and spill push is always done on the local stack */
2145 if (!ic->parmPush) {
2147 /* and the item is spilt then do nothing */
2148 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2151 aopOp(IC_LEFT(ic),ic,FALSE);
2152 size = AOP_SIZE(IC_LEFT(ic));
2153 /* push it on the stack */
2155 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2160 pic14_emitcode("push","%s",l);
2165 /* this is a paramter push: in this case we call
2166 the routine to find the call and save those
2167 registers that need to be saved */
2170 /* then do the push */
2171 aopOp(IC_LEFT(ic),ic,FALSE);
2174 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2175 size = AOP_SIZE(IC_LEFT(ic));
2178 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2179 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2180 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2182 pic14_emitcode("mov","a,%s",l);
2183 pic14_emitcode("push","acc");
2185 pic14_emitcode("push","%s",l);
2188 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2192 /*-----------------------------------------------------------------*/
2193 /* genIpop - recover the registers: can happen only for spilling */
2194 /*-----------------------------------------------------------------*/
2195 static void genIpop (iCode *ic)
2197 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2202 /* if the temp was not pushed then */
2203 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2206 aopOp(IC_LEFT(ic),ic,FALSE);
2207 size = AOP_SIZE(IC_LEFT(ic));
2210 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2213 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2217 /*-----------------------------------------------------------------*/
2218 /* unsaverbank - restores the resgister bank from stack */
2219 /*-----------------------------------------------------------------*/
2220 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2222 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2230 if (options.useXstack) {
2232 r = getFreePtr(ic,&aop,FALSE);
2235 pic14_emitcode("mov","%s,_spx",r->name);
2236 pic14_emitcode("movx","a,@%s",r->name);
2237 pic14_emitcode("mov","psw,a");
2238 pic14_emitcode("dec","%s",r->name);
2241 pic14_emitcode ("pop","psw");
2244 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2245 if (options.useXstack) {
2246 pic14_emitcode("movx","a,@%s",r->name);
2247 //pic14_emitcode("mov","(%s+%d),a",
2248 // regspic14[i].base,8*bank+regspic14[i].offset);
2249 pic14_emitcode("dec","%s",r->name);
2252 pic14_emitcode("pop",""); //"(%s+%d)",
2253 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2256 if (options.useXstack) {
2258 pic14_emitcode("mov","_spx,%s",r->name);
2259 freeAsmop(NULL,aop,ic,TRUE);
2265 /*-----------------------------------------------------------------*/
2266 /* saverbank - saves an entire register bank on the stack */
2267 /*-----------------------------------------------------------------*/
2268 static void saverbank (int bank, iCode *ic, bool pushPsw)
2270 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2277 if (options.useXstack) {
2280 r = getFreePtr(ic,&aop,FALSE);
2281 pic14_emitcode("mov","%s,_spx",r->name);
2285 for (i = 0 ; i < pic14_nRegs ;i++) {
2286 if (options.useXstack) {
2287 pic14_emitcode("inc","%s",r->name);
2288 //pic14_emitcode("mov","a,(%s+%d)",
2289 // regspic14[i].base,8*bank+regspic14[i].offset);
2290 pic14_emitcode("movx","@%s,a",r->name);
2292 pic14_emitcode("push","");// "(%s+%d)",
2293 //regspic14[i].base,8*bank+regspic14[i].offset);
2297 if (options.useXstack) {
2298 pic14_emitcode("mov","a,psw");
2299 pic14_emitcode("movx","@%s,a",r->name);
2300 pic14_emitcode("inc","%s",r->name);
2301 pic14_emitcode("mov","_spx,%s",r->name);
2302 freeAsmop (NULL,aop,ic,TRUE);
2305 pic14_emitcode("push","psw");
2307 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2313 /*-----------------------------------------------------------------*/
2314 /* genCall - generates a call statement */
2315 /*-----------------------------------------------------------------*/
2316 static void genCall (iCode *ic)
2320 unsigned char *name;
2323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2325 /* if caller saves & we have not saved then */
2329 /* if we are calling a function that is not using
2330 the same register bank then we need to save the
2331 destination registers on the stack */
2332 dtype = operandType(IC_LEFT(ic));
2333 if (currFunc && dtype &&
2334 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2335 IFFUNC_ISISR(currFunc->type) &&
2338 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2340 /* if send set is not empty the assign */
2343 /* For the Pic port, there is no data stack.
2344 * So parameters passed to functions are stored
2345 * in registers. (The pCode optimizer will get
2346 * rid of most of these :).
2348 int psuedoStkPtr=-1;
2349 int firstTimeThruLoop = 1;
2351 _G.sendSet = reverseSet(_G.sendSet);
2353 /* First figure how many parameters are getting passed */
2354 for (sic = setFirstItem(_G.sendSet) ; sic ;
2355 sic = setNextItem(_G.sendSet)) {
2357 aopOp(IC_LEFT(sic),sic,FALSE);
2358 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2359 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2362 for (sic = setFirstItem(_G.sendSet) ; sic ;
2363 sic = setNextItem(_G.sendSet)) {
2364 int size, offset = 0;
2366 aopOp(IC_LEFT(sic),sic,FALSE);
2367 size = AOP_SIZE(IC_LEFT(sic));
2370 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2371 AopType(AOP_TYPE(IC_LEFT(sic))));
2373 if(!firstTimeThruLoop) {
2374 /* If this is not the first time we've been through the loop
2375 * then we need to save the parameter in a temporary
2376 * register. The last byte of the last parameter is
2378 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2381 firstTimeThruLoop=0;
2383 mov2w (AOP(IC_LEFT(sic)), offset);
2386 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2391 sym = OP_SYMBOL(IC_LEFT(ic));
2392 name = sym->rname[0] ? sym->rname : sym->name;
2393 isExtern = IS_EXTERN(sym->etype);
2395 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2397 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2399 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2402 /* if we need assign a result value */
2403 if ((IS_ITEMP(IC_RESULT(ic)) &&
2404 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2405 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2406 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2409 aopOp(IC_RESULT(ic),ic,FALSE);
2412 assignResultValue(IC_RESULT(ic));
2414 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2415 AopType(AOP_TYPE(IC_RESULT(ic))));
2417 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2420 /* adjust the stack for parameters if
2422 if (ic->parmBytes) {
2424 if (ic->parmBytes > 3) {
2425 pic14_emitcode("mov","a,%s",spname);
2426 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2427 pic14_emitcode("mov","%s,a",spname);
2429 for ( i = 0 ; i < ic->parmBytes ;i++)
2430 pic14_emitcode("dec","%s",spname);
2434 /* if register bank was saved then pop them */
2436 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2438 /* if we hade saved some registers then unsave them */
2439 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2440 unsaveRegisters (ic);
2445 /*-----------------------------------------------------------------*/
2446 /* genPcall - generates a call by pointer statement */
2447 /*-----------------------------------------------------------------*/
2448 static void genPcall (iCode *ic)
2451 symbol *albl = newiTempLabel(NULL);
2452 symbol *blbl = newiTempLabel(NULL);
2457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2458 /* if caller saves & we have not saved then */
2462 /* if we are calling a function that is not using
2463 the same register bank then we need to save the
2464 destination registers on the stack */
2465 dtype = operandType(IC_LEFT(ic));
2466 if (currFunc && dtype &&
2467 IFFUNC_ISISR(currFunc->type) &&
2468 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2469 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2472 aopOp(left,ic,FALSE);
2473 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2475 pushSide(IC_LEFT(ic), FPTRSIZE);
2477 /* if send set is not empty, assign parameters */
2480 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2481 /* no way to pass args - W always gets used to make the call */
2483 /* first idea - factor out a common helper function and call it.
2484 But don't know how to get it generated only once in its own block
2486 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2489 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2490 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2491 buffer = Safe_calloc(1,strlen(rname)+16);
2492 sprintf(buffer, "%s_goto_helper", rname);
2493 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2497 emitpcode(POC_CALL,popGetLabel(albl->key));
2498 pcop = popGetLabel(blbl->key);
2499 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2500 emitpcode(POC_GOTO,pcop);
2501 emitpLabel(albl->key);
2503 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2505 emitpcode(poc,popGet(AOP(left),1));
2506 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2507 emitpcode(poc,popGet(AOP(left),0));
2508 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2510 emitpLabel(blbl->key);
2512 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2514 /* if we need to assign a result value */
2515 if ((IS_ITEMP(IC_RESULT(ic)) &&
2516 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2517 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2518 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2521 aopOp(IC_RESULT(ic),ic,FALSE);
2524 assignResultValue(IC_RESULT(ic));
2526 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2529 /* if register bank was saved then unsave them */
2530 if (currFunc && dtype &&
2531 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2534 /* if we hade saved some registers then
2537 unsaveRegisters (ic);
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result is rematerializable */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2546 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2547 if (SKIP_IC(ic) || ic->op == IFX)
2550 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552 if (sym->remat && !POINTER_SET(ic))
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2562 #define STRCASECMP strcasecmp
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2571 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2575 if (options.excludeRegs[i] &&
2576 STRCASECMP(options.excludeRegs[i],"none") == 0)
2579 for ( i = 0 ; options.excludeRegs[i]; i++) {
2580 if (options.excludeRegs[i] &&
2581 STRCASECMP(s,options.excludeRegs[i]) == 0)
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2596 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2598 labelOffset += (max_key+4);
2602 /* create the function header */
2603 pic14_emitcode(";","-----------------------------------------");
2604 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605 pic14_emitcode(";","-----------------------------------------");
2607 pic14_emitcode("","%s:",sym->rname);
2608 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2610 ftype = operandType(IC_LEFT(ic));
2612 /* if critical function then turn interrupts off */
2613 if (IFFUNC_ISCRITICAL(ftype))
2614 pic14_emitcode("clr","ea");
2616 /* here we need to generate the equates for the
2617 register bank if required */
2619 if (FUNC_REGBANK(ftype) != rbank) {
2622 rbank = FUNC_REGBANK(ftype);
2623 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624 if (strcmp(regspic14[i].base,"0") == 0)
2625 pic14_emitcode("","%s = 0x%02x",
2627 8*rbank+regspic14[i].offset);
2629 pic14_emitcode ("","%s = %s + 0x%02x",
2632 8*rbank+regspic14[i].offset);
2637 /* if this is an interrupt service routine */
2638 if (IFFUNC_ISISR(sym->type)) {
2639 /* already done in pic14createInterruptVect() - delete me
2640 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641 emitpcodeNULLop(POC_NOP);
2642 emitpcodeNULLop(POC_NOP);
2643 emitpcodeNULLop(POC_NOP);
2645 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2646 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2647 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2648 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2649 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2650 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2651 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2653 pBlockConvert2ISR(pb);
2655 if (!inExcludeList("acc"))
2656 pic14_emitcode ("push","acc");
2657 if (!inExcludeList("b"))
2658 pic14_emitcode ("push","b");
2659 if (!inExcludeList("dpl"))
2660 pic14_emitcode ("push","dpl");
2661 if (!inExcludeList("dph"))
2662 pic14_emitcode ("push","dph");
2663 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2665 pic14_emitcode ("push", "dpx");
2666 /* Make sure we're using standard DPTR */
2667 pic14_emitcode ("push", "dps");
2668 pic14_emitcode ("mov", "dps, #0x00");
2669 if (options.stack10bit)
2671 /* This ISR could conceivably use DPTR2. Better save it. */
2672 pic14_emitcode ("push", "dpl1");
2673 pic14_emitcode ("push", "dph1");
2674 pic14_emitcode ("push", "dpx1");
2677 /* if this isr has no bank i.e. is going to
2678 run with bank 0 , then we need to save more
2680 if (!FUNC_REGBANK(sym->type)) {
2682 /* if this function does not call any other
2683 function then we can be economical and
2684 save only those registers that are used */
2685 if (! IFFUNC_HASFCALL(sym->type)) {
2688 /* if any registers used */
2689 if (sym->regsUsed) {
2690 /* save the registers used */
2691 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2692 if (bitVectBitValue(sym->regsUsed,i) ||
2693 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2694 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2699 /* this function has a function call cannot
2700 determines register usage so we will have the
2702 saverbank(0,ic,FALSE);
2707 /* if callee-save to be used for this function
2708 then save the registers being used in this function */
2709 if (IFFUNC_CALLEESAVES(sym->type)) {
2712 /* if any registers used */
2713 if (sym->regsUsed) {
2714 /* save the registers used */
2715 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2716 if (bitVectBitValue(sym->regsUsed,i) ||
2717 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2718 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2726 /* set the register bank to the desired value */
2727 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2728 pic14_emitcode("push","psw");
2729 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2732 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2734 if (options.useXstack) {
2735 pic14_emitcode("mov","r0,%s",spname);
2736 pic14_emitcode("mov","a,_bp");
2737 pic14_emitcode("movx","@r0,a");
2738 pic14_emitcode("inc","%s",spname);
2742 /* set up the stack */
2743 pic14_emitcode ("push","_bp"); /* save the callers stack */
2745 pic14_emitcode ("mov","_bp,%s",spname);
2748 /* adjust the stack for the function */
2753 werror(W_STACK_OVERFLOW,sym->name);
2755 if (i > 3 && sym->recvSize < 4) {
2757 pic14_emitcode ("mov","a,sp");
2758 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2759 pic14_emitcode ("mov","sp,a");
2764 pic14_emitcode("inc","sp");
2769 pic14_emitcode ("mov","a,_spx");
2770 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2771 pic14_emitcode ("mov","_spx,a");
2776 /*-----------------------------------------------------------------*/
2777 /* genEndFunction - generates epilogue for functions */
2778 /*-----------------------------------------------------------------*/
2779 static void genEndFunction (iCode *ic)
2781 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2785 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2787 pic14_emitcode ("mov","%s,_bp",spname);
2790 /* if use external stack but some variables were
2791 added to the local stack then decrement the
2793 if (options.useXstack && sym->stack) {
2794 pic14_emitcode("mov","a,sp");
2795 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2796 pic14_emitcode("mov","sp,a");
2800 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2801 if (options.useXstack) {
2802 pic14_emitcode("mov","r0,%s",spname);
2803 pic14_emitcode("movx","a,@r0");
2804 pic14_emitcode("mov","_bp,a");
2805 pic14_emitcode("dec","%s",spname);
2809 pic14_emitcode ("pop","_bp");
2813 /* restore the register bank */
2814 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2815 pic14_emitcode ("pop","psw");
2817 if (IFFUNC_ISISR(sym->type)) {
2819 /* now we need to restore the registers */
2820 /* if this isr has no bank i.e. is going to
2821 run with bank 0 , then we need to save more
2823 if (!FUNC_REGBANK(sym->type)) {
2825 /* if this function does not call any other
2826 function then we can be economical and
2827 save only those registers that are used */
2828 if (! IFFUNC_HASFCALL(sym->type)) {
2831 /* if any registers used */
2832 if (sym->regsUsed) {
2833 /* save the registers used */
2834 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2835 if (bitVectBitValue(sym->regsUsed,i) ||
2836 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2837 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2842 /* this function has a function call cannot
2843 determines register usage so we will have the
2845 unsaverbank(0,ic,FALSE);
2849 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2851 if (options.stack10bit)
2853 pic14_emitcode ("pop", "dpx1");
2854 pic14_emitcode ("pop", "dph1");
2855 pic14_emitcode ("pop", "dpl1");
2857 pic14_emitcode ("pop", "dps");
2858 pic14_emitcode ("pop", "dpx");
2860 if (!inExcludeList("dph"))
2861 pic14_emitcode ("pop","dph");
2862 if (!inExcludeList("dpl"))
2863 pic14_emitcode ("pop","dpl");
2864 if (!inExcludeList("b"))
2865 pic14_emitcode ("pop","b");
2866 if (!inExcludeList("acc"))
2867 pic14_emitcode ("pop","acc");
2869 if (IFFUNC_ISCRITICAL(sym->type))
2870 pic14_emitcode("setb","ea");
2873 /* if debug then send end of function */
2874 /* if (options.debug && currFunc) { */
2876 debugFile->writeEndFunction (currFunc, ic, 1);
2879 pic14_emitcode ("reti","");
2880 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2881 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2882 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2883 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2884 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2885 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2886 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2887 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2888 emitpcodeNULLop(POC_RETFIE);
2891 if (IFFUNC_ISCRITICAL(sym->type))
2892 pic14_emitcode("setb","ea");
2894 if (IFFUNC_CALLEESAVES(sym->type)) {
2897 /* if any registers used */
2898 if (sym->regsUsed) {
2899 /* save the registers used */
2900 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2901 if (bitVectBitValue(sym->regsUsed,i) ||
2902 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2903 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2909 /* if debug then send end of function */
2911 debugFile->writeEndFunction (currFunc, ic, 1);
2914 pic14_emitcode ("return","");
2915 emitpcodeNULLop(POC_RETURN);
2917 /* Mark the end of a function */
2918 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2923 /*-----------------------------------------------------------------*/
2924 /* genRet - generate code for return statement */
2925 /*-----------------------------------------------------------------*/
2926 static void genRet (iCode *ic)
2928 int size,offset = 0 , pushed = 0;
2930 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2931 /* if we have no return value then
2932 just generate the "ret" */
2936 /* we have something to return then
2937 move the return value into place */
2938 aopOp(IC_LEFT(ic),ic,FALSE);
2939 size = AOP_SIZE(IC_LEFT(ic));
2943 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2945 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2947 pic14_emitcode("push","%s",l);
2950 l = aopGet(AOP(IC_LEFT(ic)),offset,
2952 if (strcmp(fReturn[offset],l)) {
2953 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2954 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2955 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2956 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2957 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2959 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2962 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2972 if (strcmp(fReturn[pushed],"a"))
2973 pic14_emitcode("pop",fReturn[pushed]);
2975 pic14_emitcode("pop","acc");
2978 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2981 /* generate a jump to the return label
2982 if the next is not the return statement */
2983 if (!(ic->next && ic->next->op == LABEL &&
2984 IC_LABEL(ic->next) == returnLabel)) {
2986 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2987 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2992 /*-----------------------------------------------------------------*/
2993 /* genLabel - generates a label */
2994 /*-----------------------------------------------------------------*/
2995 static void genLabel (iCode *ic)
2997 /* special case never generate */
2998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2999 if (IC_LABEL(ic) == entryLabel)
3002 emitpLabel(IC_LABEL(ic)->key);
3003 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3006 /*-----------------------------------------------------------------*/
3007 /* genGoto - generates a goto */
3008 /*-----------------------------------------------------------------*/
3010 static void genGoto (iCode *ic)
3012 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3013 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3017 /*-----------------------------------------------------------------*/
3018 /* genMultbits :- multiplication of bits */
3019 /*-----------------------------------------------------------------*/
3020 static void genMultbits (operand *left,
3024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3026 if(!pic14_sameRegs(AOP(result),AOP(right)))
3027 emitpcode(POC_BSF, popGet(AOP(result),0));
3029 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3030 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3031 emitpcode(POC_BCF, popGet(AOP(result),0));
3036 /*-----------------------------------------------------------------*/
3037 /* genMultOneByte : 8 bit multiplication & division */
3038 /*-----------------------------------------------------------------*/
3039 static void genMultOneByte (operand *left,
3043 sym_link *opetype = operandType(result);
3048 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3049 DEBUGpic14_AopType(__LINE__,left,right,result);
3050 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3052 /* (if two literals, the value is computed before) */
3053 /* if one literal, literal on the right */
3054 if (AOP_TYPE(left) == AOP_LIT){
3060 size = AOP_SIZE(result);
3063 if (AOP_TYPE(right) == AOP_LIT){
3064 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3065 aopGet(AOP(right),0,FALSE,FALSE),
3066 aopGet(AOP(left),0,FALSE,FALSE),
3067 aopGet(AOP(result),0,FALSE,FALSE));
3068 pic14_emitcode("call","genMultLit");
3070 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3071 aopGet(AOP(right),0,FALSE,FALSE),
3072 aopGet(AOP(left),0,FALSE,FALSE),
3073 aopGet(AOP(result),0,FALSE,FALSE));
3074 pic14_emitcode("call","genMult8X8_8");
3077 genMult8X8_8 (left, right,result);
3080 /* signed or unsigned */
3081 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3082 //l = aopGet(AOP(left),0,FALSE,FALSE);
3084 //pic14_emitcode("mul","ab");
3085 /* if result size = 1, mul signed = mul unsigned */
3086 //aopPut(AOP(result),"a",0);
3088 } else { // (size > 1)
3090 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3091 aopGet(AOP(right),0,FALSE,FALSE),
3092 aopGet(AOP(left),0,FALSE,FALSE),
3093 aopGet(AOP(result),0,FALSE,FALSE));
3095 if (SPEC_USIGN(opetype)){
3096 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3097 genUMult8X8_16 (left, right, result, NULL);
3100 /* for filling the MSBs */
3101 emitpcode(POC_CLRF, popGet(AOP(result),2));
3102 emitpcode(POC_CLRF, popGet(AOP(result),3));
3106 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3108 pic14_emitcode("mov","a,b");
3110 /* adjust the MSB if left or right neg */
3112 /* if one literal */
3113 if (AOP_TYPE(right) == AOP_LIT){
3114 pic14_emitcode("multiply ","right is a lit");
3115 /* AND literal negative */
3116 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3117 /* adjust MSB (c==0 after mul) */
3118 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3122 genSMult8X8_16 (left, right, result, NULL);
3126 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3128 pic14_emitcode("rlc","a");
3129 pic14_emitcode("subb","a,acc");
3137 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3138 //aopPut(AOP(result),"a",offset++);
3142 /*-----------------------------------------------------------------*/
3143 /* genMult - generates code for multiplication */
3144 /*-----------------------------------------------------------------*/
3145 static void genMult (iCode *ic)
3147 operand *left = IC_LEFT(ic);
3148 operand *right = IC_RIGHT(ic);
3149 operand *result= IC_RESULT(ic);
3151 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3152 /* assign the amsops */
3153 aopOp (left,ic,FALSE);
3154 aopOp (right,ic,FALSE);
3155 aopOp (result,ic,TRUE);
3157 DEBUGpic14_AopType(__LINE__,left,right,result);
3159 /* special cases first */
3161 if (AOP_TYPE(left) == AOP_CRY &&
3162 AOP_TYPE(right)== AOP_CRY) {
3163 genMultbits(left,right,result);
3167 /* if both are of size == 1 */
3168 if (AOP_SIZE(left) == 1 &&
3169 AOP_SIZE(right) == 1 ) {
3170 genMultOneByte(left,right,result);
3174 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3176 /* should have been converted to function call */
3180 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3181 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182 freeAsmop(result,NULL,ic,TRUE);
3185 /*-----------------------------------------------------------------*/
3186 /* genDivbits :- division of bits */
3187 /*-----------------------------------------------------------------*/
3188 static void genDivbits (operand *left,
3195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3196 /* the result must be bit */
3197 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3198 l = aopGet(AOP(left),0,FALSE,FALSE);
3202 pic14_emitcode("div","ab");
3203 pic14_emitcode("rrc","a");
3204 aopPut(AOP(result),"c",0);
3207 /*-----------------------------------------------------------------*/
3208 /* genDivOneByte : 8 bit division */
3209 /*-----------------------------------------------------------------*/
3210 static void genDivOneByte (operand *left,
3214 sym_link *opetype = operandType(result);
3219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3220 size = AOP_SIZE(result) - 1;
3222 /* signed or unsigned */
3223 if (SPEC_USIGN(opetype)) {
3224 /* unsigned is easy */
3225 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3226 l = aopGet(AOP(left),0,FALSE,FALSE);
3228 pic14_emitcode("div","ab");
3229 aopPut(AOP(result),"a",0);
3231 aopPut(AOP(result),zero,offset++);
3235 /* signed is a little bit more difficult */
3237 /* save the signs of the operands */
3238 l = aopGet(AOP(left),0,FALSE,FALSE);
3240 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3241 pic14_emitcode("push","acc"); /* save it on the stack */
3243 /* now sign adjust for both left & right */
3244 l = aopGet(AOP(right),0,FALSE,FALSE);
3246 lbl = newiTempLabel(NULL);
3247 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3248 pic14_emitcode("cpl","a");
3249 pic14_emitcode("inc","a");
3250 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3251 pic14_emitcode("mov","b,a");
3253 /* sign adjust left side */
3254 l = aopGet(AOP(left),0,FALSE,FALSE);
3257 lbl = newiTempLabel(NULL);
3258 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3259 pic14_emitcode("cpl","a");
3260 pic14_emitcode("inc","a");
3261 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263 /* now the division */
3264 pic14_emitcode("div","ab");
3265 /* we are interested in the lower order
3267 pic14_emitcode("mov","b,a");
3268 lbl = newiTempLabel(NULL);
3269 pic14_emitcode("pop","acc");
3270 /* if there was an over flow we don't
3271 adjust the sign of the result */
3272 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3273 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3275 pic14_emitcode("clr","a");
3276 pic14_emitcode("subb","a,b");
3277 pic14_emitcode("mov","b,a");
3278 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3280 /* now we are done */
3281 aopPut(AOP(result),"b",0);
3283 pic14_emitcode("mov","c,b.7");
3284 pic14_emitcode("subb","a,acc");
3287 aopPut(AOP(result),"a",offset++);
3291 /*-----------------------------------------------------------------*/
3292 /* genDiv - generates code for division */
3293 /*-----------------------------------------------------------------*/
3294 static void genDiv (iCode *ic)
3296 operand *left = IC_LEFT(ic);
3297 operand *right = IC_RIGHT(ic);
3298 operand *result= IC_RESULT(ic);
3300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3301 /* assign the amsops */
3302 aopOp (left,ic,FALSE);
3303 aopOp (right,ic,FALSE);
3304 aopOp (result,ic,TRUE);
3306 /* special cases first */
3308 if (AOP_TYPE(left) == AOP_CRY &&
3309 AOP_TYPE(right)== AOP_CRY) {
3310 genDivbits(left,right,result);
3314 /* if both are of size == 1 */
3315 if (AOP_SIZE(left) == 1 &&
3316 AOP_SIZE(right) == 1 ) {
3317 genDivOneByte(left,right,result);
3321 /* should have been converted to function call */
3324 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3325 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3326 freeAsmop(result,NULL,ic,TRUE);
3329 /*-----------------------------------------------------------------*/
3330 /* genModbits :- modulus of bits */
3331 /*-----------------------------------------------------------------*/
3332 static void genModbits (operand *left,
3339 /* the result must be bit */
3340 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3341 l = aopGet(AOP(left),0,FALSE,FALSE);
3345 pic14_emitcode("div","ab");
3346 pic14_emitcode("mov","a,b");
3347 pic14_emitcode("rrc","a");
3348 aopPut(AOP(result),"c",0);
3351 /*-----------------------------------------------------------------*/
3352 /* genModOneByte : 8 bit modulus */
3353 /*-----------------------------------------------------------------*/
3354 static void genModOneByte (operand *left,
3358 sym_link *opetype = operandType(result);
3362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3363 /* signed or unsigned */
3364 if (SPEC_USIGN(opetype)) {
3365 /* unsigned is easy */
3366 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3367 l = aopGet(AOP(left),0,FALSE,FALSE);
3369 pic14_emitcode("div","ab");
3370 aopPut(AOP(result),"b",0);
3374 /* signed is a little bit more difficult */
3376 /* save the signs of the operands */
3377 l = aopGet(AOP(left),0,FALSE,FALSE);
3380 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3381 pic14_emitcode("push","acc"); /* save it on the stack */
3383 /* now sign adjust for both left & right */
3384 l = aopGet(AOP(right),0,FALSE,FALSE);
3387 lbl = newiTempLabel(NULL);
3388 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3389 pic14_emitcode("cpl","a");
3390 pic14_emitcode("inc","a");
3391 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3392 pic14_emitcode("mov","b,a");
3394 /* sign adjust left side */
3395 l = aopGet(AOP(left),0,FALSE,FALSE);
3398 lbl = newiTempLabel(NULL);
3399 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3400 pic14_emitcode("cpl","a");
3401 pic14_emitcode("inc","a");
3402 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3404 /* now the multiplication */
3405 pic14_emitcode("div","ab");
3406 /* we are interested in the lower order
3408 lbl = newiTempLabel(NULL);
3409 pic14_emitcode("pop","acc");
3410 /* if there was an over flow we don't
3411 adjust the sign of the result */
3412 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3413 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3415 pic14_emitcode("clr","a");
3416 pic14_emitcode("subb","a,b");
3417 pic14_emitcode("mov","b,a");
3418 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3420 /* now we are done */
3421 aopPut(AOP(result),"b",0);
3425 /*-----------------------------------------------------------------*/
3426 /* genMod - generates code for division */
3427 /*-----------------------------------------------------------------*/
3428 static void genMod (iCode *ic)
3430 operand *left = IC_LEFT(ic);
3431 operand *right = IC_RIGHT(ic);
3432 operand *result= IC_RESULT(ic);
3434 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3435 /* assign the amsops */
3436 aopOp (left,ic,FALSE);
3437 aopOp (right,ic,FALSE);
3438 aopOp (result,ic,TRUE);
3440 /* special cases first */
3442 if (AOP_TYPE(left) == AOP_CRY &&
3443 AOP_TYPE(right)== AOP_CRY) {
3444 genModbits(left,right,result);
3448 /* if both are of size == 1 */
3449 if (AOP_SIZE(left) == 1 &&
3450 AOP_SIZE(right) == 1 ) {
3451 genModOneByte(left,right,result);
3455 /* should have been converted to function call */
3459 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3460 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3461 freeAsmop(result,NULL,ic,TRUE);
3464 /*-----------------------------------------------------------------*/
3465 /* genIfxJump :- will create a jump depending on the ifx */
3466 /*-----------------------------------------------------------------*/
3468 note: May need to add parameter to indicate when a variable is in bit space.
3470 static void genIfxJump (iCode *ic, char *jval)
3473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3474 /* if true label then we jump if condition
3476 if ( IC_TRUE(ic) ) {
3478 if(strcmp(jval,"a") == 0)
3480 else if (strcmp(jval,"c") == 0)
3483 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3484 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3487 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3488 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3492 /* false label is present */
3493 if(strcmp(jval,"a") == 0)
3495 else if (strcmp(jval,"c") == 0)
3498 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3499 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3502 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3503 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3508 /* mark the icode as generated */
3512 /*-----------------------------------------------------------------*/
3514 /*-----------------------------------------------------------------*/
3515 static void genSkip(iCode *ifx,int status_bit)
3520 if ( IC_TRUE(ifx) ) {
3521 switch(status_bit) {
3536 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3537 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3541 switch(status_bit) {
3555 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3556 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3562 /*-----------------------------------------------------------------*/
3564 /*-----------------------------------------------------------------*/
3565 static void genSkipc(resolvedIfx *rifx)
3575 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3576 rifx->generated = 1;
3579 /*-----------------------------------------------------------------*/
3581 /*-----------------------------------------------------------------*/
3582 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3587 if( (rifx->condition ^ invert_condition) & 1)
3592 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3593 rifx->generated = 1;
3596 /*-----------------------------------------------------------------*/
3598 /*-----------------------------------------------------------------*/
3599 static void genSkipz(iCode *ifx, int condition)
3610 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3612 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3615 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3617 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3620 /*-----------------------------------------------------------------*/
3622 /*-----------------------------------------------------------------*/
3623 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3629 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3631 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3634 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3635 rifx->generated = 1;
3639 /*-----------------------------------------------------------------*/
3640 /* genChkZeroes :- greater or less than comparison */
3641 /* For each byte in a literal that is zero, inclusive or the */
3642 /* the corresponding byte in the operand with W */
3643 /* returns true if any of the bytes are zero */
3644 /*-----------------------------------------------------------------*/
3645 static int genChkZeroes(operand *op, int lit, int size)
3652 i = (lit >> (size*8)) & 0xff;
3656 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3658 emitpcode(POC_IORFW, popGet(AOP(op),size));
3667 /*-----------------------------------------------------------------*/
3668 /* genCmp :- greater or less than comparison */
3669 /*-----------------------------------------------------------------*/
3670 static void genCmp (operand *left,operand *right,
3671 operand *result, iCode *ifx, int sign)
3673 int size; //, offset = 0 ;
3674 unsigned long lit = 0L,i = 0;
3675 resolvedIfx rFalseIfx;
3676 // resolvedIfx rTrueIfx;
3678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3681 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3682 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3686 resolveIfx(&rFalseIfx,ifx);
3687 truelbl = newiTempLabel(NULL);
3688 size = max(AOP_SIZE(left),AOP_SIZE(right));
3690 DEBUGpic14_AopType(__LINE__,left,right,result);
3694 /* if literal is on the right then swap with left */
3695 if ((AOP_TYPE(right) == AOP_LIT)) {
3696 operand *tmp = right ;
3697 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3698 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3701 lit = (lit - 1) & mask;
3704 rFalseIfx.condition ^= 1;
3707 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3708 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3712 //if(IC_TRUE(ifx) == NULL)
3713 /* if left & right are bit variables */
3714 if (AOP_TYPE(left) == AOP_CRY &&
3715 AOP_TYPE(right) == AOP_CRY ) {
3716 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3717 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3719 /* subtract right from left if at the
3720 end the carry flag is set then we know that
3721 left is greater than right */
3723 symbol *lbl = newiTempLabel(NULL);
3726 if(AOP_TYPE(right) == AOP_LIT) {
3728 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3730 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3737 genSkipCond(&rFalseIfx,left,size-1,7);
3739 /* no need to compare to 0...*/
3740 /* NOTE: this is a de-generate compare that most certainly
3741 * creates some dead code. */
3742 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3744 if(ifx) ifx->generated = 1;
3751 //i = (lit >> (size*8)) & 0xff;
3752 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3754 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3756 i = ((0-lit) & 0xff);
3759 /* lit is 0x7f, all signed chars are less than
3760 * this except for 0x7f itself */
3761 emitpcode(POC_XORLW, popGetLit(0x7f));
3762 genSkipz2(&rFalseIfx,0);
3764 emitpcode(POC_ADDLW, popGetLit(0x80));
3765 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3766 genSkipc(&rFalseIfx);
3771 genSkipz2(&rFalseIfx,1);
3773 emitpcode(POC_ADDLW, popGetLit(i));
3774 genSkipc(&rFalseIfx);
3778 if(ifx) ifx->generated = 1;
3782 /* chars are out of the way. now do ints and longs */
3785 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3792 genSkipCond(&rFalseIfx,left,size,7);
3793 if(ifx) ifx->generated = 1;
3798 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3800 //rFalseIfx.condition ^= 1;
3801 //genSkipCond(&rFalseIfx,left,size,7);
3802 //rFalseIfx.condition ^= 1;
3804 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3805 if(rFalseIfx.condition)
3806 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3808 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3810 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3811 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3812 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3815 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3817 if(rFalseIfx.condition) {
3819 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3825 genSkipc(&rFalseIfx);
3826 emitpLabel(truelbl->key);
3827 if(ifx) ifx->generated = 1;
3834 if( (lit & 0xff) == 0) {
3835 /* lower byte is zero */
3836 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3837 i = ((lit >> 8) & 0xff) ^0x80;
3838 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3839 emitpcode(POC_ADDLW, popGetLit( 0x80));
3840 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3841 genSkipc(&rFalseIfx);
3844 if(ifx) ifx->generated = 1;
3849 /* Special cases for signed longs */
3850 if( (lit & 0xffffff) == 0) {
3851 /* lower byte is zero */
3852 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3853 i = ((lit >> 8*3) & 0xff) ^0x80;
3854 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3855 emitpcode(POC_ADDLW, popGetLit( 0x80));
3856 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3857 genSkipc(&rFalseIfx);
3860 if(ifx) ifx->generated = 1;
3868 if(lit & (0x80 << (size*8))) {
3869 /* lit is negative */
3870 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3872 //genSkipCond(&rFalseIfx,left,size,7);
3874 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3876 if(rFalseIfx.condition)
3877 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3879 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3883 /* lit is positive */
3884 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3885 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3886 if(rFalseIfx.condition)
3887 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3889 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3893 /* There are no more special cases, so perform a general compare */
3895 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3896 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3900 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3902 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3904 //rFalseIfx.condition ^= 1;
3905 genSkipc(&rFalseIfx);
3907 emitpLabel(truelbl->key);
3909 if(ifx) ifx->generated = 1;
3916 /* sign is out of the way. So now do an unsigned compare */
3917 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3920 /* General case - compare to an unsigned literal on the right.*/
3922 i = (lit >> (size*8)) & 0xff;
3923 emitpcode(POC_MOVLW, popGetLit(i));
3924 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3926 i = (lit >> (size*8)) & 0xff;
3929 emitpcode(POC_MOVLW, popGetLit(i));
3931 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3933 /* this byte of the lit is zero,
3934 *if it's not the last then OR in the variable */
3936 emitpcode(POC_IORFW, popGet(AOP(left),size));
3941 emitpLabel(lbl->key);
3942 //if(emitFinalCheck)
3943 genSkipc(&rFalseIfx);
3945 emitpLabel(truelbl->key);
3947 if(ifx) ifx->generated = 1;
3954 if(AOP_TYPE(left) == AOP_LIT) {
3955 //symbol *lbl = newiTempLabel(NULL);
3957 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3960 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3963 if((lit == 0) && (sign == 0)){
3966 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3968 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3970 genSkipz2(&rFalseIfx,0);
3971 if(ifx) ifx->generated = 1;
3978 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3979 /* degenerate compare can never be true */
3980 if(rFalseIfx.condition == 0)
3981 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3983 if(ifx) ifx->generated = 1;
3988 /* signed comparisons to a literal byte */
3990 int lp1 = (lit+1) & 0xff;
3992 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3995 rFalseIfx.condition ^= 1;
3996 genSkipCond(&rFalseIfx,right,0,7);
3999 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4000 emitpcode(POC_XORLW, popGetLit(0x7f));
4001 genSkipz2(&rFalseIfx,1);
4004 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4005 emitpcode(POC_ADDLW, popGetLit(0x80));
4006 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4007 rFalseIfx.condition ^= 1;
4008 genSkipc(&rFalseIfx);
4011 if(ifx) ifx->generated = 1;
4013 /* unsigned comparisons to a literal byte */
4015 switch(lit & 0xff ) {
4017 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4018 genSkipz2(&rFalseIfx,0);
4019 if(ifx) ifx->generated = 1;
4022 genSkipCond(&rFalseIfx,right,0,7);
4023 if(ifx) ifx->generated = 1;
4027 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4028 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4030 rFalseIfx.condition ^= 1;
4031 if (AOP_TYPE(result) == AOP_CRY) {
4032 genSkipc(&rFalseIfx);
4033 if(ifx) ifx->generated = 1;
4035 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4036 emitpcode(POC_CLRF, popGet(AOP(result),0));
4037 emitpcode(POC_RLF, popGet(AOP(result),0));
4038 emitpcode(POC_MOVLW, popGetLit(0x01));
4039 emitpcode(POC_XORWF, popGet(AOP(result),0));
4050 /* Size is greater than 1 */
4058 /* this means lit = 0xffffffff, or -1 */
4061 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4062 rFalseIfx.condition ^= 1;
4063 genSkipCond(&rFalseIfx,right,size,7);
4064 if(ifx) ifx->generated = 1;
4071 if(rFalseIfx.condition) {
4072 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4073 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4076 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4078 emitpcode(POC_IORFW, popGet(AOP(right),size));
4082 if(rFalseIfx.condition) {
4083 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4084 emitpLabel(truelbl->key);
4086 rFalseIfx.condition ^= 1;
4087 genSkipCond(&rFalseIfx,right,s,7);
4090 if(ifx) ifx->generated = 1;
4094 if((size == 1) && (0 == (lp1&0xff))) {
4095 /* lower byte of signed word is zero */
4096 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4097 i = ((lp1 >> 8) & 0xff) ^0x80;
4098 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4099 emitpcode(POC_ADDLW, popGetLit( 0x80));
4100 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4101 rFalseIfx.condition ^= 1;
4102 genSkipc(&rFalseIfx);
4105 if(ifx) ifx->generated = 1;
4109 if(lit & (0x80 << (size*8))) {
4110 /* Lit is less than zero */
4111 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4112 //rFalseIfx.condition ^= 1;
4113 //genSkipCond(&rFalseIfx,left,size,7);
4114 //rFalseIfx.condition ^= 1;
4115 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4116 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4118 if(rFalseIfx.condition)
4119 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4121 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4125 /* Lit is greater than or equal to zero */
4126 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4127 //rFalseIfx.condition ^= 1;
4128 //genSkipCond(&rFalseIfx,right,size,7);
4129 //rFalseIfx.condition ^= 1;
4131 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4134 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4135 if(rFalseIfx.condition)
4136 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4138 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4143 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4144 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4148 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4150 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4152 rFalseIfx.condition ^= 1;
4153 //rFalseIfx.condition = 1;
4154 genSkipc(&rFalseIfx);
4156 emitpLabel(truelbl->key);
4158 if(ifx) ifx->generated = 1;
4163 /* compare word or long to an unsigned literal on the right.*/
4168 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4171 break; /* handled above */
4174 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4176 emitpcode(POC_IORFW, popGet(AOP(right),size));
4177 genSkipz2(&rFalseIfx,0);
4181 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4183 emitpcode(POC_IORFW, popGet(AOP(right),size));
4186 if(rFalseIfx.condition)
4187 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4189 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4192 emitpcode(POC_MOVLW, popGetLit(lit+1));
4193 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4195 rFalseIfx.condition ^= 1;
4196 genSkipc(&rFalseIfx);
4199 emitpLabel(truelbl->key);
4201 if(ifx) ifx->generated = 1;
4207 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4208 i = (lit >> (size*8)) & 0xff;
4210 emitpcode(POC_MOVLW, popGetLit(i));
4211 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4214 i = (lit >> (size*8)) & 0xff;
4217 emitpcode(POC_MOVLW, popGetLit(i));
4219 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4221 /* this byte of the lit is zero,
4222 *if it's not the last then OR in the variable */
4224 emitpcode(POC_IORFW, popGet(AOP(right),size));
4229 emitpLabel(lbl->key);
4231 rFalseIfx.condition ^= 1;
4232 genSkipc(&rFalseIfx);
4236 emitpLabel(truelbl->key);
4237 if(ifx) ifx->generated = 1;
4241 /* Compare two variables */
4243 DEBUGpic14_emitcode(";sign","%d",sign);
4247 /* Sigh. thus sucks... */
4249 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4250 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4251 emitpcode(POC_MOVLW, popGetLit(0x80));
4252 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4253 emitpcode(POC_XORFW, popGet(AOP(right),size));
4254 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4256 /* Signed char comparison */
4257 /* Special thanks to Nikolai Golovchenko for this snippet */
4258 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4259 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4260 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4261 emitpcode(POC_XORFW, popGet(AOP(left),0));
4262 emitpcode(POC_XORFW, popGet(AOP(right),0));
4263 emitpcode(POC_ADDLW, popGetLit(0x80));
4265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4266 genSkipc(&rFalseIfx);
4268 if(ifx) ifx->generated = 1;
4274 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4275 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4279 /* The rest of the bytes of a multi-byte compare */
4283 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4286 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4287 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4292 emitpLabel(lbl->key);
4294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4295 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4296 (AOP_TYPE(result) == AOP_REG)) {
4297 emitpcode(POC_CLRF, popGet(AOP(result),0));
4298 emitpcode(POC_RLF, popGet(AOP(result),0));
4300 genSkipc(&rFalseIfx);
4302 //genSkipc(&rFalseIfx);
4303 if(ifx) ifx->generated = 1;
4310 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4312 pic14_outBitC(result);
4314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4315 /* if the result is used in the next
4316 ifx conditional branch then generate
4317 code a little differently */
4319 genIfxJump (ifx,"c");
4321 pic14_outBitC(result);
4322 /* leave the result in acc */
4327 /*-----------------------------------------------------------------*/
4328 /* genCmpGt :- greater than comparison */
4329 /*-----------------------------------------------------------------*/
4330 static void genCmpGt (iCode *ic, iCode *ifx)
4332 operand *left, *right, *result;
4333 sym_link *letype , *retype;
4336 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4338 right= IC_RIGHT(ic);
4339 result = IC_RESULT(ic);
4341 letype = getSpec(operandType(left));
4342 retype =getSpec(operandType(right));
4343 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4344 /* assign the amsops */
4345 aopOp (left,ic,FALSE);
4346 aopOp (right,ic,FALSE);
4347 aopOp (result,ic,TRUE);
4349 genCmp(right, left, result, ifx, sign);
4351 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4352 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4353 freeAsmop(result,NULL,ic,TRUE);
4356 /*-----------------------------------------------------------------*/
4357 /* genCmpLt - less than comparisons */
4358 /*-----------------------------------------------------------------*/
4359 static void genCmpLt (iCode *ic, iCode *ifx)
4361 operand *left, *right, *result;
4362 sym_link *letype , *retype;
4365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4367 right= IC_RIGHT(ic);
4368 result = IC_RESULT(ic);
4370 letype = getSpec(operandType(left));
4371 retype =getSpec(operandType(right));
4372 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4374 /* assign the amsops */
4375 aopOp (left,ic,FALSE);
4376 aopOp (right,ic,FALSE);
4377 aopOp (result,ic,TRUE);
4379 genCmp(left, right, result, ifx, sign);
4381 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4382 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4383 freeAsmop(result,NULL,ic,TRUE);
4386 /*-----------------------------------------------------------------*/
4387 /* genc16bit2lit - compare a 16 bit value to a literal */
4388 /*-----------------------------------------------------------------*/
4389 static void genc16bit2lit(operand *op, int lit, int offset)
4393 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4394 if( (lit&0xff) == 0)
4399 switch( BYTEofLONG(lit,i)) {
4401 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4404 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4407 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4410 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4411 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4416 switch( BYTEofLONG(lit,i)) {
4418 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4422 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4426 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4429 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4431 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4437 /*-----------------------------------------------------------------*/
4438 /* gencjneshort - compare and jump if not equal */
4439 /*-----------------------------------------------------------------*/
4440 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4442 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4444 int res_offset = 0; /* the result may be a different size then left or right */
4445 int res_size = AOP_SIZE(result);
4449 unsigned long lit = 0L;
4450 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4451 DEBUGpic14_AopType(__LINE__,left,right,result);
4453 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4454 resolveIfx(&rIfx,ifx);
4455 lbl = newiTempLabel(NULL);
4458 /* if the left side is a literal or
4459 if the right is in a pointer register and left
4461 if ((AOP_TYPE(left) == AOP_LIT) ||
4462 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4467 if(AOP_TYPE(right) == AOP_LIT)
4468 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4470 /* if the right side is a literal then anything goes */
4471 if (AOP_TYPE(right) == AOP_LIT &&
4472 AOP_TYPE(left) != AOP_DIR ) {
4475 genc16bit2lit(left, lit, 0);
4477 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4482 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4483 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4485 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4489 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4491 if(res_offset < res_size-1)
4499 /* if the right side is in a register or in direct space or
4500 if the left is a pointer register & right is not */
4501 else if (AOP_TYPE(right) == AOP_REG ||
4502 AOP_TYPE(right) == AOP_DIR ||
4503 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4504 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4505 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4506 int lbl_key = lbl->key;
4509 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4510 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4512 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4513 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4514 __FUNCTION__,__LINE__);
4518 /* switch(size) { */
4520 /* genc16bit2lit(left, lit, 0); */
4522 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4527 if((AOP_TYPE(left) == AOP_DIR) &&
4528 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4530 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4531 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4533 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4535 switch (lit & 0xff) {
4537 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4540 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4541 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4542 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4546 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4547 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4548 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4549 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4553 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4554 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4559 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4562 if(AOP_TYPE(result) == AOP_CRY) {
4563 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4568 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4570 /* fix me. probably need to check result size too */
4571 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4576 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4577 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4584 if(res_offset < res_size-1)
4589 } else if(AOP_TYPE(right) == AOP_REG &&
4590 AOP_TYPE(left) != AOP_DIR){
4593 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4594 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4595 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4600 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4602 if(res_offset < res_size-1)
4607 /* right is a pointer reg need both a & b */
4609 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4611 pic14_emitcode("mov","b,%s",l);
4612 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4613 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4618 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4620 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4622 emitpLabel(lbl->key);
4624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4631 /*-----------------------------------------------------------------*/
4632 /* gencjne - compare and jump if not equal */
4633 /*-----------------------------------------------------------------*/
4634 static void gencjne(operand *left, operand *right, iCode *ifx)
4636 symbol *tlbl = newiTempLabel(NULL);
4638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4639 gencjneshort(left, right, lbl);
4641 pic14_emitcode("mov","a,%s",one);
4642 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4643 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4644 pic14_emitcode("clr","a");
4645 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4647 emitpLabel(lbl->key);
4648 emitpLabel(tlbl->key);
4653 /*-----------------------------------------------------------------*/
4654 /* genCmpEq - generates code for equal to */
4655 /*-----------------------------------------------------------------*/
4656 static void genCmpEq (iCode *ic, iCode *ifx)
4658 operand *left, *right, *result;
4659 unsigned long lit = 0L;
4662 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4665 DEBUGpic14_emitcode ("; ifx is non-null","");
4667 DEBUGpic14_emitcode ("; ifx is null","");
4669 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4670 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4671 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4673 size = max(AOP_SIZE(left),AOP_SIZE(right));
4675 DEBUGpic14_AopType(__LINE__,left,right,result);
4677 /* if literal, literal on the right or
4678 if the right is in a pointer register and left
4680 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4681 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4682 operand *tmp = right ;
4688 if(ifx && !AOP_SIZE(result)){
4690 /* if they are both bit variables */
4691 if (AOP_TYPE(left) == AOP_CRY &&
4692 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4693 if(AOP_TYPE(right) == AOP_LIT){
4694 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4696 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4697 pic14_emitcode("cpl","c");
4698 } else if(lit == 1L) {
4699 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4701 pic14_emitcode("clr","c");
4703 /* AOP_TYPE(right) == AOP_CRY */
4705 symbol *lbl = newiTempLabel(NULL);
4706 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4707 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4708 pic14_emitcode("cpl","c");
4709 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4711 /* if true label then we jump if condition
4713 tlbl = newiTempLabel(NULL);
4714 if ( IC_TRUE(ifx) ) {
4715 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4716 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4718 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4719 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4721 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4724 /* left and right are both bit variables, result is carry */
4727 resolveIfx(&rIfx,ifx);
4729 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4730 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4731 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4732 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4737 /* They're not both bit variables. Is the right a literal? */
4738 if(AOP_TYPE(right) == AOP_LIT) {
4739 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4744 switch(lit & 0xff) {
4746 if ( IC_TRUE(ifx) ) {
4747 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4749 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4751 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4752 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4756 if ( IC_TRUE(ifx) ) {
4757 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4759 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4761 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4762 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4766 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4768 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4773 /* end of size == 1 */
4777 genc16bit2lit(left,lit,offset);
4780 /* end of size == 2 */
4785 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4786 emitpcode(POC_IORFW,popGet(AOP(left),1));
4787 emitpcode(POC_IORFW,popGet(AOP(left),2));
4788 emitpcode(POC_IORFW,popGet(AOP(left),3));
4792 /* search for patterns that can be optimized */
4794 genc16bit2lit(left,lit,0);
4797 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4799 genc16bit2lit(left,lit,2);
4801 emitpcode(POC_IORFW,popGet(AOP(left),2));
4802 emitpcode(POC_IORFW,popGet(AOP(left),3));
4815 } else if(AOP_TYPE(right) == AOP_CRY ) {
4816 /* we know the left is not a bit, but that the right is */
4817 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4818 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4819 popGet(AOP(right),offset));
4820 emitpcode(POC_XORLW,popGetLit(1));
4822 /* if the two are equal, then W will be 0 and the Z bit is set
4823 * we could test Z now, or go ahead and check the high order bytes if
4824 * the variable we're comparing is larger than a byte. */
4827 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4829 if ( IC_TRUE(ifx) ) {
4831 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4832 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4835 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4836 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4840 /* They're both variables that are larger than bits */
4843 tlbl = newiTempLabel(NULL);
4846 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4847 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4849 if ( IC_TRUE(ifx) ) {
4852 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4853 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4856 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4857 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4861 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4862 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4866 if(s>1 && IC_TRUE(ifx)) {
4867 emitpLabel(tlbl->key);
4868 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4872 /* mark the icode as generated */
4877 /* if they are both bit variables */
4878 if (AOP_TYPE(left) == AOP_CRY &&
4879 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4880 if(AOP_TYPE(right) == AOP_LIT){
4881 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4883 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4884 pic14_emitcode("cpl","c");
4885 } else if(lit == 1L) {
4886 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4888 pic14_emitcode("clr","c");
4890 /* AOP_TYPE(right) == AOP_CRY */
4892 symbol *lbl = newiTempLabel(NULL);
4893 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4894 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4895 pic14_emitcode("cpl","c");
4896 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4899 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4900 pic14_outBitC(result);
4904 genIfxJump (ifx,"c");
4907 /* if the result is used in an arithmetic operation
4908 then put the result in place */
4909 pic14_outBitC(result);
4912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4913 gencjne(left,right,result,ifx);
4916 gencjne(left,right,newiTempLabel(NULL));
4918 if(IC_TRUE(ifx)->key)
4919 gencjne(left,right,IC_TRUE(ifx)->key);
4921 gencjne(left,right,IC_FALSE(ifx)->key);
4925 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4926 aopPut(AOP(result),"a",0);
4931 genIfxJump (ifx,"a");
4935 /* if the result is used in an arithmetic operation
4936 then put the result in place */
4938 if (AOP_TYPE(result) != AOP_CRY)
4939 pic14_outAcc(result);
4941 /* leave the result in acc */
4945 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4946 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4947 freeAsmop(result,NULL,ic,TRUE);
4950 /*-----------------------------------------------------------------*/
4951 /* ifxForOp - returns the icode containing the ifx for operand */
4952 /*-----------------------------------------------------------------*/
4953 static iCode *ifxForOp ( operand *op, iCode *ic )
4955 /* if true symbol then needs to be assigned */
4956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4957 if (IS_TRUE_SYMOP(op))
4960 /* if this has register type condition and
4961 the next instruction is ifx with the same operand
4962 and live to of the operand is upto the ifx only then */
4964 ic->next->op == IFX &&
4965 IC_COND(ic->next)->key == op->key &&
4966 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4970 ic->next->op == IFX &&
4971 IC_COND(ic->next)->key == op->key) {
4972 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4976 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4978 ic->next->op == IFX)
4979 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4982 ic->next->op == IFX &&
4983 IC_COND(ic->next)->key == op->key) {
4984 DEBUGpic14_emitcode ("; "," key is okay");
4985 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4986 OP_SYMBOL(op)->liveTo,
4993 /*-----------------------------------------------------------------*/
4994 /* genAndOp - for && operation */
4995 /*-----------------------------------------------------------------*/
4996 static void genAndOp (iCode *ic)
4998 operand *left,*right, *result;
5001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5002 /* note here that && operations that are in an
5003 if statement are taken away by backPatchLabels
5004 only those used in arthmetic operations remain */
5005 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5006 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5007 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5009 DEBUGpic14_AopType(__LINE__,left,right,result);
5011 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5012 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5013 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5015 /* if both are bit variables */
5016 /* if (AOP_TYPE(left) == AOP_CRY && */
5017 /* AOP_TYPE(right) == AOP_CRY ) { */
5018 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5019 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5020 /* pic14_outBitC(result); */
5022 /* tlbl = newiTempLabel(NULL); */
5023 /* pic14_toBoolean(left); */
5024 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5025 /* pic14_toBoolean(right); */
5026 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5027 /* pic14_outBitAcc(result); */
5030 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5031 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032 freeAsmop(result,NULL,ic,TRUE);
5036 /*-----------------------------------------------------------------*/
5037 /* genOrOp - for || operation */
5038 /*-----------------------------------------------------------------*/
5041 modified this code, but it doesn't appear to ever get called
5044 static void genOrOp (iCode *ic)
5046 operand *left,*right, *result;
5049 /* note here that || operations that are in an
5050 if statement are taken away by backPatchLabels
5051 only those used in arthmetic operations remain */
5052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5053 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5054 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5055 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5057 DEBUGpic14_AopType(__LINE__,left,right,result);
5059 /* if both are bit variables */
5060 if (AOP_TYPE(left) == AOP_CRY &&
5061 AOP_TYPE(right) == AOP_CRY ) {
5062 pic14_emitcode("clrc","");
5063 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5064 AOP(left)->aopu.aop_dir,
5065 AOP(left)->aopu.aop_dir);
5066 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5067 AOP(right)->aopu.aop_dir,
5068 AOP(right)->aopu.aop_dir);
5069 pic14_emitcode("setc","");
5072 tlbl = newiTempLabel(NULL);
5073 pic14_toBoolean(left);
5075 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5076 pic14_toBoolean(right);
5077 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5079 pic14_outBitAcc(result);
5082 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5083 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084 freeAsmop(result,NULL,ic,TRUE);
5087 /*-----------------------------------------------------------------*/
5088 /* isLiteralBit - test if lit == 2^n */
5089 /*-----------------------------------------------------------------*/
5090 static int isLiteralBit(unsigned long lit)
5092 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5093 0x100L,0x200L,0x400L,0x800L,
5094 0x1000L,0x2000L,0x4000L,0x8000L,
5095 0x10000L,0x20000L,0x40000L,0x80000L,
5096 0x100000L,0x200000L,0x400000L,0x800000L,
5097 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5098 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5102 for(idx = 0; idx < 32; idx++)
5108 /*-----------------------------------------------------------------*/
5109 /* continueIfTrue - */
5110 /*-----------------------------------------------------------------*/
5111 static void continueIfTrue (iCode *ic)
5113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5115 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5119 /*-----------------------------------------------------------------*/
5121 /*-----------------------------------------------------------------*/
5122 static void jumpIfTrue (iCode *ic)
5124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5126 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5130 /*-----------------------------------------------------------------*/
5131 /* jmpTrueOrFalse - */
5132 /*-----------------------------------------------------------------*/
5133 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5135 // ugly but optimized by peephole
5136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5138 symbol *nlbl = newiTempLabel(NULL);
5139 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5140 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5141 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5142 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5145 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5146 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5151 /*-----------------------------------------------------------------*/
5152 /* genAnd - code for and */
5153 /*-----------------------------------------------------------------*/
5154 static void genAnd (iCode *ic, iCode *ifx)
5156 operand *left, *right, *result;
5158 unsigned long lit = 0L;
5163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5164 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5165 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5166 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5168 resolveIfx(&rIfx,ifx);
5170 /* if left is a literal & right is not then exchange them */
5171 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5172 AOP_NEEDSACC(left)) {
5173 operand *tmp = right ;
5178 /* if result = right then exchange them */
5179 if(pic14_sameRegs(AOP(result),AOP(right))){
5180 operand *tmp = right ;
5185 /* if right is bit then exchange them */
5186 if (AOP_TYPE(right) == AOP_CRY &&
5187 AOP_TYPE(left) != AOP_CRY){
5188 operand *tmp = right ;
5192 if(AOP_TYPE(right) == AOP_LIT)
5193 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5195 size = AOP_SIZE(result);
5197 DEBUGpic14_AopType(__LINE__,left,right,result);
5200 // result = bit & yy;
5201 if (AOP_TYPE(left) == AOP_CRY){
5202 // c = bit & literal;
5203 if(AOP_TYPE(right) == AOP_LIT){
5205 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5208 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5211 if(size && (AOP_TYPE(result) == AOP_CRY)){
5212 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5215 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5219 pic14_emitcode("clr","c");
5222 if (AOP_TYPE(right) == AOP_CRY){
5224 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5225 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5228 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5230 pic14_emitcode("rrc","a");
5231 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5237 pic14_outBitC(result);
5239 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5240 genIfxJump(ifx, "c");
5244 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5245 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5246 if((AOP_TYPE(right) == AOP_LIT) &&
5247 (AOP_TYPE(result) == AOP_CRY) &&
5248 (AOP_TYPE(left) != AOP_CRY)){
5249 int posbit = isLiteralBit(lit);
5253 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5256 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5261 while (posbit > 7) {
5265 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5266 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5267 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5274 symbol *tlbl = newiTempLabel(NULL);
5275 int sizel = AOP_SIZE(left);
5277 pic14_emitcode("setb","c");
5279 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5280 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5282 if((posbit = isLiteralBit(bytelit)) != 0)
5283 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5285 if(bytelit != 0x0FFL)
5286 pic14_emitcode("anl","a,%s",
5287 aopGet(AOP(right),offset,FALSE,TRUE));
5288 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5293 // bit = left & literal
5295 pic14_emitcode("clr","c");
5296 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5298 // if(left & literal)
5301 jmpTrueOrFalse(ifx, tlbl);
5305 pic14_outBitC(result);
5309 /* if left is same as result */
5310 if(pic14_sameRegs(AOP(result),AOP(left))){
5312 for(;size--; offset++,lit>>=8) {
5313 if(AOP_TYPE(right) == AOP_LIT){
5314 switch(lit & 0xff) {
5316 /* and'ing with 0 has clears the result */
5317 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5318 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5321 /* and'ing with 0xff is a nop when the result and left are the same */
5326 int p = my_powof2( (~lit) & 0xff );
5328 /* only one bit is set in the literal, so use a bcf instruction */
5329 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5330 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5333 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5334 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5335 if(know_W != (int)(lit&0xff))
5336 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5338 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5343 if (AOP_TYPE(left) == AOP_ACC) {
5344 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5346 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5347 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5354 // left & result in different registers
5355 if(AOP_TYPE(result) == AOP_CRY){
5357 // if(size), result in bit
5358 // if(!size && ifx), conditional oper: if(left & right)
5359 symbol *tlbl = newiTempLabel(NULL);
5360 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5362 pic14_emitcode("setb","c");
5364 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5365 pic14_emitcode("anl","a,%s",
5366 aopGet(AOP(left),offset,FALSE,FALSE));
5367 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5372 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5373 pic14_outBitC(result);
5375 jmpTrueOrFalse(ifx, tlbl);
5377 for(;(size--);offset++) {
5379 // result = left & right
5380 if(AOP_TYPE(right) == AOP_LIT){
5381 int t = (lit >> (offset*8)) & 0x0FFL;
5384 pic14_emitcode("clrf","%s",
5385 aopGet(AOP(result),offset,FALSE,FALSE));
5386 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5389 if(AOP_TYPE(left) != AOP_ACC) {
5390 pic14_emitcode("movf","%s,w",
5391 aopGet(AOP(left),offset,FALSE,FALSE));
5392 pic14_emitcode("movwf","%s",
5393 aopGet(AOP(result),offset,FALSE,FALSE));
5394 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5396 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5399 if(AOP_TYPE(left) == AOP_ACC) {
5400 emitpcode(POC_ANDLW, popGetLit(t));
5402 pic14_emitcode("movlw","0x%x",t);
5403 pic14_emitcode("andwf","%s,w",
5404 aopGet(AOP(left),offset,FALSE,FALSE));
5405 pic14_emitcode("movwf","%s",
5406 aopGet(AOP(result),offset,FALSE,FALSE));
5408 emitpcode(POC_MOVLW, popGetLit(t));
5409 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5411 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5416 if (AOP_TYPE(left) == AOP_ACC) {
5417 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5418 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5420 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5421 pic14_emitcode("andwf","%s,w",
5422 aopGet(AOP(left),offset,FALSE,FALSE));
5423 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5424 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5426 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5427 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5433 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5434 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5435 freeAsmop(result,NULL,ic,TRUE);
5438 /*-----------------------------------------------------------------*/
5439 /* genOr - code for or */
5440 /*-----------------------------------------------------------------*/
5441 static void genOr (iCode *ic, iCode *ifx)
5443 operand *left, *right, *result;
5445 unsigned long lit = 0L;
5447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5449 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5450 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5451 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5453 DEBUGpic14_AopType(__LINE__,left,right,result);
5455 /* if left is a literal & right is not then exchange them */
5456 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5457 AOP_NEEDSACC(left)) {
5458 operand *tmp = right ;
5463 /* if result = right then exchange them */
5464 if(pic14_sameRegs(AOP(result),AOP(right))){
5465 operand *tmp = right ;
5470 /* if right is bit then exchange them */
5471 if (AOP_TYPE(right) == AOP_CRY &&
5472 AOP_TYPE(left) != AOP_CRY){
5473 operand *tmp = right ;
5478 DEBUGpic14_AopType(__LINE__,left,right,result);
5480 if(AOP_TYPE(right) == AOP_LIT)
5481 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5483 size = AOP_SIZE(result);
5487 if (AOP_TYPE(left) == AOP_CRY){
5488 if(AOP_TYPE(right) == AOP_LIT){
5489 // c = bit & literal;
5491 // lit != 0 => result = 1
5492 if(AOP_TYPE(result) == AOP_CRY){
5494 emitpcode(POC_BSF, popGet(AOP(result),0));
5495 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5496 // AOP(result)->aopu.aop_dir,
5497 // AOP(result)->aopu.aop_dir);
5499 continueIfTrue(ifx);
5503 // lit == 0 => result = left
5504 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5506 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5509 if (AOP_TYPE(right) == AOP_CRY){
5510 if(pic14_sameRegs(AOP(result),AOP(left))){
5512 emitpcode(POC_BCF, popGet(AOP(result),0));
5513 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5514 emitpcode(POC_BSF, popGet(AOP(result),0));
5516 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5517 AOP(result)->aopu.aop_dir,
5518 AOP(result)->aopu.aop_dir);
5519 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5520 AOP(right)->aopu.aop_dir,
5521 AOP(right)->aopu.aop_dir);
5522 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5523 AOP(result)->aopu.aop_dir,
5524 AOP(result)->aopu.aop_dir);
5526 if( AOP_TYPE(result) == AOP_ACC) {
5527 emitpcode(POC_MOVLW, popGetLit(0));
5528 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5529 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5530 emitpcode(POC_MOVLW, popGetLit(1));
5534 emitpcode(POC_BCF, popGet(AOP(result),0));
5535 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5536 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5537 emitpcode(POC_BSF, popGet(AOP(result),0));
5539 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5540 AOP(result)->aopu.aop_dir,
5541 AOP(result)->aopu.aop_dir);
5542 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5543 AOP(right)->aopu.aop_dir,
5544 AOP(right)->aopu.aop_dir);
5545 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5546 AOP(left)->aopu.aop_dir,
5547 AOP(left)->aopu.aop_dir);
5548 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5549 AOP(result)->aopu.aop_dir,
5550 AOP(result)->aopu.aop_dir);
5555 symbol *tlbl = newiTempLabel(NULL);
5556 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5559 emitpcode(POC_BCF, popGet(AOP(result),0));
5560 if( AOP_TYPE(right) == AOP_ACC) {
5561 emitpcode(POC_IORLW, popGetLit(0));
5563 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5564 emitpcode(POC_BSF, popGet(AOP(result),0));
5569 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5570 pic14_emitcode(";XXX setb","c");
5571 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5572 AOP(left)->aopu.aop_dir,tlbl->key+100);
5573 pic14_toBoolean(right);
5574 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5575 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5576 jmpTrueOrFalse(ifx, tlbl);
5580 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5587 pic14_outBitC(result);
5589 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5590 genIfxJump(ifx, "c");
5594 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5595 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5596 if((AOP_TYPE(right) == AOP_LIT) &&
5597 (AOP_TYPE(result) == AOP_CRY) &&
5598 (AOP_TYPE(left) != AOP_CRY)){
5600 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5603 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5605 continueIfTrue(ifx);
5608 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5609 // lit = 0, result = boolean(left)
5611 pic14_emitcode(";XXX setb","c");
5612 pic14_toBoolean(right);
5614 symbol *tlbl = newiTempLabel(NULL);
5615 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5617 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5619 genIfxJump (ifx,"a");
5623 pic14_outBitC(result);
5627 /* if left is same as result */
5628 if(pic14_sameRegs(AOP(result),AOP(left))){
5630 for(;size--; offset++,lit>>=8) {
5631 if(AOP_TYPE(right) == AOP_LIT){
5632 if((lit & 0xff) == 0)
5633 /* or'ing with 0 has no effect */
5636 int p = my_powof2(lit & 0xff);
5638 /* only one bit is set in the literal, so use a bsf instruction */
5640 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5642 if(know_W != (int)(lit & 0xff))
5643 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5644 know_W = lit & 0xff;
5645 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5650 if (AOP_TYPE(left) == AOP_ACC) {
5651 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5652 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5654 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5655 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5657 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5658 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5664 // left & result in different registers
5665 if(AOP_TYPE(result) == AOP_CRY){
5667 // if(size), result in bit
5668 // if(!size && ifx), conditional oper: if(left | right)
5669 symbol *tlbl = newiTempLabel(NULL);
5670 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5671 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5675 pic14_emitcode(";XXX setb","c");
5677 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5678 pic14_emitcode(";XXX orl","a,%s",
5679 aopGet(AOP(left),offset,FALSE,FALSE));
5680 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5685 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5686 pic14_outBitC(result);
5688 jmpTrueOrFalse(ifx, tlbl);
5689 } else for(;(size--);offset++){
5691 // result = left & right
5692 if(AOP_TYPE(right) == AOP_LIT){
5693 int t = (lit >> (offset*8)) & 0x0FFL;
5696 if (AOP_TYPE(left) != AOP_ACC) {
5697 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5699 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5703 if (AOP_TYPE(left) == AOP_ACC) {
5704 emitpcode(POC_IORLW, popGetLit(t));
5706 emitpcode(POC_MOVLW, popGetLit(t));
5707 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5709 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5714 // faster than result <- left, anl result,right
5715 // and better if result is SFR
5716 if (AOP_TYPE(left) == AOP_ACC) {
5717 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5718 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5720 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5721 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5723 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5724 pic14_emitcode("iorwf","%s,w",
5725 aopGet(AOP(left),offset,FALSE,FALSE));
5727 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5728 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5733 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5734 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5735 freeAsmop(result,NULL,ic,TRUE);
5738 /*-----------------------------------------------------------------*/
5739 /* genXor - code for xclusive or */
5740 /*-----------------------------------------------------------------*/
5741 static void genXor (iCode *ic, iCode *ifx)
5743 operand *left, *right, *result;
5745 unsigned long lit = 0L;
5747 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5749 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5750 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5751 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5753 /* if left is a literal & right is not ||
5754 if left needs acc & right does not */
5755 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5756 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5757 operand *tmp = right ;
5762 /* if result = right then exchange them */
5763 if(pic14_sameRegs(AOP(result),AOP(right))){
5764 operand *tmp = right ;
5769 /* if right is bit then exchange them */
5770 if (AOP_TYPE(right) == AOP_CRY &&
5771 AOP_TYPE(left) != AOP_CRY){
5772 operand *tmp = right ;
5776 if(AOP_TYPE(right) == AOP_LIT)
5777 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5779 size = AOP_SIZE(result);
5783 if (AOP_TYPE(left) == AOP_CRY){
5784 if(AOP_TYPE(right) == AOP_LIT){
5785 // c = bit & literal;
5787 // lit>>1 != 0 => result = 1
5788 if(AOP_TYPE(result) == AOP_CRY){
5790 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5791 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5793 continueIfTrue(ifx);
5796 pic14_emitcode("setb","c");
5800 // lit == 0, result = left
5801 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5803 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5805 // lit == 1, result = not(left)
5806 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5807 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5808 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5809 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5812 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5813 pic14_emitcode("cpl","c");
5820 symbol *tlbl = newiTempLabel(NULL);
5821 if (AOP_TYPE(right) == AOP_CRY){
5823 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5826 int sizer = AOP_SIZE(right);
5828 // if val>>1 != 0, result = 1
5829 pic14_emitcode("setb","c");
5831 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5833 // test the msb of the lsb
5834 pic14_emitcode("anl","a,#0xfe");
5835 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5839 pic14_emitcode("rrc","a");
5841 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5842 pic14_emitcode("cpl","c");
5843 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5848 pic14_outBitC(result);
5850 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5851 genIfxJump(ifx, "c");
5855 if(pic14_sameRegs(AOP(result),AOP(left))){
5856 /* if left is same as result */
5857 for(;size--; offset++) {
5858 if(AOP_TYPE(right) == AOP_LIT){
5859 int t = (lit >> (offset*8)) & 0x0FFL;
5863 if (IS_AOP_PREG(left)) {
5864 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5865 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5866 aopPut(AOP(result),"a",offset);
5868 emitpcode(POC_MOVLW, popGetLit(t));
5869 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5870 pic14_emitcode("xrl","%s,%s",
5871 aopGet(AOP(left),offset,FALSE,TRUE),
5872 aopGet(AOP(right),offset,FALSE,FALSE));
5875 if (AOP_TYPE(left) == AOP_ACC)
5876 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5878 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5879 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5881 if (IS_AOP_PREG(left)) {
5882 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5883 aopPut(AOP(result),"a",offset);
5885 pic14_emitcode("xrl","%s,a",
5886 aopGet(AOP(left),offset,FALSE,TRUE));
5892 // left & result in different registers
5893 if(AOP_TYPE(result) == AOP_CRY){
5895 // if(size), result in bit
5896 // if(!size && ifx), conditional oper: if(left ^ right)
5897 symbol *tlbl = newiTempLabel(NULL);
5898 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5900 pic14_emitcode("setb","c");
5902 if((AOP_TYPE(right) == AOP_LIT) &&
5903 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5904 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5906 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5907 pic14_emitcode("xrl","a,%s",
5908 aopGet(AOP(left),offset,FALSE,FALSE));
5910 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5915 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5916 pic14_outBitC(result);
5918 jmpTrueOrFalse(ifx, tlbl);
5919 } else for(;(size--);offset++){
5921 // result = left & right
5922 if(AOP_TYPE(right) == AOP_LIT){
5923 int t = (lit >> (offset*8)) & 0x0FFL;
5926 if (AOP_TYPE(left) != AOP_ACC) {
5927 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5929 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5930 pic14_emitcode("movf","%s,w",
5931 aopGet(AOP(left),offset,FALSE,FALSE));
5932 pic14_emitcode("movwf","%s",
5933 aopGet(AOP(result),offset,FALSE,FALSE));
5936 if (AOP_TYPE(left) == AOP_ACC) {
5937 emitpcode(POC_XORLW, popGetLit(t));
5939 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5941 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5944 if (AOP_TYPE(left) == AOP_ACC) {
5945 emitpcode(POC_XORLW, popGetLit(t));
5947 emitpcode(POC_MOVLW, popGetLit(t));
5948 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5950 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5951 pic14_emitcode("movlw","0x%x",t);
5952 pic14_emitcode("xorwf","%s,w",
5953 aopGet(AOP(left),offset,FALSE,FALSE));
5954 pic14_emitcode("movwf","%s",
5955 aopGet(AOP(result),offset,FALSE,FALSE));
5961 // faster than result <- left, anl result,right
5962 // and better if result is SFR
5963 if (AOP_TYPE(left) == AOP_ACC) {
5964 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5965 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5967 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5968 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5969 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5970 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5972 if ( AOP_TYPE(result) != AOP_ACC){
5973 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5974 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5980 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5981 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5982 freeAsmop(result,NULL,ic,TRUE);
5985 /*-----------------------------------------------------------------*/
5986 /* genInline - write the inline code out */
5987 /*-----------------------------------------------------------------*/
5988 static void genInline (iCode *ic)
5990 char *buffer, *bp, *bp1;
5992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5994 _G.inLine += (!options.asmpeep);
5996 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5997 strcpy(buffer,IC_INLINE(ic));
5999 /* emit each line as a code */
6005 addpCode2pBlock(pb,AssembleLine(bp1));
6012 pic14_emitcode(bp1,"");
6018 if ((bp1 != bp) && *bp1)
6019 addpCode2pBlock(pb,AssembleLine(bp1));
6023 _G.inLine -= (!options.asmpeep);
6026 /*-----------------------------------------------------------------*/
6027 /* genRRC - rotate right with carry */
6028 /*-----------------------------------------------------------------*/
6029 static void genRRC (iCode *ic)
6031 operand *left , *result ;
6032 int size, offset = 0, same;
6034 /* rotate right with carry */
6036 result=IC_RESULT(ic);
6037 aopOp (left,ic,FALSE);
6038 aopOp (result,ic,FALSE);
6040 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6042 same = pic14_sameRegs(AOP(result),AOP(left));
6044 size = AOP_SIZE(result);
6046 /* get the lsb and put it into the carry */
6047 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6054 emitpcode(POC_RRF, popGet(AOP(left),offset));
6056 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6057 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6063 freeAsmop(left,NULL,ic,TRUE);
6064 freeAsmop(result,NULL,ic,TRUE);
6067 /*-----------------------------------------------------------------*/
6068 /* genRLC - generate code for rotate left with carry */
6069 /*-----------------------------------------------------------------*/
6070 static void genRLC (iCode *ic)
6072 operand *left , *result ;
6073 int size, offset = 0;
6076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6077 /* rotate right with carry */
6079 result=IC_RESULT(ic);
6080 aopOp (left,ic,FALSE);
6081 aopOp (result,ic,FALSE);
6083 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6085 same = pic14_sameRegs(AOP(result),AOP(left));
6087 /* move it to the result */
6088 size = AOP_SIZE(result);
6090 /* get the msb and put it into the carry */
6091 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6098 emitpcode(POC_RLF, popGet(AOP(left),offset));
6100 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6101 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6108 freeAsmop(left,NULL,ic,TRUE);
6109 freeAsmop(result,NULL,ic,TRUE);
6112 /*-----------------------------------------------------------------*/
6113 /* genGetHbit - generates code get highest order bit */
6114 /*-----------------------------------------------------------------*/
6115 static void genGetHbit (iCode *ic)
6117 operand *left, *result;
6119 result=IC_RESULT(ic);
6120 aopOp (left,ic,FALSE);
6121 aopOp (result,ic,FALSE);
6123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6124 /* get the highest order byte into a */
6125 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6126 if(AOP_TYPE(result) == AOP_CRY){
6127 pic14_emitcode("rlc","a");
6128 pic14_outBitC(result);
6131 pic14_emitcode("rl","a");
6132 pic14_emitcode("anl","a,#0x01");
6133 pic14_outAcc(result);
6137 freeAsmop(left,NULL,ic,TRUE);
6138 freeAsmop(result,NULL,ic,TRUE);
6141 /*-----------------------------------------------------------------*/
6142 /* AccRol - rotate left accumulator by known count */
6143 /*-----------------------------------------------------------------*/
6144 static void AccRol (int shCount)
6146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6147 shCount &= 0x0007; // shCount : 0..7
6152 pic14_emitcode("rl","a");
6155 pic14_emitcode("rl","a");
6156 pic14_emitcode("rl","a");
6159 pic14_emitcode("swap","a");
6160 pic14_emitcode("rr","a");
6163 pic14_emitcode("swap","a");
6166 pic14_emitcode("swap","a");
6167 pic14_emitcode("rl","a");
6170 pic14_emitcode("rr","a");
6171 pic14_emitcode("rr","a");
6174 pic14_emitcode("rr","a");
6179 /*-----------------------------------------------------------------*/
6180 /* AccLsh - left shift accumulator by known count */
6181 /*-----------------------------------------------------------------*/
6182 static void AccLsh (int shCount)
6184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6187 pic14_emitcode("add","a,acc");
6190 pic14_emitcode("add","a,acc");
6191 pic14_emitcode("add","a,acc");
6193 /* rotate left accumulator */
6195 /* and kill the lower order bits */
6196 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6201 /*-----------------------------------------------------------------*/
6202 /* AccRsh - right shift accumulator by known count */
6203 /*-----------------------------------------------------------------*/
6204 static void AccRsh (int shCount)
6206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6210 pic14_emitcode("rrc","a");
6212 /* rotate right accumulator */
6213 AccRol(8 - shCount);
6214 /* and kill the higher order bits */
6215 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6221 /*-----------------------------------------------------------------*/
6222 /* AccSRsh - signed right shift accumulator by known count */
6223 /*-----------------------------------------------------------------*/
6224 static void AccSRsh (int shCount)
6227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6230 pic14_emitcode("mov","c,acc.7");
6231 pic14_emitcode("rrc","a");
6232 } else if(shCount == 2){
6233 pic14_emitcode("mov","c,acc.7");
6234 pic14_emitcode("rrc","a");
6235 pic14_emitcode("mov","c,acc.7");
6236 pic14_emitcode("rrc","a");
6238 tlbl = newiTempLabel(NULL);
6239 /* rotate right accumulator */
6240 AccRol(8 - shCount);
6241 /* and kill the higher order bits */
6242 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6243 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6244 pic14_emitcode("orl","a,#0x%02x",
6245 (unsigned char)~SRMask[shCount]);
6246 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6251 /*-----------------------------------------------------------------*/
6252 /* shiftR1Left2Result - shift right one byte from left to result */
6253 /*-----------------------------------------------------------------*/
6254 static void shiftR1Left2ResultSigned (operand *left, int offl,
6255 operand *result, int offr,
6260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6262 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6266 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6268 emitpcode(POC_RRF, popGet(AOP(result),offr));
6270 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6271 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6277 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6279 emitpcode(POC_RRF, popGet(AOP(result),offr));
6281 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6282 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6284 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6285 emitpcode(POC_RRF, popGet(AOP(result),offr));
6291 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6293 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6294 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6297 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6298 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6299 emitpcode(POC_ANDLW, popGetLit(0x1f));
6301 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6302 emitpcode(POC_IORLW, popGetLit(0xe0));
6304 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6308 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6309 emitpcode(POC_ANDLW, popGetLit(0x0f));
6310 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6311 emitpcode(POC_IORLW, popGetLit(0xf0));
6312 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6316 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6318 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6319 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6321 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6322 emitpcode(POC_ANDLW, popGetLit(0x07));
6323 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6324 emitpcode(POC_IORLW, popGetLit(0xf8));
6325 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6330 emitpcode(POC_MOVLW, popGetLit(0x00));
6331 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6332 emitpcode(POC_MOVLW, popGetLit(0xfe));
6333 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6334 emitpcode(POC_IORLW, popGetLit(0x01));
6335 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6337 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6338 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6339 emitpcode(POC_DECF, popGet(AOP(result),offr));
6340 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6341 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6347 emitpcode(POC_MOVLW, popGetLit(0x00));
6348 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6349 emitpcode(POC_MOVLW, popGetLit(0xff));
6350 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6352 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6353 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6354 emitpcode(POC_DECF, popGet(AOP(result),offr));
6362 /*-----------------------------------------------------------------*/
6363 /* shiftR1Left2Result - shift right one byte from left to result */
6364 /*-----------------------------------------------------------------*/
6365 static void shiftR1Left2Result (operand *left, int offl,
6366 operand *result, int offr,
6367 int shCount, int sign)
6371 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6373 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6375 /* Copy the msb into the carry if signed. */
6377 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6387 emitpcode(POC_RRF, popGet(AOP(result),offr));
6389 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6390 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6396 emitpcode(POC_RRF, popGet(AOP(result),offr));
6398 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6399 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6402 emitpcode(POC_RRF, popGet(AOP(result),offr));
6407 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6409 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6410 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6414 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6415 emitpcode(POC_ANDLW, popGetLit(0x1f));
6416 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6420 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6421 emitpcode(POC_ANDLW, popGetLit(0x0f));
6422 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6426 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6427 emitpcode(POC_ANDLW, popGetLit(0x0f));
6428 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6430 emitpcode(POC_RRF, popGet(AOP(result),offr));
6435 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6436 emitpcode(POC_ANDLW, popGetLit(0x80));
6437 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438 emitpcode(POC_RLF, popGet(AOP(result),offr));
6439 emitpcode(POC_RLF, popGet(AOP(result),offr));
6444 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6445 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6446 emitpcode(POC_RLF, popGet(AOP(result),offr));
6455 /*-----------------------------------------------------------------*/
6456 /* shiftL1Left2Result - shift left one byte from left to result */
6457 /*-----------------------------------------------------------------*/
6458 static void shiftL1Left2Result (operand *left, int offl,
6459 operand *result, int offr, int shCount)
6464 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6466 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6467 DEBUGpic14_emitcode ("; ***","same = %d",same);
6468 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6470 /* shift left accumulator */
6471 //AccLsh(shCount); // don't comment out just yet...
6472 // aopPut(AOP(result),"a",offr);
6476 /* Shift left 1 bit position */
6477 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6479 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6481 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6482 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6486 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6487 emitpcode(POC_ANDLW,popGetLit(0x7e));
6488 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6489 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6492 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6493 emitpcode(POC_ANDLW,popGetLit(0x3e));
6494 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6495 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6496 emitpcode(POC_RLF, popGet(AOP(result),offr));
6499 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6500 emitpcode(POC_ANDLW, popGetLit(0xf0));
6501 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6504 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6505 emitpcode(POC_ANDLW, popGetLit(0xf0));
6506 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6507 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6510 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6511 emitpcode(POC_ANDLW, popGetLit(0x30));
6512 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6513 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6514 emitpcode(POC_RLF, popGet(AOP(result),offr));
6517 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6518 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6519 emitpcode(POC_RRF, popGet(AOP(result),offr));
6523 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6528 /*-----------------------------------------------------------------*/
6529 /* movLeft2Result - move byte from left to result */
6530 /*-----------------------------------------------------------------*/
6531 static void movLeft2Result (operand *left, int offl,
6532 operand *result, int offr)
6535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6536 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6537 l = aopGet(AOP(left),offl,FALSE,FALSE);
6539 if (*l == '@' && (IS_AOP_PREG(result))) {
6540 pic14_emitcode("mov","a,%s",l);
6541 aopPut(AOP(result),"a",offr);
6543 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6544 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6549 /*-----------------------------------------------------------------*/
6550 /* shiftL2Left2Result - shift left two bytes from left to result */
6551 /*-----------------------------------------------------------------*/
6552 static void shiftL2Left2Result (operand *left, int offl,
6553 operand *result, int offr, int shCount)
6557 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6559 if(pic14_sameRegs(AOP(result), AOP(left))) {
6567 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6568 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6569 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6573 emitpcode(POC_RLF, popGet(AOP(result),offr));
6574 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6580 emitpcode(POC_MOVLW, popGetLit(0x0f));
6581 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6582 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6584 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6585 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6586 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6588 emitpcode(POC_RLF, popGet(AOP(result),offr));
6589 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6593 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6594 emitpcode(POC_RRF, popGet(AOP(result),offr));
6595 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6596 emitpcode(POC_RRF, popGet(AOP(result),offr));
6597 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6598 emitpcode(POC_ANDLW,popGetLit(0xc0));
6599 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6600 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6601 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6602 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6607 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6609 emitpcode(POC_RRF, popGet(AOP(result),offr));
6619 /* note, use a mov/add for the shift since the mov has a
6620 chance of getting optimized out */
6621 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6622 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6623 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6624 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6625 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6629 emitpcode(POC_RLF, popGet(AOP(result),offr));
6630 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6636 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6637 emitpcode(POC_ANDLW, popGetLit(0xF0));
6638 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6639 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6640 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6641 emitpcode(POC_ANDLW, popGetLit(0xF0));
6642 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6643 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6647 emitpcode(POC_RLF, popGet(AOP(result),offr));
6648 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6652 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6653 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6654 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6655 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6657 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_RRF, popGet(AOP(result),offr));
6659 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6660 emitpcode(POC_ANDLW,popGetLit(0xc0));
6661 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6662 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6663 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6664 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6668 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6669 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6671 emitpcode(POC_RRF, popGet(AOP(result),offr));
6676 /*-----------------------------------------------------------------*/
6677 /* shiftR2Left2Result - shift right two bytes from left to result */
6678 /*-----------------------------------------------------------------*/
6679 static void shiftR2Left2Result (operand *left, int offl,
6680 operand *result, int offr,
6681 int shCount, int sign)
6685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6686 same = pic14_sameRegs(AOP(result), AOP(left));
6688 if(same && ((offl + MSB16) == offr)){
6690 /* don't crash result[offr] */
6691 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6692 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6695 movLeft2Result(left,offl, result, offr);
6696 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6699 /* a:x >> shCount (x = lsb(result))*/
6702 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6704 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6713 emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6718 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6719 emitpcode(POC_RRF,popGet(AOP(result),offr));
6721 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6722 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6723 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6724 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6729 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6732 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6733 emitpcode(POC_RRF,popGet(AOP(result),offr));
6740 emitpcode(POC_MOVLW, popGetLit(0xf0));
6741 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6742 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6744 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6745 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6747 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6749 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6750 emitpcode(POC_ANDLW, popGetLit(0x0f));
6751 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6753 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6754 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_ANDLW, popGetLit(0xf0));
6756 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6757 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6761 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6762 emitpcode(POC_RRF, popGet(AOP(result),offr));
6766 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6767 emitpcode(POC_BTFSC,
6768 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6769 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6777 emitpcode(POC_RLF, popGet(AOP(result),offr));
6778 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6780 emitpcode(POC_RLF, popGet(AOP(result),offr));
6781 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6782 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6783 emitpcode(POC_ANDLW,popGetLit(0x03));
6785 emitpcode(POC_BTFSC,
6786 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6787 emitpcode(POC_IORLW,popGetLit(0xfc));
6789 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6790 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6791 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6792 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6794 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6795 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6796 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6797 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6798 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6799 emitpcode(POC_RLF, popGet(AOP(result),offr));
6800 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6801 emitpcode(POC_ANDLW,popGetLit(0x03));
6803 emitpcode(POC_BTFSC,
6804 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6805 emitpcode(POC_IORLW,popGetLit(0xfc));
6807 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6808 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6815 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6816 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6817 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6818 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6821 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6823 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6828 /*-----------------------------------------------------------------*/
6829 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6830 /*-----------------------------------------------------------------*/
6831 static void shiftLLeftOrResult (operand *left, int offl,
6832 operand *result, int offr, int shCount)
6834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6835 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6836 /* shift left accumulator */
6838 /* or with result */
6839 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6840 /* back to result */
6841 aopPut(AOP(result),"a",offr);
6844 /*-----------------------------------------------------------------*/
6845 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6846 /*-----------------------------------------------------------------*/
6847 static void shiftRLeftOrResult (operand *left, int offl,
6848 operand *result, int offr, int shCount)
6850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6851 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6852 /* shift right accumulator */
6854 /* or with result */
6855 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6856 /* back to result */
6857 aopPut(AOP(result),"a",offr);
6860 /*-----------------------------------------------------------------*/
6861 /* genlshOne - left shift a one byte quantity by known count */
6862 /*-----------------------------------------------------------------*/
6863 static void genlshOne (operand *result, operand *left, int shCount)
6865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6866 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6869 /*-----------------------------------------------------------------*/
6870 /* genlshTwo - left shift two bytes by known amount != 0 */
6871 /*-----------------------------------------------------------------*/
6872 static void genlshTwo (operand *result,operand *left, int shCount)
6876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6877 size = pic14_getDataSize(result);
6879 /* if shCount >= 8 */
6885 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6887 movLeft2Result(left, LSB, result, MSB16);
6889 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6892 /* 1 <= shCount <= 7 */
6895 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6897 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6901 /*-----------------------------------------------------------------*/
6902 /* shiftLLong - shift left one long from left to result */
6903 /* offl = LSB or MSB16 */
6904 /*-----------------------------------------------------------------*/
6905 static void shiftLLong (operand *left, operand *result, int offr )
6908 int size = AOP_SIZE(result);
6910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6911 if(size >= LSB+offr){
6912 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6914 pic14_emitcode("add","a,acc");
6915 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6916 size >= MSB16+offr && offr != LSB )
6917 pic14_emitcode("xch","a,%s",
6918 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6920 aopPut(AOP(result),"a",LSB+offr);
6923 if(size >= MSB16+offr){
6924 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6925 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6928 pic14_emitcode("rlc","a");
6929 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6930 size >= MSB24+offr && offr != LSB)
6931 pic14_emitcode("xch","a,%s",
6932 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6934 aopPut(AOP(result),"a",MSB16+offr);
6937 if(size >= MSB24+offr){
6938 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6939 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6942 pic14_emitcode("rlc","a");
6943 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6944 size >= MSB32+offr && offr != LSB )
6945 pic14_emitcode("xch","a,%s",
6946 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6948 aopPut(AOP(result),"a",MSB24+offr);
6951 if(size > MSB32+offr){
6952 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6953 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6956 pic14_emitcode("rlc","a");
6957 aopPut(AOP(result),"a",MSB32+offr);
6960 aopPut(AOP(result),zero,LSB);
6963 /*-----------------------------------------------------------------*/
6964 /* genlshFour - shift four byte by a known amount != 0 */
6965 /*-----------------------------------------------------------------*/
6966 static void genlshFour (operand *result, operand *left, int shCount)
6970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6971 size = AOP_SIZE(result);
6973 /* if shifting more that 3 bytes */
6974 if (shCount >= 24 ) {
6977 /* lowest order of left goes to the highest
6978 order of the destination */
6979 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6981 movLeft2Result(left, LSB, result, MSB32);
6982 aopPut(AOP(result),zero,LSB);
6983 aopPut(AOP(result),zero,MSB16);
6984 aopPut(AOP(result),zero,MSB32);
6988 /* more than two bytes */
6989 else if ( shCount >= 16 ) {
6990 /* lower order two bytes goes to higher order two bytes */
6992 /* if some more remaining */
6994 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6996 movLeft2Result(left, MSB16, result, MSB32);
6997 movLeft2Result(left, LSB, result, MSB24);
6999 aopPut(AOP(result),zero,MSB16);
7000 aopPut(AOP(result),zero,LSB);
7004 /* if more than 1 byte */
7005 else if ( shCount >= 8 ) {
7006 /* lower order three bytes goes to higher order three bytes */
7010 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7012 movLeft2Result(left, LSB, result, MSB16);
7014 else{ /* size = 4 */
7016 movLeft2Result(left, MSB24, result, MSB32);
7017 movLeft2Result(left, MSB16, result, MSB24);
7018 movLeft2Result(left, LSB, result, MSB16);
7019 aopPut(AOP(result),zero,LSB);
7021 else if(shCount == 1)
7022 shiftLLong(left, result, MSB16);
7024 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7025 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7026 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7027 aopPut(AOP(result),zero,LSB);
7032 /* 1 <= shCount <= 7 */
7033 else if(shCount <= 2){
7034 shiftLLong(left, result, LSB);
7036 shiftLLong(result, result, LSB);
7038 /* 3 <= shCount <= 7, optimize */
7040 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7041 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7042 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7046 /*-----------------------------------------------------------------*/
7047 /* genLeftShiftLiteral - left shifting by known count */
7048 /*-----------------------------------------------------------------*/
7049 static void genLeftShiftLiteral (operand *left,
7054 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7058 freeAsmop(right,NULL,ic,TRUE);
7060 aopOp(left,ic,FALSE);
7061 aopOp(result,ic,FALSE);
7063 size = getSize(operandType(result));
7066 pic14_emitcode("; shift left ","result %d, left %d",size,
7070 /* I suppose that the left size >= result size */
7073 movLeft2Result(left, size, result, size);
7077 else if(shCount >= (size * 8))
7079 aopPut(AOP(result),zero,size);
7083 genlshOne (result,left,shCount);
7088 genlshTwo (result,left,shCount);
7092 genlshFour (result,left,shCount);
7096 freeAsmop(left,NULL,ic,TRUE);
7097 freeAsmop(result,NULL,ic,TRUE);
7100 /*-----------------------------------------------------------------*
7101 * genMultiAsm - repeat assembly instruction for size of register.
7102 * if endian == 1, then the high byte (i.e base address + size of
7103 * register) is used first else the low byte is used first;
7104 *-----------------------------------------------------------------*/
7105 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7123 emitpcode(poc, popGet(AOP(reg),offset));
7128 /*-----------------------------------------------------------------*/
7129 /* genLeftShift - generates code for left shifting */
7130 /*-----------------------------------------------------------------*/
7131 static void genLeftShift (iCode *ic)
7133 operand *left,*right, *result;
7136 symbol *tlbl , *tlbl1;
7139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7141 right = IC_RIGHT(ic);
7143 result = IC_RESULT(ic);
7145 aopOp(right,ic,FALSE);
7147 /* if the shift count is known then do it
7148 as efficiently as possible */
7149 if (AOP_TYPE(right) == AOP_LIT) {
7150 genLeftShiftLiteral (left,right,result,ic);
7154 /* shift count is unknown then we have to form
7155 a loop get the loop count in B : Note: we take
7156 only the lower order byte since shifting
7157 more that 32 bits make no sense anyway, ( the
7158 largest size of an object can be only 32 bits ) */
7161 aopOp(left,ic,FALSE);
7162 aopOp(result,ic,FALSE);
7164 /* now move the left to the result if they are not the
7166 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7167 AOP_SIZE(result) > 1) {
7169 size = AOP_SIZE(result);
7172 l = aopGet(AOP(left),offset,FALSE,TRUE);
7173 if (*l == '@' && (IS_AOP_PREG(result))) {
7175 pic14_emitcode("mov","a,%s",l);
7176 aopPut(AOP(result),"a",offset);
7178 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7179 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7180 //aopPut(AOP(result),l,offset);
7186 size = AOP_SIZE(result);
7188 /* if it is only one byte then */
7190 if(optimized_for_speed) {
7191 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7192 emitpcode(POC_ANDLW, popGetLit(0xf0));
7193 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7194 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7195 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7196 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7197 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7198 emitpcode(POC_RLFW, popGet(AOP(result),0));
7199 emitpcode(POC_ANDLW, popGetLit(0xfe));
7200 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7201 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7202 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7205 tlbl = newiTempLabel(NULL);
7206 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7207 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7208 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7211 emitpcode(POC_COMFW, popGet(AOP(right),0));
7212 emitpcode(POC_RRF, popGet(AOP(result),0));
7213 emitpLabel(tlbl->key);
7214 emitpcode(POC_RLF, popGet(AOP(result),0));
7215 emitpcode(POC_ADDLW, popGetLit(1));
7217 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7222 if (pic14_sameRegs(AOP(left),AOP(result))) {
7224 tlbl = newiTempLabel(NULL);
7225 emitpcode(POC_COMFW, popGet(AOP(right),0));
7226 genMultiAsm(POC_RRF, result, size,1);
7227 emitpLabel(tlbl->key);
7228 genMultiAsm(POC_RLF, result, size,0);
7229 emitpcode(POC_ADDLW, popGetLit(1));
7231 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7235 //tlbl = newiTempLabel(NULL);
7237 //tlbl1 = newiTempLabel(NULL);
7239 //reAdjustPreg(AOP(result));
7241 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7242 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7243 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7245 //pic14_emitcode("add","a,acc");
7246 //aopPut(AOP(result),"a",offset++);
7248 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7250 // pic14_emitcode("rlc","a");
7251 // aopPut(AOP(result),"a",offset++);
7253 //reAdjustPreg(AOP(result));
7255 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7256 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7259 tlbl = newiTempLabel(NULL);
7260 tlbl1= newiTempLabel(NULL);
7262 size = AOP_SIZE(result);
7265 pctemp = popGetTempReg(); /* grab a temporary working register. */
7267 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7269 /* offset should be 0, 1 or 3 */
7270 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7272 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7274 emitpcode(POC_MOVWF, pctemp);
7277 emitpLabel(tlbl->key);
7280 emitpcode(POC_RLF, popGet(AOP(result),0));
7282 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7284 emitpcode(POC_DECFSZ, pctemp);
7285 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7286 emitpLabel(tlbl1->key);
7288 popReleaseTempReg(pctemp);
7292 freeAsmop (right,NULL,ic,TRUE);
7293 freeAsmop(left,NULL,ic,TRUE);
7294 freeAsmop(result,NULL,ic,TRUE);
7297 /*-----------------------------------------------------------------*/
7298 /* genrshOne - right shift a one byte quantity by known count */
7299 /*-----------------------------------------------------------------*/
7300 static void genrshOne (operand *result, operand *left,
7301 int shCount, int sign)
7303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7304 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7307 /*-----------------------------------------------------------------*/
7308 /* genrshTwo - right shift two bytes by known amount != 0 */
7309 /*-----------------------------------------------------------------*/
7310 static void genrshTwo (operand *result,operand *left,
7311 int shCount, int sign)
7313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7314 /* if shCount >= 8 */
7318 shiftR1Left2Result(left, MSB16, result, LSB,
7321 movLeft2Result(left, MSB16, result, LSB);
7323 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7326 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7327 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7331 /* 1 <= shCount <= 7 */
7333 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7336 /*-----------------------------------------------------------------*/
7337 /* shiftRLong - shift right one long from left to result */
7338 /* offl = LSB or MSB16 */
7339 /*-----------------------------------------------------------------*/
7340 static void shiftRLong (operand *left, int offl,
7341 operand *result, int sign)
7343 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7345 pic14_emitcode("clr","c");
7346 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7348 pic14_emitcode("mov","c,acc.7");
7349 pic14_emitcode("rrc","a");
7350 aopPut(AOP(result),"a",MSB32-offl);
7352 /* add sign of "a" */
7353 addSign(result, MSB32, sign);
7355 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7356 pic14_emitcode("rrc","a");
7357 aopPut(AOP(result),"a",MSB24-offl);
7359 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7360 pic14_emitcode("rrc","a");
7361 aopPut(AOP(result),"a",MSB16-offl);
7364 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7365 pic14_emitcode("rrc","a");
7366 aopPut(AOP(result),"a",LSB);
7370 /*-----------------------------------------------------------------*/
7371 /* genrshFour - shift four byte by a known amount != 0 */
7372 /*-----------------------------------------------------------------*/
7373 static void genrshFour (operand *result, operand *left,
7374 int shCount, int sign)
7376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7377 /* if shifting more that 3 bytes */
7378 if(shCount >= 24 ) {
7381 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7383 movLeft2Result(left, MSB32, result, LSB);
7385 addSign(result, MSB16, sign);
7387 else if(shCount >= 16){
7390 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7392 movLeft2Result(left, MSB24, result, LSB);
7393 movLeft2Result(left, MSB32, result, MSB16);
7395 addSign(result, MSB24, sign);
7397 else if(shCount >= 8){
7400 shiftRLong(left, MSB16, result, sign);
7401 else if(shCount == 0){
7402 movLeft2Result(left, MSB16, result, LSB);
7403 movLeft2Result(left, MSB24, result, MSB16);
7404 movLeft2Result(left, MSB32, result, MSB24);
7405 addSign(result, MSB32, sign);
7408 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7409 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7410 /* the last shift is signed */
7411 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7412 addSign(result, MSB32, sign);
7415 else{ /* 1 <= shCount <= 7 */
7417 shiftRLong(left, LSB, result, sign);
7419 shiftRLong(result, LSB, result, sign);
7422 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7423 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7424 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7429 /*-----------------------------------------------------------------*/
7430 /* genRightShiftLiteral - right shifting by known count */
7431 /*-----------------------------------------------------------------*/
7432 static void genRightShiftLiteral (operand *left,
7438 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7441 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7442 freeAsmop(right,NULL,ic,TRUE);
7444 aopOp(left,ic,FALSE);
7445 aopOp(result,ic,FALSE);
7448 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7452 lsize = pic14_getDataSize(left);
7453 res_size = pic14_getDataSize(result);
7454 /* test the LEFT size !!! */
7456 /* I suppose that the left size >= result size */
7459 movLeft2Result(left, lsize, result, res_size);
7462 else if(shCount >= (lsize * 8)){
7465 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7467 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7468 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7473 emitpcode(POC_MOVLW, popGetLit(0));
7474 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7475 emitpcode(POC_MOVLW, popGetLit(0xff));
7477 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7482 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7489 genrshOne (result,left,shCount,sign);
7493 genrshTwo (result,left,shCount,sign);
7497 genrshFour (result,left,shCount,sign);
7505 freeAsmop(left,NULL,ic,TRUE);
7506 freeAsmop(result,NULL,ic,TRUE);
7509 /*-----------------------------------------------------------------*/
7510 /* genSignedRightShift - right shift of signed number */
7511 /*-----------------------------------------------------------------*/
7512 static void genSignedRightShift (iCode *ic)
7514 operand *right, *left, *result;
7517 symbol *tlbl, *tlbl1 ;
7520 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7522 /* we do it the hard way put the shift count in b
7523 and loop thru preserving the sign */
7524 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7526 right = IC_RIGHT(ic);
7528 result = IC_RESULT(ic);
7530 aopOp(right,ic,FALSE);
7531 aopOp(left,ic,FALSE);
7532 aopOp(result,ic,FALSE);
7535 if ( AOP_TYPE(right) == AOP_LIT) {
7536 genRightShiftLiteral (left,right,result,ic,1);
7539 /* shift count is unknown then we have to form
7540 a loop get the loop count in B : Note: we take
7541 only the lower order byte since shifting
7542 more that 32 bits make no sense anyway, ( the
7543 largest size of an object can be only 32 bits ) */
7545 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7546 //pic14_emitcode("inc","b");
7547 //freeAsmop (right,NULL,ic,TRUE);
7548 //aopOp(left,ic,FALSE);
7549 //aopOp(result,ic,FALSE);
7551 /* now move the left to the result if they are not the
7553 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7554 AOP_SIZE(result) > 1) {
7556 size = AOP_SIZE(result);
7560 l = aopGet(AOP(left),offset,FALSE,TRUE);
7561 if (*l == '@' && IS_AOP_PREG(result)) {
7563 pic14_emitcode("mov","a,%s",l);
7564 aopPut(AOP(result),"a",offset);
7566 aopPut(AOP(result),l,offset);
7568 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7569 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7575 /* mov the highest order bit to OVR */
7576 tlbl = newiTempLabel(NULL);
7577 tlbl1= newiTempLabel(NULL);
7579 size = AOP_SIZE(result);
7582 pctemp = popGetTempReg(); /* grab a temporary working register. */
7584 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7586 /* offset should be 0, 1 or 3 */
7587 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7589 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7591 emitpcode(POC_MOVWF, pctemp);
7594 emitpLabel(tlbl->key);
7596 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7597 emitpcode(POC_RRF, popGet(AOP(result),offset));
7600 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7603 emitpcode(POC_DECFSZ, pctemp);
7604 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7605 emitpLabel(tlbl1->key);
7607 popReleaseTempReg(pctemp);
7609 size = AOP_SIZE(result);
7611 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7612 pic14_emitcode("rlc","a");
7613 pic14_emitcode("mov","ov,c");
7614 /* if it is only one byte then */
7616 l = aopGet(AOP(left),0,FALSE,FALSE);
7618 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7619 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7620 pic14_emitcode("mov","c,ov");
7621 pic14_emitcode("rrc","a");
7622 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7623 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7624 aopPut(AOP(result),"a",0);
7628 reAdjustPreg(AOP(result));
7629 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7630 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7631 pic14_emitcode("mov","c,ov");
7633 l = aopGet(AOP(result),offset,FALSE,FALSE);
7635 pic14_emitcode("rrc","a");
7636 aopPut(AOP(result),"a",offset--);
7638 reAdjustPreg(AOP(result));
7639 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7640 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7645 freeAsmop(left,NULL,ic,TRUE);
7646 freeAsmop(result,NULL,ic,TRUE);
7647 freeAsmop(right,NULL,ic,TRUE);
7650 /*-----------------------------------------------------------------*/
7651 /* genRightShift - generate code for right shifting */
7652 /*-----------------------------------------------------------------*/
7653 static void genRightShift (iCode *ic)
7655 operand *right, *left, *result;
7659 symbol *tlbl, *tlbl1 ;
7661 /* if signed then we do it the hard way preserve the
7662 sign bit moving it inwards */
7663 retype = getSpec(operandType(IC_RESULT(ic)));
7664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7666 if (!SPEC_USIGN(retype)) {
7667 genSignedRightShift (ic);
7671 /* signed & unsigned types are treated the same : i.e. the
7672 signed is NOT propagated inwards : quoting from the
7673 ANSI - standard : "for E1 >> E2, is equivalent to division
7674 by 2**E2 if unsigned or if it has a non-negative value,
7675 otherwise the result is implementation defined ", MY definition
7676 is that the sign does not get propagated */
7678 right = IC_RIGHT(ic);
7680 result = IC_RESULT(ic);
7682 aopOp(right,ic,FALSE);
7684 /* if the shift count is known then do it
7685 as efficiently as possible */
7686 if (AOP_TYPE(right) == AOP_LIT) {
7687 genRightShiftLiteral (left,right,result,ic, 0);
7691 /* shift count is unknown then we have to form
7692 a loop get the loop count in B : Note: we take
7693 only the lower order byte since shifting
7694 more that 32 bits make no sense anyway, ( the
7695 largest size of an object can be only 32 bits ) */
7697 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7698 pic14_emitcode("inc","b");
7699 aopOp(left,ic,FALSE);
7700 aopOp(result,ic,FALSE);
7702 /* now move the left to the result if they are not the
7704 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7705 AOP_SIZE(result) > 1) {
7707 size = AOP_SIZE(result);
7710 l = aopGet(AOP(left),offset,FALSE,TRUE);
7711 if (*l == '@' && IS_AOP_PREG(result)) {
7713 pic14_emitcode("mov","a,%s",l);
7714 aopPut(AOP(result),"a",offset);
7716 aopPut(AOP(result),l,offset);
7721 tlbl = newiTempLabel(NULL);
7722 tlbl1= newiTempLabel(NULL);
7723 size = AOP_SIZE(result);
7726 /* if it is only one byte then */
7729 tlbl = newiTempLabel(NULL);
7730 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7731 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7732 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7735 emitpcode(POC_COMFW, popGet(AOP(right),0));
7736 emitpcode(POC_RLF, popGet(AOP(result),0));
7737 emitpLabel(tlbl->key);
7738 emitpcode(POC_RRF, popGet(AOP(result),0));
7739 emitpcode(POC_ADDLW, popGetLit(1));
7741 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7746 reAdjustPreg(AOP(result));
7747 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7748 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7751 l = aopGet(AOP(result),offset,FALSE,FALSE);
7753 pic14_emitcode("rrc","a");
7754 aopPut(AOP(result),"a",offset--);
7756 reAdjustPreg(AOP(result));
7758 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7759 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7762 freeAsmop(left,NULL,ic,TRUE);
7763 freeAsmop (right,NULL,ic,TRUE);
7764 freeAsmop(result,NULL,ic,TRUE);
7767 /*-----------------------------------------------------------------*/
7768 /* genUnpackBits - generates code for unpacking bits */
7769 /*-----------------------------------------------------------------*/
7770 static void genUnpackBits (operand *result, char *rname, int ptype)
7777 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7778 etype = getSpec(operandType(result));
7780 /* read the first byte */
7785 pic14_emitcode("mov","a,@%s",rname);
7789 pic14_emitcode("movx","a,@%s",rname);
7793 pic14_emitcode("movx","a,@dptr");
7797 pic14_emitcode("clr","a");
7798 pic14_emitcode("movc","a","@a+dptr");
7802 pic14_emitcode("lcall","__gptrget");
7806 /* if we have bitdisplacement then it fits */
7807 /* into this byte completely or if length is */
7808 /* less than a byte */
7809 if ((shCnt = SPEC_BSTR(etype)) ||
7810 (SPEC_BLEN(etype) <= 8)) {
7812 /* shift right acc */
7815 pic14_emitcode("anl","a,#0x%02x",
7816 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7817 aopPut(AOP(result),"a",offset);
7821 /* bit field did not fit in a byte */
7822 rlen = SPEC_BLEN(etype) - 8;
7823 aopPut(AOP(result),"a",offset++);
7830 pic14_emitcode("inc","%s",rname);
7831 pic14_emitcode("mov","a,@%s",rname);
7835 pic14_emitcode("inc","%s",rname);
7836 pic14_emitcode("movx","a,@%s",rname);
7840 pic14_emitcode("inc","dptr");
7841 pic14_emitcode("movx","a,@dptr");
7845 pic14_emitcode("clr","a");
7846 pic14_emitcode("inc","dptr");
7847 pic14_emitcode("movc","a","@a+dptr");
7851 pic14_emitcode("inc","dptr");
7852 pic14_emitcode("lcall","__gptrget");
7857 /* if we are done */
7861 aopPut(AOP(result),"a",offset++);
7866 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7867 aopPut(AOP(result),"a",offset);
7874 /*-----------------------------------------------------------------*/
7875 /* genDataPointerGet - generates code when ptr offset is known */
7876 /*-----------------------------------------------------------------*/
7877 static void genDataPointerGet (operand *left,
7881 int size , offset = 0;
7884 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7887 /* optimization - most of the time, left and result are the same
7888 * address, but different types. for the pic code, we could omit
7892 aopOp(result,ic,TRUE);
7894 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7896 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7898 size = AOP_SIZE(result);
7901 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7905 freeAsmop(left,NULL,ic,TRUE);
7906 freeAsmop(result,NULL,ic,TRUE);
7909 /*-----------------------------------------------------------------*/
7910 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7911 /*-----------------------------------------------------------------*/
7912 static void genNearPointerGet (operand *left,
7917 //regs *preg = NULL ;
7919 sym_link *rtype, *retype;
7920 sym_link *ltype = operandType(left);
7923 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7925 rtype = operandType(result);
7926 retype= getSpec(rtype);
7928 aopOp(left,ic,FALSE);
7930 /* if left is rematerialisable and
7931 result is not bit variable type and
7932 the left is pointer to data space i.e
7933 lower 128 bytes of space */
7934 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7935 !IS_BITVAR(retype) &&
7936 DCL_TYPE(ltype) == POINTER) {
7937 //genDataPointerGet (left,result,ic);
7941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7943 /* if the value is already in a pointer register
7944 then don't need anything more */
7945 if (!AOP_INPREG(AOP(left))) {
7946 /* otherwise get a free pointer register */
7947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7950 preg = getFreePtr(ic,&aop,FALSE);
7951 pic14_emitcode("mov","%s,%s",
7953 aopGet(AOP(left),0,FALSE,TRUE));
7954 rname = preg->name ;
7958 rname = aopGet(AOP(left),0,FALSE,FALSE);
7960 aopOp (result,ic,FALSE);
7962 /* if bitfield then unpack the bits */
7963 if (IS_BITFIELD(retype))
7964 genUnpackBits (result,rname,POINTER);
7966 /* we have can just get the values */
7967 int size = AOP_SIZE(result);
7970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7972 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7973 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7975 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7976 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7978 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7982 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7984 pic14_emitcode("mov","a,@%s",rname);
7985 aopPut(AOP(result),"a",offset);
7987 sprintf(buffer,"@%s",rname);
7988 aopPut(AOP(result),buffer,offset);
7992 pic14_emitcode("inc","%s",rname);
7997 /* now some housekeeping stuff */
7999 /* we had to allocate for this iCode */
8000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8001 freeAsmop(NULL,aop,ic,TRUE);
8003 /* we did not allocate which means left
8004 already in a pointer register, then
8005 if size > 0 && this could be used again
8006 we have to point it back to where it
8008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8009 if (AOP_SIZE(result) > 1 &&
8010 !OP_SYMBOL(left)->remat &&
8011 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8013 int size = AOP_SIZE(result) - 1;
8015 pic14_emitcode("dec","%s",rname);
8020 freeAsmop(left,NULL,ic,TRUE);
8021 freeAsmop(result,NULL,ic,TRUE);
8025 /*-----------------------------------------------------------------*/
8026 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8027 /*-----------------------------------------------------------------*/
8028 static void genPagedPointerGet (operand *left,
8035 sym_link *rtype, *retype;
8037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8039 rtype = operandType(result);
8040 retype= getSpec(rtype);
8042 aopOp(left,ic,FALSE);
8044 /* if the value is already in a pointer register
8045 then don't need anything more */
8046 if (!AOP_INPREG(AOP(left))) {
8047 /* otherwise get a free pointer register */
8049 preg = getFreePtr(ic,&aop,FALSE);
8050 pic14_emitcode("mov","%s,%s",
8052 aopGet(AOP(left),0,FALSE,TRUE));
8053 rname = preg->name ;
8055 rname = aopGet(AOP(left),0,FALSE,FALSE);
8057 freeAsmop(left,NULL,ic,TRUE);
8058 aopOp (result,ic,FALSE);
8060 /* if bitfield then unpack the bits */
8061 if (IS_BITFIELD(retype))
8062 genUnpackBits (result,rname,PPOINTER);
8064 /* we have can just get the values */
8065 int size = AOP_SIZE(result);
8070 pic14_emitcode("movx","a,@%s",rname);
8071 aopPut(AOP(result),"a",offset);
8076 pic14_emitcode("inc","%s",rname);
8080 /* now some housekeeping stuff */
8082 /* we had to allocate for this iCode */
8083 freeAsmop(NULL,aop,ic,TRUE);
8085 /* we did not allocate which means left
8086 already in a pointer register, then
8087 if size > 0 && this could be used again
8088 we have to point it back to where it
8090 if (AOP_SIZE(result) > 1 &&
8091 !OP_SYMBOL(left)->remat &&
8092 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8094 int size = AOP_SIZE(result) - 1;
8096 pic14_emitcode("dec","%s",rname);
8101 freeAsmop(result,NULL,ic,TRUE);
8106 /*-----------------------------------------------------------------*/
8107 /* genFarPointerGet - gget value from far space */
8108 /*-----------------------------------------------------------------*/
8109 static void genFarPointerGet (operand *left,
8110 operand *result, iCode *ic)
8113 sym_link *retype = getSpec(operandType(result));
8115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8117 aopOp(left,ic,FALSE);
8119 /* if the operand is already in dptr
8120 then we do nothing else we move the value to dptr */
8121 if (AOP_TYPE(left) != AOP_STR) {
8122 /* if this is remateriazable */
8123 if (AOP_TYPE(left) == AOP_IMMD)
8124 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8125 else { /* we need to get it byte by byte */
8126 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8127 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8128 if (options.model == MODEL_FLAT24)
8130 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8134 /* so dptr know contains the address */
8135 freeAsmop(left,NULL,ic,TRUE);
8136 aopOp(result,ic,FALSE);
8138 /* if bit then unpack */
8139 if (IS_BITFIELD(retype))
8140 genUnpackBits(result,"dptr",FPOINTER);
8142 size = AOP_SIZE(result);
8146 pic14_emitcode("movx","a,@dptr");
8147 aopPut(AOP(result),"a",offset++);
8149 pic14_emitcode("inc","dptr");
8153 freeAsmop(result,NULL,ic,TRUE);
8156 /*-----------------------------------------------------------------*/
8157 /* genCodePointerGet - get value from code space */
8158 /*-----------------------------------------------------------------*/
8159 static void genCodePointerGet (operand *left,
8160 operand *result, iCode *ic)
8163 sym_link *retype = getSpec(operandType(result));
8165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8167 aopOp(left,ic,FALSE);
8169 /* if the operand is already in dptr
8170 then we do nothing else we move the value to dptr */
8171 if (AOP_TYPE(left) != AOP_STR) {
8172 /* if this is remateriazable */
8173 if (AOP_TYPE(left) == AOP_IMMD)
8174 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8175 else { /* we need to get it byte by byte */
8176 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8177 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8178 if (options.model == MODEL_FLAT24)
8180 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8184 /* so dptr know contains the address */
8185 freeAsmop(left,NULL,ic,TRUE);
8186 aopOp(result,ic,FALSE);
8188 /* if bit then unpack */
8189 if (IS_BITFIELD(retype))
8190 genUnpackBits(result,"dptr",CPOINTER);
8192 size = AOP_SIZE(result);
8196 pic14_emitcode("clr","a");
8197 pic14_emitcode("movc","a,@a+dptr");
8198 aopPut(AOP(result),"a",offset++);
8200 pic14_emitcode("inc","dptr");
8204 freeAsmop(result,NULL,ic,TRUE);
8207 /*-----------------------------------------------------------------*/
8208 /* genGenPointerGet - gget value from generic pointer space */
8209 /*-----------------------------------------------------------------*/
8210 static void genGenPointerGet (operand *left,
8211 operand *result, iCode *ic)
8214 sym_link *retype = getSpec(operandType(result));
8216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8217 aopOp(left,ic,FALSE);
8218 aopOp(result,ic,FALSE);
8221 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8223 /* if the operand is already in dptr
8224 then we do nothing else we move the value to dptr */
8225 // if (AOP_TYPE(left) != AOP_STR) {
8226 /* if this is remateriazable */
8227 if (AOP_TYPE(left) == AOP_IMMD) {
8228 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8229 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8231 else { /* we need to get it byte by byte */
8233 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8234 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8236 size = AOP_SIZE(result);
8240 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8241 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8243 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8248 /* so dptr know contains the address */
8250 /* if bit then unpack */
8251 //if (IS_BITFIELD(retype))
8252 // genUnpackBits(result,"dptr",GPOINTER);
8255 freeAsmop(left,NULL,ic,TRUE);
8256 freeAsmop(result,NULL,ic,TRUE);
8260 /*-----------------------------------------------------------------*/
8261 /* genConstPointerGet - get value from const generic pointer space */
8262 /*-----------------------------------------------------------------*/
8263 static void genConstPointerGet (operand *left,
8264 operand *result, iCode *ic)
8266 //sym_link *retype = getSpec(operandType(result));
8267 symbol *albl = newiTempLabel(NULL);
8268 symbol *blbl = newiTempLabel(NULL);
8272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8273 aopOp(left,ic,FALSE);
8274 aopOp(result,ic,FALSE);
8277 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8279 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8281 emitpcode(POC_CALL,popGetLabel(albl->key));
8282 pcop = popGetLabel(blbl->key);
8283 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8284 emitpcode(POC_GOTO,pcop);
8285 emitpLabel(albl->key);
8287 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8289 emitpcode(poc,popGet(AOP(left),1));
8290 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8291 emitpcode(poc,popGet(AOP(left),0));
8292 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8294 emitpLabel(blbl->key);
8296 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8299 freeAsmop(left,NULL,ic,TRUE);
8300 freeAsmop(result,NULL,ic,TRUE);
8303 /*-----------------------------------------------------------------*/
8304 /* genPointerGet - generate code for pointer get */
8305 /*-----------------------------------------------------------------*/
8306 static void genPointerGet (iCode *ic)
8308 operand *left, *result ;
8309 sym_link *type, *etype;
8312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8315 result = IC_RESULT(ic) ;
8317 /* depending on the type of pointer we need to
8318 move it to the correct pointer register */
8319 type = operandType(left);
8320 etype = getSpec(type);
8322 if (IS_PTR_CONST(type))
8323 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8325 /* if left is of type of pointer then it is simple */
8326 if (IS_PTR(type) && !IS_FUNC(type->next))
8327 p_type = DCL_TYPE(type);
8329 /* we have to go by the storage class */
8330 p_type = PTR_TYPE(SPEC_OCLS(etype));
8332 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8334 if (SPEC_OCLS(etype)->codesp ) {
8335 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8336 //p_type = CPOINTER ;
8339 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8340 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8341 /*p_type = FPOINTER ;*/
8343 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8344 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8345 /* p_type = PPOINTER; */
8347 if (SPEC_OCLS(etype) == idata )
8348 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8349 /* p_type = IPOINTER; */
8351 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8352 /* p_type = POINTER ; */
8355 /* now that we have the pointer type we assign
8356 the pointer values */
8361 genNearPointerGet (left,result,ic);
8365 genPagedPointerGet(left,result,ic);
8369 genFarPointerGet (left,result,ic);
8373 genConstPointerGet (left,result,ic);
8374 //pic14_emitcodePointerGet (left,result,ic);
8378 if (IS_PTR_CONST(type))
8379 genConstPointerGet (left,result,ic);
8381 genGenPointerGet (left,result,ic);
8387 /*-----------------------------------------------------------------*/
8388 /* genPackBits - generates code for packed bit storage */
8389 /*-----------------------------------------------------------------*/
8390 static void genPackBits (sym_link *etype ,
8392 char *rname, int p_type)
8400 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8401 blen = SPEC_BLEN(etype);
8402 bstr = SPEC_BSTR(etype);
8404 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8407 /* if the bit lenth is less than or */
8408 /* it exactly fits a byte then */
8409 if (SPEC_BLEN(etype) <= 8 ) {
8410 shCount = SPEC_BSTR(etype) ;
8412 /* shift left acc */
8415 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8420 pic14_emitcode ("mov","b,a");
8421 pic14_emitcode("mov","a,@%s",rname);
8425 pic14_emitcode ("mov","b,a");
8426 pic14_emitcode("movx","a,@dptr");
8430 pic14_emitcode ("push","b");
8431 pic14_emitcode ("push","acc");
8432 pic14_emitcode ("lcall","__gptrget");
8433 pic14_emitcode ("pop","b");
8437 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8438 ((unsigned char)(0xFF << (blen+bstr)) |
8439 (unsigned char)(0xFF >> (8-bstr)) ) );
8440 pic14_emitcode ("orl","a,b");
8441 if (p_type == GPOINTER)
8442 pic14_emitcode("pop","b");
8448 pic14_emitcode("mov","@%s,a",rname);
8452 pic14_emitcode("movx","@dptr,a");
8456 DEBUGpic14_emitcode(";lcall","__gptrput");
8461 if ( SPEC_BLEN(etype) <= 8 )
8464 pic14_emitcode("inc","%s",rname);
8465 rLen = SPEC_BLEN(etype) ;
8467 /* now generate for lengths greater than one byte */
8470 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8480 pic14_emitcode("mov","@%s,a",rname);
8482 pic14_emitcode("mov","@%s,%s",rname,l);
8487 pic14_emitcode("movx","@dptr,a");
8492 DEBUGpic14_emitcode(";lcall","__gptrput");
8495 pic14_emitcode ("inc","%s",rname);
8500 /* last last was not complete */
8502 /* save the byte & read byte */
8505 pic14_emitcode ("mov","b,a");
8506 pic14_emitcode("mov","a,@%s",rname);
8510 pic14_emitcode ("mov","b,a");
8511 pic14_emitcode("movx","a,@dptr");
8515 pic14_emitcode ("push","b");
8516 pic14_emitcode ("push","acc");
8517 pic14_emitcode ("lcall","__gptrget");
8518 pic14_emitcode ("pop","b");
8522 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8523 pic14_emitcode ("orl","a,b");
8526 if (p_type == GPOINTER)
8527 pic14_emitcode("pop","b");
8532 pic14_emitcode("mov","@%s,a",rname);
8536 pic14_emitcode("movx","@dptr,a");
8540 DEBUGpic14_emitcode(";lcall","__gptrput");
8544 /*-----------------------------------------------------------------*/
8545 /* genDataPointerSet - remat pointer to data space */
8546 /*-----------------------------------------------------------------*/
8547 static void genDataPointerSet(operand *right,
8551 int size, offset = 0 ;
8552 char *l, buffer[256];
8554 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8555 aopOp(right,ic,FALSE);
8557 l = aopGet(AOP(result),0,FALSE,TRUE);
8558 size = AOP_SIZE(right);
8560 if ( AOP_TYPE(result) == AOP_PCODE) {
8561 fprintf(stderr,"genDataPointerSet %s, %d\n",
8562 AOP(result)->aopu.pcop->name,
8563 PCOI(AOP(result)->aopu.pcop)->offset);
8567 // tsd, was l+1 - the underline `_' prefix was being stripped
8570 sprintf(buffer,"(%s + %d)",l,offset);
8571 fprintf(stderr,"oops %s\n",buffer);
8573 sprintf(buffer,"%s",l);
8575 if (AOP_TYPE(right) == AOP_LIT) {
8576 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8577 lit = lit >> (8*offset);
8579 pic14_emitcode("movlw","%d",lit);
8580 pic14_emitcode("movwf","%s",buffer);
8582 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8583 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8584 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8587 pic14_emitcode("clrf","%s",buffer);
8588 //emitpcode(POC_CLRF, popRegFromString(buffer));
8589 emitpcode(POC_CLRF, popGet(AOP(result),0));
8592 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8593 pic14_emitcode("movwf","%s",buffer);
8595 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8596 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8597 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8604 freeAsmop(right,NULL,ic,TRUE);
8605 freeAsmop(result,NULL,ic,TRUE);
8608 /*-----------------------------------------------------------------*/
8609 /* genNearPointerSet - pic14_emitcode for near pointer put */
8610 /*-----------------------------------------------------------------*/
8611 static void genNearPointerSet (operand *right,
8618 sym_link *ptype = operandType(result);
8621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8622 retype= getSpec(operandType(right));
8624 aopOp(result,ic,FALSE);
8627 /* if the result is rematerializable &
8628 in data space & not a bit variable */
8629 //if (AOP_TYPE(result) == AOP_IMMD &&
8630 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8631 DCL_TYPE(ptype) == POINTER &&
8632 !IS_BITFIELD(retype)) {
8633 genDataPointerSet (right,result,ic);
8634 freeAsmop(result,NULL,ic,TRUE);
8638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8639 aopOp(right,ic,FALSE);
8640 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8642 /* if the value is already in a pointer register
8643 then don't need anything more */
8644 if (!AOP_INPREG(AOP(result))) {
8645 /* otherwise get a free pointer register */
8646 //aop = newAsmop(0);
8647 //preg = getFreePtr(ic,&aop,FALSE);
8648 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8649 //pic14_emitcode("mov","%s,%s",
8651 // aopGet(AOP(result),0,FALSE,TRUE));
8652 //rname = preg->name ;
8653 //pic14_emitcode("movwf","fsr");
8654 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8655 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8656 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8657 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8661 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8664 /* if bitfield then unpack the bits */
8665 if (IS_BITFIELD(retype)) {
8666 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8667 "The programmer is obviously confused");
8668 //genPackBits (retype,right,rname,POINTER);
8672 /* we have can just get the values */
8673 int size = AOP_SIZE(right);
8676 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8678 l = aopGet(AOP(right),offset,FALSE,TRUE);
8681 //pic14_emitcode("mov","@%s,a",rname);
8682 pic14_emitcode("movf","indf,w ;1");
8685 if (AOP_TYPE(right) == AOP_LIT) {
8686 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8688 pic14_emitcode("movlw","%s",l);
8689 pic14_emitcode("movwf","indf ;2");
8691 pic14_emitcode("clrf","indf");
8693 pic14_emitcode("movf","%s,w",l);
8694 pic14_emitcode("movwf","indf ;2");
8696 //pic14_emitcode("mov","@%s,%s",rname,l);
8699 pic14_emitcode("incf","fsr,f ;3");
8700 //pic14_emitcode("inc","%s",rname);
8705 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8706 /* now some housekeeping stuff */
8708 /* we had to allocate for this iCode */
8709 freeAsmop(NULL,aop,ic,TRUE);
8711 /* we did not allocate which means left
8712 already in a pointer register, then
8713 if size > 0 && this could be used again
8714 we have to point it back to where it
8716 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8717 if (AOP_SIZE(right) > 1 &&
8718 !OP_SYMBOL(result)->remat &&
8719 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8721 int size = AOP_SIZE(right) - 1;
8723 pic14_emitcode("decf","fsr,f");
8724 //pic14_emitcode("dec","%s",rname);
8728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8731 freeAsmop(right,NULL,ic,TRUE);
8732 freeAsmop(result,NULL,ic,TRUE);
8735 /*-----------------------------------------------------------------*/
8736 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8737 /*-----------------------------------------------------------------*/
8738 static void genPagedPointerSet (operand *right,
8747 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8749 retype= getSpec(operandType(right));
8751 aopOp(result,ic,FALSE);
8753 /* if the value is already in a pointer register
8754 then don't need anything more */
8755 if (!AOP_INPREG(AOP(result))) {
8756 /* otherwise get a free pointer register */
8758 preg = getFreePtr(ic,&aop,FALSE);
8759 pic14_emitcode("mov","%s,%s",
8761 aopGet(AOP(result),0,FALSE,TRUE));
8762 rname = preg->name ;
8764 rname = aopGet(AOP(result),0,FALSE,FALSE);
8766 freeAsmop(result,NULL,ic,TRUE);
8767 aopOp (right,ic,FALSE);
8769 /* if bitfield then unpack the bits */
8770 if (IS_BITFIELD(retype))
8771 genPackBits (retype,right,rname,PPOINTER);
8773 /* we have can just get the values */
8774 int size = AOP_SIZE(right);
8778 l = aopGet(AOP(right),offset,FALSE,TRUE);
8781 pic14_emitcode("movx","@%s,a",rname);
8784 pic14_emitcode("inc","%s",rname);
8790 /* now some housekeeping stuff */
8792 /* we had to allocate for this iCode */
8793 freeAsmop(NULL,aop,ic,TRUE);
8795 /* we did not allocate which means left
8796 already in a pointer register, then
8797 if size > 0 && this could be used again
8798 we have to point it back to where it
8800 if (AOP_SIZE(right) > 1 &&
8801 !OP_SYMBOL(result)->remat &&
8802 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8804 int size = AOP_SIZE(right) - 1;
8806 pic14_emitcode("dec","%s",rname);
8811 freeAsmop(right,NULL,ic,TRUE);
8816 /*-----------------------------------------------------------------*/
8817 /* genFarPointerSet - set value from far space */
8818 /*-----------------------------------------------------------------*/
8819 static void genFarPointerSet (operand *right,
8820 operand *result, iCode *ic)
8823 sym_link *retype = getSpec(operandType(right));
8825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8826 aopOp(result,ic,FALSE);
8828 /* if the operand is already in dptr
8829 then we do nothing else we move the value to dptr */
8830 if (AOP_TYPE(result) != AOP_STR) {
8831 /* if this is remateriazable */
8832 if (AOP_TYPE(result) == AOP_IMMD)
8833 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8834 else { /* we need to get it byte by byte */
8835 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8836 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8837 if (options.model == MODEL_FLAT24)
8839 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8843 /* so dptr know contains the address */
8844 freeAsmop(result,NULL,ic,TRUE);
8845 aopOp(right,ic,FALSE);
8847 /* if bit then unpack */
8848 if (IS_BITFIELD(retype))
8849 genPackBits(retype,right,"dptr",FPOINTER);
8851 size = AOP_SIZE(right);
8855 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8857 pic14_emitcode("movx","@dptr,a");
8859 pic14_emitcode("inc","dptr");
8863 freeAsmop(right,NULL,ic,TRUE);
8866 /*-----------------------------------------------------------------*/
8867 /* genGenPointerSet - set value from generic pointer space */
8868 /*-----------------------------------------------------------------*/
8869 static void genGenPointerSet (operand *right,
8870 operand *result, iCode *ic)
8873 sym_link *retype = getSpec(operandType(right));
8875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8877 aopOp(result,ic,FALSE);
8878 aopOp(right,ic,FALSE);
8879 size = AOP_SIZE(right);
8881 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8883 /* if the operand is already in dptr
8884 then we do nothing else we move the value to dptr */
8885 if (AOP_TYPE(result) != AOP_STR) {
8886 /* if this is remateriazable */
8887 if (AOP_TYPE(result) == AOP_IMMD) {
8888 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8889 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8891 else { /* we need to get it byte by byte */
8892 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8893 size = AOP_SIZE(right);
8896 /* hack hack! see if this the FSR. If so don't load W */
8897 if(AOP_TYPE(right) != AOP_ACC) {
8900 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8901 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8903 if(AOP_SIZE(result) > 1) {
8904 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8905 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8906 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8911 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8913 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8914 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8918 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8919 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8922 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8929 if(aopIdx(AOP(result),0) != 4) {
8931 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8935 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8940 /* so dptr know contains the address */
8943 /* if bit then unpack */
8944 if (IS_BITFIELD(retype))
8945 genPackBits(retype,right,"dptr",GPOINTER);
8947 size = AOP_SIZE(right);
8950 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8954 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8955 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8957 if (AOP_TYPE(right) == AOP_LIT)
8958 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8960 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8962 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8969 freeAsmop(right,NULL,ic,TRUE);
8970 freeAsmop(result,NULL,ic,TRUE);
8973 /*-----------------------------------------------------------------*/
8974 /* genPointerSet - stores the value into a pointer location */
8975 /*-----------------------------------------------------------------*/
8976 static void genPointerSet (iCode *ic)
8978 operand *right, *result ;
8979 sym_link *type, *etype;
8982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8984 right = IC_RIGHT(ic);
8985 result = IC_RESULT(ic) ;
8987 /* depending on the type of pointer we need to
8988 move it to the correct pointer register */
8989 type = operandType(result);
8990 etype = getSpec(type);
8991 /* if left is of type of pointer then it is simple */
8992 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8993 p_type = DCL_TYPE(type);
8996 /* we have to go by the storage class */
8997 p_type = PTR_TYPE(SPEC_OCLS(etype));
8999 /* if (SPEC_OCLS(etype)->codesp ) { */
9000 /* p_type = CPOINTER ; */
9003 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9004 /* p_type = FPOINTER ; */
9006 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9007 /* p_type = PPOINTER ; */
9009 /* if (SPEC_OCLS(etype) == idata ) */
9010 /* p_type = IPOINTER ; */
9012 /* p_type = POINTER ; */
9015 /* now that we have the pointer type we assign
9016 the pointer values */
9021 genNearPointerSet (right,result,ic);
9025 genPagedPointerSet (right,result,ic);
9029 genFarPointerSet (right,result,ic);
9033 genGenPointerSet (right,result,ic);
9037 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9038 "genPointerSet: illegal pointer type");
9042 /*-----------------------------------------------------------------*/
9043 /* genIfx - generate code for Ifx statement */
9044 /*-----------------------------------------------------------------*/
9045 static void genIfx (iCode *ic, iCode *popIc)
9047 operand *cond = IC_COND(ic);
9050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9052 aopOp(cond,ic,FALSE);
9054 /* get the value into acc */
9055 if (AOP_TYPE(cond) != AOP_CRY)
9056 pic14_toBoolean(cond);
9059 /* the result is now in the accumulator */
9060 freeAsmop(cond,NULL,ic,TRUE);
9062 /* if there was something to be popped then do it */
9066 /* if the condition is a bit variable */
9067 if (isbit && IS_ITEMP(cond) &&
9069 genIfxJump(ic,SPIL_LOC(cond)->rname);
9070 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9073 if (isbit && !IS_ITEMP(cond))
9074 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9082 /*-----------------------------------------------------------------*/
9083 /* genAddrOf - generates code for address of */
9084 /*-----------------------------------------------------------------*/
9085 static void genAddrOf (iCode *ic)
9087 operand *right, *result, *left;
9090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9093 //aopOp(IC_RESULT(ic),ic,FALSE);
9095 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9096 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9097 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9099 DEBUGpic14_AopType(__LINE__,left,right,result);
9101 size = AOP_SIZE(IC_RESULT(ic));
9105 /* fixing bug #863624, reported from (errolv) */
9106 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9107 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9110 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9111 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9116 freeAsmop(left,NULL,ic,FALSE);
9117 freeAsmop(result,NULL,ic,TRUE);
9122 /*-----------------------------------------------------------------*/
9123 /* genFarFarAssign - assignment when both are in far space */
9124 /*-----------------------------------------------------------------*/
9125 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9127 int size = AOP_SIZE(right);
9130 /* first push the right side on to the stack */
9132 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9134 pic14_emitcode ("push","acc");
9137 freeAsmop(right,NULL,ic,FALSE);
9138 /* now assign DPTR to result */
9139 aopOp(result,ic,FALSE);
9140 size = AOP_SIZE(result);
9142 pic14_emitcode ("pop","acc");
9143 aopPut(AOP(result),"a",--offset);
9145 freeAsmop(result,NULL,ic,FALSE);
9150 /*-----------------------------------------------------------------*/
9151 /* genAssign - generate code for assignment */
9152 /*-----------------------------------------------------------------*/
9153 static void genAssign (iCode *ic)
9155 operand *result, *right;
9156 int size, offset,know_W;
9157 unsigned long lit = 0L;
9159 result = IC_RESULT(ic);
9160 right = IC_RIGHT(ic) ;
9162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9164 /* if they are the same */
9165 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9168 aopOp(right,ic,FALSE);
9169 aopOp(result,ic,TRUE);
9171 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9173 /* if they are the same registers */
9174 if (pic14_sameRegs(AOP(right),AOP(result)))
9177 /* if the result is a bit */
9178 if (AOP_TYPE(result) == AOP_CRY) {
9180 /* if the right size is a literal then
9181 we know what the value is */
9182 if (AOP_TYPE(right) == AOP_LIT) {
9184 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9185 popGet(AOP(result),0));
9187 if (((int) operandLitValue(right)))
9188 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9189 AOP(result)->aopu.aop_dir,
9190 AOP(result)->aopu.aop_dir);
9192 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9193 AOP(result)->aopu.aop_dir,
9194 AOP(result)->aopu.aop_dir);
9198 /* the right is also a bit variable */
9199 if (AOP_TYPE(right) == AOP_CRY) {
9200 emitpcode(POC_BCF, popGet(AOP(result),0));
9201 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9202 emitpcode(POC_BSF, popGet(AOP(result),0));
9204 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9205 AOP(result)->aopu.aop_dir,
9206 AOP(result)->aopu.aop_dir);
9207 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9208 AOP(right)->aopu.aop_dir,
9209 AOP(right)->aopu.aop_dir);
9210 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9211 AOP(result)->aopu.aop_dir,
9212 AOP(result)->aopu.aop_dir);
9217 emitpcode(POC_BCF, popGet(AOP(result),0));
9218 pic14_toBoolean(right);
9220 emitpcode(POC_BSF, popGet(AOP(result),0));
9221 //aopPut(AOP(result),"a",0);
9225 /* bit variables done */
9227 size = AOP_SIZE(result);
9229 if(AOP_TYPE(right) == AOP_LIT)
9230 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9232 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9234 if(aopIdx(AOP(result),0) == 4) {
9235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9236 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9237 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9240 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9246 if(AOP_TYPE(right) == AOP_LIT) {
9248 if(know_W != (int)(lit&0xff))
9249 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9251 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9253 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9257 } else if (AOP_TYPE(right) == AOP_CRY) {
9258 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9260 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9261 emitpcode(POC_INCF, popGet(AOP(result),0));
9264 mov2w (AOP(right), offset);
9265 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9273 freeAsmop (right,NULL,ic,FALSE);
9274 freeAsmop (result,NULL,ic,TRUE);
9277 /*-----------------------------------------------------------------*/
9278 /* genJumpTab - genrates code for jump table */
9279 /*-----------------------------------------------------------------*/
9280 static void genJumpTab (iCode *ic)
9285 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9287 aopOp(IC_JTCOND(ic),ic,FALSE);
9288 /* get the condition into accumulator */
9289 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9291 /* multiply by three */
9292 pic14_emitcode("add","a,acc");
9293 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9295 jtab = newiTempLabel(NULL);
9296 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9297 pic14_emitcode("jmp","@a+dptr");
9298 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9300 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9301 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9302 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9303 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9305 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9306 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9307 emitpLabel(jtab->key);
9309 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9311 /* now generate the jump labels */
9312 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9313 jtab = setNextItem(IC_JTLABELS(ic))) {
9314 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9315 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9321 /*-----------------------------------------------------------------*/
9322 /* genMixedOperation - gen code for operators between mixed types */
9323 /*-----------------------------------------------------------------*/
9325 TSD - Written for the PIC port - but this unfortunately is buggy.
9326 This routine is good in that it is able to efficiently promote
9327 types to different (larger) sizes. Unfortunately, the temporary
9328 variables that are optimized out by this routine are sometimes
9329 used in other places. So until I know how to really parse the
9330 iCode tree, I'm going to not be using this routine :(.
9332 static int genMixedOperation (iCode *ic)
9335 operand *result = IC_RESULT(ic);
9336 sym_link *ctype = operandType(IC_LEFT(ic));
9337 operand *right = IC_RIGHT(ic);
9343 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9345 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9351 nextright = IC_RIGHT(nextic);
9352 nextleft = IC_LEFT(nextic);
9353 nextresult = IC_RESULT(nextic);
9355 aopOp(right,ic,FALSE);
9356 aopOp(result,ic,FALSE);
9357 aopOp(nextright, nextic, FALSE);
9358 aopOp(nextleft, nextic, FALSE);
9359 aopOp(nextresult, nextic, FALSE);
9361 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9367 pic14_emitcode(";remove right +","");
9369 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9375 pic14_emitcode(";remove left +","");
9379 big = AOP_SIZE(nextleft);
9380 small = AOP_SIZE(nextright);
9382 switch(nextic->op) {
9385 pic14_emitcode(";optimize a +","");
9386 /* if unsigned or not an integral type */
9387 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9388 pic14_emitcode(";add a bit to something","");
9391 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9393 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9394 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9395 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9397 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9405 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9406 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9407 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9410 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9412 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9413 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9414 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9415 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9416 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9419 pic14_emitcode("rlf","known_zero,w");
9426 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9427 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9430 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9440 freeAsmop(right,NULL,ic,TRUE);
9441 freeAsmop(result,NULL,ic,TRUE);
9442 freeAsmop(nextright,NULL,ic,TRUE);
9443 freeAsmop(nextleft,NULL,ic,TRUE);
9445 nextic->generated = 1;
9452 /*-----------------------------------------------------------------*/
9453 /* genCast - gen code for casting */
9454 /*-----------------------------------------------------------------*/
9455 static void genCast (iCode *ic)
9457 operand *result = IC_RESULT(ic);
9458 sym_link *ctype = operandType(IC_LEFT(ic));
9459 sym_link *rtype = operandType(IC_RIGHT(ic));
9460 operand *right = IC_RIGHT(ic);
9463 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9464 /* if they are equivalent then do nothing */
9465 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9468 aopOp(right,ic,FALSE) ;
9469 aopOp(result,ic,FALSE);
9471 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9473 /* if the result is a bit */
9474 if (AOP_TYPE(result) == AOP_CRY) {
9475 /* if the right size is a literal then
9476 we know what the value is */
9477 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9478 if (AOP_TYPE(right) == AOP_LIT) {
9480 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9481 popGet(AOP(result),0));
9483 if (((int) operandLitValue(right)))
9484 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9485 AOP(result)->aopu.aop_dir,
9486 AOP(result)->aopu.aop_dir);
9488 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9489 AOP(result)->aopu.aop_dir,
9490 AOP(result)->aopu.aop_dir);
9495 /* the right is also a bit variable */
9496 if (AOP_TYPE(right) == AOP_CRY) {
9499 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9501 pic14_emitcode("clrc","");
9502 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9503 AOP(right)->aopu.aop_dir,
9504 AOP(right)->aopu.aop_dir);
9505 aopPut(AOP(result),"c",0);
9510 if (AOP_TYPE(right) == AOP_REG) {
9511 emitpcode(POC_BCF, popGet(AOP(result),0));
9512 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9513 emitpcode(POC_BSF, popGet(AOP(result),0));
9515 pic14_toBoolean(right);
9516 aopPut(AOP(result),"a",0);
9520 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9522 size = AOP_SIZE(result);
9524 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9526 emitpcode(POC_CLRF, popGet(AOP(result),0));
9527 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9528 emitpcode(POC_INCF, popGet(AOP(result),0));
9531 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9536 /* if they are the same size : or less */
9537 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9539 /* if they are in the same place */
9540 if (pic14_sameRegs(AOP(right),AOP(result)))
9543 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9544 if (IS_PTR_CONST(rtype))
9545 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9546 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9547 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9549 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9550 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9551 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9552 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9553 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9554 if(AOP_SIZE(result) <2)
9555 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9559 /* if they in different places then copy */
9560 size = AOP_SIZE(result);
9563 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9564 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9566 //aopPut(AOP(result),
9567 // aopGet(AOP(right),offset,FALSE,FALSE),
9577 /* if the result is of type pointer */
9578 if (IS_PTR(ctype)) {
9581 sym_link *type = operandType(right);
9582 sym_link *etype = getSpec(type);
9583 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9585 /* pointer to generic pointer */
9586 if (IS_GENPTR(ctype)) {
9590 p_type = DCL_TYPE(type);
9592 /* we have to go by the storage class */
9593 p_type = PTR_TYPE(SPEC_OCLS(etype));
9595 /* if (SPEC_OCLS(etype)->codesp ) */
9596 /* p_type = CPOINTER ; */
9598 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9599 /* p_type = FPOINTER ; */
9601 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9602 /* p_type = PPOINTER; */
9604 /* if (SPEC_OCLS(etype) == idata ) */
9605 /* p_type = IPOINTER ; */
9607 /* p_type = POINTER ; */
9610 /* the first two bytes are known */
9611 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9612 size = GPTRSIZE - 1;
9615 if(offset < AOP_SIZE(right)) {
9616 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9617 if ((AOP_TYPE(right) == AOP_PCODE) &&
9618 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9619 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9620 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9623 aopGet(AOP(right),offset,FALSE,FALSE),
9627 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9630 /* the last byte depending on type */
9634 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9637 pic14_emitcode(";BUG!? ","%d",__LINE__);
9641 pic14_emitcode(";BUG!? ","%d",__LINE__);
9645 pic14_emitcode(";BUG!? ","%d",__LINE__);
9650 /* this should never happen */
9651 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9652 "got unknown pointer type");
9655 //aopPut(AOP(result),l, GPTRSIZE - 1);
9659 /* just copy the pointers */
9660 size = AOP_SIZE(result);
9664 aopGet(AOP(right),offset,FALSE,FALSE),
9673 /* so we now know that the size of destination is greater
9674 than the size of the source.
9675 Now, if the next iCode is an operator then we might be
9676 able to optimize the operation without performing a cast.
9678 if(genMixedOperation(ic))
9681 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9683 /* we move to result for the size of source */
9684 size = AOP_SIZE(right);
9687 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9688 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9692 /* now depending on the sign of the destination */
9693 size = AOP_SIZE(result) - AOP_SIZE(right);
9694 /* if unsigned or not an integral type */
9695 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9697 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9699 /* we need to extend the sign :{ */
9702 /* Save one instruction of casting char to int */
9703 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9704 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9705 emitpcode(POC_DECF, popGet(AOP(result),offset));
9707 emitpcodeNULLop(POC_CLRW);
9710 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9712 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9714 emitpcode(POC_MOVLW, popGetLit(0xff));
9717 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9722 freeAsmop(right,NULL,ic,TRUE);
9723 freeAsmop(result,NULL,ic,TRUE);
9727 /*-----------------------------------------------------------------*/
9728 /* genDjnz - generate decrement & jump if not zero instrucion */
9729 /*-----------------------------------------------------------------*/
9730 static int genDjnz (iCode *ic, iCode *ifx)
9733 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9738 /* if the if condition has a false label
9739 then we cannot save */
9743 /* if the minus is not of the form
9745 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9746 !IS_OP_LITERAL(IC_RIGHT(ic)))
9749 if (operandLitValue(IC_RIGHT(ic)) != 1)
9752 /* if the size of this greater than one then no
9754 if (getSize(operandType(IC_RESULT(ic))) > 1)
9757 /* otherwise we can save BIG */
9758 lbl = newiTempLabel(NULL);
9759 lbl1= newiTempLabel(NULL);
9761 aopOp(IC_RESULT(ic),ic,FALSE);
9763 if (IS_AOP_PREG(IC_RESULT(ic))) {
9764 pic14_emitcode("dec","%s",
9765 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9766 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9767 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9771 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9772 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9774 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9775 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9778 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9779 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9780 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9781 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9784 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9789 /*-----------------------------------------------------------------*/
9790 /* genReceive - generate code for a receive iCode */
9791 /*-----------------------------------------------------------------*/
9792 static void genReceive (iCode *ic)
9794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9796 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9797 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9798 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9800 int size = getSize(operandType(IC_RESULT(ic)));
9801 int offset = fReturnSizePic - size;
9803 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9804 fReturn[fReturnSizePic - offset - 1] : "acc"));
9807 aopOp(IC_RESULT(ic),ic,FALSE);
9808 size = AOP_SIZE(IC_RESULT(ic));
9811 pic14_emitcode ("pop","acc");
9812 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9817 aopOp(IC_RESULT(ic),ic,FALSE);
9819 assignResultValue(IC_RESULT(ic));
9822 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9825 /*-----------------------------------------------------------------*/
9826 /* genDummyRead - generate code for dummy read of volatiles */
9827 /*-----------------------------------------------------------------*/
9829 genDummyRead (iCode * ic)
9831 pic14_emitcode ("; genDummyRead","");
9832 pic14_emitcode ("; not implemented","");
9837 /*-----------------------------------------------------------------*/
9838 /* genpic14Code - generate code for pic14 based controllers */
9839 /*-----------------------------------------------------------------*/
9841 * At this point, ralloc.c has gone through the iCode and attempted
9842 * to optimize in a way suitable for a PIC. Now we've got to generate
9843 * PIC instructions that correspond to the iCode.
9845 * Once the instructions are generated, we'll pass through both the
9846 * peep hole optimizer and the pCode optimizer.
9847 *-----------------------------------------------------------------*/
9849 void genpic14Code (iCode *lic)
9854 lineHead = lineCurr = NULL;
9856 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9859 /* if debug information required */
9860 if (options.debug && currFunc) {
9862 debugFile->writeFunction (currFunc, lic);
9867 for (ic = lic ; ic ; ic = ic->next ) {
9869 DEBUGpic14_emitcode(";ic","");
9870 if ( cln != ic->lineno ) {
9871 if ( options.debug ) {
9872 debugFile->writeCLine (ic);
9875 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9876 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9877 printCLine(ic->filename, ic->lineno));
9879 if (!options.noCcodeInAsm) {
9881 newpCodeCSource(ic->lineno,
9883 printCLine(ic->filename, ic->lineno)));
9889 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9891 /* if the result is marked as
9892 spilt and rematerializable or code for
9893 this has already been generated then
9895 if (resultRemat(ic) || ic->generated )
9898 /* depending on the operation */
9917 /* IPOP happens only when trying to restore a
9918 spilt live range, if there is an ifx statement
9919 following this pop then the if statement might
9920 be using some of the registers being popped which
9921 would destory the contents of the register so
9922 we need to check for this condition and handle it */
9924 ic->next->op == IFX &&
9925 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9926 genIfx (ic->next,ic);
9944 genEndFunction (ic);
9964 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9981 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9985 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9992 /* note these two are xlated by algebraic equivalence
9993 during parsing SDCC.y */
9994 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9995 "got '>=' or '<=' shouldn't have come here");
9999 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10011 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10015 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10019 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10043 genRightShift (ic);
10046 case GET_VALUE_AT_ADDRESS:
10051 if (POINTER_SET(ic))
10078 addSet(&_G.sendSet,ic);
10081 case DUMMY_READ_VOLATILE:
10091 /* now we are ready to call the
10092 peep hole optimizer */
10093 if (!options.nopeep) {
10094 peepHole (&lineHead);
10096 /* now do the actual printing */
10097 printLine (lineHead,codeOutFile);
10100 DFPRINTF((stderr,"printing pBlock\n\n"));
10101 printpBlock(stdout,pb);