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 =
821 aop->size = getSize(sym->type);
822 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
828 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
829 aop->size = getSize(sym->type);
830 for ( i = 0 ; i < 2 ; i++ )
831 aop->aopu.aop_str[i] = accUse[i];
832 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
837 if(sym->isptr) { // && sym->uptr
838 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
839 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
841 //PCOI(aop->aopu.pcop)->_const = 0;
842 //PCOI(aop->aopu.pcop)->index = 0;
844 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
845 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
847 //allocDirReg (IC_LEFT(ic));
849 aop->size = getSize(sym->type);
850 DEBUGpic14_emitcode(";","%d",__LINE__);
857 aop = op->aop = sym->aop = newAsmop(AOP_STR);
858 aop->size = getSize(sym->type);
859 for ( i = 0 ; i < fReturnSizePic ; i++ )
860 aop->aopu.aop_str[i] = fReturn[i];
862 DEBUGpic14_emitcode(";","%d",__LINE__);
867 /* else spill location */
868 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
869 /* force a new aop if sizes differ */
870 sym->usl.spillLoc->aop = NULL;
872 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
873 __FUNCTION__,__LINE__,
874 sym->usl.spillLoc->rname,
875 sym->rname, sym->usl.spillLoc->offset);
877 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
878 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
879 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
881 sym->usl.spillLoc->offset);
882 aop->size = getSize(sym->type);
888 sym_link *type = operandType(op);
889 if(IS_PTR_CONST(type))
890 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
893 /* must be in a register */
894 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
895 sym->aop = op->aop = aop = newAsmop(AOP_REG);
896 aop->size = sym->nRegs;
897 for ( i = 0 ; i < sym->nRegs ;i++)
898 aop->aopu.aop_reg[i] = sym->regs[i];
901 /*-----------------------------------------------------------------*/
902 /* freeAsmop - free up the asmop given to an operand */
903 /*----------------------------------------------------------------*/
904 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
921 /* depending on the asmop type only three cases need work AOP_RO
922 , AOP_R1 && AOP_STK */
928 pic14_emitcode ("pop","ar0");
932 bitVectUnSetBit(ic->rUsed,R0_IDX);
938 pic14_emitcode ("pop","ar1");
942 bitVectUnSetBit(ic->rUsed,R1_IDX);
948 int stk = aop->aopu.aop_stk + aop->size;
949 bitVectUnSetBit(ic->rUsed,R0_IDX);
950 bitVectUnSetBit(ic->rUsed,R1_IDX);
952 getFreePtr(ic,&aop,FALSE);
954 if (options.stack10bit)
956 /* I'm not sure what to do here yet... */
959 "*** Warning: probably generating bad code for "
960 "10 bit stack mode.\n");
964 pic14_emitcode ("mov","a,_bp");
965 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
966 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
968 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
972 pic14_emitcode("pop","acc");
973 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
975 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
978 freeAsmop(op,NULL,ic,TRUE);
980 pic14_emitcode("pop","ar0");
985 pic14_emitcode("pop","ar1");
993 /* all other cases just dealloc */
997 OP_SYMBOL(op)->aop = NULL;
998 /* if the symbol has a spill */
1000 SPIL_LOC(op)->aop = NULL;
1005 /*-----------------------------------------------------------------*/
1006 /* aopGet - for fetching value of the aop */
1007 /*-----------------------------------------------------------------*/
1008 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1013 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1014 /* offset is greater than
1016 if (offset > (aop->size - 1) &&
1017 aop->type != AOP_LIT)
1020 /* depending on type */
1021 switch (aop->type) {
1025 DEBUGpic14_emitcode(";","%d",__LINE__);
1026 /* if we need to increment it */
1027 while (offset > aop->coff) {
1028 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1032 while (offset < aop->coff) {
1033 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1037 aop->coff = offset ;
1039 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1040 return (dname ? "acc" : "a");
1042 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1043 rs = Safe_calloc(1,strlen(s)+1);
1049 DEBUGpic14_emitcode(";","%d",__LINE__);
1050 if (aop->type == AOP_DPTR2)
1055 while (offset > aop->coff) {
1056 pic14_emitcode ("inc","dptr");
1060 while (offset < aop->coff) {
1061 pic14_emitcode("lcall","__decdptr");
1067 pic14_emitcode("clr","a");
1068 pic14_emitcode("movc","a,@a+dptr");
1071 pic14_emitcode("movx","a,@dptr");
1074 if (aop->type == AOP_DPTR2)
1079 return (dname ? "acc" : "a");
1084 sprintf (s,"%s",aop->aopu.aop_immd);
1087 sprintf(s,"(%s >> %d)",
1092 aop->aopu.aop_immd);
1093 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1094 rs = Safe_calloc(1,strlen(s)+1);
1100 sprintf(s,"(%s + %d)",
1103 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1105 sprintf(s,"%s",aop->aopu.aop_dir);
1106 rs = Safe_calloc(1,strlen(s)+1);
1112 // return aop->aopu.aop_reg[offset]->dname;
1114 return aop->aopu.aop_reg[offset]->name;
1117 //pic14_emitcode(";","%d",__LINE__);
1118 return aop->aopu.aop_dir;
1121 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1122 return "AOP_accumulator_bug";
1125 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1126 rs = Safe_calloc(1,strlen(s)+1);
1131 aop->coff = offset ;
1132 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1135 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1137 return aop->aopu.aop_str[offset];
1141 pCodeOp *pcop = aop->aopu.pcop;
1142 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1144 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1145 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1146 sprintf(s,"%s", pcop->name);
1148 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1151 rs = Safe_calloc(1,strlen(s)+1);
1157 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1158 "aopget got unsupported aop->type");
1163 /*-----------------------------------------------------------------*/
1164 /* popGetTempReg - create a new temporary pCodeOp */
1165 /*-----------------------------------------------------------------*/
1166 pCodeOp *popGetTempReg(void)
1171 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1172 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1173 PCOR(pcop)->r->wasUsed=1;
1174 PCOR(pcop)->r->isFree=0;
1180 /*-----------------------------------------------------------------*/
1181 /* popGetTempReg - create a new temporary pCodeOp */
1182 /*-----------------------------------------------------------------*/
1183 void popReleaseTempReg(pCodeOp *pcop)
1186 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1187 PCOR(pcop)->r->isFree = 1;
1190 /*-----------------------------------------------------------------*/
1191 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1192 /*-----------------------------------------------------------------*/
1193 pCodeOp *popGetLabel(unsigned int key)
1196 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1198 if(key>(unsigned int)max_key)
1201 return newpCodeOpLabel(NULL,key+100+labelOffset);
1204 /*-------------------------------------------------------------------*/
1205 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1206 /*-------------------------------------------------------------------*/
1207 pCodeOp *popGetHighLabel(unsigned int key)
1210 pcop = popGetLabel(key);
1211 PCOLAB(pcop)->offset = 1;
1215 /*-----------------------------------------------------------------*/
1216 /* popGet - asm operator to pcode operator conversion */
1217 /*-----------------------------------------------------------------*/
1218 pCodeOp *popGetLit(unsigned int lit)
1221 return newpCodeOpLit(lit);
1224 /*-----------------------------------------------------------------*/
1225 /* popGetImmd - asm operator to pcode immediate conversion */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1230 return newpCodeOpImmd(name, offset,index, 0, is_func);
1234 /*-----------------------------------------------------------------*/
1235 /* popGet - asm operator to pcode operator conversion */
1236 /*-----------------------------------------------------------------*/
1237 pCodeOp *popGetWithString(char *str, int isExtern)
1243 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1247 pcop = newpCodeOp(str,PO_STR);
1248 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1253 /*-----------------------------------------------------------------*/
1254 /* popRegFromString - */
1255 /*-----------------------------------------------------------------*/
1256 pCodeOp *popRegFromString(char *str, int size, int offset)
1259 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1260 pcop->type = PO_DIR;
1262 DEBUGpic14_emitcode(";","%d",__LINE__);
1267 pcop->name = Safe_calloc(1,strlen(str)+1);
1268 strcpy(pcop->name,str);
1270 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1272 PCOR(pcop)->r = dirregWithName(pcop->name);
1273 if(PCOR(pcop)->r == NULL) {
1274 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1275 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1276 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1278 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1280 PCOR(pcop)->instance = offset;
1285 /*-----------------------------------------------------------------*/
1286 /*-----------------------------------------------------------------*/
1287 pCodeOp *popRegFromIdx(int rIdx)
1291 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1292 __FUNCTION__,__LINE__,rIdx);
1294 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1296 PCOR(pcop)->rIdx = rIdx;
1297 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1298 PCOR(pcop)->r->isFree = 0;
1299 PCOR(pcop)->r->wasUsed = 1;
1301 pcop->type = PCOR(pcop)->r->pc_type;
1307 /*-----------------------------------------------------------------*/
1308 /* popGet - asm operator to pcode operator conversion */
1309 /*-----------------------------------------------------------------*/
1310 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1312 //char *s = buffer ;
1317 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1318 /* offset is greater than
1321 if (offset > (aop->size - 1) &&
1322 aop->type != AOP_LIT)
1323 return NULL; //zero;
1325 /* depending on type */
1326 switch (aop->type) {
1333 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1337 DEBUGpic14_emitcode(";","%d",__LINE__);
1338 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1341 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1343 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1344 pcop->type = PO_DIR;
1348 sprintf(s,"(%s + %d)",
1352 sprintf(s,"%s",aop->aopu.aop_dir);
1353 pcop->name = Safe_calloc(1,strlen(s)+1);
1354 strcpy(pcop->name,s);
1356 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1357 strcpy(pcop->name,aop->aopu.aop_dir);
1358 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1359 if(PCOR(pcop)->r == NULL) {
1360 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1361 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1362 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1364 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1366 PCOR(pcop)->instance = offset;
1373 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1375 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1376 PCOR(pcop)->rIdx = rIdx;
1377 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1378 PCOR(pcop)->r->wasUsed=1;
1379 PCOR(pcop)->r->isFree=0;
1381 PCOR(pcop)->instance = offset;
1382 pcop->type = PCOR(pcop)->r->pc_type;
1383 //rs = aop->aopu.aop_reg[offset]->name;
1384 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1389 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1390 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1391 //if(PCOR(pcop)->r == NULL)
1392 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1396 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1399 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1400 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1402 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1403 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1404 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1405 pcop->type = PCOR(pcop)->r->pc_type;
1406 pcop->name = PCOR(pcop)->r->name;
1412 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1414 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1415 pcop = pCodeOpCopy(aop->aopu.pcop);
1416 PCOI(pcop)->offset = offset;
1420 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1421 "popGet got unsupported aop->type");
1424 /*-----------------------------------------------------------------*/
1425 /* aopPut - puts a string for a aop */
1426 /*-----------------------------------------------------------------*/
1427 void aopPut (asmop *aop, char *s, int offset)
1432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1434 if (aop->size && offset > ( aop->size - 1)) {
1435 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1436 "aopPut got offset > aop->size");
1440 /* will assign value to value */
1441 /* depending on where it is ofcourse */
1442 switch (aop->type) {
1445 sprintf(d,"(%s + %d)",
1446 aop->aopu.aop_dir,offset);
1447 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1450 sprintf(d,"%s",aop->aopu.aop_dir);
1453 DEBUGpic14_emitcode(";","%d",__LINE__);
1455 pic14_emitcode("movf","%s,w",s);
1456 pic14_emitcode("movwf","%s",d);
1459 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1460 if(offset >= aop->size) {
1461 emitpcode(POC_CLRF,popGet(aop,offset));
1464 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1467 emitpcode(POC_MOVWF,popGet(aop,offset));
1474 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1475 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1478 strcmp(s,"r0") == 0 ||
1479 strcmp(s,"r1") == 0 ||
1480 strcmp(s,"r2") == 0 ||
1481 strcmp(s,"r3") == 0 ||
1482 strcmp(s,"r4") == 0 ||
1483 strcmp(s,"r5") == 0 ||
1484 strcmp(s,"r6") == 0 ||
1485 strcmp(s,"r7") == 0 )
1486 pic14_emitcode("mov","%s,%s ; %d",
1487 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1491 if(strcmp(s,"W")==0 )
1492 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1494 pic14_emitcode("movwf","%s",
1495 aop->aopu.aop_reg[offset]->name);
1497 if(strcmp(s,zero)==0) {
1498 emitpcode(POC_CLRF,popGet(aop,offset));
1500 } else if(strcmp(s,"W")==0) {
1501 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1502 pcop->type = PO_GPR_REGISTER;
1504 PCOR(pcop)->rIdx = -1;
1505 PCOR(pcop)->r = NULL;
1507 DEBUGpic14_emitcode(";","%d",__LINE__);
1508 pcop->name = Safe_strdup(s);
1509 emitpcode(POC_MOVFW,pcop);
1510 emitpcode(POC_MOVWF,popGet(aop,offset));
1511 } else if(strcmp(s,one)==0) {
1512 emitpcode(POC_CLRF,popGet(aop,offset));
1513 emitpcode(POC_INCF,popGet(aop,offset));
1515 emitpcode(POC_MOVWF,popGet(aop,offset));
1523 if (aop->type == AOP_DPTR2)
1529 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1530 "aopPut writting to code space");
1534 while (offset > aop->coff) {
1536 pic14_emitcode ("inc","dptr");
1539 while (offset < aop->coff) {
1541 pic14_emitcode("lcall","__decdptr");
1546 /* if not in accumulater */
1549 pic14_emitcode ("movx","@dptr,a");
1551 if (aop->type == AOP_DPTR2)
1559 while (offset > aop->coff) {
1561 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1563 while (offset < aop->coff) {
1565 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1571 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1576 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1578 if (strcmp(s,"r0") == 0 ||
1579 strcmp(s,"r1") == 0 ||
1580 strcmp(s,"r2") == 0 ||
1581 strcmp(s,"r3") == 0 ||
1582 strcmp(s,"r4") == 0 ||
1583 strcmp(s,"r5") == 0 ||
1584 strcmp(s,"r6") == 0 ||
1585 strcmp(s,"r7") == 0 ) {
1587 sprintf(buffer,"a%s",s);
1588 pic14_emitcode("mov","@%s,%s",
1589 aop->aopu.aop_ptr->name,buffer);
1591 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1596 if (strcmp(s,"a") == 0)
1597 pic14_emitcode("push","acc");
1599 pic14_emitcode("push","%s",s);
1604 /* if bit variable */
1605 if (!aop->aopu.aop_dir) {
1606 pic14_emitcode("clr","a");
1607 pic14_emitcode("rlc","a");
1610 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1613 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1616 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1618 lbl = newiTempLabel(NULL);
1620 if (strcmp(s,"a")) {
1623 pic14_emitcode("clr","c");
1624 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1625 pic14_emitcode("cpl","c");
1626 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1627 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1634 if (strcmp(aop->aopu.aop_str[offset],s))
1635 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1640 if (!offset && (strcmp(s,"acc") == 0))
1643 if (strcmp(aop->aopu.aop_str[offset],s))
1644 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1648 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1649 "aopPut got unsupported aop->type");
1655 /*-----------------------------------------------------------------*/
1656 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1657 /*-----------------------------------------------------------------*/
1658 void mov2w (asmop *aop, int offset)
1664 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1666 if ( aop->type == AOP_PCODE ||
1667 aop->type == AOP_LIT ||
1668 aop->type == AOP_IMMD )
1669 emitpcode(POC_MOVLW,popGet(aop,offset));
1671 emitpcode(POC_MOVFW,popGet(aop,offset));
1675 /*-----------------------------------------------------------------*/
1676 /* reAdjustPreg - points a register back to where it should */
1677 /*-----------------------------------------------------------------*/
1678 static void reAdjustPreg (asmop *aop)
1682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1684 if ((size = aop->size) <= 1)
1687 switch (aop->type) {
1691 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1695 if (aop->type == AOP_DPTR2)
1701 pic14_emitcode("lcall","__decdptr");
1704 if (aop->type == AOP_DPTR2)
1716 /*-----------------------------------------------------------------*/
1717 /* opIsGptr: returns non-zero if the passed operand is */
1718 /* a generic pointer type. */
1719 /*-----------------------------------------------------------------*/
1720 static int opIsGptr(operand *op)
1722 sym_link *type = operandType(op);
1724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1725 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1733 /*-----------------------------------------------------------------*/
1734 /* pic14_getDataSize - get the operand data size */
1735 /*-----------------------------------------------------------------*/
1736 int pic14_getDataSize(operand *op)
1738 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1741 return AOP_SIZE(op);
1743 // tsd- in the pic port, the genptr size is 1, so this code here
1744 // fails. ( in the 8051 port, the size was 4).
1747 size = AOP_SIZE(op);
1748 if (size == GPTRSIZE)
1750 sym_link *type = operandType(op);
1751 if (IS_GENPTR(type))
1753 /* generic pointer; arithmetic operations
1754 * should ignore the high byte (pointer type).
1757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1764 /*-----------------------------------------------------------------*/
1765 /* pic14_outAcc - output Acc */
1766 /*-----------------------------------------------------------------*/
1767 void pic14_outAcc(operand *result)
1770 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1771 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1774 size = pic14_getDataSize(result);
1776 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1779 /* unsigned or positive */
1781 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1786 /*-----------------------------------------------------------------*/
1787 /* pic14_outBitC - output a bit C */
1788 /*-----------------------------------------------------------------*/
1789 void pic14_outBitC(operand *result)
1792 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1793 /* if the result is bit */
1794 if (AOP_TYPE(result) == AOP_CRY)
1795 aopPut(AOP(result),"c",0);
1797 pic14_emitcode("clr","a ; %d", __LINE__);
1798 pic14_emitcode("rlc","a");
1799 pic14_outAcc(result);
1803 /*-----------------------------------------------------------------*/
1804 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1805 /*-----------------------------------------------------------------*/
1806 void pic14_toBoolean(operand *oper)
1808 int size = AOP_SIZE(oper) - 1;
1811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1813 if ( AOP_TYPE(oper) != AOP_ACC) {
1814 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1817 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1822 /*-----------------------------------------------------------------*/
1823 /* genNot - generate code for ! operation */
1824 /*-----------------------------------------------------------------*/
1825 static void genNot (iCode *ic)
1830 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1831 /* assign asmOps to operand & result */
1832 aopOp (IC_LEFT(ic),ic,FALSE);
1833 aopOp (IC_RESULT(ic),ic,TRUE);
1835 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1836 /* if in bit space then a special case */
1837 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1838 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1839 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1840 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1842 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1843 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1844 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1849 size = AOP_SIZE(IC_LEFT(ic));
1851 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1852 emitpcode(POC_ANDLW,popGetLit(1));
1853 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1856 pic14_toBoolean(IC_LEFT(ic));
1858 tlbl = newiTempLabel(NULL);
1859 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1860 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1861 pic14_outBitC(IC_RESULT(ic));
1864 /* release the aops */
1865 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1866 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1870 /*-----------------------------------------------------------------*/
1871 /* genCpl - generate code for complement */
1872 /*-----------------------------------------------------------------*/
1873 static void genCpl (iCode *ic)
1875 operand *left, *result;
1879 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1880 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1881 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1883 /* if both are in bit space then
1885 if (AOP_TYPE(result) == AOP_CRY &&
1886 AOP_TYPE(left) == AOP_CRY ) {
1888 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1889 pic14_emitcode("cpl","c");
1890 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1894 size = AOP_SIZE(result);
1897 if(AOP_TYPE(left) == AOP_ACC)
1898 emitpcode(POC_XORLW, popGetLit(0xff));
1900 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1902 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1908 /* release the aops */
1909 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1910 freeAsmop(result,NULL,ic,TRUE);
1913 /*-----------------------------------------------------------------*/
1914 /* genUminusFloat - unary minus for floating points */
1915 /*-----------------------------------------------------------------*/
1916 static void genUminusFloat(operand *op,operand *result)
1918 int size ,offset =0 ;
1921 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1922 /* for this we just need to flip the
1923 first it then copy the rest in place */
1924 size = AOP_SIZE(op) - 1;
1925 l = aopGet(AOP(op),3,FALSE,FALSE);
1929 pic14_emitcode("cpl","acc.7");
1930 aopPut(AOP(result),"a",3);
1934 aopGet(AOP(op),offset,FALSE,FALSE),
1940 /*-----------------------------------------------------------------*/
1941 /* genUminus - unary minus code generation */
1942 /*-----------------------------------------------------------------*/
1943 static void genUminus (iCode *ic)
1946 sym_link *optype, *rtype;
1949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1951 aopOp(IC_LEFT(ic),ic,FALSE);
1952 aopOp(IC_RESULT(ic),ic,TRUE);
1954 /* if both in bit space then special
1956 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1957 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1959 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1960 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1961 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1966 optype = operandType(IC_LEFT(ic));
1967 rtype = operandType(IC_RESULT(ic));
1969 /* if float then do float stuff */
1970 if (IS_FLOAT(optype)) {
1971 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1975 /* otherwise subtract from zero by taking the 2's complement */
1976 size = AOP_SIZE(IC_LEFT(ic));
1978 for(i=0; i<size; i++) {
1979 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1980 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1982 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1983 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1987 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1988 for(i=1; i<size; i++) {
1990 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1994 /* release the aops */
1995 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1996 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1999 /*-----------------------------------------------------------------*/
2000 /* saveRegisters - will look for a call and save the registers */
2001 /*-----------------------------------------------------------------*/
2002 static void saveRegisters(iCode *lic)
2009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2011 for (ic = lic ; ic ; ic = ic->next)
2012 if (ic->op == CALL || ic->op == PCALL)
2016 fprintf(stderr,"found parameter push with no function call\n");
2020 /* if the registers have been saved already then
2022 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2025 /* find the registers in use at this time
2026 and push them away to safety */
2027 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2031 if (options.useXstack) {
2032 if (bitVectBitValue(rsave,R0_IDX))
2033 pic14_emitcode("mov","b,r0");
2034 pic14_emitcode("mov","r0,%s",spname);
2035 for (i = 0 ; i < pic14_nRegs ; i++) {
2036 if (bitVectBitValue(rsave,i)) {
2038 pic14_emitcode("mov","a,b");
2040 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2041 pic14_emitcode("movx","@r0,a");
2042 pic14_emitcode("inc","r0");
2045 pic14_emitcode("mov","%s,r0",spname);
2046 if (bitVectBitValue(rsave,R0_IDX))
2047 pic14_emitcode("mov","r0,b");
2049 //for (i = 0 ; i < pic14_nRegs ; i++) {
2050 // if (bitVectBitValue(rsave,i))
2051 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2054 dtype = operandType(IC_LEFT(ic));
2055 if (currFunc && dtype &&
2056 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2057 IFFUNC_ISISR(currFunc->type) &&
2060 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2063 /*-----------------------------------------------------------------*/
2064 /* unsaveRegisters - pop the pushed registers */
2065 /*-----------------------------------------------------------------*/
2066 static void unsaveRegisters (iCode *ic)
2071 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2072 /* find the registers in use at this time
2073 and push them away to safety */
2074 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2077 if (options.useXstack) {
2078 pic14_emitcode("mov","r0,%s",spname);
2079 for (i = pic14_nRegs ; i >= 0 ; i--) {
2080 if (bitVectBitValue(rsave,i)) {
2081 pic14_emitcode("dec","r0");
2082 pic14_emitcode("movx","a,@r0");
2084 pic14_emitcode("mov","b,a");
2086 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2090 pic14_emitcode("mov","%s,r0",spname);
2091 if (bitVectBitValue(rsave,R0_IDX))
2092 pic14_emitcode("mov","r0,b");
2094 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2095 // if (bitVectBitValue(rsave,i))
2096 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2102 /*-----------------------------------------------------------------*/
2104 /*-----------------------------------------------------------------*/
2105 static void pushSide(operand * oper, int size)
2109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2111 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2112 if (AOP_TYPE(oper) != AOP_REG &&
2113 AOP_TYPE(oper) != AOP_DIR &&
2115 pic14_emitcode("mov","a,%s",l);
2116 pic14_emitcode("push","acc");
2118 pic14_emitcode("push","%s",l);
2123 /*-----------------------------------------------------------------*/
2124 /* assignResultValue - */
2125 /*-----------------------------------------------------------------*/
2126 static void assignResultValue(operand * oper)
2128 int size = AOP_SIZE(oper);
2130 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2132 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2135 if (GpsuedoStkPtr++)
2136 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2137 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2142 /*-----------------------------------------------------------------*/
2143 /* genIpush - genrate code for pushing this gets a little complex */
2144 /*-----------------------------------------------------------------*/
2145 static void genIpush (iCode *ic)
2148 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2150 int size, offset = 0 ;
2154 /* if this is not a parm push : ie. it is spill push
2155 and spill push is always done on the local stack */
2156 if (!ic->parmPush) {
2158 /* and the item is spilt then do nothing */
2159 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2162 aopOp(IC_LEFT(ic),ic,FALSE);
2163 size = AOP_SIZE(IC_LEFT(ic));
2164 /* push it on the stack */
2166 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2171 pic14_emitcode("push","%s",l);
2176 /* this is a paramter push: in this case we call
2177 the routine to find the call and save those
2178 registers that need to be saved */
2181 /* then do the push */
2182 aopOp(IC_LEFT(ic),ic,FALSE);
2185 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2186 size = AOP_SIZE(IC_LEFT(ic));
2189 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2190 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2191 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2193 pic14_emitcode("mov","a,%s",l);
2194 pic14_emitcode("push","acc");
2196 pic14_emitcode("push","%s",l);
2199 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2203 /*-----------------------------------------------------------------*/
2204 /* genIpop - recover the registers: can happen only for spilling */
2205 /*-----------------------------------------------------------------*/
2206 static void genIpop (iCode *ic)
2208 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2213 /* if the temp was not pushed then */
2214 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2217 aopOp(IC_LEFT(ic),ic,FALSE);
2218 size = AOP_SIZE(IC_LEFT(ic));
2221 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2224 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2228 /*-----------------------------------------------------------------*/
2229 /* unsaverbank - restores the resgister bank from stack */
2230 /*-----------------------------------------------------------------*/
2231 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2233 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2239 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2241 if (options.useXstack) {
2243 r = getFreePtr(ic,&aop,FALSE);
2246 pic14_emitcode("mov","%s,_spx",r->name);
2247 pic14_emitcode("movx","a,@%s",r->name);
2248 pic14_emitcode("mov","psw,a");
2249 pic14_emitcode("dec","%s",r->name);
2252 pic14_emitcode ("pop","psw");
2255 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2256 if (options.useXstack) {
2257 pic14_emitcode("movx","a,@%s",r->name);
2258 //pic14_emitcode("mov","(%s+%d),a",
2259 // regspic14[i].base,8*bank+regspic14[i].offset);
2260 pic14_emitcode("dec","%s",r->name);
2263 pic14_emitcode("pop",""); //"(%s+%d)",
2264 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2267 if (options.useXstack) {
2269 pic14_emitcode("mov","_spx,%s",r->name);
2270 freeAsmop(NULL,aop,ic,TRUE);
2276 /*-----------------------------------------------------------------*/
2277 /* saverbank - saves an entire register bank on the stack */
2278 /*-----------------------------------------------------------------*/
2279 static void saverbank (int bank, iCode *ic, bool pushPsw)
2281 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2287 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2288 if (options.useXstack) {
2291 r = getFreePtr(ic,&aop,FALSE);
2292 pic14_emitcode("mov","%s,_spx",r->name);
2296 for (i = 0 ; i < pic14_nRegs ;i++) {
2297 if (options.useXstack) {
2298 pic14_emitcode("inc","%s",r->name);
2299 //pic14_emitcode("mov","a,(%s+%d)",
2300 // regspic14[i].base,8*bank+regspic14[i].offset);
2301 pic14_emitcode("movx","@%s,a",r->name);
2303 pic14_emitcode("push","");// "(%s+%d)",
2304 //regspic14[i].base,8*bank+regspic14[i].offset);
2308 if (options.useXstack) {
2309 pic14_emitcode("mov","a,psw");
2310 pic14_emitcode("movx","@%s,a",r->name);
2311 pic14_emitcode("inc","%s",r->name);
2312 pic14_emitcode("mov","_spx,%s",r->name);
2313 freeAsmop (NULL,aop,ic,TRUE);
2316 pic14_emitcode("push","psw");
2318 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2324 /*-----------------------------------------------------------------*/
2325 /* genCall - generates a call statement */
2326 /*-----------------------------------------------------------------*/
2327 static void genCall (iCode *ic)
2331 unsigned char *name;
2334 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2336 /* if caller saves & we have not saved then */
2340 /* if we are calling a function that is not using
2341 the same register bank then we need to save the
2342 destination registers on the stack */
2343 dtype = operandType(IC_LEFT(ic));
2344 if (currFunc && dtype &&
2345 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2346 IFFUNC_ISISR(currFunc->type) &&
2349 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2351 /* if send set is not empty the assign */
2354 /* For the Pic port, there is no data stack.
2355 * So parameters passed to functions are stored
2356 * in registers. (The pCode optimizer will get
2357 * rid of most of these :).
2359 int psuedoStkPtr=-1;
2360 int firstTimeThruLoop = 1;
2362 _G.sendSet = reverseSet(_G.sendSet);
2364 /* First figure how many parameters are getting passed */
2365 for (sic = setFirstItem(_G.sendSet) ; sic ;
2366 sic = setNextItem(_G.sendSet)) {
2368 aopOp(IC_LEFT(sic),sic,FALSE);
2369 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2370 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2373 for (sic = setFirstItem(_G.sendSet) ; sic ;
2374 sic = setNextItem(_G.sendSet)) {
2375 int size, offset = 0;
2377 aopOp(IC_LEFT(sic),sic,FALSE);
2378 size = AOP_SIZE(IC_LEFT(sic));
2381 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2382 AopType(AOP_TYPE(IC_LEFT(sic))));
2384 if(!firstTimeThruLoop) {
2385 /* If this is not the first time we've been through the loop
2386 * then we need to save the parameter in a temporary
2387 * register. The last byte of the last parameter is
2389 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2392 firstTimeThruLoop=0;
2394 mov2w (AOP(IC_LEFT(sic)), offset);
2397 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2402 sym = OP_SYMBOL(IC_LEFT(ic));
2403 name = sym->rname[0] ? sym->rname : sym->name;
2404 isExtern = IS_EXTERN(sym->etype);
2406 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2408 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2410 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2413 /* if we need assign a result value */
2414 if ((IS_ITEMP(IC_RESULT(ic)) &&
2415 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2416 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2417 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2420 aopOp(IC_RESULT(ic),ic,FALSE);
2423 assignResultValue(IC_RESULT(ic));
2425 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2426 AopType(AOP_TYPE(IC_RESULT(ic))));
2428 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2431 /* adjust the stack for parameters if
2433 if (ic->parmBytes) {
2435 if (ic->parmBytes > 3) {
2436 pic14_emitcode("mov","a,%s",spname);
2437 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2438 pic14_emitcode("mov","%s,a",spname);
2440 for ( i = 0 ; i < ic->parmBytes ;i++)
2441 pic14_emitcode("dec","%s",spname);
2445 /* if register bank was saved then pop them */
2447 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2449 /* if we hade saved some registers then unsave them */
2450 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2451 unsaveRegisters (ic);
2456 /*-----------------------------------------------------------------*/
2457 /* genPcall - generates a call by pointer statement */
2458 /*-----------------------------------------------------------------*/
2459 static void genPcall (iCode *ic)
2462 symbol *albl = newiTempLabel(NULL);
2463 symbol *blbl = newiTempLabel(NULL);
2468 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2469 /* if caller saves & we have not saved then */
2473 /* if we are calling a function that is not using
2474 the same register bank then we need to save the
2475 destination registers on the stack */
2476 dtype = operandType(IC_LEFT(ic));
2477 if (currFunc && dtype &&
2478 IFFUNC_ISISR(currFunc->type) &&
2479 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2480 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2483 aopOp(left,ic,FALSE);
2484 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2486 pushSide(IC_LEFT(ic), FPTRSIZE);
2488 /* if send set is not empty, assign parameters */
2491 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2492 /* no way to pass args - W always gets used to make the call */
2494 /* first idea - factor out a common helper function and call it.
2495 But don't know how to get it generated only once in its own block
2497 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2500 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2501 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2502 buffer = Safe_calloc(1,strlen(rname)+16);
2503 sprintf(buffer, "%s_goto_helper", rname);
2504 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2508 emitpcode(POC_CALL,popGetLabel(albl->key));
2509 pcop = popGetLabel(blbl->key);
2510 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2511 emitpcode(POC_GOTO,pcop);
2512 emitpLabel(albl->key);
2514 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2516 emitpcode(poc,popGet(AOP(left),1));
2517 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2518 emitpcode(poc,popGet(AOP(left),0));
2519 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2521 emitpLabel(blbl->key);
2523 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2525 /* if we need to assign a result value */
2526 if ((IS_ITEMP(IC_RESULT(ic)) &&
2527 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2528 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2529 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2532 aopOp(IC_RESULT(ic),ic,FALSE);
2535 assignResultValue(IC_RESULT(ic));
2537 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2540 /* if register bank was saved then unsave them */
2541 if (currFunc && dtype &&
2542 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2543 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2545 /* if we hade saved some registers then
2548 unsaveRegisters (ic);
2552 /*-----------------------------------------------------------------*/
2553 /* resultRemat - result is rematerializable */
2554 /*-----------------------------------------------------------------*/
2555 static int resultRemat (iCode *ic)
2557 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2558 if (SKIP_IC(ic) || ic->op == IFX)
2561 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2562 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2563 if (sym->remat && !POINTER_SET(ic))
2570 #if defined(__BORLANDC__) || defined(_MSC_VER)
2571 #define STRCASECMP stricmp
2573 #define STRCASECMP strcasecmp
2577 /*-----------------------------------------------------------------*/
2578 /* inExcludeList - return 1 if the string is in exclude Reg list */
2579 /*-----------------------------------------------------------------*/
2580 static bool inExcludeList(char *s)
2582 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2586 if (options.excludeRegs[i] &&
2587 STRCASECMP(options.excludeRegs[i],"none") == 0)
2590 for ( i = 0 ; options.excludeRegs[i]; i++) {
2591 if (options.excludeRegs[i] &&
2592 STRCASECMP(s,options.excludeRegs[i]) == 0)
2599 /*-----------------------------------------------------------------*/
2600 /* genFunction - generated code for function entry */
2601 /*-----------------------------------------------------------------*/
2602 static void genFunction (iCode *ic)
2607 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2609 labelOffset += (max_key+4);
2613 /* create the function header */
2614 pic14_emitcode(";","-----------------------------------------");
2615 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2616 pic14_emitcode(";","-----------------------------------------");
2618 pic14_emitcode("","%s:",sym->rname);
2619 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2621 ftype = operandType(IC_LEFT(ic));
2623 /* if critical function then turn interrupts off */
2624 if (IFFUNC_ISCRITICAL(ftype))
2625 pic14_emitcode("clr","ea");
2627 /* here we need to generate the equates for the
2628 register bank if required */
2630 if (FUNC_REGBANK(ftype) != rbank) {
2633 rbank = FUNC_REGBANK(ftype);
2634 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2635 if (strcmp(regspic14[i].base,"0") == 0)
2636 pic14_emitcode("","%s = 0x%02x",
2638 8*rbank+regspic14[i].offset);
2640 pic14_emitcode ("","%s = %s + 0x%02x",
2643 8*rbank+regspic14[i].offset);
2648 /* if this is an interrupt service routine */
2649 if (IFFUNC_ISISR(sym->type)) {
2650 /* already done in pic14createInterruptVect() - delete me
2651 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2652 emitpcodeNULLop(POC_NOP);
2653 emitpcodeNULLop(POC_NOP);
2654 emitpcodeNULLop(POC_NOP);
2656 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2657 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2658 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2659 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2660 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2661 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2662 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2664 pBlockConvert2ISR(pb);
2666 if (!inExcludeList("acc"))
2667 pic14_emitcode ("push","acc");
2668 if (!inExcludeList("b"))
2669 pic14_emitcode ("push","b");
2670 if (!inExcludeList("dpl"))
2671 pic14_emitcode ("push","dpl");
2672 if (!inExcludeList("dph"))
2673 pic14_emitcode ("push","dph");
2674 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2676 pic14_emitcode ("push", "dpx");
2677 /* Make sure we're using standard DPTR */
2678 pic14_emitcode ("push", "dps");
2679 pic14_emitcode ("mov", "dps, #0x00");
2680 if (options.stack10bit)
2682 /* This ISR could conceivably use DPTR2. Better save it. */
2683 pic14_emitcode ("push", "dpl1");
2684 pic14_emitcode ("push", "dph1");
2685 pic14_emitcode ("push", "dpx1");
2688 /* if this isr has no bank i.e. is going to
2689 run with bank 0 , then we need to save more
2691 if (!FUNC_REGBANK(sym->type)) {
2693 /* if this function does not call any other
2694 function then we can be economical and
2695 save only those registers that are used */
2696 if (! IFFUNC_HASFCALL(sym->type)) {
2699 /* if any registers used */
2700 if (sym->regsUsed) {
2701 /* save the registers used */
2702 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2703 if (bitVectBitValue(sym->regsUsed,i) ||
2704 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2705 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2710 /* this function has a function call cannot
2711 determines register usage so we will have the
2713 saverbank(0,ic,FALSE);
2718 /* if callee-save to be used for this function
2719 then save the registers being used in this function */
2720 if (IFFUNC_CALLEESAVES(sym->type)) {
2723 /* if any registers used */
2724 if (sym->regsUsed) {
2725 /* save the registers used */
2726 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2727 if (bitVectBitValue(sym->regsUsed,i) ||
2728 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2729 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2737 /* set the register bank to the desired value */
2738 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2739 pic14_emitcode("push","psw");
2740 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2743 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2745 if (options.useXstack) {
2746 pic14_emitcode("mov","r0,%s",spname);
2747 pic14_emitcode("mov","a,_bp");
2748 pic14_emitcode("movx","@r0,a");
2749 pic14_emitcode("inc","%s",spname);
2753 /* set up the stack */
2754 pic14_emitcode ("push","_bp"); /* save the callers stack */
2756 pic14_emitcode ("mov","_bp,%s",spname);
2759 /* adjust the stack for the function */
2764 werror(W_STACK_OVERFLOW,sym->name);
2766 if (i > 3 && sym->recvSize < 4) {
2768 pic14_emitcode ("mov","a,sp");
2769 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2770 pic14_emitcode ("mov","sp,a");
2775 pic14_emitcode("inc","sp");
2780 pic14_emitcode ("mov","a,_spx");
2781 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2782 pic14_emitcode ("mov","_spx,a");
2787 /*-----------------------------------------------------------------*/
2788 /* genEndFunction - generates epilogue for functions */
2789 /*-----------------------------------------------------------------*/
2790 static void genEndFunction (iCode *ic)
2792 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2796 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2798 pic14_emitcode ("mov","%s,_bp",spname);
2801 /* if use external stack but some variables were
2802 added to the local stack then decrement the
2804 if (options.useXstack && sym->stack) {
2805 pic14_emitcode("mov","a,sp");
2806 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2807 pic14_emitcode("mov","sp,a");
2811 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2812 if (options.useXstack) {
2813 pic14_emitcode("mov","r0,%s",spname);
2814 pic14_emitcode("movx","a,@r0");
2815 pic14_emitcode("mov","_bp,a");
2816 pic14_emitcode("dec","%s",spname);
2820 pic14_emitcode ("pop","_bp");
2824 /* restore the register bank */
2825 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2826 pic14_emitcode ("pop","psw");
2828 if (IFFUNC_ISISR(sym->type)) {
2830 /* now we need to restore the registers */
2831 /* if this isr has no bank i.e. is going to
2832 run with bank 0 , then we need to save more
2834 if (!FUNC_REGBANK(sym->type)) {
2836 /* if this function does not call any other
2837 function then we can be economical and
2838 save only those registers that are used */
2839 if (! IFFUNC_HASFCALL(sym->type)) {
2842 /* if any registers used */
2843 if (sym->regsUsed) {
2844 /* save the registers used */
2845 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2846 if (bitVectBitValue(sym->regsUsed,i) ||
2847 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2848 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2853 /* this function has a function call cannot
2854 determines register usage so we will have the
2856 unsaverbank(0,ic,FALSE);
2860 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2862 if (options.stack10bit)
2864 pic14_emitcode ("pop", "dpx1");
2865 pic14_emitcode ("pop", "dph1");
2866 pic14_emitcode ("pop", "dpl1");
2868 pic14_emitcode ("pop", "dps");
2869 pic14_emitcode ("pop", "dpx");
2871 if (!inExcludeList("dph"))
2872 pic14_emitcode ("pop","dph");
2873 if (!inExcludeList("dpl"))
2874 pic14_emitcode ("pop","dpl");
2875 if (!inExcludeList("b"))
2876 pic14_emitcode ("pop","b");
2877 if (!inExcludeList("acc"))
2878 pic14_emitcode ("pop","acc");
2880 if (IFFUNC_ISCRITICAL(sym->type))
2881 pic14_emitcode("setb","ea");
2884 /* if debug then send end of function */
2885 /* if (options.debug && currFunc) { */
2887 debugFile->writeEndFunction (currFunc, ic, 1);
2890 pic14_emitcode ("reti","");
2891 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2892 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2893 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2894 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2895 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2896 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2897 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2898 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2899 emitpcodeNULLop(POC_RETFIE);
2902 if (IFFUNC_ISCRITICAL(sym->type))
2903 pic14_emitcode("setb","ea");
2905 if (IFFUNC_CALLEESAVES(sym->type)) {
2908 /* if any registers used */
2909 if (sym->regsUsed) {
2910 /* save the registers used */
2911 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2912 if (bitVectBitValue(sym->regsUsed,i) ||
2913 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2914 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2920 /* if debug then send end of function */
2922 debugFile->writeEndFunction (currFunc, ic, 1);
2925 pic14_emitcode ("return","");
2926 emitpcodeNULLop(POC_RETURN);
2928 /* Mark the end of a function */
2929 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2934 /*-----------------------------------------------------------------*/
2935 /* genRet - generate code for return statement */
2936 /*-----------------------------------------------------------------*/
2937 static void genRet (iCode *ic)
2939 int size,offset = 0 , pushed = 0;
2941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2942 /* if we have no return value then
2943 just generate the "ret" */
2947 /* we have something to return then
2948 move the return value into place */
2949 aopOp(IC_LEFT(ic),ic,FALSE);
2950 size = AOP_SIZE(IC_LEFT(ic));
2954 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2956 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2958 pic14_emitcode("push","%s",l);
2961 l = aopGet(AOP(IC_LEFT(ic)),offset,
2963 if (strcmp(fReturn[offset],l)) {
2964 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2965 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2966 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2967 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2968 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2970 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2973 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2983 if (strcmp(fReturn[pushed],"a"))
2984 pic14_emitcode("pop",fReturn[pushed]);
2986 pic14_emitcode("pop","acc");
2989 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2992 /* generate a jump to the return label
2993 if the next is not the return statement */
2994 if (!(ic->next && ic->next->op == LABEL &&
2995 IC_LABEL(ic->next) == returnLabel)) {
2997 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2998 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3003 /*-----------------------------------------------------------------*/
3004 /* genLabel - generates a label */
3005 /*-----------------------------------------------------------------*/
3006 static void genLabel (iCode *ic)
3008 /* special case never generate */
3009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3010 if (IC_LABEL(ic) == entryLabel)
3013 emitpLabel(IC_LABEL(ic)->key);
3014 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3017 /*-----------------------------------------------------------------*/
3018 /* genGoto - generates a goto */
3019 /*-----------------------------------------------------------------*/
3021 static void genGoto (iCode *ic)
3023 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3024 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3028 /*-----------------------------------------------------------------*/
3029 /* genMultbits :- multiplication of bits */
3030 /*-----------------------------------------------------------------*/
3031 static void genMultbits (operand *left,
3035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3037 if(!pic14_sameRegs(AOP(result),AOP(right)))
3038 emitpcode(POC_BSF, popGet(AOP(result),0));
3040 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3041 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3042 emitpcode(POC_BCF, popGet(AOP(result),0));
3047 /*-----------------------------------------------------------------*/
3048 /* genMultOneByte : 8 bit multiplication & division */
3049 /*-----------------------------------------------------------------*/
3050 static void genMultOneByte (operand *left,
3054 sym_link *opetype = operandType(result);
3059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3060 DEBUGpic14_AopType(__LINE__,left,right,result);
3061 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3063 /* (if two literals, the value is computed before) */
3064 /* if one literal, literal on the right */
3065 if (AOP_TYPE(left) == AOP_LIT){
3071 size = AOP_SIZE(result);
3074 if (AOP_TYPE(right) == AOP_LIT){
3075 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3076 aopGet(AOP(right),0,FALSE,FALSE),
3077 aopGet(AOP(left),0,FALSE,FALSE),
3078 aopGet(AOP(result),0,FALSE,FALSE));
3079 pic14_emitcode("call","genMultLit");
3081 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3082 aopGet(AOP(right),0,FALSE,FALSE),
3083 aopGet(AOP(left),0,FALSE,FALSE),
3084 aopGet(AOP(result),0,FALSE,FALSE));
3085 pic14_emitcode("call","genMult8X8_8");
3088 genMult8X8_8 (left, right,result);
3091 /* signed or unsigned */
3092 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3093 //l = aopGet(AOP(left),0,FALSE,FALSE);
3095 //pic14_emitcode("mul","ab");
3096 /* if result size = 1, mul signed = mul unsigned */
3097 //aopPut(AOP(result),"a",0);
3099 } else { // (size > 1)
3101 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3102 aopGet(AOP(right),0,FALSE,FALSE),
3103 aopGet(AOP(left),0,FALSE,FALSE),
3104 aopGet(AOP(result),0,FALSE,FALSE));
3106 if (SPEC_USIGN(opetype)){
3107 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3108 genUMult8X8_16 (left, right, result, NULL);
3111 /* for filling the MSBs */
3112 emitpcode(POC_CLRF, popGet(AOP(result),2));
3113 emitpcode(POC_CLRF, popGet(AOP(result),3));
3117 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3119 pic14_emitcode("mov","a,b");
3121 /* adjust the MSB if left or right neg */
3123 /* if one literal */
3124 if (AOP_TYPE(right) == AOP_LIT){
3125 pic14_emitcode("multiply ","right is a lit");
3126 /* AND literal negative */
3127 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3128 /* adjust MSB (c==0 after mul) */
3129 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3133 genSMult8X8_16 (left, right, result, NULL);
3137 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3139 pic14_emitcode("rlc","a");
3140 pic14_emitcode("subb","a,acc");
3148 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3149 //aopPut(AOP(result),"a",offset++);
3153 /*-----------------------------------------------------------------*/
3154 /* genMult - generates code for multiplication */
3155 /*-----------------------------------------------------------------*/
3156 static void genMult (iCode *ic)
3158 operand *left = IC_LEFT(ic);
3159 operand *right = IC_RIGHT(ic);
3160 operand *result= IC_RESULT(ic);
3162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3163 /* assign the amsops */
3164 aopOp (left,ic,FALSE);
3165 aopOp (right,ic,FALSE);
3166 aopOp (result,ic,TRUE);
3168 DEBUGpic14_AopType(__LINE__,left,right,result);
3170 /* special cases first */
3172 if (AOP_TYPE(left) == AOP_CRY &&
3173 AOP_TYPE(right)== AOP_CRY) {
3174 genMultbits(left,right,result);
3178 /* if both are of size == 1 */
3179 if (AOP_SIZE(left) == 1 &&
3180 AOP_SIZE(right) == 1 ) {
3181 genMultOneByte(left,right,result);
3185 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3187 /* should have been converted to function call */
3191 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3192 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3193 freeAsmop(result,NULL,ic,TRUE);
3196 /*-----------------------------------------------------------------*/
3197 /* genDivbits :- division of bits */
3198 /*-----------------------------------------------------------------*/
3199 static void genDivbits (operand *left,
3206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3207 /* the result must be bit */
3208 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3209 l = aopGet(AOP(left),0,FALSE,FALSE);
3213 pic14_emitcode("div","ab");
3214 pic14_emitcode("rrc","a");
3215 aopPut(AOP(result),"c",0);
3218 /*-----------------------------------------------------------------*/
3219 /* genDivOneByte : 8 bit division */
3220 /*-----------------------------------------------------------------*/
3221 static void genDivOneByte (operand *left,
3225 sym_link *opetype = operandType(result);
3230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3231 size = AOP_SIZE(result) - 1;
3233 /* signed or unsigned */
3234 if (SPEC_USIGN(opetype)) {
3235 /* unsigned is easy */
3236 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3237 l = aopGet(AOP(left),0,FALSE,FALSE);
3239 pic14_emitcode("div","ab");
3240 aopPut(AOP(result),"a",0);
3242 aopPut(AOP(result),zero,offset++);
3246 /* signed is a little bit more difficult */
3248 /* save the signs of the operands */
3249 l = aopGet(AOP(left),0,FALSE,FALSE);
3251 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3252 pic14_emitcode("push","acc"); /* save it on the stack */
3254 /* now sign adjust for both left & right */
3255 l = aopGet(AOP(right),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));
3262 pic14_emitcode("mov","b,a");
3264 /* sign adjust left side */
3265 l = aopGet(AOP(left),0,FALSE,FALSE);
3268 lbl = newiTempLabel(NULL);
3269 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3270 pic14_emitcode("cpl","a");
3271 pic14_emitcode("inc","a");
3272 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3274 /* now the division */
3275 pic14_emitcode("div","ab");
3276 /* we are interested in the lower order
3278 pic14_emitcode("mov","b,a");
3279 lbl = newiTempLabel(NULL);
3280 pic14_emitcode("pop","acc");
3281 /* if there was an over flow we don't
3282 adjust the sign of the result */
3283 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3284 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3286 pic14_emitcode("clr","a");
3287 pic14_emitcode("subb","a,b");
3288 pic14_emitcode("mov","b,a");
3289 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3291 /* now we are done */
3292 aopPut(AOP(result),"b",0);
3294 pic14_emitcode("mov","c,b.7");
3295 pic14_emitcode("subb","a,acc");
3298 aopPut(AOP(result),"a",offset++);
3302 /*-----------------------------------------------------------------*/
3303 /* genDiv - generates code for division */
3304 /*-----------------------------------------------------------------*/
3305 static void genDiv (iCode *ic)
3307 operand *left = IC_LEFT(ic);
3308 operand *right = IC_RIGHT(ic);
3309 operand *result= IC_RESULT(ic);
3311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3312 /* assign the amsops */
3313 aopOp (left,ic,FALSE);
3314 aopOp (right,ic,FALSE);
3315 aopOp (result,ic,TRUE);
3317 /* special cases first */
3319 if (AOP_TYPE(left) == AOP_CRY &&
3320 AOP_TYPE(right)== AOP_CRY) {
3321 genDivbits(left,right,result);
3325 /* if both are of size == 1 */
3326 if (AOP_SIZE(left) == 1 &&
3327 AOP_SIZE(right) == 1 ) {
3328 genDivOneByte(left,right,result);
3332 /* should have been converted to function call */
3335 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3336 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3337 freeAsmop(result,NULL,ic,TRUE);
3340 /*-----------------------------------------------------------------*/
3341 /* genModbits :- modulus of bits */
3342 /*-----------------------------------------------------------------*/
3343 static void genModbits (operand *left,
3350 /* the result must be bit */
3351 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3352 l = aopGet(AOP(left),0,FALSE,FALSE);
3356 pic14_emitcode("div","ab");
3357 pic14_emitcode("mov","a,b");
3358 pic14_emitcode("rrc","a");
3359 aopPut(AOP(result),"c",0);
3362 /*-----------------------------------------------------------------*/
3363 /* genModOneByte : 8 bit modulus */
3364 /*-----------------------------------------------------------------*/
3365 static void genModOneByte (operand *left,
3369 sym_link *opetype = operandType(result);
3373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3374 /* signed or unsigned */
3375 if (SPEC_USIGN(opetype)) {
3376 /* unsigned is easy */
3377 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3378 l = aopGet(AOP(left),0,FALSE,FALSE);
3380 pic14_emitcode("div","ab");
3381 aopPut(AOP(result),"b",0);
3385 /* signed is a little bit more difficult */
3387 /* save the signs of the operands */
3388 l = aopGet(AOP(left),0,FALSE,FALSE);
3391 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3392 pic14_emitcode("push","acc"); /* save it on the stack */
3394 /* now sign adjust for both left & right */
3395 l = aopGet(AOP(right),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));
3403 pic14_emitcode("mov","b,a");
3405 /* sign adjust left side */
3406 l = aopGet(AOP(left),0,FALSE,FALSE);
3409 lbl = newiTempLabel(NULL);
3410 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3411 pic14_emitcode("cpl","a");
3412 pic14_emitcode("inc","a");
3413 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3415 /* now the multiplication */
3416 pic14_emitcode("div","ab");
3417 /* we are interested in the lower order
3419 lbl = newiTempLabel(NULL);
3420 pic14_emitcode("pop","acc");
3421 /* if there was an over flow we don't
3422 adjust the sign of the result */
3423 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3424 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3426 pic14_emitcode("clr","a");
3427 pic14_emitcode("subb","a,b");
3428 pic14_emitcode("mov","b,a");
3429 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3431 /* now we are done */
3432 aopPut(AOP(result),"b",0);
3436 /*-----------------------------------------------------------------*/
3437 /* genMod - generates code for division */
3438 /*-----------------------------------------------------------------*/
3439 static void genMod (iCode *ic)
3441 operand *left = IC_LEFT(ic);
3442 operand *right = IC_RIGHT(ic);
3443 operand *result= IC_RESULT(ic);
3445 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3446 /* assign the amsops */
3447 aopOp (left,ic,FALSE);
3448 aopOp (right,ic,FALSE);
3449 aopOp (result,ic,TRUE);
3451 /* special cases first */
3453 if (AOP_TYPE(left) == AOP_CRY &&
3454 AOP_TYPE(right)== AOP_CRY) {
3455 genModbits(left,right,result);
3459 /* if both are of size == 1 */
3460 if (AOP_SIZE(left) == 1 &&
3461 AOP_SIZE(right) == 1 ) {
3462 genModOneByte(left,right,result);
3466 /* should have been converted to function call */
3470 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3471 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3472 freeAsmop(result,NULL,ic,TRUE);
3475 /*-----------------------------------------------------------------*/
3476 /* genIfxJump :- will create a jump depending on the ifx */
3477 /*-----------------------------------------------------------------*/
3479 note: May need to add parameter to indicate when a variable is in bit space.
3481 static void genIfxJump (iCode *ic, char *jval)
3484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3485 /* if true label then we jump if condition
3487 if ( IC_TRUE(ic) ) {
3489 if(strcmp(jval,"a") == 0)
3491 else if (strcmp(jval,"c") == 0)
3494 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3495 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3498 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3499 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3503 /* false label is present */
3504 if(strcmp(jval,"a") == 0)
3506 else if (strcmp(jval,"c") == 0)
3509 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3510 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3513 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3514 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3519 /* mark the icode as generated */
3523 /*-----------------------------------------------------------------*/
3525 /*-----------------------------------------------------------------*/
3526 static void genSkip(iCode *ifx,int status_bit)
3531 if ( IC_TRUE(ifx) ) {
3532 switch(status_bit) {
3547 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3548 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3552 switch(status_bit) {
3566 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3567 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3573 /*-----------------------------------------------------------------*/
3575 /*-----------------------------------------------------------------*/
3576 static void genSkipc(resolvedIfx *rifx)
3586 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3587 rifx->generated = 1;
3590 /*-----------------------------------------------------------------*/
3592 /*-----------------------------------------------------------------*/
3593 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3598 if( (rifx->condition ^ invert_condition) & 1)
3603 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3604 rifx->generated = 1;
3607 /*-----------------------------------------------------------------*/
3609 /*-----------------------------------------------------------------*/
3610 static void genSkipz(iCode *ifx, int condition)
3621 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3623 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3626 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3628 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3631 /*-----------------------------------------------------------------*/
3633 /*-----------------------------------------------------------------*/
3634 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3640 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3642 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3645 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3646 rifx->generated = 1;
3650 /*-----------------------------------------------------------------*/
3651 /* genChkZeroes :- greater or less than comparison */
3652 /* For each byte in a literal that is zero, inclusive or the */
3653 /* the corresponding byte in the operand with W */
3654 /* returns true if any of the bytes are zero */
3655 /*-----------------------------------------------------------------*/
3656 static int genChkZeroes(operand *op, int lit, int size)
3663 i = (lit >> (size*8)) & 0xff;
3667 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3669 emitpcode(POC_IORFW, popGet(AOP(op),size));
3678 /*-----------------------------------------------------------------*/
3679 /* genCmp :- greater or less than comparison */
3680 /*-----------------------------------------------------------------*/
3681 static void genCmp (operand *left,operand *right,
3682 operand *result, iCode *ifx, int sign)
3684 int size; //, offset = 0 ;
3685 unsigned long lit = 0L,i = 0;
3686 resolvedIfx rFalseIfx;
3687 // resolvedIfx rTrueIfx;
3689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3692 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3693 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3697 resolveIfx(&rFalseIfx,ifx);
3698 truelbl = newiTempLabel(NULL);
3699 size = max(AOP_SIZE(left),AOP_SIZE(right));
3701 DEBUGpic14_AopType(__LINE__,left,right,result);
3705 /* if literal is on the right then swap with left */
3706 if ((AOP_TYPE(right) == AOP_LIT)) {
3707 operand *tmp = right ;
3708 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3709 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3712 lit = (lit - 1) & mask;
3715 rFalseIfx.condition ^= 1;
3718 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3719 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3723 //if(IC_TRUE(ifx) == NULL)
3724 /* if left & right are bit variables */
3725 if (AOP_TYPE(left) == AOP_CRY &&
3726 AOP_TYPE(right) == AOP_CRY ) {
3727 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3728 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3730 /* subtract right from left if at the
3731 end the carry flag is set then we know that
3732 left is greater than right */
3736 symbol *lbl = newiTempLabel(NULL);
3739 if(AOP_TYPE(right) == AOP_LIT) {
3741 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3743 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3750 genSkipCond(&rFalseIfx,left,size-1,7);
3752 /* no need to compare to 0...*/
3753 /* NOTE: this is a de-generate compare that most certainly
3754 * creates some dead code. */
3755 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3757 if(ifx) ifx->generated = 1;
3764 //i = (lit >> (size*8)) & 0xff;
3765 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3767 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3769 i = ((0-lit) & 0xff);
3772 /* lit is 0x7f, all signed chars are less than
3773 * this except for 0x7f itself */
3774 emitpcode(POC_XORLW, popGetLit(0x7f));
3775 genSkipz2(&rFalseIfx,0);
3777 emitpcode(POC_ADDLW, popGetLit(0x80));
3778 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3779 genSkipc(&rFalseIfx);
3784 genSkipz2(&rFalseIfx,1);
3786 emitpcode(POC_ADDLW, popGetLit(i));
3787 genSkipc(&rFalseIfx);
3791 if(ifx) ifx->generated = 1;
3795 /* chars are out of the way. now do ints and longs */
3798 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3805 genSkipCond(&rFalseIfx,left,size,7);
3806 if(ifx) ifx->generated = 1;
3811 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3813 //rFalseIfx.condition ^= 1;
3814 //genSkipCond(&rFalseIfx,left,size,7);
3815 //rFalseIfx.condition ^= 1;
3817 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3818 if(rFalseIfx.condition)
3819 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3821 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3823 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3824 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3825 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3828 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3830 if(rFalseIfx.condition) {
3832 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3838 genSkipc(&rFalseIfx);
3839 emitpLabel(truelbl->key);
3840 if(ifx) ifx->generated = 1;
3847 if( (lit & 0xff) == 0) {
3848 /* lower byte is zero */
3849 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3850 i = ((lit >> 8) & 0xff) ^0x80;
3851 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3852 emitpcode(POC_ADDLW, popGetLit( 0x80));
3853 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3854 genSkipc(&rFalseIfx);
3857 if(ifx) ifx->generated = 1;
3862 /* Special cases for signed longs */
3863 if( (lit & 0xffffff) == 0) {
3864 /* lower byte is zero */
3865 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3866 i = ((lit >> 8*3) & 0xff) ^0x80;
3867 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3868 emitpcode(POC_ADDLW, popGetLit( 0x80));
3869 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3870 genSkipc(&rFalseIfx);
3873 if(ifx) ifx->generated = 1;
3881 if(lit & (0x80 << (size*8))) {
3882 /* lit is negative */
3883 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3885 //genSkipCond(&rFalseIfx,left,size,7);
3887 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3889 if(rFalseIfx.condition)
3890 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3892 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3896 /* lit is positive */
3897 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3898 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3899 if(rFalseIfx.condition)
3900 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3902 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3906 /* There are no more special cases, so perform a general compare */
3908 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3909 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3913 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3915 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3917 //rFalseIfx.condition ^= 1;
3918 genSkipc(&rFalseIfx);
3920 emitpLabel(truelbl->key);
3922 if(ifx) ifx->generated = 1;
3929 /* sign is out of the way. So now do an unsigned compare */
3930 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3933 /* General case - compare to an unsigned literal on the right.*/
3935 i = (lit >> (size*8)) & 0xff;
3936 emitpcode(POC_MOVLW, popGetLit(i));
3937 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3939 i = (lit >> (size*8)) & 0xff;
3942 emitpcode(POC_MOVLW, popGetLit(i));
3944 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3946 /* this byte of the lit is zero,
3947 *if it's not the last then OR in the variable */
3949 emitpcode(POC_IORFW, popGet(AOP(left),size));
3954 emitpLabel(lbl->key);
3955 //if(emitFinalCheck)
3956 genSkipc(&rFalseIfx);
3958 emitpLabel(truelbl->key);
3960 if(ifx) ifx->generated = 1;
3967 if(AOP_TYPE(left) == AOP_LIT) {
3968 //symbol *lbl = newiTempLabel(NULL);
3970 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3973 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3976 if((lit == 0) && (sign == 0)){
3979 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3981 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3983 genSkipz2(&rFalseIfx,0);
3984 if(ifx) ifx->generated = 1;
3991 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3992 /* degenerate compare can never be true */
3993 if(rFalseIfx.condition == 0)
3994 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3996 if(ifx) ifx->generated = 1;
4001 /* signed comparisons to a literal byte */
4003 int lp1 = (lit+1) & 0xff;
4005 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4008 rFalseIfx.condition ^= 1;
4009 genSkipCond(&rFalseIfx,right,0,7);
4012 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4013 emitpcode(POC_XORLW, popGetLit(0x7f));
4014 genSkipz2(&rFalseIfx,1);
4017 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4018 emitpcode(POC_ADDLW, popGetLit(0x80));
4019 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4020 rFalseIfx.condition ^= 1;
4021 genSkipc(&rFalseIfx);
4024 if(ifx) ifx->generated = 1;
4026 /* unsigned comparisons to a literal byte */
4028 switch(lit & 0xff ) {
4030 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4031 genSkipz2(&rFalseIfx,0);
4032 if(ifx) ifx->generated = 1;
4035 genSkipCond(&rFalseIfx,right,0,7);
4036 if(ifx) ifx->generated = 1;
4040 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4041 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4042 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4043 rFalseIfx.condition ^= 1;
4044 if (AOP_TYPE(result) == AOP_CRY) {
4045 genSkipc(&rFalseIfx);
4046 if(ifx) ifx->generated = 1;
4048 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4049 emitpcode(POC_CLRF, popGet(AOP(result),0));
4050 emitpcode(POC_RLF, popGet(AOP(result),0));
4051 emitpcode(POC_MOVLW, popGetLit(0x01));
4052 emitpcode(POC_XORWF, popGet(AOP(result),0));
4063 /* Size is greater than 1 */
4071 /* this means lit = 0xffffffff, or -1 */
4074 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4075 rFalseIfx.condition ^= 1;
4076 genSkipCond(&rFalseIfx,right,size,7);
4077 if(ifx) ifx->generated = 1;
4084 if(rFalseIfx.condition) {
4085 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4086 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4089 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4091 emitpcode(POC_IORFW, popGet(AOP(right),size));
4095 if(rFalseIfx.condition) {
4096 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4097 emitpLabel(truelbl->key);
4099 rFalseIfx.condition ^= 1;
4100 genSkipCond(&rFalseIfx,right,s,7);
4103 if(ifx) ifx->generated = 1;
4107 if((size == 1) && (0 == (lp1&0xff))) {
4108 /* lower byte of signed word is zero */
4109 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4110 i = ((lp1 >> 8) & 0xff) ^0x80;
4111 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4112 emitpcode(POC_ADDLW, popGetLit( 0x80));
4113 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4114 rFalseIfx.condition ^= 1;
4115 genSkipc(&rFalseIfx);
4118 if(ifx) ifx->generated = 1;
4122 if(lit & (0x80 << (size*8))) {
4123 /* Lit is less than zero */
4124 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4125 //rFalseIfx.condition ^= 1;
4126 //genSkipCond(&rFalseIfx,left,size,7);
4127 //rFalseIfx.condition ^= 1;
4128 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4129 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4131 if(rFalseIfx.condition)
4132 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4134 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4138 /* Lit is greater than or equal to zero */
4139 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4140 //rFalseIfx.condition ^= 1;
4141 //genSkipCond(&rFalseIfx,right,size,7);
4142 //rFalseIfx.condition ^= 1;
4144 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4145 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4147 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4148 if(rFalseIfx.condition)
4149 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4151 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4156 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4157 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4161 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4163 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4165 rFalseIfx.condition ^= 1;
4166 //rFalseIfx.condition = 1;
4167 genSkipc(&rFalseIfx);
4169 emitpLabel(truelbl->key);
4171 if(ifx) ifx->generated = 1;
4176 /* compare word or long to an unsigned literal on the right.*/
4181 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4184 break; /* handled above */
4187 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4189 emitpcode(POC_IORFW, popGet(AOP(right),size));
4190 genSkipz2(&rFalseIfx,0);
4194 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4196 emitpcode(POC_IORFW, popGet(AOP(right),size));
4199 if(rFalseIfx.condition)
4200 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4202 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4205 emitpcode(POC_MOVLW, popGetLit(lit+1));
4206 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4208 rFalseIfx.condition ^= 1;
4209 genSkipc(&rFalseIfx);
4212 emitpLabel(truelbl->key);
4214 if(ifx) ifx->generated = 1;
4220 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4221 i = (lit >> (size*8)) & 0xff;
4223 emitpcode(POC_MOVLW, popGetLit(i));
4224 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4227 i = (lit >> (size*8)) & 0xff;
4230 emitpcode(POC_MOVLW, popGetLit(i));
4232 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4234 /* this byte of the lit is zero,
4235 *if it's not the last then OR in the variable */
4237 emitpcode(POC_IORFW, popGet(AOP(right),size));
4242 emitpLabel(lbl->key);
4244 rFalseIfx.condition ^= 1;
4245 genSkipc(&rFalseIfx);
4249 emitpLabel(truelbl->key);
4250 if(ifx) ifx->generated = 1;
4254 /* Compare two variables */
4256 DEBUGpic14_emitcode(";sign","%d",sign);
4260 /* Sigh. thus sucks... */
4262 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4263 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4264 emitpcode(POC_MOVLW, popGetLit(0x80));
4265 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4266 emitpcode(POC_XORFW, popGet(AOP(right),size));
4267 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4269 /* Signed char comparison */
4270 /* Special thanks to Nikolai Golovchenko for this snippet */
4271 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4272 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4273 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4274 emitpcode(POC_XORFW, popGet(AOP(left),0));
4275 emitpcode(POC_XORFW, popGet(AOP(right),0));
4276 emitpcode(POC_ADDLW, popGetLit(0x80));
4278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4279 genSkipc(&rFalseIfx);
4281 if(ifx) ifx->generated = 1;
4287 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4288 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4292 /* The rest of the bytes of a multi-byte compare */
4296 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4299 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4300 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4305 emitpLabel(lbl->key);
4307 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4308 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4309 (AOP_TYPE(result) == AOP_REG)) {
4310 emitpcode(POC_CLRF, popGet(AOP(result),0));
4311 emitpcode(POC_RLF, popGet(AOP(result),0));
4313 genSkipc(&rFalseIfx);
4315 //genSkipc(&rFalseIfx);
4316 if(ifx) ifx->generated = 1;
4323 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4325 pic14_outBitC(result);
4327 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4328 /* if the result is used in the next
4329 ifx conditional branch then generate
4330 code a little differently */
4332 genIfxJump (ifx,"c");
4334 pic14_outBitC(result);
4335 /* leave the result in acc */
4340 /*-----------------------------------------------------------------*/
4341 /* genCmpGt :- greater than comparison */
4342 /*-----------------------------------------------------------------*/
4343 static void genCmpGt (iCode *ic, iCode *ifx)
4345 operand *left, *right, *result;
4346 sym_link *letype , *retype;
4349 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4351 right= IC_RIGHT(ic);
4352 result = IC_RESULT(ic);
4354 letype = getSpec(operandType(left));
4355 retype =getSpec(operandType(right));
4356 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4357 /* assign the amsops */
4358 aopOp (left,ic,FALSE);
4359 aopOp (right,ic,FALSE);
4360 aopOp (result,ic,TRUE);
4362 genCmp(right, left, result, ifx, sign);
4364 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4365 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4366 freeAsmop(result,NULL,ic,TRUE);
4369 /*-----------------------------------------------------------------*/
4370 /* genCmpLt - less than comparisons */
4371 /*-----------------------------------------------------------------*/
4372 static void genCmpLt (iCode *ic, iCode *ifx)
4374 operand *left, *right, *result;
4375 sym_link *letype , *retype;
4378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4380 right= IC_RIGHT(ic);
4381 result = IC_RESULT(ic);
4383 letype = getSpec(operandType(left));
4384 retype =getSpec(operandType(right));
4385 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4387 /* assign the amsops */
4388 aopOp (left,ic,FALSE);
4389 aopOp (right,ic,FALSE);
4390 aopOp (result,ic,TRUE);
4392 genCmp(left, right, result, ifx, sign);
4394 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4395 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4396 freeAsmop(result,NULL,ic,TRUE);
4399 /*-----------------------------------------------------------------*/
4400 /* genc16bit2lit - compare a 16 bit value to a literal */
4401 /*-----------------------------------------------------------------*/
4402 static void genc16bit2lit(operand *op, int lit, int offset)
4406 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4407 if( (lit&0xff) == 0)
4412 switch( BYTEofLONG(lit,i)) {
4414 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4417 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4420 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4423 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4424 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4429 switch( BYTEofLONG(lit,i)) {
4431 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4435 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4439 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4442 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4444 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4450 /*-----------------------------------------------------------------*/
4451 /* gencjneshort - compare and jump if not equal */
4452 /*-----------------------------------------------------------------*/
4453 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4455 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4457 int res_offset = 0; /* the result may be a different size then left or right */
4458 int res_size = AOP_SIZE(result);
4462 unsigned long lit = 0L;
4463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4464 DEBUGpic14_AopType(__LINE__,left,right,result);
4466 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4467 resolveIfx(&rIfx,ifx);
4468 lbl = newiTempLabel(NULL);
4471 /* if the left side is a literal or
4472 if the right is in a pointer register and left
4474 if ((AOP_TYPE(left) == AOP_LIT) ||
4475 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4480 if(AOP_TYPE(right) == AOP_LIT)
4481 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4483 /* if the right side is a literal then anything goes */
4484 if (AOP_TYPE(right) == AOP_LIT &&
4485 AOP_TYPE(left) != AOP_DIR ) {
4488 genc16bit2lit(left, lit, 0);
4490 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4495 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4496 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4498 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4502 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4504 if(res_offset < res_size-1)
4512 /* if the right side is in a register or in direct space or
4513 if the left is a pointer register & right is not */
4514 else if (AOP_TYPE(right) == AOP_REG ||
4515 AOP_TYPE(right) == AOP_DIR ||
4516 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4517 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4518 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4519 int lbl_key = lbl->key;
4522 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4523 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4525 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4526 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4527 __FUNCTION__,__LINE__);
4531 /* switch(size) { */
4533 /* genc16bit2lit(left, lit, 0); */
4535 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4540 if((AOP_TYPE(left) == AOP_DIR) &&
4541 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4543 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4544 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4546 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4548 switch (lit & 0xff) {
4550 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4553 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4554 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4555 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4559 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4560 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4561 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4562 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4566 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4567 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4572 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4575 if(AOP_TYPE(result) == AOP_CRY) {
4576 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4581 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4583 /* fix me. probably need to check result size too */
4584 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4589 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4590 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4597 if(res_offset < res_size-1)
4602 } else if(AOP_TYPE(right) == AOP_REG &&
4603 AOP_TYPE(left) != AOP_DIR){
4606 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4607 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4608 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4613 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4615 if(res_offset < res_size-1)
4620 /* right is a pointer reg need both a & b */
4622 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4624 pic14_emitcode("mov","b,%s",l);
4625 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4626 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4631 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4633 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4635 emitpLabel(lbl->key);
4637 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4644 /*-----------------------------------------------------------------*/
4645 /* gencjne - compare and jump if not equal */
4646 /*-----------------------------------------------------------------*/
4647 static void gencjne(operand *left, operand *right, iCode *ifx)
4649 symbol *tlbl = newiTempLabel(NULL);
4651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4652 gencjneshort(left, right, lbl);
4654 pic14_emitcode("mov","a,%s",one);
4655 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4656 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4657 pic14_emitcode("clr","a");
4658 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4660 emitpLabel(lbl->key);
4661 emitpLabel(tlbl->key);
4666 /*-----------------------------------------------------------------*/
4667 /* genCmpEq - generates code for equal to */
4668 /*-----------------------------------------------------------------*/
4669 static void genCmpEq (iCode *ic, iCode *ifx)
4671 operand *left, *right, *result;
4672 unsigned long lit = 0L;
4675 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4678 DEBUGpic14_emitcode ("; ifx is non-null","");
4680 DEBUGpic14_emitcode ("; ifx is null","");
4682 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4683 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4684 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4686 size = max(AOP_SIZE(left),AOP_SIZE(right));
4688 DEBUGpic14_AopType(__LINE__,left,right,result);
4690 /* if literal, literal on the right or
4691 if the right is in a pointer register and left
4693 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4694 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4695 operand *tmp = right ;
4701 if(ifx && !AOP_SIZE(result)){
4703 /* if they are both bit variables */
4704 if (AOP_TYPE(left) == AOP_CRY &&
4705 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4706 if(AOP_TYPE(right) == AOP_LIT){
4707 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4709 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4710 pic14_emitcode("cpl","c");
4711 } else if(lit == 1L) {
4712 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4714 pic14_emitcode("clr","c");
4716 /* AOP_TYPE(right) == AOP_CRY */
4718 symbol *lbl = newiTempLabel(NULL);
4719 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4720 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4721 pic14_emitcode("cpl","c");
4722 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4724 /* if true label then we jump if condition
4726 tlbl = newiTempLabel(NULL);
4727 if ( IC_TRUE(ifx) ) {
4728 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4729 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4731 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4732 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4734 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4737 /* left and right are both bit variables, result is carry */
4740 resolveIfx(&rIfx,ifx);
4742 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4743 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4744 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4745 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4750 /* They're not both bit variables. Is the right a literal? */
4751 if(AOP_TYPE(right) == AOP_LIT) {
4752 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4757 switch(lit & 0xff) {
4759 if ( IC_TRUE(ifx) ) {
4760 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4762 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4764 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4765 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4769 if ( IC_TRUE(ifx) ) {
4770 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4772 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4774 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4775 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4779 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4781 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4786 /* end of size == 1 */
4790 genc16bit2lit(left,lit,offset);
4793 /* end of size == 2 */
4798 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4799 emitpcode(POC_IORFW,popGet(AOP(left),1));
4800 emitpcode(POC_IORFW,popGet(AOP(left),2));
4801 emitpcode(POC_IORFW,popGet(AOP(left),3));
4805 /* search for patterns that can be optimized */
4807 genc16bit2lit(left,lit,0);
4810 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4812 genc16bit2lit(left,lit,2);
4814 emitpcode(POC_IORFW,popGet(AOP(left),2));
4815 emitpcode(POC_IORFW,popGet(AOP(left),3));
4828 } else if(AOP_TYPE(right) == AOP_CRY ) {
4829 /* we know the left is not a bit, but that the right is */
4830 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4831 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4832 popGet(AOP(right),offset));
4833 emitpcode(POC_XORLW,popGetLit(1));
4835 /* if the two are equal, then W will be 0 and the Z bit is set
4836 * we could test Z now, or go ahead and check the high order bytes if
4837 * the variable we're comparing is larger than a byte. */
4840 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4842 if ( IC_TRUE(ifx) ) {
4844 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4845 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4848 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4849 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4853 /* They're both variables that are larger than bits */
4856 tlbl = newiTempLabel(NULL);
4859 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4860 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4862 if ( IC_TRUE(ifx) ) {
4865 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4866 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4869 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4870 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4874 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4875 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4879 if(s>1 && IC_TRUE(ifx)) {
4880 emitpLabel(tlbl->key);
4881 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4885 /* mark the icode as generated */
4890 /* if they are both bit variables */
4891 if (AOP_TYPE(left) == AOP_CRY &&
4892 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4893 if(AOP_TYPE(right) == AOP_LIT){
4894 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4896 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4897 pic14_emitcode("cpl","c");
4898 } else if(lit == 1L) {
4899 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4901 pic14_emitcode("clr","c");
4903 /* AOP_TYPE(right) == AOP_CRY */
4905 symbol *lbl = newiTempLabel(NULL);
4906 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4907 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4908 pic14_emitcode("cpl","c");
4909 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4912 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4913 pic14_outBitC(result);
4917 genIfxJump (ifx,"c");
4920 /* if the result is used in an arithmetic operation
4921 then put the result in place */
4922 pic14_outBitC(result);
4925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4926 gencjne(left,right,result,ifx);
4929 gencjne(left,right,newiTempLabel(NULL));
4931 if(IC_TRUE(ifx)->key)
4932 gencjne(left,right,IC_TRUE(ifx)->key);
4934 gencjne(left,right,IC_FALSE(ifx)->key);
4938 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4939 aopPut(AOP(result),"a",0);
4944 genIfxJump (ifx,"a");
4948 /* if the result is used in an arithmetic operation
4949 then put the result in place */
4951 if (AOP_TYPE(result) != AOP_CRY)
4952 pic14_outAcc(result);
4954 /* leave the result in acc */
4958 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4959 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4960 freeAsmop(result,NULL,ic,TRUE);
4963 /*-----------------------------------------------------------------*/
4964 /* ifxForOp - returns the icode containing the ifx for operand */
4965 /*-----------------------------------------------------------------*/
4966 static iCode *ifxForOp ( operand *op, iCode *ic )
4968 /* if true symbol then needs to be assigned */
4969 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4970 if (IS_TRUE_SYMOP(op))
4973 /* if this has register type condition and
4974 the next instruction is ifx with the same operand
4975 and live to of the operand is upto the ifx only then */
4977 ic->next->op == IFX &&
4978 IC_COND(ic->next)->key == op->key &&
4979 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4983 ic->next->op == IFX &&
4984 IC_COND(ic->next)->key == op->key) {
4985 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4989 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4991 ic->next->op == IFX)
4992 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4995 ic->next->op == IFX &&
4996 IC_COND(ic->next)->key == op->key) {
4997 DEBUGpic14_emitcode ("; "," key is okay");
4998 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4999 OP_SYMBOL(op)->liveTo,
5006 /*-----------------------------------------------------------------*/
5007 /* genAndOp - for && operation */
5008 /*-----------------------------------------------------------------*/
5009 static void genAndOp (iCode *ic)
5011 operand *left,*right, *result;
5014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5015 /* note here that && operations that are in an
5016 if statement are taken away by backPatchLabels
5017 only those used in arthmetic operations remain */
5018 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5019 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5020 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5022 DEBUGpic14_AopType(__LINE__,left,right,result);
5024 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5025 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5026 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5028 /* if both are bit variables */
5029 /* if (AOP_TYPE(left) == AOP_CRY && */
5030 /* AOP_TYPE(right) == AOP_CRY ) { */
5031 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5032 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5033 /* pic14_outBitC(result); */
5035 /* tlbl = newiTempLabel(NULL); */
5036 /* pic14_toBoolean(left); */
5037 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5038 /* pic14_toBoolean(right); */
5039 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5040 /* pic14_outBitAcc(result); */
5043 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5044 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5045 freeAsmop(result,NULL,ic,TRUE);
5049 /*-----------------------------------------------------------------*/
5050 /* genOrOp - for || operation */
5051 /*-----------------------------------------------------------------*/
5054 modified this code, but it doesn't appear to ever get called
5057 static void genOrOp (iCode *ic)
5059 operand *left,*right, *result;
5062 /* note here that || operations that are in an
5063 if statement are taken away by backPatchLabels
5064 only those used in arthmetic operations remain */
5065 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5066 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5067 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5068 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5070 DEBUGpic14_AopType(__LINE__,left,right,result);
5072 /* if both are bit variables */
5073 if (AOP_TYPE(left) == AOP_CRY &&
5074 AOP_TYPE(right) == AOP_CRY ) {
5075 pic14_emitcode("clrc","");
5076 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5077 AOP(left)->aopu.aop_dir,
5078 AOP(left)->aopu.aop_dir);
5079 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5080 AOP(right)->aopu.aop_dir,
5081 AOP(right)->aopu.aop_dir);
5082 pic14_emitcode("setc","");
5085 tlbl = newiTempLabel(NULL);
5086 pic14_toBoolean(left);
5088 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5089 pic14_toBoolean(right);
5090 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5092 pic14_outBitAcc(result);
5095 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5096 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5097 freeAsmop(result,NULL,ic,TRUE);
5100 /*-----------------------------------------------------------------*/
5101 /* isLiteralBit - test if lit == 2^n */
5102 /*-----------------------------------------------------------------*/
5103 static int isLiteralBit(unsigned long lit)
5105 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5106 0x100L,0x200L,0x400L,0x800L,
5107 0x1000L,0x2000L,0x4000L,0x8000L,
5108 0x10000L,0x20000L,0x40000L,0x80000L,
5109 0x100000L,0x200000L,0x400000L,0x800000L,
5110 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5111 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5115 for(idx = 0; idx < 32; idx++)
5121 /*-----------------------------------------------------------------*/
5122 /* continueIfTrue - */
5123 /*-----------------------------------------------------------------*/
5124 static void continueIfTrue (iCode *ic)
5126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5128 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5132 /*-----------------------------------------------------------------*/
5134 /*-----------------------------------------------------------------*/
5135 static void jumpIfTrue (iCode *ic)
5137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5139 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5143 /*-----------------------------------------------------------------*/
5144 /* jmpTrueOrFalse - */
5145 /*-----------------------------------------------------------------*/
5146 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5148 // ugly but optimized by peephole
5149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5151 symbol *nlbl = newiTempLabel(NULL);
5152 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5153 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5154 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5155 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5158 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5159 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5164 /*-----------------------------------------------------------------*/
5165 /* genAnd - code for and */
5166 /*-----------------------------------------------------------------*/
5167 static void genAnd (iCode *ic, iCode *ifx)
5169 operand *left, *right, *result;
5171 unsigned long lit = 0L;
5176 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5177 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5178 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5179 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5181 resolveIfx(&rIfx,ifx);
5183 /* if left is a literal & right is not then exchange them */
5184 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5185 AOP_NEEDSACC(left)) {
5186 operand *tmp = right ;
5191 /* if result = right then exchange them */
5192 if(pic14_sameRegs(AOP(result),AOP(right))){
5193 operand *tmp = right ;
5198 /* if right is bit then exchange them */
5199 if (AOP_TYPE(right) == AOP_CRY &&
5200 AOP_TYPE(left) != AOP_CRY){
5201 operand *tmp = right ;
5205 if(AOP_TYPE(right) == AOP_LIT)
5206 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5208 size = AOP_SIZE(result);
5210 DEBUGpic14_AopType(__LINE__,left,right,result);
5213 // result = bit & yy;
5214 if (AOP_TYPE(left) == AOP_CRY){
5215 // c = bit & literal;
5216 if(AOP_TYPE(right) == AOP_LIT){
5218 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5221 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5224 if(size && (AOP_TYPE(result) == AOP_CRY)){
5225 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5228 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5232 pic14_emitcode("clr","c");
5235 if (AOP_TYPE(right) == AOP_CRY){
5237 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5238 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5241 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5243 pic14_emitcode("rrc","a");
5244 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5250 pic14_outBitC(result);
5252 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5253 genIfxJump(ifx, "c");
5257 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5258 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5259 if((AOP_TYPE(right) == AOP_LIT) &&
5260 (AOP_TYPE(result) == AOP_CRY) &&
5261 (AOP_TYPE(left) != AOP_CRY)){
5262 int posbit = isLiteralBit(lit);
5266 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5269 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5274 while (posbit > 7) {
5278 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5279 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5280 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5287 symbol *tlbl = newiTempLabel(NULL);
5288 int sizel = AOP_SIZE(left);
5290 pic14_emitcode("setb","c");
5292 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5293 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5295 if((posbit = isLiteralBit(bytelit)) != 0)
5296 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5298 if(bytelit != 0x0FFL)
5299 pic14_emitcode("anl","a,%s",
5300 aopGet(AOP(right),offset,FALSE,TRUE));
5301 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5306 // bit = left & literal
5308 pic14_emitcode("clr","c");
5309 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5311 // if(left & literal)
5314 jmpTrueOrFalse(ifx, tlbl);
5318 pic14_outBitC(result);
5322 /* if left is same as result */
5323 if(pic14_sameRegs(AOP(result),AOP(left))){
5325 for(;size--; offset++,lit>>=8) {
5326 if(AOP_TYPE(right) == AOP_LIT){
5327 switch(lit & 0xff) {
5329 /* and'ing with 0 has clears the result */
5330 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5331 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5334 /* and'ing with 0xff is a nop when the result and left are the same */
5339 int p = my_powof2( (~lit) & 0xff );
5341 /* only one bit is set in the literal, so use a bcf instruction */
5342 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5343 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5346 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5347 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5348 if(know_W != (int)(lit&0xff))
5349 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5351 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5356 if (AOP_TYPE(left) == AOP_ACC) {
5357 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5359 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5360 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5367 // left & result in different registers
5368 if(AOP_TYPE(result) == AOP_CRY){
5370 // if(size), result in bit
5371 // if(!size && ifx), conditional oper: if(left & right)
5372 symbol *tlbl = newiTempLabel(NULL);
5373 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5375 pic14_emitcode("setb","c");
5377 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5378 pic14_emitcode("anl","a,%s",
5379 aopGet(AOP(left),offset,FALSE,FALSE));
5380 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5385 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5386 pic14_outBitC(result);
5388 jmpTrueOrFalse(ifx, tlbl);
5390 for(;(size--);offset++) {
5392 // result = left & right
5393 if(AOP_TYPE(right) == AOP_LIT){
5394 int t = (lit >> (offset*8)) & 0x0FFL;
5397 pic14_emitcode("clrf","%s",
5398 aopGet(AOP(result),offset,FALSE,FALSE));
5399 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5402 if(AOP_TYPE(left) != AOP_ACC) {
5403 pic14_emitcode("movf","%s,w",
5404 aopGet(AOP(left),offset,FALSE,FALSE));
5405 pic14_emitcode("movwf","%s",
5406 aopGet(AOP(result),offset,FALSE,FALSE));
5407 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5409 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5412 if(AOP_TYPE(left) == AOP_ACC) {
5413 emitpcode(POC_ANDLW, popGetLit(t));
5415 pic14_emitcode("movlw","0x%x",t);
5416 pic14_emitcode("andwf","%s,w",
5417 aopGet(AOP(left),offset,FALSE,FALSE));
5418 pic14_emitcode("movwf","%s",
5419 aopGet(AOP(result),offset,FALSE,FALSE));
5421 emitpcode(POC_MOVLW, popGetLit(t));
5422 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5424 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5429 if (AOP_TYPE(left) == AOP_ACC) {
5430 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5431 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5433 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5434 pic14_emitcode("andwf","%s,w",
5435 aopGet(AOP(left),offset,FALSE,FALSE));
5436 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5437 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5439 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5440 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5446 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5447 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5448 freeAsmop(result,NULL,ic,TRUE);
5451 /*-----------------------------------------------------------------*/
5452 /* genOr - code for or */
5453 /*-----------------------------------------------------------------*/
5454 static void genOr (iCode *ic, iCode *ifx)
5456 operand *left, *right, *result;
5458 unsigned long lit = 0L;
5460 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5462 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5463 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5464 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5466 DEBUGpic14_AopType(__LINE__,left,right,result);
5468 /* if left is a literal & right is not then exchange them */
5469 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5470 AOP_NEEDSACC(left)) {
5471 operand *tmp = right ;
5476 /* if result = right then exchange them */
5477 if(pic14_sameRegs(AOP(result),AOP(right))){
5478 operand *tmp = right ;
5483 /* if right is bit then exchange them */
5484 if (AOP_TYPE(right) == AOP_CRY &&
5485 AOP_TYPE(left) != AOP_CRY){
5486 operand *tmp = right ;
5491 DEBUGpic14_AopType(__LINE__,left,right,result);
5493 if(AOP_TYPE(right) == AOP_LIT)
5494 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5496 size = AOP_SIZE(result);
5500 if (AOP_TYPE(left) == AOP_CRY){
5501 if(AOP_TYPE(right) == AOP_LIT){
5502 // c = bit & literal;
5504 // lit != 0 => result = 1
5505 if(AOP_TYPE(result) == AOP_CRY){
5507 emitpcode(POC_BSF, popGet(AOP(result),0));
5508 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5509 // AOP(result)->aopu.aop_dir,
5510 // AOP(result)->aopu.aop_dir);
5512 continueIfTrue(ifx);
5516 // lit == 0 => result = left
5517 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5519 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5522 if (AOP_TYPE(right) == AOP_CRY){
5523 if(pic14_sameRegs(AOP(result),AOP(left))){
5525 emitpcode(POC_BCF, popGet(AOP(result),0));
5526 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5527 emitpcode(POC_BSF, popGet(AOP(result),0));
5529 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5530 AOP(result)->aopu.aop_dir,
5531 AOP(result)->aopu.aop_dir);
5532 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5533 AOP(right)->aopu.aop_dir,
5534 AOP(right)->aopu.aop_dir);
5535 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5536 AOP(result)->aopu.aop_dir,
5537 AOP(result)->aopu.aop_dir);
5539 if( AOP_TYPE(result) == AOP_ACC) {
5540 emitpcode(POC_MOVLW, popGetLit(0));
5541 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5542 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5543 emitpcode(POC_MOVLW, popGetLit(1));
5547 emitpcode(POC_BCF, popGet(AOP(result),0));
5548 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5549 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5550 emitpcode(POC_BSF, popGet(AOP(result),0));
5552 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5553 AOP(result)->aopu.aop_dir,
5554 AOP(result)->aopu.aop_dir);
5555 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5556 AOP(right)->aopu.aop_dir,
5557 AOP(right)->aopu.aop_dir);
5558 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5559 AOP(left)->aopu.aop_dir,
5560 AOP(left)->aopu.aop_dir);
5561 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5562 AOP(result)->aopu.aop_dir,
5563 AOP(result)->aopu.aop_dir);
5568 symbol *tlbl = newiTempLabel(NULL);
5569 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5572 emitpcode(POC_BCF, popGet(AOP(result),0));
5573 if( AOP_TYPE(right) == AOP_ACC) {
5574 emitpcode(POC_IORLW, popGetLit(0));
5576 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5577 emitpcode(POC_BSF, popGet(AOP(result),0));
5582 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5583 pic14_emitcode(";XXX setb","c");
5584 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5585 AOP(left)->aopu.aop_dir,tlbl->key+100);
5586 pic14_toBoolean(right);
5587 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5588 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5589 jmpTrueOrFalse(ifx, tlbl);
5593 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5600 pic14_outBitC(result);
5602 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5603 genIfxJump(ifx, "c");
5607 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5608 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5609 if((AOP_TYPE(right) == AOP_LIT) &&
5610 (AOP_TYPE(result) == AOP_CRY) &&
5611 (AOP_TYPE(left) != AOP_CRY)){
5613 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5616 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5618 continueIfTrue(ifx);
5621 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5622 // lit = 0, result = boolean(left)
5624 pic14_emitcode(";XXX setb","c");
5625 pic14_toBoolean(right);
5627 symbol *tlbl = newiTempLabel(NULL);
5628 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5630 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5632 genIfxJump (ifx,"a");
5636 pic14_outBitC(result);
5640 /* if left is same as result */
5641 if(pic14_sameRegs(AOP(result),AOP(left))){
5643 for(;size--; offset++,lit>>=8) {
5644 if(AOP_TYPE(right) == AOP_LIT){
5645 if((lit & 0xff) == 0)
5646 /* or'ing with 0 has no effect */
5649 int p = my_powof2(lit & 0xff);
5651 /* only one bit is set in the literal, so use a bsf instruction */
5653 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5655 if(know_W != (int)(lit & 0xff))
5656 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5657 know_W = lit & 0xff;
5658 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5663 if (AOP_TYPE(left) == AOP_ACC) {
5664 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5665 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5667 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5668 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5670 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5671 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5677 // left & result in different registers
5678 if(AOP_TYPE(result) == AOP_CRY){
5680 // if(size), result in bit
5681 // if(!size && ifx), conditional oper: if(left | right)
5682 symbol *tlbl = newiTempLabel(NULL);
5683 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5684 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5688 pic14_emitcode(";XXX setb","c");
5690 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5691 pic14_emitcode(";XXX orl","a,%s",
5692 aopGet(AOP(left),offset,FALSE,FALSE));
5693 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5698 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5699 pic14_outBitC(result);
5701 jmpTrueOrFalse(ifx, tlbl);
5702 } else for(;(size--);offset++){
5704 // result = left & right
5705 if(AOP_TYPE(right) == AOP_LIT){
5706 int t = (lit >> (offset*8)) & 0x0FFL;
5709 if (AOP_TYPE(left) != AOP_ACC) {
5710 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5712 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5716 if (AOP_TYPE(left) == AOP_ACC) {
5717 emitpcode(POC_IORLW, popGetLit(t));
5719 emitpcode(POC_MOVLW, popGetLit(t));
5720 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5722 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5727 // faster than result <- left, anl result,right
5728 // and better if result is SFR
5729 if (AOP_TYPE(left) == AOP_ACC) {
5730 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5731 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5733 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5734 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5736 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5737 pic14_emitcode("iorwf","%s,w",
5738 aopGet(AOP(left),offset,FALSE,FALSE));
5740 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5741 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5746 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5747 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5748 freeAsmop(result,NULL,ic,TRUE);
5751 /*-----------------------------------------------------------------*/
5752 /* genXor - code for xclusive or */
5753 /*-----------------------------------------------------------------*/
5754 static void genXor (iCode *ic, iCode *ifx)
5756 operand *left, *right, *result;
5758 unsigned long lit = 0L;
5760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5762 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5763 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5764 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5766 /* if left is a literal & right is not ||
5767 if left needs acc & right does not */
5768 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5769 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5770 operand *tmp = right ;
5775 /* if result = right then exchange them */
5776 if(pic14_sameRegs(AOP(result),AOP(right))){
5777 operand *tmp = right ;
5782 /* if right is bit then exchange them */
5783 if (AOP_TYPE(right) == AOP_CRY &&
5784 AOP_TYPE(left) != AOP_CRY){
5785 operand *tmp = right ;
5789 if(AOP_TYPE(right) == AOP_LIT)
5790 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5792 size = AOP_SIZE(result);
5796 if (AOP_TYPE(left) == AOP_CRY){
5797 if(AOP_TYPE(right) == AOP_LIT){
5798 // c = bit & literal;
5800 // lit>>1 != 0 => result = 1
5801 if(AOP_TYPE(result) == AOP_CRY){
5803 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5804 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5806 continueIfTrue(ifx);
5809 pic14_emitcode("setb","c");
5813 // lit == 0, result = left
5814 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5816 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5818 // lit == 1, result = not(left)
5819 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5820 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5821 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5822 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5825 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5826 pic14_emitcode("cpl","c");
5833 symbol *tlbl = newiTempLabel(NULL);
5834 if (AOP_TYPE(right) == AOP_CRY){
5836 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5839 int sizer = AOP_SIZE(right);
5841 // if val>>1 != 0, result = 1
5842 pic14_emitcode("setb","c");
5844 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5846 // test the msb of the lsb
5847 pic14_emitcode("anl","a,#0xfe");
5848 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5852 pic14_emitcode("rrc","a");
5854 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5855 pic14_emitcode("cpl","c");
5856 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5861 pic14_outBitC(result);
5863 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5864 genIfxJump(ifx, "c");
5868 if(pic14_sameRegs(AOP(result),AOP(left))){
5869 /* if left is same as result */
5870 for(;size--; offset++) {
5871 if(AOP_TYPE(right) == AOP_LIT){
5872 int t = (lit >> (offset*8)) & 0x0FFL;
5876 if (IS_AOP_PREG(left)) {
5877 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5878 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5879 aopPut(AOP(result),"a",offset);
5881 emitpcode(POC_MOVLW, popGetLit(t));
5882 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5883 pic14_emitcode("xrl","%s,%s",
5884 aopGet(AOP(left),offset,FALSE,TRUE),
5885 aopGet(AOP(right),offset,FALSE,FALSE));
5888 if (AOP_TYPE(left) == AOP_ACC)
5889 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5891 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5892 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5894 if (IS_AOP_PREG(left)) {
5895 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5896 aopPut(AOP(result),"a",offset);
5898 pic14_emitcode("xrl","%s,a",
5899 aopGet(AOP(left),offset,FALSE,TRUE));
5905 // left & result in different registers
5906 if(AOP_TYPE(result) == AOP_CRY){
5908 // if(size), result in bit
5909 // if(!size && ifx), conditional oper: if(left ^ right)
5910 symbol *tlbl = newiTempLabel(NULL);
5911 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5913 pic14_emitcode("setb","c");
5915 if((AOP_TYPE(right) == AOP_LIT) &&
5916 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5917 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5919 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5920 pic14_emitcode("xrl","a,%s",
5921 aopGet(AOP(left),offset,FALSE,FALSE));
5923 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5928 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5929 pic14_outBitC(result);
5931 jmpTrueOrFalse(ifx, tlbl);
5932 } else for(;(size--);offset++){
5934 // result = left & right
5935 if(AOP_TYPE(right) == AOP_LIT){
5936 int t = (lit >> (offset*8)) & 0x0FFL;
5939 if (AOP_TYPE(left) != AOP_ACC) {
5940 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5942 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5943 pic14_emitcode("movf","%s,w",
5944 aopGet(AOP(left),offset,FALSE,FALSE));
5945 pic14_emitcode("movwf","%s",
5946 aopGet(AOP(result),offset,FALSE,FALSE));
5949 if (AOP_TYPE(left) == AOP_ACC) {
5950 emitpcode(POC_XORLW, popGetLit(t));
5952 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5954 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5957 if (AOP_TYPE(left) == AOP_ACC) {
5958 emitpcode(POC_XORLW, popGetLit(t));
5960 emitpcode(POC_MOVLW, popGetLit(t));
5961 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5963 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5964 pic14_emitcode("movlw","0x%x",t);
5965 pic14_emitcode("xorwf","%s,w",
5966 aopGet(AOP(left),offset,FALSE,FALSE));
5967 pic14_emitcode("movwf","%s",
5968 aopGet(AOP(result),offset,FALSE,FALSE));
5974 // faster than result <- left, anl result,right
5975 // and better if result is SFR
5976 if (AOP_TYPE(left) == AOP_ACC) {
5977 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5978 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5980 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5981 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5982 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5983 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5985 if ( AOP_TYPE(result) != AOP_ACC){
5986 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5987 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5993 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5994 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5995 freeAsmop(result,NULL,ic,TRUE);
5998 /*-----------------------------------------------------------------*/
5999 /* genInline - write the inline code out */
6000 /*-----------------------------------------------------------------*/
6001 static void genInline (iCode *ic)
6003 char *buffer, *bp, *bp1;
6005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6007 _G.inLine += (!options.asmpeep);
6009 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6010 strcpy(buffer,IC_INLINE(ic));
6012 /* emit each line as a code */
6018 addpCode2pBlock(pb,AssembleLine(bp1));
6025 pic14_emitcode(bp1,"");
6031 if ((bp1 != bp) && *bp1)
6032 addpCode2pBlock(pb,AssembleLine(bp1));
6036 _G.inLine -= (!options.asmpeep);
6039 /*-----------------------------------------------------------------*/
6040 /* genRRC - rotate right with carry */
6041 /*-----------------------------------------------------------------*/
6042 static void genRRC (iCode *ic)
6044 operand *left , *result ;
6045 int size, offset = 0, same;
6047 /* rotate right with carry */
6049 result=IC_RESULT(ic);
6050 aopOp (left,ic,FALSE);
6051 aopOp (result,ic,FALSE);
6053 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6055 same = pic14_sameRegs(AOP(result),AOP(left));
6057 size = AOP_SIZE(result);
6059 /* get the lsb and put it into the carry */
6060 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6067 emitpcode(POC_RRF, popGet(AOP(left),offset));
6069 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6070 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6076 freeAsmop(left,NULL,ic,TRUE);
6077 freeAsmop(result,NULL,ic,TRUE);
6080 /*-----------------------------------------------------------------*/
6081 /* genRLC - generate code for rotate left with carry */
6082 /*-----------------------------------------------------------------*/
6083 static void genRLC (iCode *ic)
6085 operand *left , *result ;
6086 int size, offset = 0;
6089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6090 /* rotate right with carry */
6092 result=IC_RESULT(ic);
6093 aopOp (left,ic,FALSE);
6094 aopOp (result,ic,FALSE);
6096 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6098 same = pic14_sameRegs(AOP(result),AOP(left));
6100 /* move it to the result */
6101 size = AOP_SIZE(result);
6103 /* get the msb and put it into the carry */
6104 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6111 emitpcode(POC_RLF, popGet(AOP(left),offset));
6113 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6114 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6121 freeAsmop(left,NULL,ic,TRUE);
6122 freeAsmop(result,NULL,ic,TRUE);
6125 /*-----------------------------------------------------------------*/
6126 /* genGetHbit - generates code get highest order bit */
6127 /*-----------------------------------------------------------------*/
6128 static void genGetHbit (iCode *ic)
6130 operand *left, *result;
6132 result=IC_RESULT(ic);
6133 aopOp (left,ic,FALSE);
6134 aopOp (result,ic,FALSE);
6136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6137 /* get the highest order byte into a */
6138 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6139 if(AOP_TYPE(result) == AOP_CRY){
6140 pic14_emitcode("rlc","a");
6141 pic14_outBitC(result);
6144 pic14_emitcode("rl","a");
6145 pic14_emitcode("anl","a,#0x01");
6146 pic14_outAcc(result);
6150 freeAsmop(left,NULL,ic,TRUE);
6151 freeAsmop(result,NULL,ic,TRUE);
6154 /*-----------------------------------------------------------------*/
6155 /* AccRol - rotate left accumulator by known count */
6156 /*-----------------------------------------------------------------*/
6157 static void AccRol (int shCount)
6159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6160 shCount &= 0x0007; // shCount : 0..7
6165 pic14_emitcode("rl","a");
6168 pic14_emitcode("rl","a");
6169 pic14_emitcode("rl","a");
6172 pic14_emitcode("swap","a");
6173 pic14_emitcode("rr","a");
6176 pic14_emitcode("swap","a");
6179 pic14_emitcode("swap","a");
6180 pic14_emitcode("rl","a");
6183 pic14_emitcode("rr","a");
6184 pic14_emitcode("rr","a");
6187 pic14_emitcode("rr","a");
6192 /*-----------------------------------------------------------------*/
6193 /* AccLsh - left shift accumulator by known count */
6194 /*-----------------------------------------------------------------*/
6195 static void AccLsh (int shCount)
6197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6200 pic14_emitcode("add","a,acc");
6203 pic14_emitcode("add","a,acc");
6204 pic14_emitcode("add","a,acc");
6206 /* rotate left accumulator */
6208 /* and kill the lower order bits */
6209 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6214 /*-----------------------------------------------------------------*/
6215 /* AccRsh - right shift accumulator by known count */
6216 /*-----------------------------------------------------------------*/
6217 static void AccRsh (int shCount)
6219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6223 pic14_emitcode("rrc","a");
6225 /* rotate right accumulator */
6226 AccRol(8 - shCount);
6227 /* and kill the higher order bits */
6228 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6234 /*-----------------------------------------------------------------*/
6235 /* AccSRsh - signed right shift accumulator by known count */
6236 /*-----------------------------------------------------------------*/
6237 static void AccSRsh (int shCount)
6240 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6243 pic14_emitcode("mov","c,acc.7");
6244 pic14_emitcode("rrc","a");
6245 } else if(shCount == 2){
6246 pic14_emitcode("mov","c,acc.7");
6247 pic14_emitcode("rrc","a");
6248 pic14_emitcode("mov","c,acc.7");
6249 pic14_emitcode("rrc","a");
6251 tlbl = newiTempLabel(NULL);
6252 /* rotate right accumulator */
6253 AccRol(8 - shCount);
6254 /* and kill the higher order bits */
6255 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6256 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6257 pic14_emitcode("orl","a,#0x%02x",
6258 (unsigned char)~SRMask[shCount]);
6259 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6264 /*-----------------------------------------------------------------*/
6265 /* shiftR1Left2Result - shift right one byte from left to result */
6266 /*-----------------------------------------------------------------*/
6267 static void shiftR1Left2ResultSigned (operand *left, int offl,
6268 operand *result, int offr,
6273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6275 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6279 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6281 emitpcode(POC_RRF, popGet(AOP(result),offr));
6283 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6284 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6290 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6292 emitpcode(POC_RRF, popGet(AOP(result),offr));
6294 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6295 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6297 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6298 emitpcode(POC_RRF, popGet(AOP(result),offr));
6304 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6306 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6307 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6310 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6311 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6312 emitpcode(POC_ANDLW, popGetLit(0x1f));
6314 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6315 emitpcode(POC_IORLW, popGetLit(0xe0));
6317 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6321 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6322 emitpcode(POC_ANDLW, popGetLit(0x0f));
6323 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6324 emitpcode(POC_IORLW, popGetLit(0xf0));
6325 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6329 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6331 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6332 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6334 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6335 emitpcode(POC_ANDLW, popGetLit(0x07));
6336 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6337 emitpcode(POC_IORLW, popGetLit(0xf8));
6338 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6343 emitpcode(POC_MOVLW, popGetLit(0x00));
6344 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6345 emitpcode(POC_MOVLW, popGetLit(0xfe));
6346 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6347 emitpcode(POC_IORLW, popGetLit(0x01));
6348 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6350 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6351 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6352 emitpcode(POC_DECF, popGet(AOP(result),offr));
6353 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6354 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6360 emitpcode(POC_MOVLW, popGetLit(0x00));
6361 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6362 emitpcode(POC_MOVLW, popGetLit(0xff));
6363 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6365 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6366 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6367 emitpcode(POC_DECF, popGet(AOP(result),offr));
6375 /*-----------------------------------------------------------------*/
6376 /* shiftR1Left2Result - shift right one byte from left to result */
6377 /*-----------------------------------------------------------------*/
6378 static void shiftR1Left2Result (operand *left, int offl,
6379 operand *result, int offr,
6380 int shCount, int sign)
6384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6386 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6388 /* Copy the msb into the carry if signed. */
6390 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6400 emitpcode(POC_RRF, popGet(AOP(result),offr));
6402 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6403 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6409 emitpcode(POC_RRF, popGet(AOP(result),offr));
6411 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6412 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415 emitpcode(POC_RRF, popGet(AOP(result),offr));
6420 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6422 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6423 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6426 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6427 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6428 emitpcode(POC_ANDLW, popGetLit(0x1f));
6429 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6433 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6434 emitpcode(POC_ANDLW, popGetLit(0x0f));
6435 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6439 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6440 emitpcode(POC_ANDLW, popGetLit(0x0f));
6441 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6443 emitpcode(POC_RRF, popGet(AOP(result),offr));
6448 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6449 emitpcode(POC_ANDLW, popGetLit(0x80));
6450 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6451 emitpcode(POC_RLF, popGet(AOP(result),offr));
6452 emitpcode(POC_RLF, popGet(AOP(result),offr));
6457 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6458 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6459 emitpcode(POC_RLF, popGet(AOP(result),offr));
6468 /*-----------------------------------------------------------------*/
6469 /* shiftL1Left2Result - shift left one byte from left to result */
6470 /*-----------------------------------------------------------------*/
6471 static void shiftL1Left2Result (operand *left, int offl,
6472 operand *result, int offr, int shCount)
6477 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6479 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6480 DEBUGpic14_emitcode ("; ***","same = %d",same);
6481 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6483 /* shift left accumulator */
6484 //AccLsh(shCount); // don't comment out just yet...
6485 // aopPut(AOP(result),"a",offr);
6489 /* Shift left 1 bit position */
6490 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6492 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6494 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6495 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6499 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6500 emitpcode(POC_ANDLW,popGetLit(0x7e));
6501 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6502 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6505 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6506 emitpcode(POC_ANDLW,popGetLit(0x3e));
6507 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6508 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6509 emitpcode(POC_RLF, popGet(AOP(result),offr));
6512 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6513 emitpcode(POC_ANDLW, popGetLit(0xf0));
6514 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6517 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6518 emitpcode(POC_ANDLW, popGetLit(0xf0));
6519 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6520 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6523 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6524 emitpcode(POC_ANDLW, popGetLit(0x30));
6525 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6526 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6527 emitpcode(POC_RLF, popGet(AOP(result),offr));
6530 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6531 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6532 emitpcode(POC_RRF, popGet(AOP(result),offr));
6536 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6541 /*-----------------------------------------------------------------*/
6542 /* movLeft2Result - move byte from left to result */
6543 /*-----------------------------------------------------------------*/
6544 static void movLeft2Result (operand *left, int offl,
6545 operand *result, int offr)
6548 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6549 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6550 l = aopGet(AOP(left),offl,FALSE,FALSE);
6552 if (*l == '@' && (IS_AOP_PREG(result))) {
6553 pic14_emitcode("mov","a,%s",l);
6554 aopPut(AOP(result),"a",offr);
6556 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6557 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6562 /*-----------------------------------------------------------------*/
6563 /* shiftL2Left2Result - shift left two bytes from left to result */
6564 /*-----------------------------------------------------------------*/
6565 static void shiftL2Left2Result (operand *left, int offl,
6566 operand *result, int offr, int shCount)
6570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6572 if(pic14_sameRegs(AOP(result), AOP(left))) {
6580 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6581 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6582 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6586 emitpcode(POC_RLF, popGet(AOP(result),offr));
6587 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6593 emitpcode(POC_MOVLW, popGetLit(0x0f));
6594 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6595 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6596 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6597 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6598 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6599 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_RLF, popGet(AOP(result),offr));
6602 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6607 emitpcode(POC_RRF, popGet(AOP(result),offr));
6608 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6609 emitpcode(POC_RRF, popGet(AOP(result),offr));
6610 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6611 emitpcode(POC_ANDLW,popGetLit(0xc0));
6612 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6613 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6614 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6615 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6619 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6620 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6621 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6622 emitpcode(POC_RRF, popGet(AOP(result),offr));
6632 /* note, use a mov/add for the shift since the mov has a
6633 chance of getting optimized out */
6634 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6635 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6636 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6637 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6638 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6642 emitpcode(POC_RLF, popGet(AOP(result),offr));
6643 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6650 emitpcode(POC_ANDLW, popGetLit(0xF0));
6651 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6652 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6653 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6654 emitpcode(POC_ANDLW, popGetLit(0xF0));
6655 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6656 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6660 emitpcode(POC_RLF, popGet(AOP(result),offr));
6661 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6665 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6666 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6668 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6670 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6671 emitpcode(POC_RRF, popGet(AOP(result),offr));
6672 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6673 emitpcode(POC_ANDLW,popGetLit(0xc0));
6674 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6675 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6676 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6677 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6681 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6682 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6684 emitpcode(POC_RRF, popGet(AOP(result),offr));
6689 /*-----------------------------------------------------------------*/
6690 /* shiftR2Left2Result - shift right two bytes from left to result */
6691 /*-----------------------------------------------------------------*/
6692 static void shiftR2Left2Result (operand *left, int offl,
6693 operand *result, int offr,
6694 int shCount, int sign)
6698 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6699 same = pic14_sameRegs(AOP(result), AOP(left));
6701 if(same && ((offl + MSB16) == offr)){
6703 /* don't crash result[offr] */
6704 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6705 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6708 movLeft2Result(left,offl, result, offr);
6709 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6712 /* a:x >> shCount (x = lsb(result))*/
6715 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6717 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6726 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6731 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6732 emitpcode(POC_RRF,popGet(AOP(result),offr));
6734 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6735 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6737 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6742 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6745 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_RRF,popGet(AOP(result),offr));
6753 emitpcode(POC_MOVLW, popGetLit(0xf0));
6754 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6755 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6757 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6759 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6760 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6762 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6763 emitpcode(POC_ANDLW, popGetLit(0x0f));
6764 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6766 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6767 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6768 emitpcode(POC_ANDLW, popGetLit(0xf0));
6769 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6770 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6774 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_RRF, popGet(AOP(result),offr));
6779 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6780 emitpcode(POC_BTFSC,
6781 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6782 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6790 emitpcode(POC_RLF, popGet(AOP(result),offr));
6791 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6793 emitpcode(POC_RLF, popGet(AOP(result),offr));
6794 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6796 emitpcode(POC_ANDLW,popGetLit(0x03));
6798 emitpcode(POC_BTFSC,
6799 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6800 emitpcode(POC_IORLW,popGetLit(0xfc));
6802 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6804 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6805 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6807 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6808 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6811 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6812 emitpcode(POC_RLF, popGet(AOP(result),offr));
6813 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6814 emitpcode(POC_ANDLW,popGetLit(0x03));
6816 emitpcode(POC_BTFSC,
6817 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6818 emitpcode(POC_IORLW,popGetLit(0xfc));
6820 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6821 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6828 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6829 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6830 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6831 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6834 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6836 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6841 /*-----------------------------------------------------------------*/
6842 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6843 /*-----------------------------------------------------------------*/
6844 static void shiftLLeftOrResult (operand *left, int offl,
6845 operand *result, int offr, int shCount)
6847 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6848 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6849 /* shift left accumulator */
6851 /* or with result */
6852 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6853 /* back to result */
6854 aopPut(AOP(result),"a",offr);
6857 /*-----------------------------------------------------------------*/
6858 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6859 /*-----------------------------------------------------------------*/
6860 static void shiftRLeftOrResult (operand *left, int offl,
6861 operand *result, int offr, int shCount)
6863 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6864 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6865 /* shift right accumulator */
6867 /* or with result */
6868 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6869 /* back to result */
6870 aopPut(AOP(result),"a",offr);
6873 /*-----------------------------------------------------------------*/
6874 /* genlshOne - left shift a one byte quantity by known count */
6875 /*-----------------------------------------------------------------*/
6876 static void genlshOne (operand *result, operand *left, int shCount)
6878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6879 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6882 /*-----------------------------------------------------------------*/
6883 /* genlshTwo - left shift two bytes by known amount != 0 */
6884 /*-----------------------------------------------------------------*/
6885 static void genlshTwo (operand *result,operand *left, int shCount)
6889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6890 size = pic14_getDataSize(result);
6892 /* if shCount >= 8 */
6898 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6900 movLeft2Result(left, LSB, result, MSB16);
6902 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6905 /* 1 <= shCount <= 7 */
6908 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6910 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6914 /*-----------------------------------------------------------------*/
6915 /* shiftLLong - shift left one long from left to result */
6916 /* offl = LSB or MSB16 */
6917 /*-----------------------------------------------------------------*/
6918 static void shiftLLong (operand *left, operand *result, int offr )
6921 int size = AOP_SIZE(result);
6923 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6924 if(size >= LSB+offr){
6925 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6927 pic14_emitcode("add","a,acc");
6928 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6929 size >= MSB16+offr && offr != LSB )
6930 pic14_emitcode("xch","a,%s",
6931 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6933 aopPut(AOP(result),"a",LSB+offr);
6936 if(size >= MSB16+offr){
6937 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6938 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6941 pic14_emitcode("rlc","a");
6942 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6943 size >= MSB24+offr && offr != LSB)
6944 pic14_emitcode("xch","a,%s",
6945 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6947 aopPut(AOP(result),"a",MSB16+offr);
6950 if(size >= MSB24+offr){
6951 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6952 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6955 pic14_emitcode("rlc","a");
6956 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6957 size >= MSB32+offr && offr != LSB )
6958 pic14_emitcode("xch","a,%s",
6959 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6961 aopPut(AOP(result),"a",MSB24+offr);
6964 if(size > MSB32+offr){
6965 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6966 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6969 pic14_emitcode("rlc","a");
6970 aopPut(AOP(result),"a",MSB32+offr);
6973 aopPut(AOP(result),zero,LSB);
6976 /*-----------------------------------------------------------------*/
6977 /* genlshFour - shift four byte by a known amount != 0 */
6978 /*-----------------------------------------------------------------*/
6979 static void genlshFour (operand *result, operand *left, int shCount)
6983 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6984 size = AOP_SIZE(result);
6986 /* if shifting more that 3 bytes */
6987 if (shCount >= 24 ) {
6990 /* lowest order of left goes to the highest
6991 order of the destination */
6992 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6994 movLeft2Result(left, LSB, result, MSB32);
6995 aopPut(AOP(result),zero,LSB);
6996 aopPut(AOP(result),zero,MSB16);
6997 aopPut(AOP(result),zero,MSB32);
7001 /* more than two bytes */
7002 else if ( shCount >= 16 ) {
7003 /* lower order two bytes goes to higher order two bytes */
7005 /* if some more remaining */
7007 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7009 movLeft2Result(left, MSB16, result, MSB32);
7010 movLeft2Result(left, LSB, result, MSB24);
7012 aopPut(AOP(result),zero,MSB16);
7013 aopPut(AOP(result),zero,LSB);
7017 /* if more than 1 byte */
7018 else if ( shCount >= 8 ) {
7019 /* lower order three bytes goes to higher order three bytes */
7023 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7025 movLeft2Result(left, LSB, result, MSB16);
7027 else{ /* size = 4 */
7029 movLeft2Result(left, MSB24, result, MSB32);
7030 movLeft2Result(left, MSB16, result, MSB24);
7031 movLeft2Result(left, LSB, result, MSB16);
7032 aopPut(AOP(result),zero,LSB);
7034 else if(shCount == 1)
7035 shiftLLong(left, result, MSB16);
7037 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7038 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7039 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7040 aopPut(AOP(result),zero,LSB);
7045 /* 1 <= shCount <= 7 */
7046 else if(shCount <= 2){
7047 shiftLLong(left, result, LSB);
7049 shiftLLong(result, result, LSB);
7051 /* 3 <= shCount <= 7, optimize */
7053 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7054 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7055 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7059 /*-----------------------------------------------------------------*/
7060 /* genLeftShiftLiteral - left shifting by known count */
7061 /*-----------------------------------------------------------------*/
7062 static void genLeftShiftLiteral (operand *left,
7067 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7071 freeAsmop(right,NULL,ic,TRUE);
7073 aopOp(left,ic,FALSE);
7074 aopOp(result,ic,FALSE);
7076 size = getSize(operandType(result));
7079 pic14_emitcode("; shift left ","result %d, left %d",size,
7083 /* I suppose that the left size >= result size */
7086 movLeft2Result(left, size, result, size);
7090 else if(shCount >= (size * 8))
7092 aopPut(AOP(result),zero,size);
7096 genlshOne (result,left,shCount);
7101 genlshTwo (result,left,shCount);
7105 genlshFour (result,left,shCount);
7109 freeAsmop(left,NULL,ic,TRUE);
7110 freeAsmop(result,NULL,ic,TRUE);
7113 /*-----------------------------------------------------------------*
7114 * genMultiAsm - repeat assembly instruction for size of register.
7115 * if endian == 1, then the high byte (i.e base address + size of
7116 * register) is used first else the low byte is used first;
7117 *-----------------------------------------------------------------*/
7118 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7136 emitpcode(poc, popGet(AOP(reg),offset));
7141 /*-----------------------------------------------------------------*/
7142 /* genLeftShift - generates code for left shifting */
7143 /*-----------------------------------------------------------------*/
7144 static void genLeftShift (iCode *ic)
7146 operand *left,*right, *result;
7149 symbol *tlbl , *tlbl1;
7152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7154 right = IC_RIGHT(ic);
7156 result = IC_RESULT(ic);
7158 aopOp(right,ic,FALSE);
7160 /* if the shift count is known then do it
7161 as efficiently as possible */
7162 if (AOP_TYPE(right) == AOP_LIT) {
7163 genLeftShiftLiteral (left,right,result,ic);
7167 /* shift count is unknown then we have to form
7168 a loop get the loop count in B : Note: we take
7169 only the lower order byte since shifting
7170 more that 32 bits make no sense anyway, ( the
7171 largest size of an object can be only 32 bits ) */
7174 aopOp(left,ic,FALSE);
7175 aopOp(result,ic,FALSE);
7177 /* now move the left to the result if they are not the
7179 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7180 AOP_SIZE(result) > 1) {
7182 size = AOP_SIZE(result);
7185 l = aopGet(AOP(left),offset,FALSE,TRUE);
7186 if (*l == '@' && (IS_AOP_PREG(result))) {
7188 pic14_emitcode("mov","a,%s",l);
7189 aopPut(AOP(result),"a",offset);
7191 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7192 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7193 //aopPut(AOP(result),l,offset);
7199 size = AOP_SIZE(result);
7201 /* if it is only one byte then */
7203 if(optimized_for_speed) {
7204 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7205 emitpcode(POC_ANDLW, popGetLit(0xf0));
7206 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7207 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7208 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7209 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7210 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7211 emitpcode(POC_RLFW, popGet(AOP(result),0));
7212 emitpcode(POC_ANDLW, popGetLit(0xfe));
7213 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7214 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7215 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7218 tlbl = newiTempLabel(NULL);
7219 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7220 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7221 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7224 emitpcode(POC_COMFW, popGet(AOP(right),0));
7225 emitpcode(POC_RRF, popGet(AOP(result),0));
7226 emitpLabel(tlbl->key);
7227 emitpcode(POC_RLF, popGet(AOP(result),0));
7228 emitpcode(POC_ADDLW, popGetLit(1));
7230 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7235 if (pic14_sameRegs(AOP(left),AOP(result))) {
7237 tlbl = newiTempLabel(NULL);
7238 emitpcode(POC_COMFW, popGet(AOP(right),0));
7239 genMultiAsm(POC_RRF, result, size,1);
7240 emitpLabel(tlbl->key);
7241 genMultiAsm(POC_RLF, result, size,0);
7242 emitpcode(POC_ADDLW, popGetLit(1));
7244 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7248 //tlbl = newiTempLabel(NULL);
7250 //tlbl1 = newiTempLabel(NULL);
7252 //reAdjustPreg(AOP(result));
7254 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7255 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7256 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7258 //pic14_emitcode("add","a,acc");
7259 //aopPut(AOP(result),"a",offset++);
7261 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7263 // pic14_emitcode("rlc","a");
7264 // aopPut(AOP(result),"a",offset++);
7266 //reAdjustPreg(AOP(result));
7268 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7269 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7272 tlbl = newiTempLabel(NULL);
7273 tlbl1= newiTempLabel(NULL);
7275 size = AOP_SIZE(result);
7278 pctemp = popGetTempReg(); /* grab a temporary working register. */
7280 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7282 /* offset should be 0, 1 or 3 */
7283 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7285 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7287 emitpcode(POC_MOVWF, pctemp);
7290 emitpLabel(tlbl->key);
7293 emitpcode(POC_RLF, popGet(AOP(result),0));
7295 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7297 emitpcode(POC_DECFSZ, pctemp);
7298 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7299 emitpLabel(tlbl1->key);
7301 popReleaseTempReg(pctemp);
7305 freeAsmop (right,NULL,ic,TRUE);
7306 freeAsmop(left,NULL,ic,TRUE);
7307 freeAsmop(result,NULL,ic,TRUE);
7310 /*-----------------------------------------------------------------*/
7311 /* genrshOne - right shift a one byte quantity by known count */
7312 /*-----------------------------------------------------------------*/
7313 static void genrshOne (operand *result, operand *left,
7314 int shCount, int sign)
7316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7317 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7320 /*-----------------------------------------------------------------*/
7321 /* genrshTwo - right shift two bytes by known amount != 0 */
7322 /*-----------------------------------------------------------------*/
7323 static void genrshTwo (operand *result,operand *left,
7324 int shCount, int sign)
7326 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7327 /* if shCount >= 8 */
7331 shiftR1Left2Result(left, MSB16, result, LSB,
7334 movLeft2Result(left, MSB16, result, LSB);
7336 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7339 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7340 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7344 /* 1 <= shCount <= 7 */
7346 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7349 /*-----------------------------------------------------------------*/
7350 /* shiftRLong - shift right one long from left to result */
7351 /* offl = LSB or MSB16 */
7352 /*-----------------------------------------------------------------*/
7353 static void shiftRLong (operand *left, int offl,
7354 operand *result, int sign)
7356 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7358 pic14_emitcode("clr","c");
7359 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7361 pic14_emitcode("mov","c,acc.7");
7362 pic14_emitcode("rrc","a");
7363 aopPut(AOP(result),"a",MSB32-offl);
7365 /* add sign of "a" */
7366 addSign(result, MSB32, sign);
7368 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7369 pic14_emitcode("rrc","a");
7370 aopPut(AOP(result),"a",MSB24-offl);
7372 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7373 pic14_emitcode("rrc","a");
7374 aopPut(AOP(result),"a",MSB16-offl);
7377 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7378 pic14_emitcode("rrc","a");
7379 aopPut(AOP(result),"a",LSB);
7383 /*-----------------------------------------------------------------*/
7384 /* genrshFour - shift four byte by a known amount != 0 */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshFour (operand *result, operand *left,
7387 int shCount, int sign)
7389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7390 /* if shifting more that 3 bytes */
7391 if(shCount >= 24 ) {
7394 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7396 movLeft2Result(left, MSB32, result, LSB);
7398 addSign(result, MSB16, sign);
7400 else if(shCount >= 16){
7403 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7405 movLeft2Result(left, MSB24, result, LSB);
7406 movLeft2Result(left, MSB32, result, MSB16);
7408 addSign(result, MSB24, sign);
7410 else if(shCount >= 8){
7413 shiftRLong(left, MSB16, result, sign);
7414 else if(shCount == 0){
7415 movLeft2Result(left, MSB16, result, LSB);
7416 movLeft2Result(left, MSB24, result, MSB16);
7417 movLeft2Result(left, MSB32, result, MSB24);
7418 addSign(result, MSB32, sign);
7421 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7422 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7423 /* the last shift is signed */
7424 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7425 addSign(result, MSB32, sign);
7428 else{ /* 1 <= shCount <= 7 */
7430 shiftRLong(left, LSB, result, sign);
7432 shiftRLong(result, LSB, result, sign);
7435 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7436 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7437 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7442 /*-----------------------------------------------------------------*/
7443 /* genRightShiftLiteral - right shifting by known count */
7444 /*-----------------------------------------------------------------*/
7445 static void genRightShiftLiteral (operand *left,
7451 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7454 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7455 freeAsmop(right,NULL,ic,TRUE);
7457 aopOp(left,ic,FALSE);
7458 aopOp(result,ic,FALSE);
7461 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7465 lsize = pic14_getDataSize(left);
7466 res_size = pic14_getDataSize(result);
7467 /* test the LEFT size !!! */
7469 /* I suppose that the left size >= result size */
7472 movLeft2Result(left, lsize, result, res_size);
7475 else if(shCount >= (lsize * 8)){
7478 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7480 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7481 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7486 emitpcode(POC_MOVLW, popGetLit(0));
7487 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7488 emitpcode(POC_MOVLW, popGetLit(0xff));
7490 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7495 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7502 genrshOne (result,left,shCount,sign);
7506 genrshTwo (result,left,shCount,sign);
7510 genrshFour (result,left,shCount,sign);
7518 freeAsmop(left,NULL,ic,TRUE);
7519 freeAsmop(result,NULL,ic,TRUE);
7522 /*-----------------------------------------------------------------*/
7523 /* genSignedRightShift - right shift of signed number */
7524 /*-----------------------------------------------------------------*/
7525 static void genSignedRightShift (iCode *ic)
7527 operand *right, *left, *result;
7530 symbol *tlbl, *tlbl1 ;
7533 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7535 /* we do it the hard way put the shift count in b
7536 and loop thru preserving the sign */
7537 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7539 right = IC_RIGHT(ic);
7541 result = IC_RESULT(ic);
7543 aopOp(right,ic,FALSE);
7544 aopOp(left,ic,FALSE);
7545 aopOp(result,ic,FALSE);
7548 if ( AOP_TYPE(right) == AOP_LIT) {
7549 genRightShiftLiteral (left,right,result,ic,1);
7552 /* shift count is unknown then we have to form
7553 a loop get the loop count in B : Note: we take
7554 only the lower order byte since shifting
7555 more that 32 bits make no sense anyway, ( the
7556 largest size of an object can be only 32 bits ) */
7558 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7559 //pic14_emitcode("inc","b");
7560 //freeAsmop (right,NULL,ic,TRUE);
7561 //aopOp(left,ic,FALSE);
7562 //aopOp(result,ic,FALSE);
7564 /* now move the left to the result if they are not the
7566 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7567 AOP_SIZE(result) > 1) {
7569 size = AOP_SIZE(result);
7573 l = aopGet(AOP(left),offset,FALSE,TRUE);
7574 if (*l == '@' && IS_AOP_PREG(result)) {
7576 pic14_emitcode("mov","a,%s",l);
7577 aopPut(AOP(result),"a",offset);
7579 aopPut(AOP(result),l,offset);
7581 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7582 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7588 /* mov the highest order bit to OVR */
7589 tlbl = newiTempLabel(NULL);
7590 tlbl1= newiTempLabel(NULL);
7592 size = AOP_SIZE(result);
7595 pctemp = popGetTempReg(); /* grab a temporary working register. */
7597 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7599 /* offset should be 0, 1 or 3 */
7600 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7602 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7604 emitpcode(POC_MOVWF, pctemp);
7607 emitpLabel(tlbl->key);
7609 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7610 emitpcode(POC_RRF, popGet(AOP(result),offset));
7613 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7616 emitpcode(POC_DECFSZ, pctemp);
7617 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7618 emitpLabel(tlbl1->key);
7620 popReleaseTempReg(pctemp);
7622 size = AOP_SIZE(result);
7624 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7625 pic14_emitcode("rlc","a");
7626 pic14_emitcode("mov","ov,c");
7627 /* if it is only one byte then */
7629 l = aopGet(AOP(left),0,FALSE,FALSE);
7631 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7632 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7633 pic14_emitcode("mov","c,ov");
7634 pic14_emitcode("rrc","a");
7635 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7636 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7637 aopPut(AOP(result),"a",0);
7641 reAdjustPreg(AOP(result));
7642 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7643 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7644 pic14_emitcode("mov","c,ov");
7646 l = aopGet(AOP(result),offset,FALSE,FALSE);
7648 pic14_emitcode("rrc","a");
7649 aopPut(AOP(result),"a",offset--);
7651 reAdjustPreg(AOP(result));
7652 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7653 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7658 freeAsmop(left,NULL,ic,TRUE);
7659 freeAsmop(result,NULL,ic,TRUE);
7660 freeAsmop(right,NULL,ic,TRUE);
7663 /*-----------------------------------------------------------------*/
7664 /* genRightShift - generate code for right shifting */
7665 /*-----------------------------------------------------------------*/
7666 static void genRightShift (iCode *ic)
7668 operand *right, *left, *result;
7672 symbol *tlbl, *tlbl1 ;
7674 /* if signed then we do it the hard way preserve the
7675 sign bit moving it inwards */
7676 retype = getSpec(operandType(IC_RESULT(ic)));
7677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7679 if (!SPEC_USIGN(retype)) {
7680 genSignedRightShift (ic);
7684 /* signed & unsigned types are treated the same : i.e. the
7685 signed is NOT propagated inwards : quoting from the
7686 ANSI - standard : "for E1 >> E2, is equivalent to division
7687 by 2**E2 if unsigned or if it has a non-negative value,
7688 otherwise the result is implementation defined ", MY definition
7689 is that the sign does not get propagated */
7691 right = IC_RIGHT(ic);
7693 result = IC_RESULT(ic);
7695 aopOp(right,ic,FALSE);
7697 /* if the shift count is known then do it
7698 as efficiently as possible */
7699 if (AOP_TYPE(right) == AOP_LIT) {
7700 genRightShiftLiteral (left,right,result,ic, 0);
7704 /* shift count is unknown then we have to form
7705 a loop get the loop count in B : Note: we take
7706 only the lower order byte since shifting
7707 more that 32 bits make no sense anyway, ( the
7708 largest size of an object can be only 32 bits ) */
7710 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7711 pic14_emitcode("inc","b");
7712 aopOp(left,ic,FALSE);
7713 aopOp(result,ic,FALSE);
7715 /* now move the left to the result if they are not the
7717 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7718 AOP_SIZE(result) > 1) {
7720 size = AOP_SIZE(result);
7723 l = aopGet(AOP(left),offset,FALSE,TRUE);
7724 if (*l == '@' && IS_AOP_PREG(result)) {
7726 pic14_emitcode("mov","a,%s",l);
7727 aopPut(AOP(result),"a",offset);
7729 aopPut(AOP(result),l,offset);
7734 tlbl = newiTempLabel(NULL);
7735 tlbl1= newiTempLabel(NULL);
7736 size = AOP_SIZE(result);
7739 /* if it is only one byte then */
7742 tlbl = newiTempLabel(NULL);
7743 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7744 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7745 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7748 emitpcode(POC_COMFW, popGet(AOP(right),0));
7749 emitpcode(POC_RLF, popGet(AOP(result),0));
7750 emitpLabel(tlbl->key);
7751 emitpcode(POC_RRF, popGet(AOP(result),0));
7752 emitpcode(POC_ADDLW, popGetLit(1));
7754 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7759 reAdjustPreg(AOP(result));
7760 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7761 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7764 l = aopGet(AOP(result),offset,FALSE,FALSE);
7766 pic14_emitcode("rrc","a");
7767 aopPut(AOP(result),"a",offset--);
7769 reAdjustPreg(AOP(result));
7771 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7772 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7775 freeAsmop(left,NULL,ic,TRUE);
7776 freeAsmop (right,NULL,ic,TRUE);
7777 freeAsmop(result,NULL,ic,TRUE);
7780 /*-----------------------------------------------------------------*/
7781 /* genUnpackBits - generates code for unpacking bits */
7782 /*-----------------------------------------------------------------*/
7783 static void genUnpackBits (operand *result, char *rname, int ptype)
7790 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7791 etype = getSpec(operandType(result));
7793 /* read the first byte */
7798 pic14_emitcode("mov","a,@%s",rname);
7802 pic14_emitcode("movx","a,@%s",rname);
7806 pic14_emitcode("movx","a,@dptr");
7810 pic14_emitcode("clr","a");
7811 pic14_emitcode("movc","a","@a+dptr");
7815 pic14_emitcode("lcall","__gptrget");
7819 /* if we have bitdisplacement then it fits */
7820 /* into this byte completely or if length is */
7821 /* less than a byte */
7822 if ((shCnt = SPEC_BSTR(etype)) ||
7823 (SPEC_BLEN(etype) <= 8)) {
7825 /* shift right acc */
7828 pic14_emitcode("anl","a,#0x%02x",
7829 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7830 aopPut(AOP(result),"a",offset);
7834 /* bit field did not fit in a byte */
7835 rlen = SPEC_BLEN(etype) - 8;
7836 aopPut(AOP(result),"a",offset++);
7843 pic14_emitcode("inc","%s",rname);
7844 pic14_emitcode("mov","a,@%s",rname);
7848 pic14_emitcode("inc","%s",rname);
7849 pic14_emitcode("movx","a,@%s",rname);
7853 pic14_emitcode("inc","dptr");
7854 pic14_emitcode("movx","a,@dptr");
7858 pic14_emitcode("clr","a");
7859 pic14_emitcode("inc","dptr");
7860 pic14_emitcode("movc","a","@a+dptr");
7864 pic14_emitcode("inc","dptr");
7865 pic14_emitcode("lcall","__gptrget");
7870 /* if we are done */
7874 aopPut(AOP(result),"a",offset++);
7879 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7880 aopPut(AOP(result),"a",offset);
7887 /*-----------------------------------------------------------------*/
7888 /* genDataPointerGet - generates code when ptr offset is known */
7889 /*-----------------------------------------------------------------*/
7890 static void genDataPointerGet (operand *left,
7894 int size , offset = 0;
7897 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7900 /* optimization - most of the time, left and result are the same
7901 * address, but different types. for the pic code, we could omit
7905 aopOp(result,ic,TRUE);
7907 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7909 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7911 size = AOP_SIZE(result);
7914 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7918 freeAsmop(left,NULL,ic,TRUE);
7919 freeAsmop(result,NULL,ic,TRUE);
7922 /*-----------------------------------------------------------------*/
7923 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7924 /*-----------------------------------------------------------------*/
7925 static void genNearPointerGet (operand *left,
7930 //regs *preg = NULL ;
7932 sym_link *rtype, *retype;
7933 sym_link *ltype = operandType(left);
7936 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7938 rtype = operandType(result);
7939 retype= getSpec(rtype);
7941 aopOp(left,ic,FALSE);
7943 /* if left is rematerialisable and
7944 result is not bit variable type and
7945 the left is pointer to data space i.e
7946 lower 128 bytes of space */
7947 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7948 !IS_BITVAR(retype) &&
7949 DCL_TYPE(ltype) == POINTER) {
7950 //genDataPointerGet (left,result,ic);
7954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7956 /* if the value is already in a pointer register
7957 then don't need anything more */
7958 if (!AOP_INPREG(AOP(left))) {
7959 /* otherwise get a free pointer register */
7960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 preg = getFreePtr(ic,&aop,FALSE);
7964 pic14_emitcode("mov","%s,%s",
7966 aopGet(AOP(left),0,FALSE,TRUE));
7967 rname = preg->name ;
7971 rname = aopGet(AOP(left),0,FALSE,FALSE);
7973 aopOp (result,ic,FALSE);
7975 /* if bitfield then unpack the bits */
7976 if (IS_BITFIELD(retype))
7977 genUnpackBits (result,rname,POINTER);
7979 /* we have can just get the values */
7980 int size = AOP_SIZE(result);
7983 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7985 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7986 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7988 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7989 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7991 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7995 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7997 pic14_emitcode("mov","a,@%s",rname);
7998 aopPut(AOP(result),"a",offset);
8000 sprintf(buffer,"@%s",rname);
8001 aopPut(AOP(result),buffer,offset);
8005 pic14_emitcode("inc","%s",rname);
8010 /* now some housekeeping stuff */
8012 /* we had to allocate for this iCode */
8013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8014 freeAsmop(NULL,aop,ic,TRUE);
8016 /* we did not allocate which means left
8017 already in a pointer register, then
8018 if size > 0 && this could be used again
8019 we have to point it back to where it
8021 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8022 if (AOP_SIZE(result) > 1 &&
8023 !OP_SYMBOL(left)->remat &&
8024 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8026 int size = AOP_SIZE(result) - 1;
8028 pic14_emitcode("dec","%s",rname);
8033 freeAsmop(left,NULL,ic,TRUE);
8034 freeAsmop(result,NULL,ic,TRUE);
8038 /*-----------------------------------------------------------------*/
8039 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8040 /*-----------------------------------------------------------------*/
8041 static void genPagedPointerGet (operand *left,
8048 sym_link *rtype, *retype;
8050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8052 rtype = operandType(result);
8053 retype= getSpec(rtype);
8055 aopOp(left,ic,FALSE);
8057 /* if the value is already in a pointer register
8058 then don't need anything more */
8059 if (!AOP_INPREG(AOP(left))) {
8060 /* otherwise get a free pointer register */
8062 preg = getFreePtr(ic,&aop,FALSE);
8063 pic14_emitcode("mov","%s,%s",
8065 aopGet(AOP(left),0,FALSE,TRUE));
8066 rname = preg->name ;
8068 rname = aopGet(AOP(left),0,FALSE,FALSE);
8070 freeAsmop(left,NULL,ic,TRUE);
8071 aopOp (result,ic,FALSE);
8073 /* if bitfield then unpack the bits */
8074 if (IS_BITFIELD(retype))
8075 genUnpackBits (result,rname,PPOINTER);
8077 /* we have can just get the values */
8078 int size = AOP_SIZE(result);
8083 pic14_emitcode("movx","a,@%s",rname);
8084 aopPut(AOP(result),"a",offset);
8089 pic14_emitcode("inc","%s",rname);
8093 /* now some housekeeping stuff */
8095 /* we had to allocate for this iCode */
8096 freeAsmop(NULL,aop,ic,TRUE);
8098 /* we did not allocate which means left
8099 already in a pointer register, then
8100 if size > 0 && this could be used again
8101 we have to point it back to where it
8103 if (AOP_SIZE(result) > 1 &&
8104 !OP_SYMBOL(left)->remat &&
8105 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8107 int size = AOP_SIZE(result) - 1;
8109 pic14_emitcode("dec","%s",rname);
8114 freeAsmop(result,NULL,ic,TRUE);
8119 /*-----------------------------------------------------------------*/
8120 /* genFarPointerGet - gget value from far space */
8121 /*-----------------------------------------------------------------*/
8122 static void genFarPointerGet (operand *left,
8123 operand *result, iCode *ic)
8126 sym_link *retype = getSpec(operandType(result));
8128 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8130 aopOp(left,ic,FALSE);
8132 /* if the operand is already in dptr
8133 then we do nothing else we move the value to dptr */
8134 if (AOP_TYPE(left) != AOP_STR) {
8135 /* if this is remateriazable */
8136 if (AOP_TYPE(left) == AOP_IMMD)
8137 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8138 else { /* we need to get it byte by byte */
8139 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8140 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8141 if (options.model == MODEL_FLAT24)
8143 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8147 /* so dptr know contains the address */
8148 freeAsmop(left,NULL,ic,TRUE);
8149 aopOp(result,ic,FALSE);
8151 /* if bit then unpack */
8152 if (IS_BITFIELD(retype))
8153 genUnpackBits(result,"dptr",FPOINTER);
8155 size = AOP_SIZE(result);
8159 pic14_emitcode("movx","a,@dptr");
8160 aopPut(AOP(result),"a",offset++);
8162 pic14_emitcode("inc","dptr");
8166 freeAsmop(result,NULL,ic,TRUE);
8169 /*-----------------------------------------------------------------*/
8170 /* genCodePointerGet - get value from code space */
8171 /*-----------------------------------------------------------------*/
8172 static void genCodePointerGet (operand *left,
8173 operand *result, iCode *ic)
8176 sym_link *retype = getSpec(operandType(result));
8178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8180 aopOp(left,ic,FALSE);
8182 /* if the operand is already in dptr
8183 then we do nothing else we move the value to dptr */
8184 if (AOP_TYPE(left) != AOP_STR) {
8185 /* if this is remateriazable */
8186 if (AOP_TYPE(left) == AOP_IMMD)
8187 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8188 else { /* we need to get it byte by byte */
8189 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8190 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8191 if (options.model == MODEL_FLAT24)
8193 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8197 /* so dptr know contains the address */
8198 freeAsmop(left,NULL,ic,TRUE);
8199 aopOp(result,ic,FALSE);
8201 /* if bit then unpack */
8202 if (IS_BITFIELD(retype))
8203 genUnpackBits(result,"dptr",CPOINTER);
8205 size = AOP_SIZE(result);
8209 pic14_emitcode("clr","a");
8210 pic14_emitcode("movc","a,@a+dptr");
8211 aopPut(AOP(result),"a",offset++);
8213 pic14_emitcode("inc","dptr");
8217 freeAsmop(result,NULL,ic,TRUE);
8220 /*-----------------------------------------------------------------*/
8221 /* genGenPointerGet - gget value from generic pointer space */
8222 /*-----------------------------------------------------------------*/
8223 static void genGenPointerGet (operand *left,
8224 operand *result, iCode *ic)
8227 sym_link *retype = getSpec(operandType(result));
8229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8230 aopOp(left,ic,FALSE);
8231 aopOp(result,ic,FALSE);
8234 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8236 /* if the operand is already in dptr
8237 then we do nothing else we move the value to dptr */
8238 // if (AOP_TYPE(left) != AOP_STR) {
8239 /* if this is remateriazable */
8240 if (AOP_TYPE(left) == AOP_IMMD) {
8241 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8242 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8244 else { /* we need to get it byte by byte */
8246 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8247 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8249 size = AOP_SIZE(result);
8253 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8254 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8256 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8261 /* so dptr know contains the address */
8263 /* if bit then unpack */
8264 //if (IS_BITFIELD(retype))
8265 // genUnpackBits(result,"dptr",GPOINTER);
8268 freeAsmop(left,NULL,ic,TRUE);
8269 freeAsmop(result,NULL,ic,TRUE);
8273 /*-----------------------------------------------------------------*/
8274 /* genConstPointerGet - get value from const generic pointer space */
8275 /*-----------------------------------------------------------------*/
8276 static void genConstPointerGet (operand *left,
8277 operand *result, iCode *ic)
8279 //sym_link *retype = getSpec(operandType(result));
8280 symbol *albl = newiTempLabel(NULL);
8281 symbol *blbl = newiTempLabel(NULL);
8285 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8286 aopOp(left,ic,FALSE);
8287 aopOp(result,ic,FALSE);
8290 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8292 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8294 emitpcode(POC_CALL,popGetLabel(albl->key));
8295 pcop = popGetLabel(blbl->key);
8296 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8297 emitpcode(POC_GOTO,pcop);
8298 emitpLabel(albl->key);
8300 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8302 emitpcode(poc,popGet(AOP(left),1));
8303 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8304 emitpcode(poc,popGet(AOP(left),0));
8305 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8307 emitpLabel(blbl->key);
8309 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8312 freeAsmop(left,NULL,ic,TRUE);
8313 freeAsmop(result,NULL,ic,TRUE);
8316 /*-----------------------------------------------------------------*/
8317 /* genPointerGet - generate code for pointer get */
8318 /*-----------------------------------------------------------------*/
8319 static void genPointerGet (iCode *ic)
8321 operand *left, *result ;
8322 sym_link *type, *etype;
8325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8328 result = IC_RESULT(ic) ;
8330 /* depending on the type of pointer we need to
8331 move it to the correct pointer register */
8332 type = operandType(left);
8333 etype = getSpec(type);
8335 if (IS_PTR_CONST(type))
8336 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8338 /* if left is of type of pointer then it is simple */
8339 if (IS_PTR(type) && !IS_FUNC(type->next))
8340 p_type = DCL_TYPE(type);
8342 /* we have to go by the storage class */
8343 p_type = PTR_TYPE(SPEC_OCLS(etype));
8345 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8347 if (SPEC_OCLS(etype)->codesp ) {
8348 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8349 //p_type = CPOINTER ;
8352 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8353 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8354 /*p_type = FPOINTER ;*/
8356 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8357 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8358 /* p_type = PPOINTER; */
8360 if (SPEC_OCLS(etype) == idata )
8361 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8362 /* p_type = IPOINTER; */
8364 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8365 /* p_type = POINTER ; */
8368 /* now that we have the pointer type we assign
8369 the pointer values */
8374 genNearPointerGet (left,result,ic);
8378 genPagedPointerGet(left,result,ic);
8382 genFarPointerGet (left,result,ic);
8386 genConstPointerGet (left,result,ic);
8387 //pic14_emitcodePointerGet (left,result,ic);
8391 if (IS_PTR_CONST(type))
8392 genConstPointerGet (left,result,ic);
8394 genGenPointerGet (left,result,ic);
8400 /*-----------------------------------------------------------------*/
8401 /* genPackBits - generates code for packed bit storage */
8402 /*-----------------------------------------------------------------*/
8403 static void genPackBits (sym_link *etype ,
8405 char *rname, int p_type)
8413 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8414 blen = SPEC_BLEN(etype);
8415 bstr = SPEC_BSTR(etype);
8417 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8420 /* if the bit lenth is less than or */
8421 /* it exactly fits a byte then */
8422 if (SPEC_BLEN(etype) <= 8 ) {
8423 shCount = SPEC_BSTR(etype) ;
8425 /* shift left acc */
8428 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8433 pic14_emitcode ("mov","b,a");
8434 pic14_emitcode("mov","a,@%s",rname);
8438 pic14_emitcode ("mov","b,a");
8439 pic14_emitcode("movx","a,@dptr");
8443 pic14_emitcode ("push","b");
8444 pic14_emitcode ("push","acc");
8445 pic14_emitcode ("lcall","__gptrget");
8446 pic14_emitcode ("pop","b");
8450 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8451 ((unsigned char)(0xFF << (blen+bstr)) |
8452 (unsigned char)(0xFF >> (8-bstr)) ) );
8453 pic14_emitcode ("orl","a,b");
8454 if (p_type == GPOINTER)
8455 pic14_emitcode("pop","b");
8461 pic14_emitcode("mov","@%s,a",rname);
8465 pic14_emitcode("movx","@dptr,a");
8469 DEBUGpic14_emitcode(";lcall","__gptrput");
8474 if ( SPEC_BLEN(etype) <= 8 )
8477 pic14_emitcode("inc","%s",rname);
8478 rLen = SPEC_BLEN(etype) ;
8480 /* now generate for lengths greater than one byte */
8483 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8493 pic14_emitcode("mov","@%s,a",rname);
8495 pic14_emitcode("mov","@%s,%s",rname,l);
8500 pic14_emitcode("movx","@dptr,a");
8505 DEBUGpic14_emitcode(";lcall","__gptrput");
8508 pic14_emitcode ("inc","%s",rname);
8513 /* last last was not complete */
8515 /* save the byte & read byte */
8518 pic14_emitcode ("mov","b,a");
8519 pic14_emitcode("mov","a,@%s",rname);
8523 pic14_emitcode ("mov","b,a");
8524 pic14_emitcode("movx","a,@dptr");
8528 pic14_emitcode ("push","b");
8529 pic14_emitcode ("push","acc");
8530 pic14_emitcode ("lcall","__gptrget");
8531 pic14_emitcode ("pop","b");
8535 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8536 pic14_emitcode ("orl","a,b");
8539 if (p_type == GPOINTER)
8540 pic14_emitcode("pop","b");
8545 pic14_emitcode("mov","@%s,a",rname);
8549 pic14_emitcode("movx","@dptr,a");
8553 DEBUGpic14_emitcode(";lcall","__gptrput");
8557 /*-----------------------------------------------------------------*/
8558 /* genDataPointerSet - remat pointer to data space */
8559 /*-----------------------------------------------------------------*/
8560 static void genDataPointerSet(operand *right,
8564 int size, offset = 0 ;
8565 char *l, buffer[256];
8567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8568 aopOp(right,ic,FALSE);
8570 l = aopGet(AOP(result),0,FALSE,TRUE);
8571 size = AOP_SIZE(right);
8573 if ( AOP_TYPE(result) == AOP_PCODE) {
8574 fprintf(stderr,"genDataPointerSet %s, %d\n",
8575 AOP(result)->aopu.pcop->name,
8576 PCOI(AOP(result)->aopu.pcop)->offset);
8580 // tsd, was l+1 - the underline `_' prefix was being stripped
8583 sprintf(buffer,"(%s + %d)",l,offset);
8584 fprintf(stderr,"oops %s\n",buffer);
8586 sprintf(buffer,"%s",l);
8588 if (AOP_TYPE(right) == AOP_LIT) {
8589 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8590 lit = lit >> (8*offset);
8592 pic14_emitcode("movlw","%d",lit);
8593 pic14_emitcode("movwf","%s",buffer);
8595 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8596 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8597 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8600 pic14_emitcode("clrf","%s",buffer);
8601 //emitpcode(POC_CLRF, popRegFromString(buffer));
8602 emitpcode(POC_CLRF, popGet(AOP(result),0));
8605 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8606 pic14_emitcode("movwf","%s",buffer);
8608 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8609 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8610 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8617 freeAsmop(right,NULL,ic,TRUE);
8618 freeAsmop(result,NULL,ic,TRUE);
8621 /*-----------------------------------------------------------------*/
8622 /* genNearPointerSet - pic14_emitcode for near pointer put */
8623 /*-----------------------------------------------------------------*/
8624 static void genNearPointerSet (operand *right,
8631 sym_link *ptype = operandType(result);
8634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8635 retype= getSpec(operandType(right));
8637 aopOp(result,ic,FALSE);
8640 /* if the result is rematerializable &
8641 in data space & not a bit variable */
8642 //if (AOP_TYPE(result) == AOP_IMMD &&
8643 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8644 DCL_TYPE(ptype) == POINTER &&
8645 !IS_BITFIELD(retype)) {
8646 genDataPointerSet (right,result,ic);
8647 freeAsmop(result,NULL,ic,TRUE);
8651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8652 aopOp(right,ic,FALSE);
8653 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8655 /* if the value is already in a pointer register
8656 then don't need anything more */
8657 if (!AOP_INPREG(AOP(result))) {
8658 /* otherwise get a free pointer register */
8659 //aop = newAsmop(0);
8660 //preg = getFreePtr(ic,&aop,FALSE);
8661 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8662 //pic14_emitcode("mov","%s,%s",
8664 // aopGet(AOP(result),0,FALSE,TRUE));
8665 //rname = preg->name ;
8666 //pic14_emitcode("movwf","fsr");
8667 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8668 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8669 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8670 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8674 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8677 /* if bitfield then unpack the bits */
8678 if (IS_BITFIELD(retype)) {
8679 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8680 "The programmer is obviously confused");
8681 //genPackBits (retype,right,rname,POINTER);
8685 /* we have can just get the values */
8686 int size = AOP_SIZE(right);
8689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8691 l = aopGet(AOP(right),offset,FALSE,TRUE);
8694 //pic14_emitcode("mov","@%s,a",rname);
8695 pic14_emitcode("movf","indf,w ;1");
8698 if (AOP_TYPE(right) == AOP_LIT) {
8699 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8701 pic14_emitcode("movlw","%s",l);
8702 pic14_emitcode("movwf","indf ;2");
8704 pic14_emitcode("clrf","indf");
8706 pic14_emitcode("movf","%s,w",l);
8707 pic14_emitcode("movwf","indf ;2");
8709 //pic14_emitcode("mov","@%s,%s",rname,l);
8712 pic14_emitcode("incf","fsr,f ;3");
8713 //pic14_emitcode("inc","%s",rname);
8718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8719 /* now some housekeeping stuff */
8721 /* we had to allocate for this iCode */
8722 freeAsmop(NULL,aop,ic,TRUE);
8724 /* we did not allocate which means left
8725 already in a pointer register, then
8726 if size > 0 && this could be used again
8727 we have to point it back to where it
8729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8730 if (AOP_SIZE(right) > 1 &&
8731 !OP_SYMBOL(result)->remat &&
8732 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8734 int size = AOP_SIZE(right) - 1;
8736 pic14_emitcode("decf","fsr,f");
8737 //pic14_emitcode("dec","%s",rname);
8741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8744 freeAsmop(right,NULL,ic,TRUE);
8745 freeAsmop(result,NULL,ic,TRUE);
8748 /*-----------------------------------------------------------------*/
8749 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8750 /*-----------------------------------------------------------------*/
8751 static void genPagedPointerSet (operand *right,
8760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8762 retype= getSpec(operandType(right));
8764 aopOp(result,ic,FALSE);
8766 /* if the value is already in a pointer register
8767 then don't need anything more */
8768 if (!AOP_INPREG(AOP(result))) {
8769 /* otherwise get a free pointer register */
8771 preg = getFreePtr(ic,&aop,FALSE);
8772 pic14_emitcode("mov","%s,%s",
8774 aopGet(AOP(result),0,FALSE,TRUE));
8775 rname = preg->name ;
8777 rname = aopGet(AOP(result),0,FALSE,FALSE);
8779 freeAsmop(result,NULL,ic,TRUE);
8780 aopOp (right,ic,FALSE);
8782 /* if bitfield then unpack the bits */
8783 if (IS_BITFIELD(retype))
8784 genPackBits (retype,right,rname,PPOINTER);
8786 /* we have can just get the values */
8787 int size = AOP_SIZE(right);
8791 l = aopGet(AOP(right),offset,FALSE,TRUE);
8794 pic14_emitcode("movx","@%s,a",rname);
8797 pic14_emitcode("inc","%s",rname);
8803 /* now some housekeeping stuff */
8805 /* we had to allocate for this iCode */
8806 freeAsmop(NULL,aop,ic,TRUE);
8808 /* we did not allocate which means left
8809 already in a pointer register, then
8810 if size > 0 && this could be used again
8811 we have to point it back to where it
8813 if (AOP_SIZE(right) > 1 &&
8814 !OP_SYMBOL(result)->remat &&
8815 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8817 int size = AOP_SIZE(right) - 1;
8819 pic14_emitcode("dec","%s",rname);
8824 freeAsmop(right,NULL,ic,TRUE);
8829 /*-----------------------------------------------------------------*/
8830 /* genFarPointerSet - set value from far space */
8831 /*-----------------------------------------------------------------*/
8832 static void genFarPointerSet (operand *right,
8833 operand *result, iCode *ic)
8836 sym_link *retype = getSpec(operandType(right));
8838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8839 aopOp(result,ic,FALSE);
8841 /* if the operand is already in dptr
8842 then we do nothing else we move the value to dptr */
8843 if (AOP_TYPE(result) != AOP_STR) {
8844 /* if this is remateriazable */
8845 if (AOP_TYPE(result) == AOP_IMMD)
8846 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8847 else { /* we need to get it byte by byte */
8848 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8849 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8850 if (options.model == MODEL_FLAT24)
8852 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8856 /* so dptr know contains the address */
8857 freeAsmop(result,NULL,ic,TRUE);
8858 aopOp(right,ic,FALSE);
8860 /* if bit then unpack */
8861 if (IS_BITFIELD(retype))
8862 genPackBits(retype,right,"dptr",FPOINTER);
8864 size = AOP_SIZE(right);
8868 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8870 pic14_emitcode("movx","@dptr,a");
8872 pic14_emitcode("inc","dptr");
8876 freeAsmop(right,NULL,ic,TRUE);
8879 /*-----------------------------------------------------------------*/
8880 /* genGenPointerSet - set value from generic pointer space */
8881 /*-----------------------------------------------------------------*/
8882 static void genGenPointerSet (operand *right,
8883 operand *result, iCode *ic)
8886 sym_link *retype = getSpec(operandType(right));
8888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8890 aopOp(result,ic,FALSE);
8891 aopOp(right,ic,FALSE);
8892 size = AOP_SIZE(right);
8894 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8896 /* if the operand is already in dptr
8897 then we do nothing else we move the value to dptr */
8898 if (AOP_TYPE(result) != AOP_STR) {
8899 /* if this is remateriazable */
8900 if (AOP_TYPE(result) == AOP_IMMD) {
8901 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8902 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8904 else { /* we need to get it byte by byte */
8905 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8906 size = AOP_SIZE(right);
8909 /* hack hack! see if this the FSR. If so don't load W */
8910 if(AOP_TYPE(right) != AOP_ACC) {
8913 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8914 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8916 if(AOP_SIZE(result) > 1) {
8917 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8918 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8919 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8924 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8926 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8927 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8931 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8932 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8935 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8942 if(aopIdx(AOP(result),0) != 4) {
8944 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8948 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8953 /* so dptr know contains the address */
8956 /* if bit then unpack */
8957 if (IS_BITFIELD(retype))
8958 genPackBits(retype,right,"dptr",GPOINTER);
8960 size = AOP_SIZE(right);
8963 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8967 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8968 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8970 if (AOP_TYPE(right) == AOP_LIT)
8971 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8973 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8975 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8982 freeAsmop(right,NULL,ic,TRUE);
8983 freeAsmop(result,NULL,ic,TRUE);
8986 /*-----------------------------------------------------------------*/
8987 /* genPointerSet - stores the value into a pointer location */
8988 /*-----------------------------------------------------------------*/
8989 static void genPointerSet (iCode *ic)
8991 operand *right, *result ;
8992 sym_link *type, *etype;
8995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8997 right = IC_RIGHT(ic);
8998 result = IC_RESULT(ic) ;
9000 /* depending on the type of pointer we need to
9001 move it to the correct pointer register */
9002 type = operandType(result);
9003 etype = getSpec(type);
9004 /* if left is of type of pointer then it is simple */
9005 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9006 p_type = DCL_TYPE(type);
9009 /* we have to go by the storage class */
9010 p_type = PTR_TYPE(SPEC_OCLS(etype));
9012 /* if (SPEC_OCLS(etype)->codesp ) { */
9013 /* p_type = CPOINTER ; */
9016 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9017 /* p_type = FPOINTER ; */
9019 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9020 /* p_type = PPOINTER ; */
9022 /* if (SPEC_OCLS(etype) == idata ) */
9023 /* p_type = IPOINTER ; */
9025 /* p_type = POINTER ; */
9028 /* now that we have the pointer type we assign
9029 the pointer values */
9034 genNearPointerSet (right,result,ic);
9038 genPagedPointerSet (right,result,ic);
9042 genFarPointerSet (right,result,ic);
9046 genGenPointerSet (right,result,ic);
9050 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9051 "genPointerSet: illegal pointer type");
9055 /*-----------------------------------------------------------------*/
9056 /* genIfx - generate code for Ifx statement */
9057 /*-----------------------------------------------------------------*/
9058 static void genIfx (iCode *ic, iCode *popIc)
9060 operand *cond = IC_COND(ic);
9063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9065 aopOp(cond,ic,FALSE);
9067 /* get the value into acc */
9068 if (AOP_TYPE(cond) != AOP_CRY)
9069 pic14_toBoolean(cond);
9072 /* the result is now in the accumulator */
9073 freeAsmop(cond,NULL,ic,TRUE);
9075 /* if there was something to be popped then do it */
9079 /* if the condition is a bit variable */
9080 if (isbit && IS_ITEMP(cond) &&
9082 genIfxJump(ic,SPIL_LOC(cond)->rname);
9083 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9086 if (isbit && !IS_ITEMP(cond))
9087 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9095 /*-----------------------------------------------------------------*/
9096 /* genAddrOf - generates code for address of */
9097 /*-----------------------------------------------------------------*/
9098 static void genAddrOf (iCode *ic)
9100 operand *right, *result, *left;
9103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9106 //aopOp(IC_RESULT(ic),ic,FALSE);
9108 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9109 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9110 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9112 DEBUGpic14_AopType(__LINE__,left,right,result);
9114 size = AOP_SIZE(IC_RESULT(ic));
9118 /* fixing bug #863624, reported from (errolv) */
9119 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9120 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9123 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9124 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9129 freeAsmop(left,NULL,ic,FALSE);
9130 freeAsmop(result,NULL,ic,TRUE);
9135 /*-----------------------------------------------------------------*/
9136 /* genFarFarAssign - assignment when both are in far space */
9137 /*-----------------------------------------------------------------*/
9138 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9140 int size = AOP_SIZE(right);
9143 /* first push the right side on to the stack */
9145 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9147 pic14_emitcode ("push","acc");
9150 freeAsmop(right,NULL,ic,FALSE);
9151 /* now assign DPTR to result */
9152 aopOp(result,ic,FALSE);
9153 size = AOP_SIZE(result);
9155 pic14_emitcode ("pop","acc");
9156 aopPut(AOP(result),"a",--offset);
9158 freeAsmop(result,NULL,ic,FALSE);
9163 /*-----------------------------------------------------------------*/
9164 /* genAssign - generate code for assignment */
9165 /*-----------------------------------------------------------------*/
9166 static void genAssign (iCode *ic)
9168 operand *result, *right;
9169 int size, offset,know_W;
9170 unsigned long lit = 0L;
9172 result = IC_RESULT(ic);
9173 right = IC_RIGHT(ic) ;
9175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9177 /* if they are the same */
9178 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9181 aopOp(right,ic,FALSE);
9182 aopOp(result,ic,TRUE);
9184 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9186 /* if they are the same registers */
9187 if (pic14_sameRegs(AOP(right),AOP(result)))
9190 /* if the result is a bit */
9191 if (AOP_TYPE(result) == AOP_CRY) {
9193 /* if the right size is a literal then
9194 we know what the value is */
9195 if (AOP_TYPE(right) == AOP_LIT) {
9197 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9198 popGet(AOP(result),0));
9200 if (((int) operandLitValue(right)))
9201 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9202 AOP(result)->aopu.aop_dir,
9203 AOP(result)->aopu.aop_dir);
9205 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9206 AOP(result)->aopu.aop_dir,
9207 AOP(result)->aopu.aop_dir);
9211 /* the right is also a bit variable */
9212 if (AOP_TYPE(right) == AOP_CRY) {
9213 emitpcode(POC_BCF, popGet(AOP(result),0));
9214 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9215 emitpcode(POC_BSF, popGet(AOP(result),0));
9217 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9218 AOP(result)->aopu.aop_dir,
9219 AOP(result)->aopu.aop_dir);
9220 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9221 AOP(right)->aopu.aop_dir,
9222 AOP(right)->aopu.aop_dir);
9223 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9224 AOP(result)->aopu.aop_dir,
9225 AOP(result)->aopu.aop_dir);
9230 emitpcode(POC_BCF, popGet(AOP(result),0));
9231 pic14_toBoolean(right);
9233 emitpcode(POC_BSF, popGet(AOP(result),0));
9234 //aopPut(AOP(result),"a",0);
9238 /* bit variables done */
9240 size = AOP_SIZE(result);
9242 if(AOP_TYPE(right) == AOP_LIT)
9243 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9245 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9247 if(aopIdx(AOP(result),0) == 4) {
9248 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9249 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9250 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9253 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9258 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9259 if(AOP_TYPE(right) == AOP_LIT) {
9261 if(know_W != (int)(lit&0xff))
9262 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9264 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9266 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9270 } else if (AOP_TYPE(right) == AOP_CRY) {
9271 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9273 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9274 emitpcode(POC_INCF, popGet(AOP(result),0));
9277 mov2w (AOP(right), offset);
9278 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9286 freeAsmop (right,NULL,ic,FALSE);
9287 freeAsmop (result,NULL,ic,TRUE);
9290 /*-----------------------------------------------------------------*/
9291 /* genJumpTab - genrates code for jump table */
9292 /*-----------------------------------------------------------------*/
9293 static void genJumpTab (iCode *ic)
9298 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9300 aopOp(IC_JTCOND(ic),ic,FALSE);
9301 /* get the condition into accumulator */
9302 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9304 /* multiply by three */
9305 pic14_emitcode("add","a,acc");
9306 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9308 jtab = newiTempLabel(NULL);
9309 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9310 pic14_emitcode("jmp","@a+dptr");
9311 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9313 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9314 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9315 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9316 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9318 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9319 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9320 emitpLabel(jtab->key);
9322 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9324 /* now generate the jump labels */
9325 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9326 jtab = setNextItem(IC_JTLABELS(ic))) {
9327 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9328 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9334 /*-----------------------------------------------------------------*/
9335 /* genMixedOperation - gen code for operators between mixed types */
9336 /*-----------------------------------------------------------------*/
9338 TSD - Written for the PIC port - but this unfortunately is buggy.
9339 This routine is good in that it is able to efficiently promote
9340 types to different (larger) sizes. Unfortunately, the temporary
9341 variables that are optimized out by this routine are sometimes
9342 used in other places. So until I know how to really parse the
9343 iCode tree, I'm going to not be using this routine :(.
9345 static int genMixedOperation (iCode *ic)
9348 operand *result = IC_RESULT(ic);
9349 sym_link *ctype = operandType(IC_LEFT(ic));
9350 operand *right = IC_RIGHT(ic);
9356 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9358 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9364 nextright = IC_RIGHT(nextic);
9365 nextleft = IC_LEFT(nextic);
9366 nextresult = IC_RESULT(nextic);
9368 aopOp(right,ic,FALSE);
9369 aopOp(result,ic,FALSE);
9370 aopOp(nextright, nextic, FALSE);
9371 aopOp(nextleft, nextic, FALSE);
9372 aopOp(nextresult, nextic, FALSE);
9374 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9380 pic14_emitcode(";remove right +","");
9382 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9388 pic14_emitcode(";remove left +","");
9392 big = AOP_SIZE(nextleft);
9393 small = AOP_SIZE(nextright);
9395 switch(nextic->op) {
9398 pic14_emitcode(";optimize a +","");
9399 /* if unsigned or not an integral type */
9400 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9401 pic14_emitcode(";add a bit to something","");
9404 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9406 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9407 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9408 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9410 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9418 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9419 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9420 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9423 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9425 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9426 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9427 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9428 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9429 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9432 pic14_emitcode("rlf","known_zero,w");
9439 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9440 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9441 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9443 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9453 freeAsmop(right,NULL,ic,TRUE);
9454 freeAsmop(result,NULL,ic,TRUE);
9455 freeAsmop(nextright,NULL,ic,TRUE);
9456 freeAsmop(nextleft,NULL,ic,TRUE);
9458 nextic->generated = 1;
9465 /*-----------------------------------------------------------------*/
9466 /* genCast - gen code for casting */
9467 /*-----------------------------------------------------------------*/
9468 static void genCast (iCode *ic)
9470 operand *result = IC_RESULT(ic);
9471 sym_link *ctype = operandType(IC_LEFT(ic));
9472 sym_link *rtype = operandType(IC_RIGHT(ic));
9473 operand *right = IC_RIGHT(ic);
9476 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9477 /* if they are equivalent then do nothing */
9478 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9481 aopOp(right,ic,FALSE) ;
9482 aopOp(result,ic,FALSE);
9484 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9486 /* if the result is a bit */
9487 if (AOP_TYPE(result) == AOP_CRY) {
9488 /* if the right size is a literal then
9489 we know what the value is */
9490 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9491 if (AOP_TYPE(right) == AOP_LIT) {
9493 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9494 popGet(AOP(result),0));
9496 if (((int) operandLitValue(right)))
9497 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9498 AOP(result)->aopu.aop_dir,
9499 AOP(result)->aopu.aop_dir);
9501 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9502 AOP(result)->aopu.aop_dir,
9503 AOP(result)->aopu.aop_dir);
9508 /* the right is also a bit variable */
9509 if (AOP_TYPE(right) == AOP_CRY) {
9512 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9514 pic14_emitcode("clrc","");
9515 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9516 AOP(right)->aopu.aop_dir,
9517 AOP(right)->aopu.aop_dir);
9518 aopPut(AOP(result),"c",0);
9523 if (AOP_TYPE(right) == AOP_REG) {
9524 emitpcode(POC_BCF, popGet(AOP(result),0));
9525 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9526 emitpcode(POC_BSF, popGet(AOP(result),0));
9528 pic14_toBoolean(right);
9529 aopPut(AOP(result),"a",0);
9533 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9535 size = AOP_SIZE(result);
9537 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9539 emitpcode(POC_CLRF, popGet(AOP(result),0));
9540 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9541 emitpcode(POC_INCF, popGet(AOP(result),0));
9544 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9549 /* if they are the same size : or less */
9550 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9552 /* if they are in the same place */
9553 if (pic14_sameRegs(AOP(right),AOP(result)))
9556 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9557 if (IS_PTR_CONST(rtype))
9558 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9559 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9560 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9562 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9563 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9564 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9565 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9566 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9567 if(AOP_SIZE(result) <2)
9568 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9572 /* if they in different places then copy */
9573 size = AOP_SIZE(result);
9576 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9577 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9579 //aopPut(AOP(result),
9580 // aopGet(AOP(right),offset,FALSE,FALSE),
9590 /* if the result is of type pointer */
9591 if (IS_PTR(ctype)) {
9594 sym_link *type = operandType(right);
9595 sym_link *etype = getSpec(type);
9596 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9598 /* pointer to generic pointer */
9599 if (IS_GENPTR(ctype)) {
9603 p_type = DCL_TYPE(type);
9605 /* we have to go by the storage class */
9606 p_type = PTR_TYPE(SPEC_OCLS(etype));
9608 /* if (SPEC_OCLS(etype)->codesp ) */
9609 /* p_type = CPOINTER ; */
9611 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9612 /* p_type = FPOINTER ; */
9614 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9615 /* p_type = PPOINTER; */
9617 /* if (SPEC_OCLS(etype) == idata ) */
9618 /* p_type = IPOINTER ; */
9620 /* p_type = POINTER ; */
9623 /* the first two bytes are known */
9624 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9625 size = GPTRSIZE - 1;
9628 if(offset < AOP_SIZE(right)) {
9629 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9630 if ((AOP_TYPE(right) == AOP_PCODE) &&
9631 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9632 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9633 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9636 aopGet(AOP(right),offset,FALSE,FALSE),
9640 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9643 /* the last byte depending on type */
9647 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9650 pic14_emitcode(";BUG!? ","%d",__LINE__);
9654 pic14_emitcode(";BUG!? ","%d",__LINE__);
9658 pic14_emitcode(";BUG!? ","%d",__LINE__);
9663 /* this should never happen */
9664 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9665 "got unknown pointer type");
9668 //aopPut(AOP(result),l, GPTRSIZE - 1);
9672 /* just copy the pointers */
9673 size = AOP_SIZE(result);
9677 aopGet(AOP(right),offset,FALSE,FALSE),
9686 /* so we now know that the size of destination is greater
9687 than the size of the source.
9688 Now, if the next iCode is an operator then we might be
9689 able to optimize the operation without performing a cast.
9691 if(genMixedOperation(ic))
9694 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9696 /* we move to result for the size of source */
9697 size = AOP_SIZE(right);
9700 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9701 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9705 /* now depending on the sign of the destination */
9706 size = AOP_SIZE(result) - AOP_SIZE(right);
9707 /* if unsigned or not an integral type */
9708 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9710 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9712 /* we need to extend the sign :{ */
9715 /* Save one instruction of casting char to int */
9716 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9717 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9718 emitpcode(POC_DECF, popGet(AOP(result),offset));
9720 emitpcodeNULLop(POC_CLRW);
9723 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9725 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9727 emitpcode(POC_MOVLW, popGetLit(0xff));
9730 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9735 freeAsmop(right,NULL,ic,TRUE);
9736 freeAsmop(result,NULL,ic,TRUE);
9740 /*-----------------------------------------------------------------*/
9741 /* genDjnz - generate decrement & jump if not zero instrucion */
9742 /*-----------------------------------------------------------------*/
9743 static int genDjnz (iCode *ic, iCode *ifx)
9746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9751 /* if the if condition has a false label
9752 then we cannot save */
9756 /* if the minus is not of the form
9758 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9759 !IS_OP_LITERAL(IC_RIGHT(ic)))
9762 if (operandLitValue(IC_RIGHT(ic)) != 1)
9765 /* if the size of this greater than one then no
9767 if (getSize(operandType(IC_RESULT(ic))) > 1)
9770 /* otherwise we can save BIG */
9771 lbl = newiTempLabel(NULL);
9772 lbl1= newiTempLabel(NULL);
9774 aopOp(IC_RESULT(ic),ic,FALSE);
9776 if (IS_AOP_PREG(IC_RESULT(ic))) {
9777 pic14_emitcode("dec","%s",
9778 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9779 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9780 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9784 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9785 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9787 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9788 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9791 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9792 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9793 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9794 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9797 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9802 /*-----------------------------------------------------------------*/
9803 /* genReceive - generate code for a receive iCode */
9804 /*-----------------------------------------------------------------*/
9805 static void genReceive (iCode *ic)
9807 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9809 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9810 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9811 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9813 int size = getSize(operandType(IC_RESULT(ic)));
9814 int offset = fReturnSizePic - size;
9816 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9817 fReturn[fReturnSizePic - offset - 1] : "acc"));
9820 aopOp(IC_RESULT(ic),ic,FALSE);
9821 size = AOP_SIZE(IC_RESULT(ic));
9824 pic14_emitcode ("pop","acc");
9825 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9830 aopOp(IC_RESULT(ic),ic,FALSE);
9832 assignResultValue(IC_RESULT(ic));
9835 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9838 /*-----------------------------------------------------------------*/
9839 /* genDummyRead - generate code for dummy read of volatiles */
9840 /*-----------------------------------------------------------------*/
9842 genDummyRead (iCode * ic)
9844 pic14_emitcode ("; genDummyRead","");
9845 pic14_emitcode ("; not implemented","");
9850 /*-----------------------------------------------------------------*/
9851 /* genpic14Code - generate code for pic14 based controllers */
9852 /*-----------------------------------------------------------------*/
9854 * At this point, ralloc.c has gone through the iCode and attempted
9855 * to optimize in a way suitable for a PIC. Now we've got to generate
9856 * PIC instructions that correspond to the iCode.
9858 * Once the instructions are generated, we'll pass through both the
9859 * peep hole optimizer and the pCode optimizer.
9860 *-----------------------------------------------------------------*/
9862 void genpic14Code (iCode *lic)
9867 lineHead = lineCurr = NULL;
9869 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9872 /* if debug information required */
9873 if (options.debug && currFunc) {
9875 debugFile->writeFunction (currFunc, lic);
9880 for (ic = lic ; ic ; ic = ic->next ) {
9882 DEBUGpic14_emitcode(";ic","");
9883 if ( cln != ic->lineno ) {
9884 if ( options.debug ) {
9885 debugFile->writeCLine (ic);
9888 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9889 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9890 printCLine(ic->filename, ic->lineno));
9892 if (!options.noCcodeInAsm) {
9894 newpCodeCSource(ic->lineno,
9896 printCLine(ic->filename, ic->lineno)));
9902 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9904 /* if the result is marked as
9905 spilt and rematerializable or code for
9906 this has already been generated then
9908 if (resultRemat(ic) || ic->generated )
9911 /* depending on the operation */
9930 /* IPOP happens only when trying to restore a
9931 spilt live range, if there is an ifx statement
9932 following this pop then the if statement might
9933 be using some of the registers being popped which
9934 would destory the contents of the register so
9935 we need to check for this condition and handle it */
9937 ic->next->op == IFX &&
9938 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9939 genIfx (ic->next,ic);
9957 genEndFunction (ic);
9977 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9994 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9998 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10005 /* note these two are xlated by algebraic equivalence
10006 during parsing SDCC.y */
10007 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10008 "got '>=' or '<=' shouldn't have come here");
10012 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10024 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10028 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10032 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10056 genRightShift (ic);
10059 case GET_VALUE_AT_ADDRESS:
10064 if (POINTER_SET(ic))
10091 addSet(&_G.sendSet,ic);
10094 case DUMMY_READ_VOLATILE:
10104 /* now we are ready to call the
10105 peep hole optimizer */
10106 if (!options.nopeep) {
10107 peepHole (&lineHead);
10109 /* now do the actual printing */
10110 printLine (lineHead,codeOutFile);
10113 DFPRINTF((stderr,"printing pBlock\n\n"));
10114 printpBlock(stdout,pb);