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 (strcmp(sym1->rname,sym2->rname) == 0)
704 /* if left is a tmp & right is not */
708 (sym1->usl.spillLoc == sym2))
715 (sym2->usl.spillLoc == sym1))
721 /*-----------------------------------------------------------------*/
722 /* pic14_sameRegs - two asmops have the same registers */
723 /*-----------------------------------------------------------------*/
724 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
731 if (aop1->type != AOP_REG ||
732 aop2->type != AOP_REG )
735 if (aop1->size != aop2->size )
738 for (i = 0 ; i < aop1->size ; i++ )
739 if (aop1->aopu.aop_reg[i] !=
740 aop2->aopu.aop_reg[i] )
746 /*-----------------------------------------------------------------*/
747 /* aopOp - allocates an asmop for an operand : */
748 /*-----------------------------------------------------------------*/
749 void aopOp (operand *op, iCode *ic, bool result)
758 // DEBUGpic14_emitcode(";","%d",__LINE__);
759 /* if this a literal */
760 if (IS_OP_LITERAL(op)) {
761 op->aop = aop = newAsmop(AOP_LIT);
762 aop->aopu.aop_lit = op->operand.valOperand;
763 aop->size = getSize(operandType(op));
768 sym_link *type = operandType(op);
769 if(IS_PTR_CONST(type))
770 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
773 /* if already has a asmop then continue */
777 /* if the underlying symbol has a aop */
778 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
779 DEBUGpic14_emitcode(";","%d",__LINE__);
780 op->aop = OP_SYMBOL(op)->aop;
784 /* if this is a true symbol */
785 if (IS_TRUE_SYMOP(op)) {
786 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
787 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
791 /* this is a temporary : this has
797 e) can be a return use only */
802 /* if the type is a conditional */
803 if (sym->regType == REG_CND) {
804 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
809 /* if it is spilt then two situations
811 b) has a spill location */
812 if (sym->isspilt || sym->nRegs == 0) {
814 DEBUGpic14_emitcode(";","%d",__LINE__);
815 /* rematerialize it NOW */
818 sym->aop = op->aop = aop =
820 aop->size = getSize(sym->type);
821 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
827 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
828 aop->size = getSize(sym->type);
829 for ( i = 0 ; i < 2 ; i++ )
830 aop->aopu.aop_str[i] = accUse[i];
831 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
836 if(sym->isptr) { // && sym->uptr
837 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
838 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
840 //PCOI(aop->aopu.pcop)->_const = 0;
841 //PCOI(aop->aopu.pcop)->index = 0;
843 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
844 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
846 //allocDirReg (IC_LEFT(ic));
848 aop->size = getSize(sym->type);
849 DEBUGpic14_emitcode(";","%d",__LINE__);
856 aop = op->aop = sym->aop = newAsmop(AOP_STR);
857 aop->size = getSize(sym->type);
858 for ( i = 0 ; i < fReturnSizePic ; i++ )
859 aop->aopu.aop_str[i] = fReturn[i];
861 DEBUGpic14_emitcode(";","%d",__LINE__);
866 /* else spill location */
867 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
868 /* force a new aop if sizes differ */
869 sym->usl.spillLoc->aop = NULL;
871 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
872 __FUNCTION__,__LINE__,
873 sym->usl.spillLoc->rname,
874 sym->rname, sym->usl.spillLoc->offset);
876 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
877 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
878 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
880 sym->usl.spillLoc->offset);
881 aop->size = getSize(sym->type);
887 sym_link *type = operandType(op);
888 if(IS_PTR_CONST(type))
889 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
892 /* must be in a register */
893 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
894 sym->aop = op->aop = aop = newAsmop(AOP_REG);
895 aop->size = sym->nRegs;
896 for ( i = 0 ; i < sym->nRegs ;i++)
897 aop->aopu.aop_reg[i] = sym->regs[i];
900 /*-----------------------------------------------------------------*/
901 /* freeAsmop - free up the asmop given to an operand */
902 /*----------------------------------------------------------------*/
903 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
920 /* depending on the asmop type only three cases need work AOP_RO
921 , AOP_R1 && AOP_STK */
927 pic14_emitcode ("pop","ar0");
931 bitVectUnSetBit(ic->rUsed,R0_IDX);
937 pic14_emitcode ("pop","ar1");
941 bitVectUnSetBit(ic->rUsed,R1_IDX);
947 int stk = aop->aopu.aop_stk + aop->size;
948 bitVectUnSetBit(ic->rUsed,R0_IDX);
949 bitVectUnSetBit(ic->rUsed,R1_IDX);
951 getFreePtr(ic,&aop,FALSE);
953 if (options.stack10bit)
955 /* I'm not sure what to do here yet... */
958 "*** Warning: probably generating bad code for "
959 "10 bit stack mode.\n");
963 pic14_emitcode ("mov","a,_bp");
964 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
965 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
967 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
971 pic14_emitcode("pop","acc");
972 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
974 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
977 freeAsmop(op,NULL,ic,TRUE);
979 pic14_emitcode("pop","ar0");
984 pic14_emitcode("pop","ar1");
992 /* all other cases just dealloc */
996 OP_SYMBOL(op)->aop = NULL;
997 /* if the symbol has a spill */
999 SPIL_LOC(op)->aop = NULL;
1004 /*-----------------------------------------------------------------*/
1005 /* aopGet - for fetching value of the aop */
1006 /*-----------------------------------------------------------------*/
1007 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1012 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1013 /* offset is greater than
1015 if (offset > (aop->size - 1) &&
1016 aop->type != AOP_LIT)
1019 /* depending on type */
1020 switch (aop->type) {
1024 DEBUGpic14_emitcode(";","%d",__LINE__);
1025 /* if we need to increment it */
1026 while (offset > aop->coff) {
1027 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1031 while (offset < aop->coff) {
1032 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1036 aop->coff = offset ;
1038 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1039 return (dname ? "acc" : "a");
1041 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1042 rs = Safe_calloc(1,strlen(s)+1);
1048 DEBUGpic14_emitcode(";","%d",__LINE__);
1049 if (aop->type == AOP_DPTR2)
1054 while (offset > aop->coff) {
1055 pic14_emitcode ("inc","dptr");
1059 while (offset < aop->coff) {
1060 pic14_emitcode("lcall","__decdptr");
1066 pic14_emitcode("clr","a");
1067 pic14_emitcode("movc","a,@a+dptr");
1070 pic14_emitcode("movx","a,@dptr");
1073 if (aop->type == AOP_DPTR2)
1078 return (dname ? "acc" : "a");
1083 sprintf (s,"%s",aop->aopu.aop_immd);
1086 sprintf(s,"(%s >> %d)",
1091 aop->aopu.aop_immd);
1092 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1093 rs = Safe_calloc(1,strlen(s)+1);
1099 sprintf(s,"(%s + %d)",
1102 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1104 sprintf(s,"%s",aop->aopu.aop_dir);
1105 rs = Safe_calloc(1,strlen(s)+1);
1111 // return aop->aopu.aop_reg[offset]->dname;
1113 return aop->aopu.aop_reg[offset]->name;
1116 //pic14_emitcode(";","%d",__LINE__);
1117 return aop->aopu.aop_dir;
1120 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1121 return "AOP_accumulator_bug";
1124 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1125 rs = Safe_calloc(1,strlen(s)+1);
1130 aop->coff = offset ;
1131 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1134 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1136 return aop->aopu.aop_str[offset];
1140 pCodeOp *pcop = aop->aopu.pcop;
1141 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1143 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1144 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1145 sprintf(s,"%s", pcop->name);
1147 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1150 rs = Safe_calloc(1,strlen(s)+1);
1156 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1157 "aopget got unsupported aop->type");
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGetTempReg(void)
1170 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1171 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1172 PCOR(pcop)->r->wasUsed=1;
1173 PCOR(pcop)->r->isFree=0;
1179 /*-----------------------------------------------------------------*/
1180 /* popGetTempReg - create a new temporary pCodeOp */
1181 /*-----------------------------------------------------------------*/
1182 void popReleaseTempReg(pCodeOp *pcop)
1185 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1186 PCOR(pcop)->r->isFree = 1;
1189 /*-----------------------------------------------------------------*/
1190 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1191 /*-----------------------------------------------------------------*/
1192 pCodeOp *popGetLabel(unsigned int key)
1195 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1197 if(key>(unsigned int)max_key)
1200 return newpCodeOpLabel(NULL,key+100+labelOffset);
1203 /*-------------------------------------------------------------------*/
1204 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1205 /*-------------------------------------------------------------------*/
1206 pCodeOp *popGetHighLabel(unsigned int key)
1209 pcop = popGetLabel(key);
1210 PCOLAB(pcop)->offset = 1;
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1220 return newpCodeOpLit(lit);
1223 /*-----------------------------------------------------------------*/
1224 /* popGetImmd - asm operator to pcode immediate conversion */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1229 return newpCodeOpImmd(name, offset,index, 0, is_func);
1233 /*-----------------------------------------------------------------*/
1234 /* popGet - asm operator to pcode operator conversion */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetWithString(char *str, int isExtern)
1242 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1246 pcop = newpCodeOp(str,PO_STR);
1247 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString - */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1258 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259 pcop->type = PO_DIR;
1261 DEBUGpic14_emitcode(";","%d",__LINE__);
1266 pcop->name = Safe_calloc(1,strlen(str)+1);
1267 strcpy(pcop->name,str);
1269 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271 PCOR(pcop)->r = dirregWithName(pcop->name);
1272 if(PCOR(pcop)->r == NULL) {
1273 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1277 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1279 PCOR(pcop)->instance = offset;
1284 /*-----------------------------------------------------------------*/
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popRegFromIdx(int rIdx)
1290 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1291 __FUNCTION__,__LINE__,rIdx);
1293 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295 PCOR(pcop)->rIdx = rIdx;
1296 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1297 PCOR(pcop)->r->isFree = 0;
1298 PCOR(pcop)->r->wasUsed = 1;
1300 pcop->type = PCOR(pcop)->r->pc_type;
1306 /*-----------------------------------------------------------------*/
1307 /* popGet - asm operator to pcode operator conversion */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1311 //char *s = buffer ;
1316 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1317 /* offset is greater than
1320 if (offset > (aop->size - 1) &&
1321 aop->type != AOP_LIT)
1322 return NULL; //zero;
1324 /* depending on type */
1325 switch (aop->type) {
1332 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1336 DEBUGpic14_emitcode(";","%d",__LINE__);
1337 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1340 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1342 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1343 pcop->type = PO_DIR;
1347 sprintf(s,"(%s + %d)",
1351 sprintf(s,"%s",aop->aopu.aop_dir);
1352 pcop->name = Safe_calloc(1,strlen(s)+1);
1353 strcpy(pcop->name,s);
1355 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1356 strcpy(pcop->name,aop->aopu.aop_dir);
1357 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1358 if(PCOR(pcop)->r == NULL) {
1359 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1360 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1361 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1363 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1365 PCOR(pcop)->instance = offset;
1372 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1374 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1375 PCOR(pcop)->rIdx = rIdx;
1376 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1377 PCOR(pcop)->r->wasUsed=1;
1378 PCOR(pcop)->r->isFree=0;
1380 PCOR(pcop)->instance = offset;
1381 pcop->type = PCOR(pcop)->r->pc_type;
1382 //rs = aop->aopu.aop_reg[offset]->name;
1383 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1388 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1389 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1390 //if(PCOR(pcop)->r == NULL)
1391 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1395 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1398 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1399 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1401 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1402 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1403 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1404 pcop->type = PCOR(pcop)->r->pc_type;
1405 pcop->name = PCOR(pcop)->r->name;
1411 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1413 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1414 pcop = pCodeOpCopy(aop->aopu.pcop);
1415 PCOI(pcop)->offset = offset;
1419 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1420 "popGet got unsupported aop->type");
1423 /*-----------------------------------------------------------------*/
1424 /* aopPut - puts a string for a aop */
1425 /*-----------------------------------------------------------------*/
1426 void aopPut (asmop *aop, char *s, int offset)
1431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1433 if (aop->size && offset > ( aop->size - 1)) {
1434 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1435 "aopPut got offset > aop->size");
1439 /* will assign value to value */
1440 /* depending on where it is ofcourse */
1441 switch (aop->type) {
1444 sprintf(d,"(%s + %d)",
1445 aop->aopu.aop_dir,offset);
1446 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1449 sprintf(d,"%s",aop->aopu.aop_dir);
1452 DEBUGpic14_emitcode(";","%d",__LINE__);
1454 pic14_emitcode("movf","%s,w",s);
1455 pic14_emitcode("movwf","%s",d);
1458 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1459 if(offset >= aop->size) {
1460 emitpcode(POC_CLRF,popGet(aop,offset));
1463 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1466 emitpcode(POC_MOVWF,popGet(aop,offset));
1473 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1474 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1477 strcmp(s,"r0") == 0 ||
1478 strcmp(s,"r1") == 0 ||
1479 strcmp(s,"r2") == 0 ||
1480 strcmp(s,"r3") == 0 ||
1481 strcmp(s,"r4") == 0 ||
1482 strcmp(s,"r5") == 0 ||
1483 strcmp(s,"r6") == 0 ||
1484 strcmp(s,"r7") == 0 )
1485 pic14_emitcode("mov","%s,%s ; %d",
1486 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1490 if(strcmp(s,"W")==0 )
1491 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1493 pic14_emitcode("movwf","%s",
1494 aop->aopu.aop_reg[offset]->name);
1496 if(strcmp(s,zero)==0) {
1497 emitpcode(POC_CLRF,popGet(aop,offset));
1499 } else if(strcmp(s,"W")==0) {
1500 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1501 pcop->type = PO_GPR_REGISTER;
1503 PCOR(pcop)->rIdx = -1;
1504 PCOR(pcop)->r = NULL;
1506 DEBUGpic14_emitcode(";","%d",__LINE__);
1507 pcop->name = Safe_strdup(s);
1508 emitpcode(POC_MOVFW,pcop);
1509 emitpcode(POC_MOVWF,popGet(aop,offset));
1510 } else if(strcmp(s,one)==0) {
1511 emitpcode(POC_CLRF,popGet(aop,offset));
1512 emitpcode(POC_INCF,popGet(aop,offset));
1514 emitpcode(POC_MOVWF,popGet(aop,offset));
1522 if (aop->type == AOP_DPTR2)
1528 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1529 "aopPut writting to code space");
1533 while (offset > aop->coff) {
1535 pic14_emitcode ("inc","dptr");
1538 while (offset < aop->coff) {
1540 pic14_emitcode("lcall","__decdptr");
1545 /* if not in accumulater */
1548 pic14_emitcode ("movx","@dptr,a");
1550 if (aop->type == AOP_DPTR2)
1558 while (offset > aop->coff) {
1560 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1562 while (offset < aop->coff) {
1564 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1570 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1575 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1577 if (strcmp(s,"r0") == 0 ||
1578 strcmp(s,"r1") == 0 ||
1579 strcmp(s,"r2") == 0 ||
1580 strcmp(s,"r3") == 0 ||
1581 strcmp(s,"r4") == 0 ||
1582 strcmp(s,"r5") == 0 ||
1583 strcmp(s,"r6") == 0 ||
1584 strcmp(s,"r7") == 0 ) {
1586 sprintf(buffer,"a%s",s);
1587 pic14_emitcode("mov","@%s,%s",
1588 aop->aopu.aop_ptr->name,buffer);
1590 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1595 if (strcmp(s,"a") == 0)
1596 pic14_emitcode("push","acc");
1598 pic14_emitcode("push","%s",s);
1603 /* if bit variable */
1604 if (!aop->aopu.aop_dir) {
1605 pic14_emitcode("clr","a");
1606 pic14_emitcode("rlc","a");
1609 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1612 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1615 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1617 lbl = newiTempLabel(NULL);
1619 if (strcmp(s,"a")) {
1622 pic14_emitcode("clr","c");
1623 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1624 pic14_emitcode("cpl","c");
1625 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1626 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1633 if (strcmp(aop->aopu.aop_str[offset],s))
1634 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1639 if (!offset && (strcmp(s,"acc") == 0))
1642 if (strcmp(aop->aopu.aop_str[offset],s))
1643 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1647 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1648 "aopPut got unsupported aop->type");
1654 /*-----------------------------------------------------------------*/
1655 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1656 /*-----------------------------------------------------------------*/
1657 void mov2w (asmop *aop, int offset)
1663 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1665 if ( aop->type == AOP_PCODE ||
1666 aop->type == AOP_LIT ||
1667 aop->type == AOP_IMMD )
1668 emitpcode(POC_MOVLW,popGet(aop,offset));
1670 emitpcode(POC_MOVFW,popGet(aop,offset));
1674 /*-----------------------------------------------------------------*/
1675 /* reAdjustPreg - points a register back to where it should */
1676 /*-----------------------------------------------------------------*/
1677 static void reAdjustPreg (asmop *aop)
1681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1683 if ((size = aop->size) <= 1)
1686 switch (aop->type) {
1690 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1694 if (aop->type == AOP_DPTR2)
1700 pic14_emitcode("lcall","__decdptr");
1703 if (aop->type == AOP_DPTR2)
1715 /*-----------------------------------------------------------------*/
1716 /* opIsGptr: returns non-zero if the passed operand is */
1717 /* a generic pointer type. */
1718 /*-----------------------------------------------------------------*/
1719 static int opIsGptr(operand *op)
1721 sym_link *type = operandType(op);
1723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1724 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1732 /*-----------------------------------------------------------------*/
1733 /* pic14_getDataSize - get the operand data size */
1734 /*-----------------------------------------------------------------*/
1735 int pic14_getDataSize(operand *op)
1737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1740 return AOP_SIZE(op);
1742 // tsd- in the pic port, the genptr size is 1, so this code here
1743 // fails. ( in the 8051 port, the size was 4).
1746 size = AOP_SIZE(op);
1747 if (size == GPTRSIZE)
1749 sym_link *type = operandType(op);
1750 if (IS_GENPTR(type))
1752 /* generic pointer; arithmetic operations
1753 * should ignore the high byte (pointer type).
1756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1763 /*-----------------------------------------------------------------*/
1764 /* pic14_outAcc - output Acc */
1765 /*-----------------------------------------------------------------*/
1766 void pic14_outAcc(operand *result)
1769 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1770 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1773 size = pic14_getDataSize(result);
1775 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1778 /* unsigned or positive */
1780 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1785 /*-----------------------------------------------------------------*/
1786 /* pic14_outBitC - output a bit C */
1787 /*-----------------------------------------------------------------*/
1788 void pic14_outBitC(operand *result)
1791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1792 /* if the result is bit */
1793 if (AOP_TYPE(result) == AOP_CRY)
1794 aopPut(AOP(result),"c",0);
1796 pic14_emitcode("clr","a ; %d", __LINE__);
1797 pic14_emitcode("rlc","a");
1798 pic14_outAcc(result);
1802 /*-----------------------------------------------------------------*/
1803 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1804 /*-----------------------------------------------------------------*/
1805 void pic14_toBoolean(operand *oper)
1807 int size = AOP_SIZE(oper) - 1;
1810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1812 if ( AOP_TYPE(oper) != AOP_ACC) {
1813 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1816 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1821 /*-----------------------------------------------------------------*/
1822 /* genNot - generate code for ! operation */
1823 /*-----------------------------------------------------------------*/
1824 static void genNot (iCode *ic)
1829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1830 /* assign asmOps to operand & result */
1831 aopOp (IC_LEFT(ic),ic,FALSE);
1832 aopOp (IC_RESULT(ic),ic,TRUE);
1834 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1835 /* if in bit space then a special case */
1836 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1837 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1838 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1839 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1841 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1842 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1843 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1848 size = AOP_SIZE(IC_LEFT(ic));
1850 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1851 emitpcode(POC_ANDLW,popGetLit(1));
1852 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1855 pic14_toBoolean(IC_LEFT(ic));
1857 tlbl = newiTempLabel(NULL);
1858 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1859 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1860 pic14_outBitC(IC_RESULT(ic));
1863 /* release the aops */
1864 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1865 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1869 /*-----------------------------------------------------------------*/
1870 /* genCpl - generate code for complement */
1871 /*-----------------------------------------------------------------*/
1872 static void genCpl (iCode *ic)
1874 operand *left, *result;
1878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1879 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1880 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1882 /* if both are in bit space then
1884 if (AOP_TYPE(result) == AOP_CRY &&
1885 AOP_TYPE(left) == AOP_CRY ) {
1887 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1888 pic14_emitcode("cpl","c");
1889 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1893 size = AOP_SIZE(result);
1896 if(AOP_TYPE(left) == AOP_ACC)
1897 emitpcode(POC_XORLW, popGetLit(0xff));
1899 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1901 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1907 /* release the aops */
1908 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1909 freeAsmop(result,NULL,ic,TRUE);
1912 /*-----------------------------------------------------------------*/
1913 /* genUminusFloat - unary minus for floating points */
1914 /*-----------------------------------------------------------------*/
1915 static void genUminusFloat(operand *op,operand *result)
1917 int size ,offset =0 ;
1920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1921 /* for this we just need to flip the
1922 first it then copy the rest in place */
1923 size = AOP_SIZE(op) - 1;
1924 l = aopGet(AOP(op),3,FALSE,FALSE);
1928 pic14_emitcode("cpl","acc.7");
1929 aopPut(AOP(result),"a",3);
1933 aopGet(AOP(op),offset,FALSE,FALSE),
1939 /*-----------------------------------------------------------------*/
1940 /* genUminus - unary minus code generation */
1941 /*-----------------------------------------------------------------*/
1942 static void genUminus (iCode *ic)
1945 sym_link *optype, *rtype;
1948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1950 aopOp(IC_LEFT(ic),ic,FALSE);
1951 aopOp(IC_RESULT(ic),ic,TRUE);
1953 /* if both in bit space then special
1955 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1956 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1958 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1959 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1960 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1965 optype = operandType(IC_LEFT(ic));
1966 rtype = operandType(IC_RESULT(ic));
1968 /* if float then do float stuff */
1969 if (IS_FLOAT(optype)) {
1970 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1974 /* otherwise subtract from zero by taking the 2's complement */
1975 size = AOP_SIZE(IC_LEFT(ic));
1977 for(i=0; i<size; i++) {
1978 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1979 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1981 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1982 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1986 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1987 for(i=1; i<size; i++) {
1989 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1993 /* release the aops */
1994 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1995 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1998 /*-----------------------------------------------------------------*/
1999 /* saveRegisters - will look for a call and save the registers */
2000 /*-----------------------------------------------------------------*/
2001 static void saveRegisters(iCode *lic)
2008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2010 for (ic = lic ; ic ; ic = ic->next)
2011 if (ic->op == CALL || ic->op == PCALL)
2015 fprintf(stderr,"found parameter push with no function call\n");
2019 /* if the registers have been saved already then
2021 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2024 /* find the registers in use at this time
2025 and push them away to safety */
2026 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2030 if (options.useXstack) {
2031 if (bitVectBitValue(rsave,R0_IDX))
2032 pic14_emitcode("mov","b,r0");
2033 pic14_emitcode("mov","r0,%s",spname);
2034 for (i = 0 ; i < pic14_nRegs ; i++) {
2035 if (bitVectBitValue(rsave,i)) {
2037 pic14_emitcode("mov","a,b");
2039 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2040 pic14_emitcode("movx","@r0,a");
2041 pic14_emitcode("inc","r0");
2044 pic14_emitcode("mov","%s,r0",spname);
2045 if (bitVectBitValue(rsave,R0_IDX))
2046 pic14_emitcode("mov","r0,b");
2048 //for (i = 0 ; i < pic14_nRegs ; i++) {
2049 // if (bitVectBitValue(rsave,i))
2050 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2053 dtype = operandType(IC_LEFT(ic));
2054 if (currFunc && dtype &&
2055 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2056 IFFUNC_ISISR(currFunc->type) &&
2059 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2062 /*-----------------------------------------------------------------*/
2063 /* unsaveRegisters - pop the pushed registers */
2064 /*-----------------------------------------------------------------*/
2065 static void unsaveRegisters (iCode *ic)
2070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2071 /* find the registers in use at this time
2072 and push them away to safety */
2073 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2076 if (options.useXstack) {
2077 pic14_emitcode("mov","r0,%s",spname);
2078 for (i = pic14_nRegs ; i >= 0 ; i--) {
2079 if (bitVectBitValue(rsave,i)) {
2080 pic14_emitcode("dec","r0");
2081 pic14_emitcode("movx","a,@r0");
2083 pic14_emitcode("mov","b,a");
2085 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2089 pic14_emitcode("mov","%s,r0",spname);
2090 if (bitVectBitValue(rsave,R0_IDX))
2091 pic14_emitcode("mov","r0,b");
2093 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2094 // if (bitVectBitValue(rsave,i))
2095 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2101 /*-----------------------------------------------------------------*/
2103 /*-----------------------------------------------------------------*/
2104 static void pushSide(operand * oper, int size)
2108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2110 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2111 if (AOP_TYPE(oper) != AOP_REG &&
2112 AOP_TYPE(oper) != AOP_DIR &&
2114 pic14_emitcode("mov","a,%s",l);
2115 pic14_emitcode("push","acc");
2117 pic14_emitcode("push","%s",l);
2122 /*-----------------------------------------------------------------*/
2123 /* assignResultValue - */
2124 /*-----------------------------------------------------------------*/
2125 static void assignResultValue(operand * oper)
2127 int size = AOP_SIZE(oper);
2129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2131 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2134 if (GpsuedoStkPtr++)
2135 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2136 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2141 /*-----------------------------------------------------------------*/
2142 /* genIpush - genrate code for pushing this gets a little complex */
2143 /*-----------------------------------------------------------------*/
2144 static void genIpush (iCode *ic)
2147 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2149 int size, offset = 0 ;
2153 /* if this is not a parm push : ie. it is spill push
2154 and spill push is always done on the local stack */
2155 if (!ic->parmPush) {
2157 /* and the item is spilt then do nothing */
2158 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2161 aopOp(IC_LEFT(ic),ic,FALSE);
2162 size = AOP_SIZE(IC_LEFT(ic));
2163 /* push it on the stack */
2165 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2170 pic14_emitcode("push","%s",l);
2175 /* this is a paramter push: in this case we call
2176 the routine to find the call and save those
2177 registers that need to be saved */
2180 /* then do the push */
2181 aopOp(IC_LEFT(ic),ic,FALSE);
2184 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2185 size = AOP_SIZE(IC_LEFT(ic));
2188 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2189 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2190 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2192 pic14_emitcode("mov","a,%s",l);
2193 pic14_emitcode("push","acc");
2195 pic14_emitcode("push","%s",l);
2198 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2202 /*-----------------------------------------------------------------*/
2203 /* genIpop - recover the registers: can happen only for spilling */
2204 /*-----------------------------------------------------------------*/
2205 static void genIpop (iCode *ic)
2207 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2212 /* if the temp was not pushed then */
2213 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2216 aopOp(IC_LEFT(ic),ic,FALSE);
2217 size = AOP_SIZE(IC_LEFT(ic));
2220 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2223 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2227 /*-----------------------------------------------------------------*/
2228 /* unsaverbank - restores the resgister bank from stack */
2229 /*-----------------------------------------------------------------*/
2230 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2232 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2240 if (options.useXstack) {
2242 r = getFreePtr(ic,&aop,FALSE);
2245 pic14_emitcode("mov","%s,_spx",r->name);
2246 pic14_emitcode("movx","a,@%s",r->name);
2247 pic14_emitcode("mov","psw,a");
2248 pic14_emitcode("dec","%s",r->name);
2251 pic14_emitcode ("pop","psw");
2254 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2255 if (options.useXstack) {
2256 pic14_emitcode("movx","a,@%s",r->name);
2257 //pic14_emitcode("mov","(%s+%d),a",
2258 // regspic14[i].base,8*bank+regspic14[i].offset);
2259 pic14_emitcode("dec","%s",r->name);
2262 pic14_emitcode("pop",""); //"(%s+%d)",
2263 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2266 if (options.useXstack) {
2268 pic14_emitcode("mov","_spx,%s",r->name);
2269 freeAsmop(NULL,aop,ic,TRUE);
2275 /*-----------------------------------------------------------------*/
2276 /* saverbank - saves an entire register bank on the stack */
2277 /*-----------------------------------------------------------------*/
2278 static void saverbank (int bank, iCode *ic, bool pushPsw)
2280 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2287 if (options.useXstack) {
2290 r = getFreePtr(ic,&aop,FALSE);
2291 pic14_emitcode("mov","%s,_spx",r->name);
2295 for (i = 0 ; i < pic14_nRegs ;i++) {
2296 if (options.useXstack) {
2297 pic14_emitcode("inc","%s",r->name);
2298 //pic14_emitcode("mov","a,(%s+%d)",
2299 // regspic14[i].base,8*bank+regspic14[i].offset);
2300 pic14_emitcode("movx","@%s,a",r->name);
2302 pic14_emitcode("push","");// "(%s+%d)",
2303 //regspic14[i].base,8*bank+regspic14[i].offset);
2307 if (options.useXstack) {
2308 pic14_emitcode("mov","a,psw");
2309 pic14_emitcode("movx","@%s,a",r->name);
2310 pic14_emitcode("inc","%s",r->name);
2311 pic14_emitcode("mov","_spx,%s",r->name);
2312 freeAsmop (NULL,aop,ic,TRUE);
2315 pic14_emitcode("push","psw");
2317 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2323 /*-----------------------------------------------------------------*/
2324 /* genCall - generates a call statement */
2325 /*-----------------------------------------------------------------*/
2326 static void genCall (iCode *ic)
2330 unsigned char *name;
2333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2335 /* if caller saves & we have not saved then */
2339 /* if we are calling a function that is not using
2340 the same register bank then we need to save the
2341 destination registers on the stack */
2342 dtype = operandType(IC_LEFT(ic));
2343 if (currFunc && dtype &&
2344 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2345 IFFUNC_ISISR(currFunc->type) &&
2348 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2350 /* if send set is not empty the assign */
2353 /* For the Pic port, there is no data stack.
2354 * So parameters passed to functions are stored
2355 * in registers. (The pCode optimizer will get
2356 * rid of most of these :).
2358 int psuedoStkPtr=-1;
2359 int firstTimeThruLoop = 1;
2361 _G.sendSet = reverseSet(_G.sendSet);
2363 /* First figure how many parameters are getting passed */
2364 for (sic = setFirstItem(_G.sendSet) ; sic ;
2365 sic = setNextItem(_G.sendSet)) {
2367 aopOp(IC_LEFT(sic),sic,FALSE);
2368 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2369 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2372 for (sic = setFirstItem(_G.sendSet) ; sic ;
2373 sic = setNextItem(_G.sendSet)) {
2374 int size, offset = 0;
2376 aopOp(IC_LEFT(sic),sic,FALSE);
2377 size = AOP_SIZE(IC_LEFT(sic));
2380 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2381 AopType(AOP_TYPE(IC_LEFT(sic))));
2383 if(!firstTimeThruLoop) {
2384 /* If this is not the first time we've been through the loop
2385 * then we need to save the parameter in a temporary
2386 * register. The last byte of the last parameter is
2388 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2391 firstTimeThruLoop=0;
2393 mov2w (AOP(IC_LEFT(sic)), offset);
2396 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2401 sym = OP_SYMBOL(IC_LEFT(ic));
2402 name = sym->rname[0] ? sym->rname : sym->name;
2403 isExtern = IS_EXTERN(sym->etype);
2405 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2407 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2409 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2412 /* if we need assign a result value */
2413 if ((IS_ITEMP(IC_RESULT(ic)) &&
2414 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2415 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2416 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2419 aopOp(IC_RESULT(ic),ic,FALSE);
2422 assignResultValue(IC_RESULT(ic));
2424 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2425 AopType(AOP_TYPE(IC_RESULT(ic))));
2427 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2430 /* adjust the stack for parameters if
2432 if (ic->parmBytes) {
2434 if (ic->parmBytes > 3) {
2435 pic14_emitcode("mov","a,%s",spname);
2436 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2437 pic14_emitcode("mov","%s,a",spname);
2439 for ( i = 0 ; i < ic->parmBytes ;i++)
2440 pic14_emitcode("dec","%s",spname);
2444 /* if register bank was saved then pop them */
2446 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2448 /* if we hade saved some registers then unsave them */
2449 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2450 unsaveRegisters (ic);
2455 /*-----------------------------------------------------------------*/
2456 /* genPcall - generates a call by pointer statement */
2457 /*-----------------------------------------------------------------*/
2458 static void genPcall (iCode *ic)
2461 symbol *albl = newiTempLabel(NULL);
2462 symbol *blbl = newiTempLabel(NULL);
2467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2468 /* if caller saves & we have not saved then */
2472 /* if we are calling a function that is not using
2473 the same register bank then we need to save the
2474 destination registers on the stack */
2475 dtype = operandType(IC_LEFT(ic));
2476 if (currFunc && dtype &&
2477 IFFUNC_ISISR(currFunc->type) &&
2478 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2479 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2482 aopOp(left,ic,FALSE);
2483 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2485 pushSide(IC_LEFT(ic), FPTRSIZE);
2487 /* if send set is not empty, assign parameters */
2490 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2491 /* no way to pass args - W always gets used to make the call */
2493 /* first idea - factor out a common helper function and call it.
2494 But don't know how to get it generated only once in its own block
2496 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2499 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2500 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2501 buffer = Safe_calloc(1,strlen(rname)+16);
2502 sprintf(buffer, "%s_goto_helper", rname);
2503 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2507 emitpcode(POC_CALL,popGetLabel(albl->key));
2508 pcop = popGetLabel(blbl->key);
2509 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2510 emitpcode(POC_GOTO,pcop);
2511 emitpLabel(albl->key);
2513 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2515 emitpcode(poc,popGet(AOP(left),1));
2516 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2517 emitpcode(poc,popGet(AOP(left),0));
2518 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2520 emitpLabel(blbl->key);
2522 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2524 /* if we need to assign a result value */
2525 if ((IS_ITEMP(IC_RESULT(ic)) &&
2526 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2527 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2528 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2531 aopOp(IC_RESULT(ic),ic,FALSE);
2534 assignResultValue(IC_RESULT(ic));
2536 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2539 /* if register bank was saved then unsave them */
2540 if (currFunc && dtype &&
2541 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2542 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2544 /* if we hade saved some registers then
2547 unsaveRegisters (ic);
2551 /*-----------------------------------------------------------------*/
2552 /* resultRemat - result is rematerializable */
2553 /*-----------------------------------------------------------------*/
2554 static int resultRemat (iCode *ic)
2556 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2557 if (SKIP_IC(ic) || ic->op == IFX)
2560 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2561 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2562 if (sym->remat && !POINTER_SET(ic))
2569 #if defined(__BORLANDC__) || defined(_MSC_VER)
2570 #define STRCASECMP stricmp
2572 #define STRCASECMP strcasecmp
2576 /*-----------------------------------------------------------------*/
2577 /* inExcludeList - return 1 if the string is in exclude Reg list */
2578 /*-----------------------------------------------------------------*/
2579 static bool inExcludeList(char *s)
2581 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2584 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2585 if (options.excludeRegs[i] &&
2586 STRCASECMP(options.excludeRegs[i],"none") == 0)
2589 for ( i = 0 ; options.excludeRegs[i]; i++) {
2590 if (options.excludeRegs[i] &&
2591 STRCASECMP(s,options.excludeRegs[i]) == 0)
2598 /*-----------------------------------------------------------------*/
2599 /* genFunction - generated code for function entry */
2600 /*-----------------------------------------------------------------*/
2601 static void genFunction (iCode *ic)
2606 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2608 labelOffset += (max_key+4);
2612 /* create the function header */
2613 pic14_emitcode(";","-----------------------------------------");
2614 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2615 pic14_emitcode(";","-----------------------------------------");
2617 pic14_emitcode("","%s:",sym->rname);
2618 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2620 ftype = operandType(IC_LEFT(ic));
2622 /* if critical function then turn interrupts off */
2623 if (IFFUNC_ISCRITICAL(ftype))
2624 pic14_emitcode("clr","ea");
2626 /* here we need to generate the equates for the
2627 register bank if required */
2629 if (FUNC_REGBANK(ftype) != rbank) {
2632 rbank = FUNC_REGBANK(ftype);
2633 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2634 if (strcmp(regspic14[i].base,"0") == 0)
2635 pic14_emitcode("","%s = 0x%02x",
2637 8*rbank+regspic14[i].offset);
2639 pic14_emitcode ("","%s = %s + 0x%02x",
2642 8*rbank+regspic14[i].offset);
2647 /* if this is an interrupt service routine */
2648 if (IFFUNC_ISISR(sym->type)) {
2649 /* already done in pic14createInterruptVect() - delete me
2650 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2651 emitpcodeNULLop(POC_NOP);
2652 emitpcodeNULLop(POC_NOP);
2653 emitpcodeNULLop(POC_NOP);
2655 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2656 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2657 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2658 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2659 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2660 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2661 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2663 pBlockConvert2ISR(pb);
2665 if (!inExcludeList("acc"))
2666 pic14_emitcode ("push","acc");
2667 if (!inExcludeList("b"))
2668 pic14_emitcode ("push","b");
2669 if (!inExcludeList("dpl"))
2670 pic14_emitcode ("push","dpl");
2671 if (!inExcludeList("dph"))
2672 pic14_emitcode ("push","dph");
2673 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2675 pic14_emitcode ("push", "dpx");
2676 /* Make sure we're using standard DPTR */
2677 pic14_emitcode ("push", "dps");
2678 pic14_emitcode ("mov", "dps, #0x00");
2679 if (options.stack10bit)
2681 /* This ISR could conceivably use DPTR2. Better save it. */
2682 pic14_emitcode ("push", "dpl1");
2683 pic14_emitcode ("push", "dph1");
2684 pic14_emitcode ("push", "dpx1");
2687 /* if this isr has no bank i.e. is going to
2688 run with bank 0 , then we need to save more
2690 if (!FUNC_REGBANK(sym->type)) {
2692 /* if this function does not call any other
2693 function then we can be economical and
2694 save only those registers that are used */
2695 if (! IFFUNC_HASFCALL(sym->type)) {
2698 /* if any registers used */
2699 if (sym->regsUsed) {
2700 /* save the registers used */
2701 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2702 if (bitVectBitValue(sym->regsUsed,i) ||
2703 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2704 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2709 /* this function has a function call cannot
2710 determines register usage so we will have the
2712 saverbank(0,ic,FALSE);
2717 /* if callee-save to be used for this function
2718 then save the registers being used in this function */
2719 if (IFFUNC_CALLEESAVES(sym->type)) {
2722 /* if any registers used */
2723 if (sym->regsUsed) {
2724 /* save the registers used */
2725 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2726 if (bitVectBitValue(sym->regsUsed,i) ||
2727 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2728 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2736 /* set the register bank to the desired value */
2737 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2738 pic14_emitcode("push","psw");
2739 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2742 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2744 if (options.useXstack) {
2745 pic14_emitcode("mov","r0,%s",spname);
2746 pic14_emitcode("mov","a,_bp");
2747 pic14_emitcode("movx","@r0,a");
2748 pic14_emitcode("inc","%s",spname);
2752 /* set up the stack */
2753 pic14_emitcode ("push","_bp"); /* save the callers stack */
2755 pic14_emitcode ("mov","_bp,%s",spname);
2758 /* adjust the stack for the function */
2763 werror(W_STACK_OVERFLOW,sym->name);
2765 if (i > 3 && sym->recvSize < 4) {
2767 pic14_emitcode ("mov","a,sp");
2768 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2769 pic14_emitcode ("mov","sp,a");
2774 pic14_emitcode("inc","sp");
2779 pic14_emitcode ("mov","a,_spx");
2780 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2781 pic14_emitcode ("mov","_spx,a");
2786 /*-----------------------------------------------------------------*/
2787 /* genEndFunction - generates epilogue for functions */
2788 /*-----------------------------------------------------------------*/
2789 static void genEndFunction (iCode *ic)
2791 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2795 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2797 pic14_emitcode ("mov","%s,_bp",spname);
2800 /* if use external stack but some variables were
2801 added to the local stack then decrement the
2803 if (options.useXstack && sym->stack) {
2804 pic14_emitcode("mov","a,sp");
2805 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2806 pic14_emitcode("mov","sp,a");
2810 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2811 if (options.useXstack) {
2812 pic14_emitcode("mov","r0,%s",spname);
2813 pic14_emitcode("movx","a,@r0");
2814 pic14_emitcode("mov","_bp,a");
2815 pic14_emitcode("dec","%s",spname);
2819 pic14_emitcode ("pop","_bp");
2823 /* restore the register bank */
2824 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2825 pic14_emitcode ("pop","psw");
2827 if (IFFUNC_ISISR(sym->type)) {
2829 /* now we need to restore the registers */
2830 /* if this isr has no bank i.e. is going to
2831 run with bank 0 , then we need to save more
2833 if (!FUNC_REGBANK(sym->type)) {
2835 /* if this function does not call any other
2836 function then we can be economical and
2837 save only those registers that are used */
2838 if (! IFFUNC_HASFCALL(sym->type)) {
2841 /* if any registers used */
2842 if (sym->regsUsed) {
2843 /* save the registers used */
2844 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2845 if (bitVectBitValue(sym->regsUsed,i) ||
2846 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2847 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2852 /* this function has a function call cannot
2853 determines register usage so we will have the
2855 unsaverbank(0,ic,FALSE);
2859 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2861 if (options.stack10bit)
2863 pic14_emitcode ("pop", "dpx1");
2864 pic14_emitcode ("pop", "dph1");
2865 pic14_emitcode ("pop", "dpl1");
2867 pic14_emitcode ("pop", "dps");
2868 pic14_emitcode ("pop", "dpx");
2870 if (!inExcludeList("dph"))
2871 pic14_emitcode ("pop","dph");
2872 if (!inExcludeList("dpl"))
2873 pic14_emitcode ("pop","dpl");
2874 if (!inExcludeList("b"))
2875 pic14_emitcode ("pop","b");
2876 if (!inExcludeList("acc"))
2877 pic14_emitcode ("pop","acc");
2879 if (IFFUNC_ISCRITICAL(sym->type))
2880 pic14_emitcode("setb","ea");
2883 /* if debug then send end of function */
2884 /* if (options.debug && currFunc) { */
2886 debugFile->writeEndFunction (currFunc, ic, 1);
2889 pic14_emitcode ("reti","");
2890 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2891 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2892 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2893 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2894 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2895 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2896 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2897 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2898 emitpcodeNULLop(POC_RETFIE);
2901 if (IFFUNC_ISCRITICAL(sym->type))
2902 pic14_emitcode("setb","ea");
2904 if (IFFUNC_CALLEESAVES(sym->type)) {
2907 /* if any registers used */
2908 if (sym->regsUsed) {
2909 /* save the registers used */
2910 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2911 if (bitVectBitValue(sym->regsUsed,i) ||
2912 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2913 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2919 /* if debug then send end of function */
2921 debugFile->writeEndFunction (currFunc, ic, 1);
2924 pic14_emitcode ("return","");
2925 emitpcodeNULLop(POC_RETURN);
2927 /* Mark the end of a function */
2928 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2933 /*-----------------------------------------------------------------*/
2934 /* genRet - generate code for return statement */
2935 /*-----------------------------------------------------------------*/
2936 static void genRet (iCode *ic)
2938 int size,offset = 0 , pushed = 0;
2940 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2941 /* if we have no return value then
2942 just generate the "ret" */
2946 /* we have something to return then
2947 move the return value into place */
2948 aopOp(IC_LEFT(ic),ic,FALSE);
2949 size = AOP_SIZE(IC_LEFT(ic));
2953 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2955 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2957 pic14_emitcode("push","%s",l);
2960 l = aopGet(AOP(IC_LEFT(ic)),offset,
2962 if (strcmp(fReturn[offset],l)) {
2963 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2964 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2965 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2966 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2967 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2969 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2972 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2982 if (strcmp(fReturn[pushed],"a"))
2983 pic14_emitcode("pop",fReturn[pushed]);
2985 pic14_emitcode("pop","acc");
2988 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2991 /* generate a jump to the return label
2992 if the next is not the return statement */
2993 if (!(ic->next && ic->next->op == LABEL &&
2994 IC_LABEL(ic->next) == returnLabel)) {
2996 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2997 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3002 /*-----------------------------------------------------------------*/
3003 /* genLabel - generates a label */
3004 /*-----------------------------------------------------------------*/
3005 static void genLabel (iCode *ic)
3007 /* special case never generate */
3008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3009 if (IC_LABEL(ic) == entryLabel)
3012 emitpLabel(IC_LABEL(ic)->key);
3013 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3016 /*-----------------------------------------------------------------*/
3017 /* genGoto - generates a goto */
3018 /*-----------------------------------------------------------------*/
3020 static void genGoto (iCode *ic)
3022 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3023 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3027 /*-----------------------------------------------------------------*/
3028 /* genMultbits :- multiplication of bits */
3029 /*-----------------------------------------------------------------*/
3030 static void genMultbits (operand *left,
3034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3036 if(!pic14_sameRegs(AOP(result),AOP(right)))
3037 emitpcode(POC_BSF, popGet(AOP(result),0));
3039 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3040 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3041 emitpcode(POC_BCF, popGet(AOP(result),0));
3046 /*-----------------------------------------------------------------*/
3047 /* genMultOneByte : 8 bit multiplication & division */
3048 /*-----------------------------------------------------------------*/
3049 static void genMultOneByte (operand *left,
3053 sym_link *opetype = operandType(result);
3058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3059 DEBUGpic14_AopType(__LINE__,left,right,result);
3060 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3062 /* (if two literals, the value is computed before) */
3063 /* if one literal, literal on the right */
3064 if (AOP_TYPE(left) == AOP_LIT){
3070 size = AOP_SIZE(result);
3073 if (AOP_TYPE(right) == AOP_LIT){
3074 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3075 aopGet(AOP(right),0,FALSE,FALSE),
3076 aopGet(AOP(left),0,FALSE,FALSE),
3077 aopGet(AOP(result),0,FALSE,FALSE));
3078 pic14_emitcode("call","genMultLit");
3080 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3081 aopGet(AOP(right),0,FALSE,FALSE),
3082 aopGet(AOP(left),0,FALSE,FALSE),
3083 aopGet(AOP(result),0,FALSE,FALSE));
3084 pic14_emitcode("call","genMult8X8_8");
3087 genMult8X8_8 (left, right,result);
3090 /* signed or unsigned */
3091 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3092 //l = aopGet(AOP(left),0,FALSE,FALSE);
3094 //pic14_emitcode("mul","ab");
3095 /* if result size = 1, mul signed = mul unsigned */
3096 //aopPut(AOP(result),"a",0);
3098 } else { // (size > 1)
3100 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3101 aopGet(AOP(right),0,FALSE,FALSE),
3102 aopGet(AOP(left),0,FALSE,FALSE),
3103 aopGet(AOP(result),0,FALSE,FALSE));
3105 if (SPEC_USIGN(opetype)){
3106 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3107 genUMult8X8_16 (left, right, result, NULL);
3110 /* for filling the MSBs */
3111 emitpcode(POC_CLRF, popGet(AOP(result),2));
3112 emitpcode(POC_CLRF, popGet(AOP(result),3));
3116 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3118 pic14_emitcode("mov","a,b");
3120 /* adjust the MSB if left or right neg */
3122 /* if one literal */
3123 if (AOP_TYPE(right) == AOP_LIT){
3124 pic14_emitcode("multiply ","right is a lit");
3125 /* AND literal negative */
3126 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3127 /* adjust MSB (c==0 after mul) */
3128 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3132 genSMult8X8_16 (left, right, result, NULL);
3136 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3138 pic14_emitcode("rlc","a");
3139 pic14_emitcode("subb","a,acc");
3147 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3148 //aopPut(AOP(result),"a",offset++);
3152 /*-----------------------------------------------------------------*/
3153 /* genMult - generates code for multiplication */
3154 /*-----------------------------------------------------------------*/
3155 static void genMult (iCode *ic)
3157 operand *left = IC_LEFT(ic);
3158 operand *right = IC_RIGHT(ic);
3159 operand *result= IC_RESULT(ic);
3161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3162 /* assign the amsops */
3163 aopOp (left,ic,FALSE);
3164 aopOp (right,ic,FALSE);
3165 aopOp (result,ic,TRUE);
3167 DEBUGpic14_AopType(__LINE__,left,right,result);
3169 /* special cases first */
3171 if (AOP_TYPE(left) == AOP_CRY &&
3172 AOP_TYPE(right)== AOP_CRY) {
3173 genMultbits(left,right,result);
3177 /* if both are of size == 1 */
3178 if (AOP_SIZE(left) == 1 &&
3179 AOP_SIZE(right) == 1 ) {
3180 genMultOneByte(left,right,result);
3184 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3186 /* should have been converted to function call */
3190 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3191 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3192 freeAsmop(result,NULL,ic,TRUE);
3195 /*-----------------------------------------------------------------*/
3196 /* genDivbits :- division of bits */
3197 /*-----------------------------------------------------------------*/
3198 static void genDivbits (operand *left,
3205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3206 /* the result must be bit */
3207 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3208 l = aopGet(AOP(left),0,FALSE,FALSE);
3212 pic14_emitcode("div","ab");
3213 pic14_emitcode("rrc","a");
3214 aopPut(AOP(result),"c",0);
3217 /*-----------------------------------------------------------------*/
3218 /* genDivOneByte : 8 bit division */
3219 /*-----------------------------------------------------------------*/
3220 static void genDivOneByte (operand *left,
3224 sym_link *opetype = operandType(result);
3229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3230 size = AOP_SIZE(result) - 1;
3232 /* signed or unsigned */
3233 if (SPEC_USIGN(opetype)) {
3234 /* unsigned is easy */
3235 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3236 l = aopGet(AOP(left),0,FALSE,FALSE);
3238 pic14_emitcode("div","ab");
3239 aopPut(AOP(result),"a",0);
3241 aopPut(AOP(result),zero,offset++);
3245 /* signed is a little bit more difficult */
3247 /* save the signs of the operands */
3248 l = aopGet(AOP(left),0,FALSE,FALSE);
3250 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3251 pic14_emitcode("push","acc"); /* save it on the stack */
3253 /* now sign adjust for both left & right */
3254 l = aopGet(AOP(right),0,FALSE,FALSE);
3256 lbl = newiTempLabel(NULL);
3257 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3258 pic14_emitcode("cpl","a");
3259 pic14_emitcode("inc","a");
3260 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3261 pic14_emitcode("mov","b,a");
3263 /* sign adjust left side */
3264 l = aopGet(AOP(left),0,FALSE,FALSE);
3267 lbl = newiTempLabel(NULL);
3268 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3269 pic14_emitcode("cpl","a");
3270 pic14_emitcode("inc","a");
3271 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3273 /* now the division */
3274 pic14_emitcode("div","ab");
3275 /* we are interested in the lower order
3277 pic14_emitcode("mov","b,a");
3278 lbl = newiTempLabel(NULL);
3279 pic14_emitcode("pop","acc");
3280 /* if there was an over flow we don't
3281 adjust the sign of the result */
3282 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3283 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3285 pic14_emitcode("clr","a");
3286 pic14_emitcode("subb","a,b");
3287 pic14_emitcode("mov","b,a");
3288 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3290 /* now we are done */
3291 aopPut(AOP(result),"b",0);
3293 pic14_emitcode("mov","c,b.7");
3294 pic14_emitcode("subb","a,acc");
3297 aopPut(AOP(result),"a",offset++);
3301 /*-----------------------------------------------------------------*/
3302 /* genDiv - generates code for division */
3303 /*-----------------------------------------------------------------*/
3304 static void genDiv (iCode *ic)
3306 operand *left = IC_LEFT(ic);
3307 operand *right = IC_RIGHT(ic);
3308 operand *result= IC_RESULT(ic);
3310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3311 /* assign the amsops */
3312 aopOp (left,ic,FALSE);
3313 aopOp (right,ic,FALSE);
3314 aopOp (result,ic,TRUE);
3316 /* special cases first */
3318 if (AOP_TYPE(left) == AOP_CRY &&
3319 AOP_TYPE(right)== AOP_CRY) {
3320 genDivbits(left,right,result);
3324 /* if both are of size == 1 */
3325 if (AOP_SIZE(left) == 1 &&
3326 AOP_SIZE(right) == 1 ) {
3327 genDivOneByte(left,right,result);
3331 /* should have been converted to function call */
3334 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3335 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3336 freeAsmop(result,NULL,ic,TRUE);
3339 /*-----------------------------------------------------------------*/
3340 /* genModbits :- modulus of bits */
3341 /*-----------------------------------------------------------------*/
3342 static void genModbits (operand *left,
3349 /* the result must be bit */
3350 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3351 l = aopGet(AOP(left),0,FALSE,FALSE);
3355 pic14_emitcode("div","ab");
3356 pic14_emitcode("mov","a,b");
3357 pic14_emitcode("rrc","a");
3358 aopPut(AOP(result),"c",0);
3361 /*-----------------------------------------------------------------*/
3362 /* genModOneByte : 8 bit modulus */
3363 /*-----------------------------------------------------------------*/
3364 static void genModOneByte (operand *left,
3368 sym_link *opetype = operandType(result);
3372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3373 /* signed or unsigned */
3374 if (SPEC_USIGN(opetype)) {
3375 /* unsigned is easy */
3376 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3377 l = aopGet(AOP(left),0,FALSE,FALSE);
3379 pic14_emitcode("div","ab");
3380 aopPut(AOP(result),"b",0);
3384 /* signed is a little bit more difficult */
3386 /* save the signs of the operands */
3387 l = aopGet(AOP(left),0,FALSE,FALSE);
3390 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3391 pic14_emitcode("push","acc"); /* save it on the stack */
3393 /* now sign adjust for both left & right */
3394 l = aopGet(AOP(right),0,FALSE,FALSE);
3397 lbl = newiTempLabel(NULL);
3398 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3399 pic14_emitcode("cpl","a");
3400 pic14_emitcode("inc","a");
3401 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3402 pic14_emitcode("mov","b,a");
3404 /* sign adjust left side */
3405 l = aopGet(AOP(left),0,FALSE,FALSE);
3408 lbl = newiTempLabel(NULL);
3409 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3410 pic14_emitcode("cpl","a");
3411 pic14_emitcode("inc","a");
3412 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3414 /* now the multiplication */
3415 pic14_emitcode("div","ab");
3416 /* we are interested in the lower order
3418 lbl = newiTempLabel(NULL);
3419 pic14_emitcode("pop","acc");
3420 /* if there was an over flow we don't
3421 adjust the sign of the result */
3422 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3423 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3425 pic14_emitcode("clr","a");
3426 pic14_emitcode("subb","a,b");
3427 pic14_emitcode("mov","b,a");
3428 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3430 /* now we are done */
3431 aopPut(AOP(result),"b",0);
3435 /*-----------------------------------------------------------------*/
3436 /* genMod - generates code for division */
3437 /*-----------------------------------------------------------------*/
3438 static void genMod (iCode *ic)
3440 operand *left = IC_LEFT(ic);
3441 operand *right = IC_RIGHT(ic);
3442 operand *result= IC_RESULT(ic);
3444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3445 /* assign the amsops */
3446 aopOp (left,ic,FALSE);
3447 aopOp (right,ic,FALSE);
3448 aopOp (result,ic,TRUE);
3450 /* special cases first */
3452 if (AOP_TYPE(left) == AOP_CRY &&
3453 AOP_TYPE(right)== AOP_CRY) {
3454 genModbits(left,right,result);
3458 /* if both are of size == 1 */
3459 if (AOP_SIZE(left) == 1 &&
3460 AOP_SIZE(right) == 1 ) {
3461 genModOneByte(left,right,result);
3465 /* should have been converted to function call */
3469 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3470 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3471 freeAsmop(result,NULL,ic,TRUE);
3474 /*-----------------------------------------------------------------*/
3475 /* genIfxJump :- will create a jump depending on the ifx */
3476 /*-----------------------------------------------------------------*/
3478 note: May need to add parameter to indicate when a variable is in bit space.
3480 static void genIfxJump (iCode *ic, char *jval)
3483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3484 /* if true label then we jump if condition
3486 if ( IC_TRUE(ic) ) {
3488 if(strcmp(jval,"a") == 0)
3490 else if (strcmp(jval,"c") == 0)
3493 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3494 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3497 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3498 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3502 /* false label is present */
3503 if(strcmp(jval,"a") == 0)
3505 else if (strcmp(jval,"c") == 0)
3508 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3509 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3512 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3513 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3518 /* mark the icode as generated */
3522 /*-----------------------------------------------------------------*/
3524 /*-----------------------------------------------------------------*/
3525 static void genSkip(iCode *ifx,int status_bit)
3530 if ( IC_TRUE(ifx) ) {
3531 switch(status_bit) {
3546 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3547 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3551 switch(status_bit) {
3565 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3566 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3572 /*-----------------------------------------------------------------*/
3574 /*-----------------------------------------------------------------*/
3575 static void genSkipc(resolvedIfx *rifx)
3585 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3586 rifx->generated = 1;
3589 /*-----------------------------------------------------------------*/
3591 /*-----------------------------------------------------------------*/
3592 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3597 if( (rifx->condition ^ invert_condition) & 1)
3602 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3603 rifx->generated = 1;
3606 /*-----------------------------------------------------------------*/
3608 /*-----------------------------------------------------------------*/
3609 static void genSkipz(iCode *ifx, int condition)
3620 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3622 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3625 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3627 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3630 /*-----------------------------------------------------------------*/
3632 /*-----------------------------------------------------------------*/
3633 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3639 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3641 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3644 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3645 rifx->generated = 1;
3649 /*-----------------------------------------------------------------*/
3650 /* genChkZeroes :- greater or less than comparison */
3651 /* For each byte in a literal that is zero, inclusive or the */
3652 /* the corresponding byte in the operand with W */
3653 /* returns true if any of the bytes are zero */
3654 /*-----------------------------------------------------------------*/
3655 static int genChkZeroes(operand *op, int lit, int size)
3662 i = (lit >> (size*8)) & 0xff;
3666 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3668 emitpcode(POC_IORFW, popGet(AOP(op),size));
3677 /*-----------------------------------------------------------------*/
3678 /* genCmp :- greater or less than comparison */
3679 /*-----------------------------------------------------------------*/
3680 static void genCmp (operand *left,operand *right,
3681 operand *result, iCode *ifx, int sign)
3683 int size; //, offset = 0 ;
3684 unsigned long lit = 0L,i = 0;
3685 resolvedIfx rFalseIfx;
3686 // resolvedIfx rTrueIfx;
3688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3691 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3692 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3696 resolveIfx(&rFalseIfx,ifx);
3697 truelbl = newiTempLabel(NULL);
3698 size = max(AOP_SIZE(left),AOP_SIZE(right));
3700 DEBUGpic14_AopType(__LINE__,left,right,result);
3704 /* if literal is on the right then swap with left */
3705 if ((AOP_TYPE(right) == AOP_LIT)) {
3706 operand *tmp = right ;
3707 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3708 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3711 lit = (lit - 1) & mask;
3714 rFalseIfx.condition ^= 1;
3717 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3718 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3722 //if(IC_TRUE(ifx) == NULL)
3723 /* if left & right are bit variables */
3724 if (AOP_TYPE(left) == AOP_CRY &&
3725 AOP_TYPE(right) == AOP_CRY ) {
3726 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3727 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3729 /* subtract right from left if at the
3730 end the carry flag is set then we know that
3731 left is greater than right */
3735 symbol *lbl = newiTempLabel(NULL);
3738 if(AOP_TYPE(right) == AOP_LIT) {
3740 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3742 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3749 genSkipCond(&rFalseIfx,left,size-1,7);
3751 /* no need to compare to 0...*/
3752 /* NOTE: this is a de-generate compare that most certainly
3753 * creates some dead code. */
3754 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3756 if(ifx) ifx->generated = 1;
3763 //i = (lit >> (size*8)) & 0xff;
3764 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3766 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3768 i = ((0-lit) & 0xff);
3771 /* lit is 0x7f, all signed chars are less than
3772 * this except for 0x7f itself */
3773 emitpcode(POC_XORLW, popGetLit(0x7f));
3774 genSkipz2(&rFalseIfx,0);
3776 emitpcode(POC_ADDLW, popGetLit(0x80));
3777 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3778 genSkipc(&rFalseIfx);
3783 genSkipz2(&rFalseIfx,1);
3785 emitpcode(POC_ADDLW, popGetLit(i));
3786 genSkipc(&rFalseIfx);
3790 if(ifx) ifx->generated = 1;
3794 /* chars are out of the way. now do ints and longs */
3797 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3804 genSkipCond(&rFalseIfx,left,size,7);
3805 if(ifx) ifx->generated = 1;
3810 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3812 //rFalseIfx.condition ^= 1;
3813 //genSkipCond(&rFalseIfx,left,size,7);
3814 //rFalseIfx.condition ^= 1;
3816 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3817 if(rFalseIfx.condition)
3818 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3820 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3822 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3823 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3824 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3827 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3829 if(rFalseIfx.condition) {
3831 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3837 genSkipc(&rFalseIfx);
3838 emitpLabel(truelbl->key);
3839 if(ifx) ifx->generated = 1;
3846 if( (lit & 0xff) == 0) {
3847 /* lower byte is zero */
3848 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3849 i = ((lit >> 8) & 0xff) ^0x80;
3850 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3851 emitpcode(POC_ADDLW, popGetLit( 0x80));
3852 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3853 genSkipc(&rFalseIfx);
3856 if(ifx) ifx->generated = 1;
3861 /* Special cases for signed longs */
3862 if( (lit & 0xffffff) == 0) {
3863 /* lower byte is zero */
3864 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3865 i = ((lit >> 8*3) & 0xff) ^0x80;
3866 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3867 emitpcode(POC_ADDLW, popGetLit( 0x80));
3868 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3869 genSkipc(&rFalseIfx);
3872 if(ifx) ifx->generated = 1;
3880 if(lit & (0x80 << (size*8))) {
3881 /* lit is negative */
3882 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3884 //genSkipCond(&rFalseIfx,left,size,7);
3886 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3888 if(rFalseIfx.condition)
3889 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3891 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3895 /* lit is positive */
3896 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3897 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3898 if(rFalseIfx.condition)
3899 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3901 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3905 /* There are no more special cases, so perform a general compare */
3907 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3908 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3912 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3914 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3916 //rFalseIfx.condition ^= 1;
3917 genSkipc(&rFalseIfx);
3919 emitpLabel(truelbl->key);
3921 if(ifx) ifx->generated = 1;
3928 /* sign is out of the way. So now do an unsigned compare */
3929 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3932 /* General case - compare to an unsigned literal on the right.*/
3934 i = (lit >> (size*8)) & 0xff;
3935 emitpcode(POC_MOVLW, popGetLit(i));
3936 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3938 i = (lit >> (size*8)) & 0xff;
3941 emitpcode(POC_MOVLW, popGetLit(i));
3943 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3945 /* this byte of the lit is zero,
3946 *if it's not the last then OR in the variable */
3948 emitpcode(POC_IORFW, popGet(AOP(left),size));
3953 emitpLabel(lbl->key);
3954 //if(emitFinalCheck)
3955 genSkipc(&rFalseIfx);
3957 emitpLabel(truelbl->key);
3959 if(ifx) ifx->generated = 1;
3966 if(AOP_TYPE(left) == AOP_LIT) {
3967 //symbol *lbl = newiTempLabel(NULL);
3969 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3972 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3975 if((lit == 0) && (sign == 0)){
3978 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3980 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3982 genSkipz2(&rFalseIfx,0);
3983 if(ifx) ifx->generated = 1;
3990 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3991 /* degenerate compare can never be true */
3992 if(rFalseIfx.condition == 0)
3993 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3995 if(ifx) ifx->generated = 1;
4000 /* signed comparisons to a literal byte */
4002 int lp1 = (lit+1) & 0xff;
4004 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4007 rFalseIfx.condition ^= 1;
4008 genSkipCond(&rFalseIfx,right,0,7);
4011 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4012 emitpcode(POC_XORLW, popGetLit(0x7f));
4013 genSkipz2(&rFalseIfx,1);
4016 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4017 emitpcode(POC_ADDLW, popGetLit(0x80));
4018 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4019 rFalseIfx.condition ^= 1;
4020 genSkipc(&rFalseIfx);
4023 if(ifx) ifx->generated = 1;
4025 /* unsigned comparisons to a literal byte */
4027 switch(lit & 0xff ) {
4029 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4030 genSkipz2(&rFalseIfx,0);
4031 if(ifx) ifx->generated = 1;
4034 genSkipCond(&rFalseIfx,right,0,7);
4035 if(ifx) ifx->generated = 1;
4039 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4040 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4041 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4042 rFalseIfx.condition ^= 1;
4043 if (AOP_TYPE(result) == AOP_CRY) {
4044 genSkipc(&rFalseIfx);
4045 if(ifx) ifx->generated = 1;
4047 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4048 emitpcode(POC_CLRF, popGet(AOP(result),0));
4049 emitpcode(POC_RLF, popGet(AOP(result),0));
4050 emitpcode(POC_MOVLW, popGetLit(0x01));
4051 emitpcode(POC_XORWF, popGet(AOP(result),0));
4062 /* Size is greater than 1 */
4070 /* this means lit = 0xffffffff, or -1 */
4073 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4074 rFalseIfx.condition ^= 1;
4075 genSkipCond(&rFalseIfx,right,size,7);
4076 if(ifx) ifx->generated = 1;
4083 if(rFalseIfx.condition) {
4084 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4085 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4088 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4090 emitpcode(POC_IORFW, popGet(AOP(right),size));
4094 if(rFalseIfx.condition) {
4095 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4096 emitpLabel(truelbl->key);
4098 rFalseIfx.condition ^= 1;
4099 genSkipCond(&rFalseIfx,right,s,7);
4102 if(ifx) ifx->generated = 1;
4106 if((size == 1) && (0 == (lp1&0xff))) {
4107 /* lower byte of signed word is zero */
4108 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4109 i = ((lp1 >> 8) & 0xff) ^0x80;
4110 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4111 emitpcode(POC_ADDLW, popGetLit( 0x80));
4112 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4113 rFalseIfx.condition ^= 1;
4114 genSkipc(&rFalseIfx);
4117 if(ifx) ifx->generated = 1;
4121 if(lit & (0x80 << (size*8))) {
4122 /* Lit is less than zero */
4123 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4124 //rFalseIfx.condition ^= 1;
4125 //genSkipCond(&rFalseIfx,left,size,7);
4126 //rFalseIfx.condition ^= 1;
4127 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4128 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4130 if(rFalseIfx.condition)
4131 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4133 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4137 /* Lit is greater than or equal to zero */
4138 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4139 //rFalseIfx.condition ^= 1;
4140 //genSkipCond(&rFalseIfx,right,size,7);
4141 //rFalseIfx.condition ^= 1;
4143 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4144 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4146 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4147 if(rFalseIfx.condition)
4148 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4150 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4155 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4156 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4160 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4162 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4164 rFalseIfx.condition ^= 1;
4165 //rFalseIfx.condition = 1;
4166 genSkipc(&rFalseIfx);
4168 emitpLabel(truelbl->key);
4170 if(ifx) ifx->generated = 1;
4175 /* compare word or long to an unsigned literal on the right.*/
4180 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4183 break; /* handled above */
4186 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4188 emitpcode(POC_IORFW, popGet(AOP(right),size));
4189 genSkipz2(&rFalseIfx,0);
4193 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4195 emitpcode(POC_IORFW, popGet(AOP(right),size));
4198 if(rFalseIfx.condition)
4199 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4201 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4204 emitpcode(POC_MOVLW, popGetLit(lit+1));
4205 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4207 rFalseIfx.condition ^= 1;
4208 genSkipc(&rFalseIfx);
4211 emitpLabel(truelbl->key);
4213 if(ifx) ifx->generated = 1;
4219 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4220 i = (lit >> (size*8)) & 0xff;
4222 emitpcode(POC_MOVLW, popGetLit(i));
4223 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4226 i = (lit >> (size*8)) & 0xff;
4229 emitpcode(POC_MOVLW, popGetLit(i));
4231 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4233 /* this byte of the lit is zero,
4234 *if it's not the last then OR in the variable */
4236 emitpcode(POC_IORFW, popGet(AOP(right),size));
4241 emitpLabel(lbl->key);
4243 rFalseIfx.condition ^= 1;
4244 genSkipc(&rFalseIfx);
4248 emitpLabel(truelbl->key);
4249 if(ifx) ifx->generated = 1;
4253 /* Compare two variables */
4255 DEBUGpic14_emitcode(";sign","%d",sign);
4259 /* Sigh. thus sucks... */
4261 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4262 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4263 emitpcode(POC_MOVLW, popGetLit(0x80));
4264 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4265 emitpcode(POC_XORFW, popGet(AOP(right),size));
4266 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4268 /* Signed char comparison */
4269 /* Special thanks to Nikolai Golovchenko for this snippet */
4270 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4271 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4272 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4273 emitpcode(POC_XORFW, popGet(AOP(left),0));
4274 emitpcode(POC_XORFW, popGet(AOP(right),0));
4275 emitpcode(POC_ADDLW, popGetLit(0x80));
4277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4278 genSkipc(&rFalseIfx);
4280 if(ifx) ifx->generated = 1;
4286 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4287 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4291 /* The rest of the bytes of a multi-byte compare */
4295 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4298 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4299 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4304 emitpLabel(lbl->key);
4306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4307 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4308 (AOP_TYPE(result) == AOP_REG)) {
4309 emitpcode(POC_CLRF, popGet(AOP(result),0));
4310 emitpcode(POC_RLF, popGet(AOP(result),0));
4312 genSkipc(&rFalseIfx);
4314 //genSkipc(&rFalseIfx);
4315 if(ifx) ifx->generated = 1;
4322 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4324 pic14_outBitC(result);
4326 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4327 /* if the result is used in the next
4328 ifx conditional branch then generate
4329 code a little differently */
4331 genIfxJump (ifx,"c");
4333 pic14_outBitC(result);
4334 /* leave the result in acc */
4339 /*-----------------------------------------------------------------*/
4340 /* genCmpGt :- greater than comparison */
4341 /*-----------------------------------------------------------------*/
4342 static void genCmpGt (iCode *ic, iCode *ifx)
4344 operand *left, *right, *result;
4345 sym_link *letype , *retype;
4348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4350 right= IC_RIGHT(ic);
4351 result = IC_RESULT(ic);
4353 letype = getSpec(operandType(left));
4354 retype =getSpec(operandType(right));
4355 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4356 /* assign the amsops */
4357 aopOp (left,ic,FALSE);
4358 aopOp (right,ic,FALSE);
4359 aopOp (result,ic,TRUE);
4361 genCmp(right, left, result, ifx, sign);
4363 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4364 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4365 freeAsmop(result,NULL,ic,TRUE);
4368 /*-----------------------------------------------------------------*/
4369 /* genCmpLt - less than comparisons */
4370 /*-----------------------------------------------------------------*/
4371 static void genCmpLt (iCode *ic, iCode *ifx)
4373 operand *left, *right, *result;
4374 sym_link *letype , *retype;
4377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4379 right= IC_RIGHT(ic);
4380 result = IC_RESULT(ic);
4382 letype = getSpec(operandType(left));
4383 retype =getSpec(operandType(right));
4384 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4386 /* assign the amsops */
4387 aopOp (left,ic,FALSE);
4388 aopOp (right,ic,FALSE);
4389 aopOp (result,ic,TRUE);
4391 genCmp(left, right, result, ifx, sign);
4393 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4394 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4395 freeAsmop(result,NULL,ic,TRUE);
4398 /*-----------------------------------------------------------------*/
4399 /* genc16bit2lit - compare a 16 bit value to a literal */
4400 /*-----------------------------------------------------------------*/
4401 static void genc16bit2lit(operand *op, int lit, int offset)
4405 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4406 if( (lit&0xff) == 0)
4411 switch( BYTEofLONG(lit,i)) {
4413 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4416 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4419 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4422 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4423 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4428 switch( BYTEofLONG(lit,i)) {
4430 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4434 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4438 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4441 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4443 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4449 /*-----------------------------------------------------------------*/
4450 /* gencjneshort - compare and jump if not equal */
4451 /*-----------------------------------------------------------------*/
4452 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4454 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4456 int res_offset = 0; /* the result may be a different size then left or right */
4457 int res_size = AOP_SIZE(result);
4461 unsigned long lit = 0L;
4462 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4463 DEBUGpic14_AopType(__LINE__,left,right,result);
4465 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4466 resolveIfx(&rIfx,ifx);
4467 lbl = newiTempLabel(NULL);
4470 /* if the left side is a literal or
4471 if the right is in a pointer register and left
4473 if ((AOP_TYPE(left) == AOP_LIT) ||
4474 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4479 if(AOP_TYPE(right) == AOP_LIT)
4480 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4482 /* if the right side is a literal then anything goes */
4483 if (AOP_TYPE(right) == AOP_LIT &&
4484 AOP_TYPE(left) != AOP_DIR ) {
4487 genc16bit2lit(left, lit, 0);
4489 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4494 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4495 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4497 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4501 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4503 if(res_offset < res_size-1)
4511 /* if the right side is in a register or in direct space or
4512 if the left is a pointer register & right is not */
4513 else if (AOP_TYPE(right) == AOP_REG ||
4514 AOP_TYPE(right) == AOP_DIR ||
4515 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4516 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4517 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4518 int lbl_key = lbl->key;
4521 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4522 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4524 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4525 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4526 __FUNCTION__,__LINE__);
4530 /* switch(size) { */
4532 /* genc16bit2lit(left, lit, 0); */
4534 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4539 if((AOP_TYPE(left) == AOP_DIR) &&
4540 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4542 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4543 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4545 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4547 switch (lit & 0xff) {
4549 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4552 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4553 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4554 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4558 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4559 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4560 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4561 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4565 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4566 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4571 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4574 if(AOP_TYPE(result) == AOP_CRY) {
4575 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4580 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4582 /* fix me. probably need to check result size too */
4583 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4588 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4589 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4596 if(res_offset < res_size-1)
4601 } else if(AOP_TYPE(right) == AOP_REG &&
4602 AOP_TYPE(left) != AOP_DIR){
4605 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4606 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4607 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4612 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4614 if(res_offset < res_size-1)
4619 /* right is a pointer reg need both a & b */
4621 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4623 pic14_emitcode("mov","b,%s",l);
4624 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4625 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4630 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4632 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4634 emitpLabel(lbl->key);
4636 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4643 /*-----------------------------------------------------------------*/
4644 /* gencjne - compare and jump if not equal */
4645 /*-----------------------------------------------------------------*/
4646 static void gencjne(operand *left, operand *right, iCode *ifx)
4648 symbol *tlbl = newiTempLabel(NULL);
4650 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4651 gencjneshort(left, right, lbl);
4653 pic14_emitcode("mov","a,%s",one);
4654 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4655 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4656 pic14_emitcode("clr","a");
4657 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4659 emitpLabel(lbl->key);
4660 emitpLabel(tlbl->key);
4665 /*-----------------------------------------------------------------*/
4666 /* genCmpEq - generates code for equal to */
4667 /*-----------------------------------------------------------------*/
4668 static void genCmpEq (iCode *ic, iCode *ifx)
4670 operand *left, *right, *result;
4671 unsigned long lit = 0L;
4674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4677 DEBUGpic14_emitcode ("; ifx is non-null","");
4679 DEBUGpic14_emitcode ("; ifx is null","");
4681 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4682 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4683 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4685 size = max(AOP_SIZE(left),AOP_SIZE(right));
4687 DEBUGpic14_AopType(__LINE__,left,right,result);
4689 /* if literal, literal on the right or
4690 if the right is in a pointer register and left
4692 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4693 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4694 operand *tmp = right ;
4700 if(ifx && !AOP_SIZE(result)){
4702 /* if they are both bit variables */
4703 if (AOP_TYPE(left) == AOP_CRY &&
4704 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4705 if(AOP_TYPE(right) == AOP_LIT){
4706 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4708 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4709 pic14_emitcode("cpl","c");
4710 } else if(lit == 1L) {
4711 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4713 pic14_emitcode("clr","c");
4715 /* AOP_TYPE(right) == AOP_CRY */
4717 symbol *lbl = newiTempLabel(NULL);
4718 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4719 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4720 pic14_emitcode("cpl","c");
4721 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4723 /* if true label then we jump if condition
4725 tlbl = newiTempLabel(NULL);
4726 if ( IC_TRUE(ifx) ) {
4727 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4728 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4730 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4731 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4733 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4736 /* left and right are both bit variables, result is carry */
4739 resolveIfx(&rIfx,ifx);
4741 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4742 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4743 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4744 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4749 /* They're not both bit variables. Is the right a literal? */
4750 if(AOP_TYPE(right) == AOP_LIT) {
4751 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4756 switch(lit & 0xff) {
4758 if ( IC_TRUE(ifx) ) {
4759 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4761 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4763 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4764 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4768 if ( IC_TRUE(ifx) ) {
4769 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4771 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4773 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4774 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4778 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4780 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4785 /* end of size == 1 */
4789 genc16bit2lit(left,lit,offset);
4792 /* end of size == 2 */
4797 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4798 emitpcode(POC_IORFW,popGet(AOP(left),1));
4799 emitpcode(POC_IORFW,popGet(AOP(left),2));
4800 emitpcode(POC_IORFW,popGet(AOP(left),3));
4804 /* search for patterns that can be optimized */
4806 genc16bit2lit(left,lit,0);
4809 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4811 genc16bit2lit(left,lit,2);
4813 emitpcode(POC_IORFW,popGet(AOP(left),2));
4814 emitpcode(POC_IORFW,popGet(AOP(left),3));
4827 } else if(AOP_TYPE(right) == AOP_CRY ) {
4828 /* we know the left is not a bit, but that the right is */
4829 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4830 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4831 popGet(AOP(right),offset));
4832 emitpcode(POC_XORLW,popGetLit(1));
4834 /* if the two are equal, then W will be 0 and the Z bit is set
4835 * we could test Z now, or go ahead and check the high order bytes if
4836 * the variable we're comparing is larger than a byte. */
4839 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4841 if ( IC_TRUE(ifx) ) {
4843 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4844 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4847 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4848 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4852 /* They're both variables that are larger than bits */
4855 tlbl = newiTempLabel(NULL);
4858 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4859 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4861 if ( IC_TRUE(ifx) ) {
4864 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4865 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4868 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4869 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4873 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4874 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4878 if(s>1 && IC_TRUE(ifx)) {
4879 emitpLabel(tlbl->key);
4880 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4884 /* mark the icode as generated */
4889 /* if they are both bit variables */
4890 if (AOP_TYPE(left) == AOP_CRY &&
4891 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4892 if(AOP_TYPE(right) == AOP_LIT){
4893 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4895 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4896 pic14_emitcode("cpl","c");
4897 } else if(lit == 1L) {
4898 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4900 pic14_emitcode("clr","c");
4902 /* AOP_TYPE(right) == AOP_CRY */
4904 symbol *lbl = newiTempLabel(NULL);
4905 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4906 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4907 pic14_emitcode("cpl","c");
4908 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4911 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4912 pic14_outBitC(result);
4916 genIfxJump (ifx,"c");
4919 /* if the result is used in an arithmetic operation
4920 then put the result in place */
4921 pic14_outBitC(result);
4924 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4925 gencjne(left,right,result,ifx);
4928 gencjne(left,right,newiTempLabel(NULL));
4930 if(IC_TRUE(ifx)->key)
4931 gencjne(left,right,IC_TRUE(ifx)->key);
4933 gencjne(left,right,IC_FALSE(ifx)->key);
4937 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4938 aopPut(AOP(result),"a",0);
4943 genIfxJump (ifx,"a");
4947 /* if the result is used in an arithmetic operation
4948 then put the result in place */
4950 if (AOP_TYPE(result) != AOP_CRY)
4951 pic14_outAcc(result);
4953 /* leave the result in acc */
4957 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4958 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4959 freeAsmop(result,NULL,ic,TRUE);
4962 /*-----------------------------------------------------------------*/
4963 /* ifxForOp - returns the icode containing the ifx for operand */
4964 /*-----------------------------------------------------------------*/
4965 static iCode *ifxForOp ( operand *op, iCode *ic )
4967 /* if true symbol then needs to be assigned */
4968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4969 if (IS_TRUE_SYMOP(op))
4972 /* if this has register type condition and
4973 the next instruction is ifx with the same operand
4974 and live to of the operand is upto the ifx only then */
4976 ic->next->op == IFX &&
4977 IC_COND(ic->next)->key == op->key &&
4978 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4982 ic->next->op == IFX &&
4983 IC_COND(ic->next)->key == op->key) {
4984 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4988 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4990 ic->next->op == IFX)
4991 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4994 ic->next->op == IFX &&
4995 IC_COND(ic->next)->key == op->key) {
4996 DEBUGpic14_emitcode ("; "," key is okay");
4997 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4998 OP_SYMBOL(op)->liveTo,
5005 /*-----------------------------------------------------------------*/
5006 /* genAndOp - for && operation */
5007 /*-----------------------------------------------------------------*/
5008 static void genAndOp (iCode *ic)
5010 operand *left,*right, *result;
5013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5014 /* note here that && operations that are in an
5015 if statement are taken away by backPatchLabels
5016 only those used in arthmetic operations remain */
5017 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5018 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5019 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5021 DEBUGpic14_AopType(__LINE__,left,right,result);
5023 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5024 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5025 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5027 /* if both are bit variables */
5028 /* if (AOP_TYPE(left) == AOP_CRY && */
5029 /* AOP_TYPE(right) == AOP_CRY ) { */
5030 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5031 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5032 /* pic14_outBitC(result); */
5034 /* tlbl = newiTempLabel(NULL); */
5035 /* pic14_toBoolean(left); */
5036 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5037 /* pic14_toBoolean(right); */
5038 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5039 /* pic14_outBitAcc(result); */
5042 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5043 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5044 freeAsmop(result,NULL,ic,TRUE);
5048 /*-----------------------------------------------------------------*/
5049 /* genOrOp - for || operation */
5050 /*-----------------------------------------------------------------*/
5053 modified this code, but it doesn't appear to ever get called
5056 static void genOrOp (iCode *ic)
5058 operand *left,*right, *result;
5061 /* note here that || operations that are in an
5062 if statement are taken away by backPatchLabels
5063 only those used in arthmetic operations remain */
5064 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5065 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5066 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5067 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5069 DEBUGpic14_AopType(__LINE__,left,right,result);
5071 /* if both are bit variables */
5072 if (AOP_TYPE(left) == AOP_CRY &&
5073 AOP_TYPE(right) == AOP_CRY ) {
5074 pic14_emitcode("clrc","");
5075 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5076 AOP(left)->aopu.aop_dir,
5077 AOP(left)->aopu.aop_dir);
5078 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5079 AOP(right)->aopu.aop_dir,
5080 AOP(right)->aopu.aop_dir);
5081 pic14_emitcode("setc","");
5084 tlbl = newiTempLabel(NULL);
5085 pic14_toBoolean(left);
5087 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5088 pic14_toBoolean(right);
5089 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5091 pic14_outBitAcc(result);
5094 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5095 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5096 freeAsmop(result,NULL,ic,TRUE);
5099 /*-----------------------------------------------------------------*/
5100 /* isLiteralBit - test if lit == 2^n */
5101 /*-----------------------------------------------------------------*/
5102 static int isLiteralBit(unsigned long lit)
5104 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5105 0x100L,0x200L,0x400L,0x800L,
5106 0x1000L,0x2000L,0x4000L,0x8000L,
5107 0x10000L,0x20000L,0x40000L,0x80000L,
5108 0x100000L,0x200000L,0x400000L,0x800000L,
5109 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5110 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5114 for(idx = 0; idx < 32; idx++)
5120 /*-----------------------------------------------------------------*/
5121 /* continueIfTrue - */
5122 /*-----------------------------------------------------------------*/
5123 static void continueIfTrue (iCode *ic)
5125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5127 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5131 /*-----------------------------------------------------------------*/
5133 /*-----------------------------------------------------------------*/
5134 static void jumpIfTrue (iCode *ic)
5136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5138 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5142 /*-----------------------------------------------------------------*/
5143 /* jmpTrueOrFalse - */
5144 /*-----------------------------------------------------------------*/
5145 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5147 // ugly but optimized by peephole
5148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5150 symbol *nlbl = newiTempLabel(NULL);
5151 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5152 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5153 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5154 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5157 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5158 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5163 /*-----------------------------------------------------------------*/
5164 /* genAnd - code for and */
5165 /*-----------------------------------------------------------------*/
5166 static void genAnd (iCode *ic, iCode *ifx)
5168 operand *left, *right, *result;
5170 unsigned long lit = 0L;
5175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5176 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5177 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5178 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5180 resolveIfx(&rIfx,ifx);
5182 /* if left is a literal & right is not then exchange them */
5183 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5184 AOP_NEEDSACC(left)) {
5185 operand *tmp = right ;
5190 /* if result = right then exchange them */
5191 if(pic14_sameRegs(AOP(result),AOP(right))){
5192 operand *tmp = right ;
5197 /* if right is bit then exchange them */
5198 if (AOP_TYPE(right) == AOP_CRY &&
5199 AOP_TYPE(left) != AOP_CRY){
5200 operand *tmp = right ;
5204 if(AOP_TYPE(right) == AOP_LIT)
5205 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5207 size = AOP_SIZE(result);
5209 DEBUGpic14_AopType(__LINE__,left,right,result);
5212 // result = bit & yy;
5213 if (AOP_TYPE(left) == AOP_CRY){
5214 // c = bit & literal;
5215 if(AOP_TYPE(right) == AOP_LIT){
5217 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5220 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5223 if(size && (AOP_TYPE(result) == AOP_CRY)){
5224 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5227 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5231 pic14_emitcode("clr","c");
5234 if (AOP_TYPE(right) == AOP_CRY){
5236 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5237 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5240 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5242 pic14_emitcode("rrc","a");
5243 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5249 pic14_outBitC(result);
5251 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5252 genIfxJump(ifx, "c");
5256 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5257 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5258 if((AOP_TYPE(right) == AOP_LIT) &&
5259 (AOP_TYPE(result) == AOP_CRY) &&
5260 (AOP_TYPE(left) != AOP_CRY)){
5261 int posbit = isLiteralBit(lit);
5265 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5268 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5273 while (posbit > 7) {
5277 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5278 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5279 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5286 symbol *tlbl = newiTempLabel(NULL);
5287 int sizel = AOP_SIZE(left);
5289 pic14_emitcode("setb","c");
5291 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5292 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5294 if((posbit = isLiteralBit(bytelit)) != 0)
5295 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5297 if(bytelit != 0x0FFL)
5298 pic14_emitcode("anl","a,%s",
5299 aopGet(AOP(right),offset,FALSE,TRUE));
5300 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5305 // bit = left & literal
5307 pic14_emitcode("clr","c");
5308 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5310 // if(left & literal)
5313 jmpTrueOrFalse(ifx, tlbl);
5317 pic14_outBitC(result);
5321 /* if left is same as result */
5322 if(pic14_sameRegs(AOP(result),AOP(left))){
5324 for(;size--; offset++,lit>>=8) {
5325 if(AOP_TYPE(right) == AOP_LIT){
5326 switch(lit & 0xff) {
5328 /* and'ing with 0 has clears the result */
5329 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5330 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5333 /* and'ing with 0xff is a nop when the result and left are the same */
5338 int p = my_powof2( (~lit) & 0xff );
5340 /* only one bit is set in the literal, so use a bcf instruction */
5341 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5342 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5345 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5346 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5347 if(know_W != (int)(lit&0xff))
5348 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5350 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5355 if (AOP_TYPE(left) == AOP_ACC) {
5356 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5358 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5359 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5366 // left & result in different registers
5367 if(AOP_TYPE(result) == AOP_CRY){
5369 // if(size), result in bit
5370 // if(!size && ifx), conditional oper: if(left & right)
5371 symbol *tlbl = newiTempLabel(NULL);
5372 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5374 pic14_emitcode("setb","c");
5376 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5377 pic14_emitcode("anl","a,%s",
5378 aopGet(AOP(left),offset,FALSE,FALSE));
5379 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5384 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5385 pic14_outBitC(result);
5387 jmpTrueOrFalse(ifx, tlbl);
5389 for(;(size--);offset++) {
5391 // result = left & right
5392 if(AOP_TYPE(right) == AOP_LIT){
5393 int t = (lit >> (offset*8)) & 0x0FFL;
5396 pic14_emitcode("clrf","%s",
5397 aopGet(AOP(result),offset,FALSE,FALSE));
5398 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5401 if(AOP_TYPE(left) != AOP_ACC) {
5402 pic14_emitcode("movf","%s,w",
5403 aopGet(AOP(left),offset,FALSE,FALSE));
5404 pic14_emitcode("movwf","%s",
5405 aopGet(AOP(result),offset,FALSE,FALSE));
5406 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5408 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5411 if(AOP_TYPE(left) == AOP_ACC) {
5412 emitpcode(POC_ANDLW, popGetLit(t));
5414 pic14_emitcode("movlw","0x%x",t);
5415 pic14_emitcode("andwf","%s,w",
5416 aopGet(AOP(left),offset,FALSE,FALSE));
5417 pic14_emitcode("movwf","%s",
5418 aopGet(AOP(result),offset,FALSE,FALSE));
5420 emitpcode(POC_MOVLW, popGetLit(t));
5421 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5423 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5428 if (AOP_TYPE(left) == AOP_ACC) {
5429 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5430 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5432 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5433 pic14_emitcode("andwf","%s,w",
5434 aopGet(AOP(left),offset,FALSE,FALSE));
5435 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5436 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5438 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5439 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5445 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5446 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5447 freeAsmop(result,NULL,ic,TRUE);
5450 /*-----------------------------------------------------------------*/
5451 /* genOr - code for or */
5452 /*-----------------------------------------------------------------*/
5453 static void genOr (iCode *ic, iCode *ifx)
5455 operand *left, *right, *result;
5457 unsigned long lit = 0L;
5459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5461 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5462 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5463 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5465 DEBUGpic14_AopType(__LINE__,left,right,result);
5467 /* if left is a literal & right is not then exchange them */
5468 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5469 AOP_NEEDSACC(left)) {
5470 operand *tmp = right ;
5475 /* if result = right then exchange them */
5476 if(pic14_sameRegs(AOP(result),AOP(right))){
5477 operand *tmp = right ;
5482 /* if right is bit then exchange them */
5483 if (AOP_TYPE(right) == AOP_CRY &&
5484 AOP_TYPE(left) != AOP_CRY){
5485 operand *tmp = right ;
5490 DEBUGpic14_AopType(__LINE__,left,right,result);
5492 if(AOP_TYPE(right) == AOP_LIT)
5493 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5495 size = AOP_SIZE(result);
5499 if (AOP_TYPE(left) == AOP_CRY){
5500 if(AOP_TYPE(right) == AOP_LIT){
5501 // c = bit & literal;
5503 // lit != 0 => result = 1
5504 if(AOP_TYPE(result) == AOP_CRY){
5506 emitpcode(POC_BSF, popGet(AOP(result),0));
5507 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5508 // AOP(result)->aopu.aop_dir,
5509 // AOP(result)->aopu.aop_dir);
5511 continueIfTrue(ifx);
5515 // lit == 0 => result = left
5516 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5518 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5521 if (AOP_TYPE(right) == AOP_CRY){
5522 if(pic14_sameRegs(AOP(result),AOP(left))){
5524 emitpcode(POC_BCF, popGet(AOP(result),0));
5525 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5526 emitpcode(POC_BSF, popGet(AOP(result),0));
5528 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5529 AOP(result)->aopu.aop_dir,
5530 AOP(result)->aopu.aop_dir);
5531 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5532 AOP(right)->aopu.aop_dir,
5533 AOP(right)->aopu.aop_dir);
5534 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5535 AOP(result)->aopu.aop_dir,
5536 AOP(result)->aopu.aop_dir);
5538 if( AOP_TYPE(result) == AOP_ACC) {
5539 emitpcode(POC_MOVLW, popGetLit(0));
5540 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5541 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5542 emitpcode(POC_MOVLW, popGetLit(1));
5546 emitpcode(POC_BCF, popGet(AOP(result),0));
5547 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5548 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5549 emitpcode(POC_BSF, popGet(AOP(result),0));
5551 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5552 AOP(result)->aopu.aop_dir,
5553 AOP(result)->aopu.aop_dir);
5554 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5555 AOP(right)->aopu.aop_dir,
5556 AOP(right)->aopu.aop_dir);
5557 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5558 AOP(left)->aopu.aop_dir,
5559 AOP(left)->aopu.aop_dir);
5560 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5561 AOP(result)->aopu.aop_dir,
5562 AOP(result)->aopu.aop_dir);
5567 symbol *tlbl = newiTempLabel(NULL);
5568 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5571 emitpcode(POC_BCF, popGet(AOP(result),0));
5572 if( AOP_TYPE(right) == AOP_ACC) {
5573 emitpcode(POC_IORLW, popGetLit(0));
5575 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5576 emitpcode(POC_BSF, popGet(AOP(result),0));
5581 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5582 pic14_emitcode(";XXX setb","c");
5583 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5584 AOP(left)->aopu.aop_dir,tlbl->key+100);
5585 pic14_toBoolean(right);
5586 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5587 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5588 jmpTrueOrFalse(ifx, tlbl);
5592 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5599 pic14_outBitC(result);
5601 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5602 genIfxJump(ifx, "c");
5606 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5607 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5608 if((AOP_TYPE(right) == AOP_LIT) &&
5609 (AOP_TYPE(result) == AOP_CRY) &&
5610 (AOP_TYPE(left) != AOP_CRY)){
5612 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5615 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5617 continueIfTrue(ifx);
5620 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5621 // lit = 0, result = boolean(left)
5623 pic14_emitcode(";XXX setb","c");
5624 pic14_toBoolean(right);
5626 symbol *tlbl = newiTempLabel(NULL);
5627 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5629 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5631 genIfxJump (ifx,"a");
5635 pic14_outBitC(result);
5639 /* if left is same as result */
5640 if(pic14_sameRegs(AOP(result),AOP(left))){
5642 for(;size--; offset++,lit>>=8) {
5643 if(AOP_TYPE(right) == AOP_LIT){
5644 if((lit & 0xff) == 0)
5645 /* or'ing with 0 has no effect */
5648 int p = my_powof2(lit & 0xff);
5650 /* only one bit is set in the literal, so use a bsf instruction */
5652 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5654 if(know_W != (int)(lit & 0xff))
5655 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5656 know_W = lit & 0xff;
5657 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5662 if (AOP_TYPE(left) == AOP_ACC) {
5663 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5664 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5666 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5667 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5669 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5670 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5676 // left & result in different registers
5677 if(AOP_TYPE(result) == AOP_CRY){
5679 // if(size), result in bit
5680 // if(!size && ifx), conditional oper: if(left | right)
5681 symbol *tlbl = newiTempLabel(NULL);
5682 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5683 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5687 pic14_emitcode(";XXX setb","c");
5689 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5690 pic14_emitcode(";XXX orl","a,%s",
5691 aopGet(AOP(left),offset,FALSE,FALSE));
5692 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5697 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5698 pic14_outBitC(result);
5700 jmpTrueOrFalse(ifx, tlbl);
5701 } else for(;(size--);offset++){
5703 // result = left & right
5704 if(AOP_TYPE(right) == AOP_LIT){
5705 int t = (lit >> (offset*8)) & 0x0FFL;
5708 if (AOP_TYPE(left) != AOP_ACC) {
5709 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5711 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5715 if (AOP_TYPE(left) == AOP_ACC) {
5716 emitpcode(POC_IORLW, popGetLit(t));
5718 emitpcode(POC_MOVLW, popGetLit(t));
5719 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5721 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5726 // faster than result <- left, anl result,right
5727 // and better if result is SFR
5728 if (AOP_TYPE(left) == AOP_ACC) {
5729 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5730 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5732 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5733 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5735 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5736 pic14_emitcode("iorwf","%s,w",
5737 aopGet(AOP(left),offset,FALSE,FALSE));
5739 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5740 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5745 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5746 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5747 freeAsmop(result,NULL,ic,TRUE);
5750 /*-----------------------------------------------------------------*/
5751 /* genXor - code for xclusive or */
5752 /*-----------------------------------------------------------------*/
5753 static void genXor (iCode *ic, iCode *ifx)
5755 operand *left, *right, *result;
5757 unsigned long lit = 0L;
5759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5761 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5762 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5763 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5765 /* if left is a literal & right is not ||
5766 if left needs acc & right does not */
5767 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5768 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5769 operand *tmp = right ;
5774 /* if result = right then exchange them */
5775 if(pic14_sameRegs(AOP(result),AOP(right))){
5776 operand *tmp = right ;
5781 /* if right is bit then exchange them */
5782 if (AOP_TYPE(right) == AOP_CRY &&
5783 AOP_TYPE(left) != AOP_CRY){
5784 operand *tmp = right ;
5788 if(AOP_TYPE(right) == AOP_LIT)
5789 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5791 size = AOP_SIZE(result);
5795 if (AOP_TYPE(left) == AOP_CRY){
5796 if(AOP_TYPE(right) == AOP_LIT){
5797 // c = bit & literal;
5799 // lit>>1 != 0 => result = 1
5800 if(AOP_TYPE(result) == AOP_CRY){
5802 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5803 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5805 continueIfTrue(ifx);
5808 pic14_emitcode("setb","c");
5812 // lit == 0, result = left
5813 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5815 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5817 // lit == 1, result = not(left)
5818 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5819 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5820 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5821 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5824 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5825 pic14_emitcode("cpl","c");
5832 symbol *tlbl = newiTempLabel(NULL);
5833 if (AOP_TYPE(right) == AOP_CRY){
5835 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5838 int sizer = AOP_SIZE(right);
5840 // if val>>1 != 0, result = 1
5841 pic14_emitcode("setb","c");
5843 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5845 // test the msb of the lsb
5846 pic14_emitcode("anl","a,#0xfe");
5847 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5851 pic14_emitcode("rrc","a");
5853 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5854 pic14_emitcode("cpl","c");
5855 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5860 pic14_outBitC(result);
5862 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5863 genIfxJump(ifx, "c");
5867 if(pic14_sameRegs(AOP(result),AOP(left))){
5868 /* if left is same as result */
5869 for(;size--; offset++) {
5870 if(AOP_TYPE(right) == AOP_LIT){
5871 int t = (lit >> (offset*8)) & 0x0FFL;
5875 if (IS_AOP_PREG(left)) {
5876 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5877 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5878 aopPut(AOP(result),"a",offset);
5880 emitpcode(POC_MOVLW, popGetLit(t));
5881 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5882 pic14_emitcode("xrl","%s,%s",
5883 aopGet(AOP(left),offset,FALSE,TRUE),
5884 aopGet(AOP(right),offset,FALSE,FALSE));
5887 if (AOP_TYPE(left) == AOP_ACC)
5888 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5890 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5891 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5893 if (IS_AOP_PREG(left)) {
5894 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5895 aopPut(AOP(result),"a",offset);
5897 pic14_emitcode("xrl","%s,a",
5898 aopGet(AOP(left),offset,FALSE,TRUE));
5904 // left & result in different registers
5905 if(AOP_TYPE(result) == AOP_CRY){
5907 // if(size), result in bit
5908 // if(!size && ifx), conditional oper: if(left ^ right)
5909 symbol *tlbl = newiTempLabel(NULL);
5910 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5912 pic14_emitcode("setb","c");
5914 if((AOP_TYPE(right) == AOP_LIT) &&
5915 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5916 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5918 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5919 pic14_emitcode("xrl","a,%s",
5920 aopGet(AOP(left),offset,FALSE,FALSE));
5922 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5927 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5928 pic14_outBitC(result);
5930 jmpTrueOrFalse(ifx, tlbl);
5931 } else for(;(size--);offset++){
5933 // result = left & right
5934 if(AOP_TYPE(right) == AOP_LIT){
5935 int t = (lit >> (offset*8)) & 0x0FFL;
5938 if (AOP_TYPE(left) != AOP_ACC) {
5939 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5941 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5942 pic14_emitcode("movf","%s,w",
5943 aopGet(AOP(left),offset,FALSE,FALSE));
5944 pic14_emitcode("movwf","%s",
5945 aopGet(AOP(result),offset,FALSE,FALSE));
5948 if (AOP_TYPE(left) == AOP_ACC) {
5949 emitpcode(POC_XORLW, popGetLit(t));
5951 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5953 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5956 if (AOP_TYPE(left) == AOP_ACC) {
5957 emitpcode(POC_XORLW, popGetLit(t));
5959 emitpcode(POC_MOVLW, popGetLit(t));
5960 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5962 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5963 pic14_emitcode("movlw","0x%x",t);
5964 pic14_emitcode("xorwf","%s,w",
5965 aopGet(AOP(left),offset,FALSE,FALSE));
5966 pic14_emitcode("movwf","%s",
5967 aopGet(AOP(result),offset,FALSE,FALSE));
5973 // faster than result <- left, anl result,right
5974 // and better if result is SFR
5975 if (AOP_TYPE(left) == AOP_ACC) {
5976 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5977 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5979 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5980 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5981 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5982 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5984 if ( AOP_TYPE(result) != AOP_ACC){
5985 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5986 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5992 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5993 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5994 freeAsmop(result,NULL,ic,TRUE);
5997 /*-----------------------------------------------------------------*/
5998 /* genInline - write the inline code out */
5999 /*-----------------------------------------------------------------*/
6000 static void genInline (iCode *ic)
6002 char *buffer, *bp, *bp1;
6004 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6006 _G.inLine += (!options.asmpeep);
6008 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6009 strcpy(buffer,IC_INLINE(ic));
6011 /* emit each line as a code */
6017 addpCode2pBlock(pb,AssembleLine(bp1));
6024 pic14_emitcode(bp1,"");
6030 if ((bp1 != bp) && *bp1)
6031 addpCode2pBlock(pb,AssembleLine(bp1));
6035 _G.inLine -= (!options.asmpeep);
6038 /*-----------------------------------------------------------------*/
6039 /* genRRC - rotate right with carry */
6040 /*-----------------------------------------------------------------*/
6041 static void genRRC (iCode *ic)
6043 operand *left , *result ;
6044 int size, offset = 0, same;
6046 /* rotate right with carry */
6048 result=IC_RESULT(ic);
6049 aopOp (left,ic,FALSE);
6050 aopOp (result,ic,FALSE);
6052 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6054 same = pic14_sameRegs(AOP(result),AOP(left));
6056 size = AOP_SIZE(result);
6058 /* get the lsb and put it into the carry */
6059 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6066 emitpcode(POC_RRF, popGet(AOP(left),offset));
6068 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6069 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6075 freeAsmop(left,NULL,ic,TRUE);
6076 freeAsmop(result,NULL,ic,TRUE);
6079 /*-----------------------------------------------------------------*/
6080 /* genRLC - generate code for rotate left with carry */
6081 /*-----------------------------------------------------------------*/
6082 static void genRLC (iCode *ic)
6084 operand *left , *result ;
6085 int size, offset = 0;
6088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6089 /* rotate right with carry */
6091 result=IC_RESULT(ic);
6092 aopOp (left,ic,FALSE);
6093 aopOp (result,ic,FALSE);
6095 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6097 same = pic14_sameRegs(AOP(result),AOP(left));
6099 /* move it to the result */
6100 size = AOP_SIZE(result);
6102 /* get the msb and put it into the carry */
6103 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6110 emitpcode(POC_RLF, popGet(AOP(left),offset));
6112 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6113 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6120 freeAsmop(left,NULL,ic,TRUE);
6121 freeAsmop(result,NULL,ic,TRUE);
6124 /*-----------------------------------------------------------------*/
6125 /* genGetHbit - generates code get highest order bit */
6126 /*-----------------------------------------------------------------*/
6127 static void genGetHbit (iCode *ic)
6129 operand *left, *result;
6131 result=IC_RESULT(ic);
6132 aopOp (left,ic,FALSE);
6133 aopOp (result,ic,FALSE);
6135 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6136 /* get the highest order byte into a */
6137 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6138 if(AOP_TYPE(result) == AOP_CRY){
6139 pic14_emitcode("rlc","a");
6140 pic14_outBitC(result);
6143 pic14_emitcode("rl","a");
6144 pic14_emitcode("anl","a,#0x01");
6145 pic14_outAcc(result);
6149 freeAsmop(left,NULL,ic,TRUE);
6150 freeAsmop(result,NULL,ic,TRUE);
6153 /*-----------------------------------------------------------------*/
6154 /* AccRol - rotate left accumulator by known count */
6155 /*-----------------------------------------------------------------*/
6156 static void AccRol (int shCount)
6158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6159 shCount &= 0x0007; // shCount : 0..7
6164 pic14_emitcode("rl","a");
6167 pic14_emitcode("rl","a");
6168 pic14_emitcode("rl","a");
6171 pic14_emitcode("swap","a");
6172 pic14_emitcode("rr","a");
6175 pic14_emitcode("swap","a");
6178 pic14_emitcode("swap","a");
6179 pic14_emitcode("rl","a");
6182 pic14_emitcode("rr","a");
6183 pic14_emitcode("rr","a");
6186 pic14_emitcode("rr","a");
6191 /*-----------------------------------------------------------------*/
6192 /* AccLsh - left shift accumulator by known count */
6193 /*-----------------------------------------------------------------*/
6194 static void AccLsh (int shCount)
6196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6199 pic14_emitcode("add","a,acc");
6202 pic14_emitcode("add","a,acc");
6203 pic14_emitcode("add","a,acc");
6205 /* rotate left accumulator */
6207 /* and kill the lower order bits */
6208 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6213 /*-----------------------------------------------------------------*/
6214 /* AccRsh - right shift accumulator by known count */
6215 /*-----------------------------------------------------------------*/
6216 static void AccRsh (int shCount)
6218 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6222 pic14_emitcode("rrc","a");
6224 /* rotate right accumulator */
6225 AccRol(8 - shCount);
6226 /* and kill the higher order bits */
6227 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6233 /*-----------------------------------------------------------------*/
6234 /* AccSRsh - signed right shift accumulator by known count */
6235 /*-----------------------------------------------------------------*/
6236 static void AccSRsh (int shCount)
6239 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6242 pic14_emitcode("mov","c,acc.7");
6243 pic14_emitcode("rrc","a");
6244 } else if(shCount == 2){
6245 pic14_emitcode("mov","c,acc.7");
6246 pic14_emitcode("rrc","a");
6247 pic14_emitcode("mov","c,acc.7");
6248 pic14_emitcode("rrc","a");
6250 tlbl = newiTempLabel(NULL);
6251 /* rotate right accumulator */
6252 AccRol(8 - shCount);
6253 /* and kill the higher order bits */
6254 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6255 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6256 pic14_emitcode("orl","a,#0x%02x",
6257 (unsigned char)~SRMask[shCount]);
6258 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6263 /*-----------------------------------------------------------------*/
6264 /* shiftR1Left2Result - shift right one byte from left to result */
6265 /*-----------------------------------------------------------------*/
6266 static void shiftR1Left2ResultSigned (operand *left, int offl,
6267 operand *result, int offr,
6272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6274 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6278 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6280 emitpcode(POC_RRF, popGet(AOP(result),offr));
6282 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6283 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6289 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6291 emitpcode(POC_RRF, popGet(AOP(result),offr));
6293 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6294 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6296 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6297 emitpcode(POC_RRF, popGet(AOP(result),offr));
6303 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6305 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6306 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6309 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6310 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6311 emitpcode(POC_ANDLW, popGetLit(0x1f));
6313 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6314 emitpcode(POC_IORLW, popGetLit(0xe0));
6316 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6320 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6321 emitpcode(POC_ANDLW, popGetLit(0x0f));
6322 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6323 emitpcode(POC_IORLW, popGetLit(0xf0));
6324 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6328 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6330 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6331 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6333 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6334 emitpcode(POC_ANDLW, popGetLit(0x07));
6335 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6336 emitpcode(POC_IORLW, popGetLit(0xf8));
6337 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6342 emitpcode(POC_MOVLW, popGetLit(0x00));
6343 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6344 emitpcode(POC_MOVLW, popGetLit(0xfe));
6345 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6346 emitpcode(POC_IORLW, popGetLit(0x01));
6347 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6349 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6350 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6351 emitpcode(POC_DECF, popGet(AOP(result),offr));
6352 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6353 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6359 emitpcode(POC_MOVLW, popGetLit(0x00));
6360 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6361 emitpcode(POC_MOVLW, popGetLit(0xff));
6362 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6364 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6365 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6366 emitpcode(POC_DECF, popGet(AOP(result),offr));
6374 /*-----------------------------------------------------------------*/
6375 /* shiftR1Left2Result - shift right one byte from left to result */
6376 /*-----------------------------------------------------------------*/
6377 static void shiftR1Left2Result (operand *left, int offl,
6378 operand *result, int offr,
6379 int shCount, int sign)
6383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6385 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6387 /* Copy the msb into the carry if signed. */
6389 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6399 emitpcode(POC_RRF, popGet(AOP(result),offr));
6401 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6402 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6408 emitpcode(POC_RRF, popGet(AOP(result),offr));
6410 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6411 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6414 emitpcode(POC_RRF, popGet(AOP(result),offr));
6419 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6421 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6422 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6425 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6426 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6427 emitpcode(POC_ANDLW, popGetLit(0x1f));
6428 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6432 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6433 emitpcode(POC_ANDLW, popGetLit(0x0f));
6434 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6439 emitpcode(POC_ANDLW, popGetLit(0x0f));
6440 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6442 emitpcode(POC_RRF, popGet(AOP(result),offr));
6447 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6448 emitpcode(POC_ANDLW, popGetLit(0x80));
6449 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6450 emitpcode(POC_RLF, popGet(AOP(result),offr));
6451 emitpcode(POC_RLF, popGet(AOP(result),offr));
6456 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6457 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6458 emitpcode(POC_RLF, popGet(AOP(result),offr));
6467 /*-----------------------------------------------------------------*/
6468 /* shiftL1Left2Result - shift left one byte from left to result */
6469 /*-----------------------------------------------------------------*/
6470 static void shiftL1Left2Result (operand *left, int offl,
6471 operand *result, int offr, int shCount)
6476 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6478 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6479 DEBUGpic14_emitcode ("; ***","same = %d",same);
6480 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6482 /* shift left accumulator */
6483 //AccLsh(shCount); // don't comment out just yet...
6484 // aopPut(AOP(result),"a",offr);
6488 /* Shift left 1 bit position */
6489 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6491 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6493 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6494 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6498 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6499 emitpcode(POC_ANDLW,popGetLit(0x7e));
6500 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6501 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6504 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6505 emitpcode(POC_ANDLW,popGetLit(0x3e));
6506 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6507 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6508 emitpcode(POC_RLF, popGet(AOP(result),offr));
6511 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW, popGetLit(0xf0));
6513 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6516 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6517 emitpcode(POC_ANDLW, popGetLit(0xf0));
6518 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6519 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6522 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6523 emitpcode(POC_ANDLW, popGetLit(0x30));
6524 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6525 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6526 emitpcode(POC_RLF, popGet(AOP(result),offr));
6529 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6530 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6531 emitpcode(POC_RRF, popGet(AOP(result),offr));
6535 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6540 /*-----------------------------------------------------------------*/
6541 /* movLeft2Result - move byte from left to result */
6542 /*-----------------------------------------------------------------*/
6543 static void movLeft2Result (operand *left, int offl,
6544 operand *result, int offr)
6547 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6548 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6549 l = aopGet(AOP(left),offl,FALSE,FALSE);
6551 if (*l == '@' && (IS_AOP_PREG(result))) {
6552 pic14_emitcode("mov","a,%s",l);
6553 aopPut(AOP(result),"a",offr);
6555 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6556 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6561 /*-----------------------------------------------------------------*/
6562 /* shiftL2Left2Result - shift left two bytes from left to result */
6563 /*-----------------------------------------------------------------*/
6564 static void shiftL2Left2Result (operand *left, int offl,
6565 operand *result, int offr, int shCount)
6569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6571 if(pic14_sameRegs(AOP(result), AOP(left))) {
6579 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6580 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6581 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6585 emitpcode(POC_RLF, popGet(AOP(result),offr));
6586 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6592 emitpcode(POC_MOVLW, popGetLit(0x0f));
6593 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6594 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6595 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6596 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6597 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6598 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6600 emitpcode(POC_RLF, popGet(AOP(result),offr));
6601 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RRF, popGet(AOP(result),offr));
6607 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_RRF, popGet(AOP(result),offr));
6609 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6610 emitpcode(POC_ANDLW,popGetLit(0xc0));
6611 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6612 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6613 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6614 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6617 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6619 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6620 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6621 emitpcode(POC_RRF, popGet(AOP(result),offr));
6631 /* note, use a mov/add for the shift since the mov has a
6632 chance of getting optimized out */
6633 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6634 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6635 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6636 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6637 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6641 emitpcode(POC_RLF, popGet(AOP(result),offr));
6642 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6648 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6649 emitpcode(POC_ANDLW, popGetLit(0xF0));
6650 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6651 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6652 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6653 emitpcode(POC_ANDLW, popGetLit(0xF0));
6654 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6655 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6659 emitpcode(POC_RLF, popGet(AOP(result),offr));
6660 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6665 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6666 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6667 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6669 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRF, popGet(AOP(result),offr));
6671 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_ANDLW,popGetLit(0xc0));
6673 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6674 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6675 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6676 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6679 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6680 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6681 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6683 emitpcode(POC_RRF, popGet(AOP(result),offr));
6688 /*-----------------------------------------------------------------*/
6689 /* shiftR2Left2Result - shift right two bytes from left to result */
6690 /*-----------------------------------------------------------------*/
6691 static void shiftR2Left2Result (operand *left, int offl,
6692 operand *result, int offr,
6693 int shCount, int sign)
6697 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6698 same = pic14_sameRegs(AOP(result), AOP(left));
6700 if(same && ((offl + MSB16) == offr)){
6702 /* don't crash result[offr] */
6703 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6704 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6707 movLeft2Result(left,offl, result, offr);
6708 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6711 /* a:x >> shCount (x = lsb(result))*/
6714 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6716 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6725 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6730 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6731 emitpcode(POC_RRF,popGet(AOP(result),offr));
6733 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6734 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6736 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6741 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6745 emitpcode(POC_RRF,popGet(AOP(result),offr));
6752 emitpcode(POC_MOVLW, popGetLit(0xf0));
6753 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6754 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6756 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6757 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6759 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6761 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6762 emitpcode(POC_ANDLW, popGetLit(0x0f));
6763 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6765 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6766 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6767 emitpcode(POC_ANDLW, popGetLit(0xf0));
6768 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6769 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6773 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6774 emitpcode(POC_RRF, popGet(AOP(result),offr));
6778 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6779 emitpcode(POC_BTFSC,
6780 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6781 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6789 emitpcode(POC_RLF, popGet(AOP(result),offr));
6790 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6792 emitpcode(POC_RLF, popGet(AOP(result),offr));
6793 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6795 emitpcode(POC_ANDLW,popGetLit(0x03));
6797 emitpcode(POC_BTFSC,
6798 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6799 emitpcode(POC_IORLW,popGetLit(0xfc));
6801 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6804 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6806 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6807 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6809 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6810 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6811 emitpcode(POC_RLF, popGet(AOP(result),offr));
6812 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6813 emitpcode(POC_ANDLW,popGetLit(0x03));
6815 emitpcode(POC_BTFSC,
6816 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6817 emitpcode(POC_IORLW,popGetLit(0xfc));
6819 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6820 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6827 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6828 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6829 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6830 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6835 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6840 /*-----------------------------------------------------------------*/
6841 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6842 /*-----------------------------------------------------------------*/
6843 static void shiftLLeftOrResult (operand *left, int offl,
6844 operand *result, int offr, int shCount)
6846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6847 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6848 /* shift left accumulator */
6850 /* or with result */
6851 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6852 /* back to result */
6853 aopPut(AOP(result),"a",offr);
6856 /*-----------------------------------------------------------------*/
6857 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6858 /*-----------------------------------------------------------------*/
6859 static void shiftRLeftOrResult (operand *left, int offl,
6860 operand *result, int offr, int shCount)
6862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6863 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6864 /* shift right accumulator */
6866 /* or with result */
6867 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6868 /* back to result */
6869 aopPut(AOP(result),"a",offr);
6872 /*-----------------------------------------------------------------*/
6873 /* genlshOne - left shift a one byte quantity by known count */
6874 /*-----------------------------------------------------------------*/
6875 static void genlshOne (operand *result, operand *left, int shCount)
6877 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6878 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6881 /*-----------------------------------------------------------------*/
6882 /* genlshTwo - left shift two bytes by known amount != 0 */
6883 /*-----------------------------------------------------------------*/
6884 static void genlshTwo (operand *result,operand *left, int shCount)
6888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6889 size = pic14_getDataSize(result);
6891 /* if shCount >= 8 */
6897 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6899 movLeft2Result(left, LSB, result, MSB16);
6901 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6904 /* 1 <= shCount <= 7 */
6907 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6909 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6913 /*-----------------------------------------------------------------*/
6914 /* shiftLLong - shift left one long from left to result */
6915 /* offl = LSB or MSB16 */
6916 /*-----------------------------------------------------------------*/
6917 static void shiftLLong (operand *left, operand *result, int offr )
6920 int size = AOP_SIZE(result);
6922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6923 if(size >= LSB+offr){
6924 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6926 pic14_emitcode("add","a,acc");
6927 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6928 size >= MSB16+offr && offr != LSB )
6929 pic14_emitcode("xch","a,%s",
6930 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6932 aopPut(AOP(result),"a",LSB+offr);
6935 if(size >= MSB16+offr){
6936 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6937 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6940 pic14_emitcode("rlc","a");
6941 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6942 size >= MSB24+offr && offr != LSB)
6943 pic14_emitcode("xch","a,%s",
6944 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6946 aopPut(AOP(result),"a",MSB16+offr);
6949 if(size >= MSB24+offr){
6950 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6951 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6954 pic14_emitcode("rlc","a");
6955 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6956 size >= MSB32+offr && offr != LSB )
6957 pic14_emitcode("xch","a,%s",
6958 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6960 aopPut(AOP(result),"a",MSB24+offr);
6963 if(size > MSB32+offr){
6964 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6965 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6968 pic14_emitcode("rlc","a");
6969 aopPut(AOP(result),"a",MSB32+offr);
6972 aopPut(AOP(result),zero,LSB);
6975 /*-----------------------------------------------------------------*/
6976 /* genlshFour - shift four byte by a known amount != 0 */
6977 /*-----------------------------------------------------------------*/
6978 static void genlshFour (operand *result, operand *left, int shCount)
6982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6983 size = AOP_SIZE(result);
6985 /* if shifting more that 3 bytes */
6986 if (shCount >= 24 ) {
6989 /* lowest order of left goes to the highest
6990 order of the destination */
6991 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6993 movLeft2Result(left, LSB, result, MSB32);
6994 aopPut(AOP(result),zero,LSB);
6995 aopPut(AOP(result),zero,MSB16);
6996 aopPut(AOP(result),zero,MSB32);
7000 /* more than two bytes */
7001 else if ( shCount >= 16 ) {
7002 /* lower order two bytes goes to higher order two bytes */
7004 /* if some more remaining */
7006 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7008 movLeft2Result(left, MSB16, result, MSB32);
7009 movLeft2Result(left, LSB, result, MSB24);
7011 aopPut(AOP(result),zero,MSB16);
7012 aopPut(AOP(result),zero,LSB);
7016 /* if more than 1 byte */
7017 else if ( shCount >= 8 ) {
7018 /* lower order three bytes goes to higher order three bytes */
7022 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7024 movLeft2Result(left, LSB, result, MSB16);
7026 else{ /* size = 4 */
7028 movLeft2Result(left, MSB24, result, MSB32);
7029 movLeft2Result(left, MSB16, result, MSB24);
7030 movLeft2Result(left, LSB, result, MSB16);
7031 aopPut(AOP(result),zero,LSB);
7033 else if(shCount == 1)
7034 shiftLLong(left, result, MSB16);
7036 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7037 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7038 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7039 aopPut(AOP(result),zero,LSB);
7044 /* 1 <= shCount <= 7 */
7045 else if(shCount <= 2){
7046 shiftLLong(left, result, LSB);
7048 shiftLLong(result, result, LSB);
7050 /* 3 <= shCount <= 7, optimize */
7052 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7053 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7054 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7058 /*-----------------------------------------------------------------*/
7059 /* genLeftShiftLiteral - left shifting by known count */
7060 /*-----------------------------------------------------------------*/
7061 static void genLeftShiftLiteral (operand *left,
7066 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7069 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7070 freeAsmop(right,NULL,ic,TRUE);
7072 aopOp(left,ic,FALSE);
7073 aopOp(result,ic,FALSE);
7075 size = getSize(operandType(result));
7078 pic14_emitcode("; shift left ","result %d, left %d",size,
7082 /* I suppose that the left size >= result size */
7085 movLeft2Result(left, size, result, size);
7089 else if(shCount >= (size * 8))
7091 aopPut(AOP(result),zero,size);
7095 genlshOne (result,left,shCount);
7100 genlshTwo (result,left,shCount);
7104 genlshFour (result,left,shCount);
7108 freeAsmop(left,NULL,ic,TRUE);
7109 freeAsmop(result,NULL,ic,TRUE);
7112 /*-----------------------------------------------------------------*
7113 * genMultiAsm - repeat assembly instruction for size of register.
7114 * if endian == 1, then the high byte (i.e base address + size of
7115 * register) is used first else the low byte is used first;
7116 *-----------------------------------------------------------------*/
7117 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7135 emitpcode(poc, popGet(AOP(reg),offset));
7140 /*-----------------------------------------------------------------*/
7141 /* genLeftShift - generates code for left shifting */
7142 /*-----------------------------------------------------------------*/
7143 static void genLeftShift (iCode *ic)
7145 operand *left,*right, *result;
7148 symbol *tlbl , *tlbl1;
7151 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7153 right = IC_RIGHT(ic);
7155 result = IC_RESULT(ic);
7157 aopOp(right,ic,FALSE);
7159 /* if the shift count is known then do it
7160 as efficiently as possible */
7161 if (AOP_TYPE(right) == AOP_LIT) {
7162 genLeftShiftLiteral (left,right,result,ic);
7166 /* shift count is unknown then we have to form
7167 a loop get the loop count in B : Note: we take
7168 only the lower order byte since shifting
7169 more that 32 bits make no sense anyway, ( the
7170 largest size of an object can be only 32 bits ) */
7173 aopOp(left,ic,FALSE);
7174 aopOp(result,ic,FALSE);
7176 /* now move the left to the result if they are not the
7178 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7179 AOP_SIZE(result) > 1) {
7181 size = AOP_SIZE(result);
7184 l = aopGet(AOP(left),offset,FALSE,TRUE);
7185 if (*l == '@' && (IS_AOP_PREG(result))) {
7187 pic14_emitcode("mov","a,%s",l);
7188 aopPut(AOP(result),"a",offset);
7190 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7191 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7192 //aopPut(AOP(result),l,offset);
7198 size = AOP_SIZE(result);
7200 /* if it is only one byte then */
7202 if(optimized_for_speed) {
7203 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7204 emitpcode(POC_ANDLW, popGetLit(0xf0));
7205 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7206 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7207 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7208 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7209 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7210 emitpcode(POC_RLFW, popGet(AOP(result),0));
7211 emitpcode(POC_ANDLW, popGetLit(0xfe));
7212 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7213 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7214 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7217 tlbl = newiTempLabel(NULL);
7218 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7219 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7220 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7223 emitpcode(POC_COMFW, popGet(AOP(right),0));
7224 emitpcode(POC_RRF, popGet(AOP(result),0));
7225 emitpLabel(tlbl->key);
7226 emitpcode(POC_RLF, popGet(AOP(result),0));
7227 emitpcode(POC_ADDLW, popGetLit(1));
7229 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7234 if (pic14_sameRegs(AOP(left),AOP(result))) {
7236 tlbl = newiTempLabel(NULL);
7237 emitpcode(POC_COMFW, popGet(AOP(right),0));
7238 genMultiAsm(POC_RRF, result, size,1);
7239 emitpLabel(tlbl->key);
7240 genMultiAsm(POC_RLF, result, size,0);
7241 emitpcode(POC_ADDLW, popGetLit(1));
7243 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7247 //tlbl = newiTempLabel(NULL);
7249 //tlbl1 = newiTempLabel(NULL);
7251 //reAdjustPreg(AOP(result));
7253 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7254 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7255 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7257 //pic14_emitcode("add","a,acc");
7258 //aopPut(AOP(result),"a",offset++);
7260 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7262 // pic14_emitcode("rlc","a");
7263 // aopPut(AOP(result),"a",offset++);
7265 //reAdjustPreg(AOP(result));
7267 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7268 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7271 tlbl = newiTempLabel(NULL);
7272 tlbl1= newiTempLabel(NULL);
7274 size = AOP_SIZE(result);
7277 pctemp = popGetTempReg(); /* grab a temporary working register. */
7279 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7281 /* offset should be 0, 1 or 3 */
7282 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7284 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7286 emitpcode(POC_MOVWF, pctemp);
7289 emitpLabel(tlbl->key);
7292 emitpcode(POC_RLF, popGet(AOP(result),0));
7294 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7296 emitpcode(POC_DECFSZ, pctemp);
7297 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7298 emitpLabel(tlbl1->key);
7300 popReleaseTempReg(pctemp);
7304 freeAsmop (right,NULL,ic,TRUE);
7305 freeAsmop(left,NULL,ic,TRUE);
7306 freeAsmop(result,NULL,ic,TRUE);
7309 /*-----------------------------------------------------------------*/
7310 /* genrshOne - right shift a one byte quantity by known count */
7311 /*-----------------------------------------------------------------*/
7312 static void genrshOne (operand *result, operand *left,
7313 int shCount, int sign)
7315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7316 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7319 /*-----------------------------------------------------------------*/
7320 /* genrshTwo - right shift two bytes by known amount != 0 */
7321 /*-----------------------------------------------------------------*/
7322 static void genrshTwo (operand *result,operand *left,
7323 int shCount, int sign)
7325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7326 /* if shCount >= 8 */
7330 shiftR1Left2Result(left, MSB16, result, LSB,
7333 movLeft2Result(left, MSB16, result, LSB);
7335 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7338 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7339 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7343 /* 1 <= shCount <= 7 */
7345 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7348 /*-----------------------------------------------------------------*/
7349 /* shiftRLong - shift right one long from left to result */
7350 /* offl = LSB or MSB16 */
7351 /*-----------------------------------------------------------------*/
7352 static void shiftRLong (operand *left, int offl,
7353 operand *result, int sign)
7355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7357 pic14_emitcode("clr","c");
7358 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7360 pic14_emitcode("mov","c,acc.7");
7361 pic14_emitcode("rrc","a");
7362 aopPut(AOP(result),"a",MSB32-offl);
7364 /* add sign of "a" */
7365 addSign(result, MSB32, sign);
7367 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7368 pic14_emitcode("rrc","a");
7369 aopPut(AOP(result),"a",MSB24-offl);
7371 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7372 pic14_emitcode("rrc","a");
7373 aopPut(AOP(result),"a",MSB16-offl);
7376 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7377 pic14_emitcode("rrc","a");
7378 aopPut(AOP(result),"a",LSB);
7382 /*-----------------------------------------------------------------*/
7383 /* genrshFour - shift four byte by a known amount != 0 */
7384 /*-----------------------------------------------------------------*/
7385 static void genrshFour (operand *result, operand *left,
7386 int shCount, int sign)
7388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7389 /* if shifting more that 3 bytes */
7390 if(shCount >= 24 ) {
7393 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7395 movLeft2Result(left, MSB32, result, LSB);
7397 addSign(result, MSB16, sign);
7399 else if(shCount >= 16){
7402 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7404 movLeft2Result(left, MSB24, result, LSB);
7405 movLeft2Result(left, MSB32, result, MSB16);
7407 addSign(result, MSB24, sign);
7409 else if(shCount >= 8){
7412 shiftRLong(left, MSB16, result, sign);
7413 else if(shCount == 0){
7414 movLeft2Result(left, MSB16, result, LSB);
7415 movLeft2Result(left, MSB24, result, MSB16);
7416 movLeft2Result(left, MSB32, result, MSB24);
7417 addSign(result, MSB32, sign);
7420 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7421 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7422 /* the last shift is signed */
7423 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7424 addSign(result, MSB32, sign);
7427 else{ /* 1 <= shCount <= 7 */
7429 shiftRLong(left, LSB, result, sign);
7431 shiftRLong(result, LSB, result, sign);
7434 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7435 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7436 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7441 /*-----------------------------------------------------------------*/
7442 /* genRightShiftLiteral - right shifting by known count */
7443 /*-----------------------------------------------------------------*/
7444 static void genRightShiftLiteral (operand *left,
7450 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7454 freeAsmop(right,NULL,ic,TRUE);
7456 aopOp(left,ic,FALSE);
7457 aopOp(result,ic,FALSE);
7460 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7464 lsize = pic14_getDataSize(left);
7465 res_size = pic14_getDataSize(result);
7466 /* test the LEFT size !!! */
7468 /* I suppose that the left size >= result size */
7471 movLeft2Result(left, lsize, result, res_size);
7474 else if(shCount >= (lsize * 8)){
7477 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7479 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7480 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7485 emitpcode(POC_MOVLW, popGetLit(0));
7486 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7487 emitpcode(POC_MOVLW, popGetLit(0xff));
7489 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7494 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7501 genrshOne (result,left,shCount,sign);
7505 genrshTwo (result,left,shCount,sign);
7509 genrshFour (result,left,shCount,sign);
7517 freeAsmop(left,NULL,ic,TRUE);
7518 freeAsmop(result,NULL,ic,TRUE);
7521 /*-----------------------------------------------------------------*/
7522 /* genSignedRightShift - right shift of signed number */
7523 /*-----------------------------------------------------------------*/
7524 static void genSignedRightShift (iCode *ic)
7526 operand *right, *left, *result;
7529 symbol *tlbl, *tlbl1 ;
7532 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7534 /* we do it the hard way put the shift count in b
7535 and loop thru preserving the sign */
7536 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7538 right = IC_RIGHT(ic);
7540 result = IC_RESULT(ic);
7542 aopOp(right,ic,FALSE);
7543 aopOp(left,ic,FALSE);
7544 aopOp(result,ic,FALSE);
7547 if ( AOP_TYPE(right) == AOP_LIT) {
7548 genRightShiftLiteral (left,right,result,ic,1);
7551 /* shift count is unknown then we have to form
7552 a loop get the loop count in B : Note: we take
7553 only the lower order byte since shifting
7554 more that 32 bits make no sense anyway, ( the
7555 largest size of an object can be only 32 bits ) */
7557 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7558 //pic14_emitcode("inc","b");
7559 //freeAsmop (right,NULL,ic,TRUE);
7560 //aopOp(left,ic,FALSE);
7561 //aopOp(result,ic,FALSE);
7563 /* now move the left to the result if they are not the
7565 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7566 AOP_SIZE(result) > 1) {
7568 size = AOP_SIZE(result);
7572 l = aopGet(AOP(left),offset,FALSE,TRUE);
7573 if (*l == '@' && IS_AOP_PREG(result)) {
7575 pic14_emitcode("mov","a,%s",l);
7576 aopPut(AOP(result),"a",offset);
7578 aopPut(AOP(result),l,offset);
7580 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7581 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7587 /* mov the highest order bit to OVR */
7588 tlbl = newiTempLabel(NULL);
7589 tlbl1= newiTempLabel(NULL);
7591 size = AOP_SIZE(result);
7594 pctemp = popGetTempReg(); /* grab a temporary working register. */
7596 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7598 /* offset should be 0, 1 or 3 */
7599 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7601 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7603 emitpcode(POC_MOVWF, pctemp);
7606 emitpLabel(tlbl->key);
7608 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7609 emitpcode(POC_RRF, popGet(AOP(result),offset));
7612 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7615 emitpcode(POC_DECFSZ, pctemp);
7616 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7617 emitpLabel(tlbl1->key);
7619 popReleaseTempReg(pctemp);
7621 size = AOP_SIZE(result);
7623 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7624 pic14_emitcode("rlc","a");
7625 pic14_emitcode("mov","ov,c");
7626 /* if it is only one byte then */
7628 l = aopGet(AOP(left),0,FALSE,FALSE);
7630 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7631 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7632 pic14_emitcode("mov","c,ov");
7633 pic14_emitcode("rrc","a");
7634 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7635 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7636 aopPut(AOP(result),"a",0);
7640 reAdjustPreg(AOP(result));
7641 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7642 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7643 pic14_emitcode("mov","c,ov");
7645 l = aopGet(AOP(result),offset,FALSE,FALSE);
7647 pic14_emitcode("rrc","a");
7648 aopPut(AOP(result),"a",offset--);
7650 reAdjustPreg(AOP(result));
7651 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7652 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7657 freeAsmop(left,NULL,ic,TRUE);
7658 freeAsmop(result,NULL,ic,TRUE);
7659 freeAsmop(right,NULL,ic,TRUE);
7662 /*-----------------------------------------------------------------*/
7663 /* genRightShift - generate code for right shifting */
7664 /*-----------------------------------------------------------------*/
7665 static void genRightShift (iCode *ic)
7667 operand *right, *left, *result;
7671 symbol *tlbl, *tlbl1 ;
7673 /* if signed then we do it the hard way preserve the
7674 sign bit moving it inwards */
7675 retype = getSpec(operandType(IC_RESULT(ic)));
7676 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7678 if (!SPEC_USIGN(retype)) {
7679 genSignedRightShift (ic);
7683 /* signed & unsigned types are treated the same : i.e. the
7684 signed is NOT propagated inwards : quoting from the
7685 ANSI - standard : "for E1 >> E2, is equivalent to division
7686 by 2**E2 if unsigned or if it has a non-negative value,
7687 otherwise the result is implementation defined ", MY definition
7688 is that the sign does not get propagated */
7690 right = IC_RIGHT(ic);
7692 result = IC_RESULT(ic);
7694 aopOp(right,ic,FALSE);
7696 /* if the shift count is known then do it
7697 as efficiently as possible */
7698 if (AOP_TYPE(right) == AOP_LIT) {
7699 genRightShiftLiteral (left,right,result,ic, 0);
7703 /* shift count is unknown then we have to form
7704 a loop get the loop count in B : Note: we take
7705 only the lower order byte since shifting
7706 more that 32 bits make no sense anyway, ( the
7707 largest size of an object can be only 32 bits ) */
7709 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7710 pic14_emitcode("inc","b");
7711 aopOp(left,ic,FALSE);
7712 aopOp(result,ic,FALSE);
7714 /* now move the left to the result if they are not the
7716 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7717 AOP_SIZE(result) > 1) {
7719 size = AOP_SIZE(result);
7722 l = aopGet(AOP(left),offset,FALSE,TRUE);
7723 if (*l == '@' && IS_AOP_PREG(result)) {
7725 pic14_emitcode("mov","a,%s",l);
7726 aopPut(AOP(result),"a",offset);
7728 aopPut(AOP(result),l,offset);
7733 tlbl = newiTempLabel(NULL);
7734 tlbl1= newiTempLabel(NULL);
7735 size = AOP_SIZE(result);
7738 /* if it is only one byte then */
7741 tlbl = newiTempLabel(NULL);
7742 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7743 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7744 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7747 emitpcode(POC_COMFW, popGet(AOP(right),0));
7748 emitpcode(POC_RLF, popGet(AOP(result),0));
7749 emitpLabel(tlbl->key);
7750 emitpcode(POC_RRF, popGet(AOP(result),0));
7751 emitpcode(POC_ADDLW, popGetLit(1));
7753 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7758 reAdjustPreg(AOP(result));
7759 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7760 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7763 l = aopGet(AOP(result),offset,FALSE,FALSE);
7765 pic14_emitcode("rrc","a");
7766 aopPut(AOP(result),"a",offset--);
7768 reAdjustPreg(AOP(result));
7770 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7771 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7774 freeAsmop(left,NULL,ic,TRUE);
7775 freeAsmop (right,NULL,ic,TRUE);
7776 freeAsmop(result,NULL,ic,TRUE);
7779 /*-----------------------------------------------------------------*/
7780 /* genUnpackBits - generates code for unpacking bits */
7781 /*-----------------------------------------------------------------*/
7782 static void genUnpackBits (operand *result, char *rname, int ptype)
7789 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7790 etype = getSpec(operandType(result));
7792 /* read the first byte */
7797 pic14_emitcode("mov","a,@%s",rname);
7801 pic14_emitcode("movx","a,@%s",rname);
7805 pic14_emitcode("movx","a,@dptr");
7809 pic14_emitcode("clr","a");
7810 pic14_emitcode("movc","a","@a+dptr");
7814 pic14_emitcode("lcall","__gptrget");
7818 /* if we have bitdisplacement then it fits */
7819 /* into this byte completely or if length is */
7820 /* less than a byte */
7821 if ((shCnt = SPEC_BSTR(etype)) ||
7822 (SPEC_BLEN(etype) <= 8)) {
7824 /* shift right acc */
7827 pic14_emitcode("anl","a,#0x%02x",
7828 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7829 aopPut(AOP(result),"a",offset);
7833 /* bit field did not fit in a byte */
7834 rlen = SPEC_BLEN(etype) - 8;
7835 aopPut(AOP(result),"a",offset++);
7842 pic14_emitcode("inc","%s",rname);
7843 pic14_emitcode("mov","a,@%s",rname);
7847 pic14_emitcode("inc","%s",rname);
7848 pic14_emitcode("movx","a,@%s",rname);
7852 pic14_emitcode("inc","dptr");
7853 pic14_emitcode("movx","a,@dptr");
7857 pic14_emitcode("clr","a");
7858 pic14_emitcode("inc","dptr");
7859 pic14_emitcode("movc","a","@a+dptr");
7863 pic14_emitcode("inc","dptr");
7864 pic14_emitcode("lcall","__gptrget");
7869 /* if we are done */
7873 aopPut(AOP(result),"a",offset++);
7878 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7879 aopPut(AOP(result),"a",offset);
7886 /*-----------------------------------------------------------------*/
7887 /* genDataPointerGet - generates code when ptr offset is known */
7888 /*-----------------------------------------------------------------*/
7889 static void genDataPointerGet (operand *left,
7893 int size , offset = 0;
7896 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7899 /* optimization - most of the time, left and result are the same
7900 * address, but different types. for the pic code, we could omit
7904 aopOp(result,ic,TRUE);
7906 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7908 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7910 size = AOP_SIZE(result);
7913 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7917 freeAsmop(left,NULL,ic,TRUE);
7918 freeAsmop(result,NULL,ic,TRUE);
7921 /*-----------------------------------------------------------------*/
7922 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7923 /*-----------------------------------------------------------------*/
7924 static void genNearPointerGet (operand *left,
7929 //regs *preg = NULL ;
7931 sym_link *rtype, *retype;
7932 sym_link *ltype = operandType(left);
7935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7937 rtype = operandType(result);
7938 retype= getSpec(rtype);
7940 aopOp(left,ic,FALSE);
7942 /* if left is rematerialisable and
7943 result is not bit variable type and
7944 the left is pointer to data space i.e
7945 lower 128 bytes of space */
7946 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7947 !IS_BITVAR(retype) &&
7948 DCL_TYPE(ltype) == POINTER) {
7949 //genDataPointerGet (left,result,ic);
7953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7955 /* if the value is already in a pointer register
7956 then don't need anything more */
7957 if (!AOP_INPREG(AOP(left))) {
7958 /* otherwise get a free pointer register */
7959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7962 preg = getFreePtr(ic,&aop,FALSE);
7963 pic14_emitcode("mov","%s,%s",
7965 aopGet(AOP(left),0,FALSE,TRUE));
7966 rname = preg->name ;
7970 rname = aopGet(AOP(left),0,FALSE,FALSE);
7972 aopOp (result,ic,FALSE);
7974 /* if bitfield then unpack the bits */
7975 if (IS_BITFIELD(retype))
7976 genUnpackBits (result,rname,POINTER);
7978 /* we have can just get the values */
7979 int size = AOP_SIZE(result);
7982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7984 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7985 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7987 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7988 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7990 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7994 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7996 pic14_emitcode("mov","a,@%s",rname);
7997 aopPut(AOP(result),"a",offset);
7999 sprintf(buffer,"@%s",rname);
8000 aopPut(AOP(result),buffer,offset);
8004 pic14_emitcode("inc","%s",rname);
8009 /* now some housekeeping stuff */
8011 /* we had to allocate for this iCode */
8012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8013 freeAsmop(NULL,aop,ic,TRUE);
8015 /* we did not allocate which means left
8016 already in a pointer register, then
8017 if size > 0 && this could be used again
8018 we have to point it back to where it
8020 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8021 if (AOP_SIZE(result) > 1 &&
8022 !OP_SYMBOL(left)->remat &&
8023 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8025 int size = AOP_SIZE(result) - 1;
8027 pic14_emitcode("dec","%s",rname);
8032 freeAsmop(left,NULL,ic,TRUE);
8033 freeAsmop(result,NULL,ic,TRUE);
8037 /*-----------------------------------------------------------------*/
8038 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8039 /*-----------------------------------------------------------------*/
8040 static void genPagedPointerGet (operand *left,
8047 sym_link *rtype, *retype;
8049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8051 rtype = operandType(result);
8052 retype= getSpec(rtype);
8054 aopOp(left,ic,FALSE);
8056 /* if the value is already in a pointer register
8057 then don't need anything more */
8058 if (!AOP_INPREG(AOP(left))) {
8059 /* otherwise get a free pointer register */
8061 preg = getFreePtr(ic,&aop,FALSE);
8062 pic14_emitcode("mov","%s,%s",
8064 aopGet(AOP(left),0,FALSE,TRUE));
8065 rname = preg->name ;
8067 rname = aopGet(AOP(left),0,FALSE,FALSE);
8069 freeAsmop(left,NULL,ic,TRUE);
8070 aopOp (result,ic,FALSE);
8072 /* if bitfield then unpack the bits */
8073 if (IS_BITFIELD(retype))
8074 genUnpackBits (result,rname,PPOINTER);
8076 /* we have can just get the values */
8077 int size = AOP_SIZE(result);
8082 pic14_emitcode("movx","a,@%s",rname);
8083 aopPut(AOP(result),"a",offset);
8088 pic14_emitcode("inc","%s",rname);
8092 /* now some housekeeping stuff */
8094 /* we had to allocate for this iCode */
8095 freeAsmop(NULL,aop,ic,TRUE);
8097 /* we did not allocate which means left
8098 already in a pointer register, then
8099 if size > 0 && this could be used again
8100 we have to point it back to where it
8102 if (AOP_SIZE(result) > 1 &&
8103 !OP_SYMBOL(left)->remat &&
8104 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8106 int size = AOP_SIZE(result) - 1;
8108 pic14_emitcode("dec","%s",rname);
8113 freeAsmop(result,NULL,ic,TRUE);
8118 /*-----------------------------------------------------------------*/
8119 /* genFarPointerGet - gget value from far space */
8120 /*-----------------------------------------------------------------*/
8121 static void genFarPointerGet (operand *left,
8122 operand *result, iCode *ic)
8125 sym_link *retype = getSpec(operandType(result));
8127 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8129 aopOp(left,ic,FALSE);
8131 /* if the operand is already in dptr
8132 then we do nothing else we move the value to dptr */
8133 if (AOP_TYPE(left) != AOP_STR) {
8134 /* if this is remateriazable */
8135 if (AOP_TYPE(left) == AOP_IMMD)
8136 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8137 else { /* we need to get it byte by byte */
8138 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8139 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8140 if (options.model == MODEL_FLAT24)
8142 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8146 /* so dptr know contains the address */
8147 freeAsmop(left,NULL,ic,TRUE);
8148 aopOp(result,ic,FALSE);
8150 /* if bit then unpack */
8151 if (IS_BITFIELD(retype))
8152 genUnpackBits(result,"dptr",FPOINTER);
8154 size = AOP_SIZE(result);
8158 pic14_emitcode("movx","a,@dptr");
8159 aopPut(AOP(result),"a",offset++);
8161 pic14_emitcode("inc","dptr");
8165 freeAsmop(result,NULL,ic,TRUE);
8168 /*-----------------------------------------------------------------*/
8169 /* genCodePointerGet - get value from code space */
8170 /*-----------------------------------------------------------------*/
8171 static void genCodePointerGet (operand *left,
8172 operand *result, iCode *ic)
8175 sym_link *retype = getSpec(operandType(result));
8177 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8179 aopOp(left,ic,FALSE);
8181 /* if the operand is already in dptr
8182 then we do nothing else we move the value to dptr */
8183 if (AOP_TYPE(left) != AOP_STR) {
8184 /* if this is remateriazable */
8185 if (AOP_TYPE(left) == AOP_IMMD)
8186 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8187 else { /* we need to get it byte by byte */
8188 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8189 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8190 if (options.model == MODEL_FLAT24)
8192 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8196 /* so dptr know contains the address */
8197 freeAsmop(left,NULL,ic,TRUE);
8198 aopOp(result,ic,FALSE);
8200 /* if bit then unpack */
8201 if (IS_BITFIELD(retype))
8202 genUnpackBits(result,"dptr",CPOINTER);
8204 size = AOP_SIZE(result);
8208 pic14_emitcode("clr","a");
8209 pic14_emitcode("movc","a,@a+dptr");
8210 aopPut(AOP(result),"a",offset++);
8212 pic14_emitcode("inc","dptr");
8216 freeAsmop(result,NULL,ic,TRUE);
8219 /*-----------------------------------------------------------------*/
8220 /* genGenPointerGet - gget value from generic pointer space */
8221 /*-----------------------------------------------------------------*/
8222 static void genGenPointerGet (operand *left,
8223 operand *result, iCode *ic)
8226 sym_link *retype = getSpec(operandType(result));
8228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8229 aopOp(left,ic,FALSE);
8230 aopOp(result,ic,FALSE);
8233 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8235 /* if the operand is already in dptr
8236 then we do nothing else we move the value to dptr */
8237 // if (AOP_TYPE(left) != AOP_STR) {
8238 /* if this is remateriazable */
8239 if (AOP_TYPE(left) == AOP_IMMD) {
8240 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8241 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8243 else { /* we need to get it byte by byte */
8245 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8246 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8248 size = AOP_SIZE(result);
8252 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8253 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8255 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8260 /* so dptr know contains the address */
8262 /* if bit then unpack */
8263 //if (IS_BITFIELD(retype))
8264 // genUnpackBits(result,"dptr",GPOINTER);
8267 freeAsmop(left,NULL,ic,TRUE);
8268 freeAsmop(result,NULL,ic,TRUE);
8272 /*-----------------------------------------------------------------*/
8273 /* genConstPointerGet - get value from const generic pointer space */
8274 /*-----------------------------------------------------------------*/
8275 static void genConstPointerGet (operand *left,
8276 operand *result, iCode *ic)
8278 //sym_link *retype = getSpec(operandType(result));
8279 symbol *albl = newiTempLabel(NULL);
8280 symbol *blbl = newiTempLabel(NULL);
8284 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8285 aopOp(left,ic,FALSE);
8286 aopOp(result,ic,FALSE);
8289 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8291 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8293 emitpcode(POC_CALL,popGetLabel(albl->key));
8294 pcop = popGetLabel(blbl->key);
8295 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8296 emitpcode(POC_GOTO,pcop);
8297 emitpLabel(albl->key);
8299 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8301 emitpcode(poc,popGet(AOP(left),1));
8302 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8303 emitpcode(poc,popGet(AOP(left),0));
8304 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8306 emitpLabel(blbl->key);
8308 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8311 freeAsmop(left,NULL,ic,TRUE);
8312 freeAsmop(result,NULL,ic,TRUE);
8315 /*-----------------------------------------------------------------*/
8316 /* genPointerGet - generate code for pointer get */
8317 /*-----------------------------------------------------------------*/
8318 static void genPointerGet (iCode *ic)
8320 operand *left, *result ;
8321 sym_link *type, *etype;
8324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8327 result = IC_RESULT(ic) ;
8329 /* depending on the type of pointer we need to
8330 move it to the correct pointer register */
8331 type = operandType(left);
8332 etype = getSpec(type);
8334 if (IS_PTR_CONST(type))
8335 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8337 /* if left is of type of pointer then it is simple */
8338 if (IS_PTR(type) && !IS_FUNC(type->next))
8339 p_type = DCL_TYPE(type);
8341 /* we have to go by the storage class */
8342 p_type = PTR_TYPE(SPEC_OCLS(etype));
8344 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8346 if (SPEC_OCLS(etype)->codesp ) {
8347 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8348 //p_type = CPOINTER ;
8351 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8352 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8353 /*p_type = FPOINTER ;*/
8355 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8356 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8357 /* p_type = PPOINTER; */
8359 if (SPEC_OCLS(etype) == idata )
8360 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8361 /* p_type = IPOINTER; */
8363 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8364 /* p_type = POINTER ; */
8367 /* now that we have the pointer type we assign
8368 the pointer values */
8373 genNearPointerGet (left,result,ic);
8377 genPagedPointerGet(left,result,ic);
8381 genFarPointerGet (left,result,ic);
8385 genConstPointerGet (left,result,ic);
8386 //pic14_emitcodePointerGet (left,result,ic);
8390 if (IS_PTR_CONST(type))
8391 genConstPointerGet (left,result,ic);
8393 genGenPointerGet (left,result,ic);
8399 /*-----------------------------------------------------------------*/
8400 /* genPackBits - generates code for packed bit storage */
8401 /*-----------------------------------------------------------------*/
8402 static void genPackBits (sym_link *etype ,
8404 char *rname, int p_type)
8412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8413 blen = SPEC_BLEN(etype);
8414 bstr = SPEC_BSTR(etype);
8416 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8419 /* if the bit lenth is less than or */
8420 /* it exactly fits a byte then */
8421 if (SPEC_BLEN(etype) <= 8 ) {
8422 shCount = SPEC_BSTR(etype) ;
8424 /* shift left acc */
8427 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8432 pic14_emitcode ("mov","b,a");
8433 pic14_emitcode("mov","a,@%s",rname);
8437 pic14_emitcode ("mov","b,a");
8438 pic14_emitcode("movx","a,@dptr");
8442 pic14_emitcode ("push","b");
8443 pic14_emitcode ("push","acc");
8444 pic14_emitcode ("lcall","__gptrget");
8445 pic14_emitcode ("pop","b");
8449 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8450 ((unsigned char)(0xFF << (blen+bstr)) |
8451 (unsigned char)(0xFF >> (8-bstr)) ) );
8452 pic14_emitcode ("orl","a,b");
8453 if (p_type == GPOINTER)
8454 pic14_emitcode("pop","b");
8460 pic14_emitcode("mov","@%s,a",rname);
8464 pic14_emitcode("movx","@dptr,a");
8468 DEBUGpic14_emitcode(";lcall","__gptrput");
8473 if ( SPEC_BLEN(etype) <= 8 )
8476 pic14_emitcode("inc","%s",rname);
8477 rLen = SPEC_BLEN(etype) ;
8479 /* now generate for lengths greater than one byte */
8482 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8492 pic14_emitcode("mov","@%s,a",rname);
8494 pic14_emitcode("mov","@%s,%s",rname,l);
8499 pic14_emitcode("movx","@dptr,a");
8504 DEBUGpic14_emitcode(";lcall","__gptrput");
8507 pic14_emitcode ("inc","%s",rname);
8512 /* last last was not complete */
8514 /* save the byte & read byte */
8517 pic14_emitcode ("mov","b,a");
8518 pic14_emitcode("mov","a,@%s",rname);
8522 pic14_emitcode ("mov","b,a");
8523 pic14_emitcode("movx","a,@dptr");
8527 pic14_emitcode ("push","b");
8528 pic14_emitcode ("push","acc");
8529 pic14_emitcode ("lcall","__gptrget");
8530 pic14_emitcode ("pop","b");
8534 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8535 pic14_emitcode ("orl","a,b");
8538 if (p_type == GPOINTER)
8539 pic14_emitcode("pop","b");
8544 pic14_emitcode("mov","@%s,a",rname);
8548 pic14_emitcode("movx","@dptr,a");
8552 DEBUGpic14_emitcode(";lcall","__gptrput");
8556 /*-----------------------------------------------------------------*/
8557 /* genDataPointerSet - remat pointer to data space */
8558 /*-----------------------------------------------------------------*/
8559 static void genDataPointerSet(operand *right,
8563 int size, offset = 0 ;
8564 char *l, buffer[256];
8566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8567 aopOp(right,ic,FALSE);
8569 l = aopGet(AOP(result),0,FALSE,TRUE);
8570 size = AOP_SIZE(right);
8572 if ( AOP_TYPE(result) == AOP_PCODE) {
8573 fprintf(stderr,"genDataPointerSet %s, %d\n",
8574 AOP(result)->aopu.pcop->name,
8575 PCOI(AOP(result)->aopu.pcop)->offset);
8579 // tsd, was l+1 - the underline `_' prefix was being stripped
8582 sprintf(buffer,"(%s + %d)",l,offset);
8583 fprintf(stderr,"oops %s\n",buffer);
8585 sprintf(buffer,"%s",l);
8587 if (AOP_TYPE(right) == AOP_LIT) {
8588 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8589 lit = lit >> (8*offset);
8591 pic14_emitcode("movlw","%d",lit);
8592 pic14_emitcode("movwf","%s",buffer);
8594 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8595 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8596 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8599 pic14_emitcode("clrf","%s",buffer);
8600 //emitpcode(POC_CLRF, popRegFromString(buffer));
8601 emitpcode(POC_CLRF, popGet(AOP(result),0));
8604 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8605 pic14_emitcode("movwf","%s",buffer);
8607 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8608 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8609 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8616 freeAsmop(right,NULL,ic,TRUE);
8617 freeAsmop(result,NULL,ic,TRUE);
8620 /*-----------------------------------------------------------------*/
8621 /* genNearPointerSet - pic14_emitcode for near pointer put */
8622 /*-----------------------------------------------------------------*/
8623 static void genNearPointerSet (operand *right,
8630 sym_link *ptype = operandType(result);
8633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8634 retype= getSpec(operandType(right));
8636 aopOp(result,ic,FALSE);
8639 /* if the result is rematerializable &
8640 in data space & not a bit variable */
8641 //if (AOP_TYPE(result) == AOP_IMMD &&
8642 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8643 DCL_TYPE(ptype) == POINTER &&
8644 !IS_BITFIELD(retype)) {
8645 genDataPointerSet (right,result,ic);
8646 freeAsmop(result,NULL,ic,TRUE);
8650 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8651 aopOp(right,ic,FALSE);
8652 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8654 /* if the value is already in a pointer register
8655 then don't need anything more */
8656 if (!AOP_INPREG(AOP(result))) {
8657 /* otherwise get a free pointer register */
8658 //aop = newAsmop(0);
8659 //preg = getFreePtr(ic,&aop,FALSE);
8660 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8661 //pic14_emitcode("mov","%s,%s",
8663 // aopGet(AOP(result),0,FALSE,TRUE));
8664 //rname = preg->name ;
8665 //pic14_emitcode("movwf","fsr");
8666 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8667 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8668 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8669 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8673 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8676 /* if bitfield then unpack the bits */
8677 if (IS_BITFIELD(retype)) {
8678 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8679 "The programmer is obviously confused");
8680 //genPackBits (retype,right,rname,POINTER);
8684 /* we have can just get the values */
8685 int size = AOP_SIZE(right);
8688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8690 l = aopGet(AOP(right),offset,FALSE,TRUE);
8693 //pic14_emitcode("mov","@%s,a",rname);
8694 pic14_emitcode("movf","indf,w ;1");
8697 if (AOP_TYPE(right) == AOP_LIT) {
8698 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8700 pic14_emitcode("movlw","%s",l);
8701 pic14_emitcode("movwf","indf ;2");
8703 pic14_emitcode("clrf","indf");
8705 pic14_emitcode("movf","%s,w",l);
8706 pic14_emitcode("movwf","indf ;2");
8708 //pic14_emitcode("mov","@%s,%s",rname,l);
8711 pic14_emitcode("incf","fsr,f ;3");
8712 //pic14_emitcode("inc","%s",rname);
8717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8718 /* now some housekeeping stuff */
8720 /* we had to allocate for this iCode */
8721 freeAsmop(NULL,aop,ic,TRUE);
8723 /* we did not allocate which means left
8724 already in a pointer register, then
8725 if size > 0 && this could be used again
8726 we have to point it back to where it
8728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8729 if (AOP_SIZE(right) > 1 &&
8730 !OP_SYMBOL(result)->remat &&
8731 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8733 int size = AOP_SIZE(right) - 1;
8735 pic14_emitcode("decf","fsr,f");
8736 //pic14_emitcode("dec","%s",rname);
8740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8743 freeAsmop(right,NULL,ic,TRUE);
8744 freeAsmop(result,NULL,ic,TRUE);
8747 /*-----------------------------------------------------------------*/
8748 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8749 /*-----------------------------------------------------------------*/
8750 static void genPagedPointerSet (operand *right,
8759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8761 retype= getSpec(operandType(right));
8763 aopOp(result,ic,FALSE);
8765 /* if the value is already in a pointer register
8766 then don't need anything more */
8767 if (!AOP_INPREG(AOP(result))) {
8768 /* otherwise get a free pointer register */
8770 preg = getFreePtr(ic,&aop,FALSE);
8771 pic14_emitcode("mov","%s,%s",
8773 aopGet(AOP(result),0,FALSE,TRUE));
8774 rname = preg->name ;
8776 rname = aopGet(AOP(result),0,FALSE,FALSE);
8778 freeAsmop(result,NULL,ic,TRUE);
8779 aopOp (right,ic,FALSE);
8781 /* if bitfield then unpack the bits */
8782 if (IS_BITFIELD(retype))
8783 genPackBits (retype,right,rname,PPOINTER);
8785 /* we have can just get the values */
8786 int size = AOP_SIZE(right);
8790 l = aopGet(AOP(right),offset,FALSE,TRUE);
8793 pic14_emitcode("movx","@%s,a",rname);
8796 pic14_emitcode("inc","%s",rname);
8802 /* now some housekeeping stuff */
8804 /* we had to allocate for this iCode */
8805 freeAsmop(NULL,aop,ic,TRUE);
8807 /* we did not allocate which means left
8808 already in a pointer register, then
8809 if size > 0 && this could be used again
8810 we have to point it back to where it
8812 if (AOP_SIZE(right) > 1 &&
8813 !OP_SYMBOL(result)->remat &&
8814 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8816 int size = AOP_SIZE(right) - 1;
8818 pic14_emitcode("dec","%s",rname);
8823 freeAsmop(right,NULL,ic,TRUE);
8828 /*-----------------------------------------------------------------*/
8829 /* genFarPointerSet - set value from far space */
8830 /*-----------------------------------------------------------------*/
8831 static void genFarPointerSet (operand *right,
8832 operand *result, iCode *ic)
8835 sym_link *retype = getSpec(operandType(right));
8837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8838 aopOp(result,ic,FALSE);
8840 /* if the operand is already in dptr
8841 then we do nothing else we move the value to dptr */
8842 if (AOP_TYPE(result) != AOP_STR) {
8843 /* if this is remateriazable */
8844 if (AOP_TYPE(result) == AOP_IMMD)
8845 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8846 else { /* we need to get it byte by byte */
8847 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8848 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8849 if (options.model == MODEL_FLAT24)
8851 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8855 /* so dptr know contains the address */
8856 freeAsmop(result,NULL,ic,TRUE);
8857 aopOp(right,ic,FALSE);
8859 /* if bit then unpack */
8860 if (IS_BITFIELD(retype))
8861 genPackBits(retype,right,"dptr",FPOINTER);
8863 size = AOP_SIZE(right);
8867 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8869 pic14_emitcode("movx","@dptr,a");
8871 pic14_emitcode("inc","dptr");
8875 freeAsmop(right,NULL,ic,TRUE);
8878 /*-----------------------------------------------------------------*/
8879 /* genGenPointerSet - set value from generic pointer space */
8880 /*-----------------------------------------------------------------*/
8881 static void genGenPointerSet (operand *right,
8882 operand *result, iCode *ic)
8885 sym_link *retype = getSpec(operandType(right));
8887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8889 aopOp(result,ic,FALSE);
8890 aopOp(right,ic,FALSE);
8891 size = AOP_SIZE(right);
8893 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8895 /* if the operand is already in dptr
8896 then we do nothing else we move the value to dptr */
8897 if (AOP_TYPE(result) != AOP_STR) {
8898 /* if this is remateriazable */
8899 if (AOP_TYPE(result) == AOP_IMMD) {
8900 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8901 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8903 else { /* we need to get it byte by byte */
8904 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8905 size = AOP_SIZE(right);
8908 /* hack hack! see if this the FSR. If so don't load W */
8909 if(AOP_TYPE(right) != AOP_ACC) {
8912 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8913 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8915 if(AOP_SIZE(result) > 1) {
8916 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8917 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8918 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8923 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8925 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8926 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8930 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8931 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8934 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8941 if(aopIdx(AOP(result),0) != 4) {
8943 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8947 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8952 /* so dptr know contains the address */
8955 /* if bit then unpack */
8956 if (IS_BITFIELD(retype))
8957 genPackBits(retype,right,"dptr",GPOINTER);
8959 size = AOP_SIZE(right);
8962 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8966 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8967 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8969 if (AOP_TYPE(right) == AOP_LIT)
8970 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8972 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8974 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8981 freeAsmop(right,NULL,ic,TRUE);
8982 freeAsmop(result,NULL,ic,TRUE);
8985 /*-----------------------------------------------------------------*/
8986 /* genPointerSet - stores the value into a pointer location */
8987 /*-----------------------------------------------------------------*/
8988 static void genPointerSet (iCode *ic)
8990 operand *right, *result ;
8991 sym_link *type, *etype;
8994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8996 right = IC_RIGHT(ic);
8997 result = IC_RESULT(ic) ;
8999 /* depending on the type of pointer we need to
9000 move it to the correct pointer register */
9001 type = operandType(result);
9002 etype = getSpec(type);
9003 /* if left is of type of pointer then it is simple */
9004 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9005 p_type = DCL_TYPE(type);
9008 /* we have to go by the storage class */
9009 p_type = PTR_TYPE(SPEC_OCLS(etype));
9011 /* if (SPEC_OCLS(etype)->codesp ) { */
9012 /* p_type = CPOINTER ; */
9015 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9016 /* p_type = FPOINTER ; */
9018 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9019 /* p_type = PPOINTER ; */
9021 /* if (SPEC_OCLS(etype) == idata ) */
9022 /* p_type = IPOINTER ; */
9024 /* p_type = POINTER ; */
9027 /* now that we have the pointer type we assign
9028 the pointer values */
9033 genNearPointerSet (right,result,ic);
9037 genPagedPointerSet (right,result,ic);
9041 genFarPointerSet (right,result,ic);
9045 genGenPointerSet (right,result,ic);
9049 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9050 "genPointerSet: illegal pointer type");
9054 /*-----------------------------------------------------------------*/
9055 /* genIfx - generate code for Ifx statement */
9056 /*-----------------------------------------------------------------*/
9057 static void genIfx (iCode *ic, iCode *popIc)
9059 operand *cond = IC_COND(ic);
9062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9064 aopOp(cond,ic,FALSE);
9066 /* get the value into acc */
9067 if (AOP_TYPE(cond) != AOP_CRY)
9068 pic14_toBoolean(cond);
9071 /* the result is now in the accumulator */
9072 freeAsmop(cond,NULL,ic,TRUE);
9074 /* if there was something to be popped then do it */
9078 /* if the condition is a bit variable */
9079 if (isbit && IS_ITEMP(cond) &&
9081 genIfxJump(ic,SPIL_LOC(cond)->rname);
9082 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9085 if (isbit && !IS_ITEMP(cond))
9086 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9094 /*-----------------------------------------------------------------*/
9095 /* genAddrOf - generates code for address of */
9096 /*-----------------------------------------------------------------*/
9097 static void genAddrOf (iCode *ic)
9099 operand *right, *result, *left;
9102 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9105 //aopOp(IC_RESULT(ic),ic,FALSE);
9107 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9108 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9109 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9111 DEBUGpic14_AopType(__LINE__,left,right,result);
9113 size = AOP_SIZE(IC_RESULT(ic));
9117 /* fixing bug #863624, reported from (errolv) */
9118 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9119 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9122 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9123 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9128 freeAsmop(left,NULL,ic,FALSE);
9129 freeAsmop(result,NULL,ic,TRUE);
9134 /*-----------------------------------------------------------------*/
9135 /* genFarFarAssign - assignment when both are in far space */
9136 /*-----------------------------------------------------------------*/
9137 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9139 int size = AOP_SIZE(right);
9142 /* first push the right side on to the stack */
9144 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9146 pic14_emitcode ("push","acc");
9149 freeAsmop(right,NULL,ic,FALSE);
9150 /* now assign DPTR to result */
9151 aopOp(result,ic,FALSE);
9152 size = AOP_SIZE(result);
9154 pic14_emitcode ("pop","acc");
9155 aopPut(AOP(result),"a",--offset);
9157 freeAsmop(result,NULL,ic,FALSE);
9162 /*-----------------------------------------------------------------*/
9163 /* genAssign - generate code for assignment */
9164 /*-----------------------------------------------------------------*/
9165 static void genAssign (iCode *ic)
9167 operand *result, *right;
9168 int size, offset,know_W;
9169 unsigned long lit = 0L;
9171 result = IC_RESULT(ic);
9172 right = IC_RIGHT(ic) ;
9174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9176 /* if they are the same */
9177 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9180 aopOp(right,ic,FALSE);
9181 aopOp(result,ic,TRUE);
9183 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9185 /* if they are the same registers */
9186 if (pic14_sameRegs(AOP(right),AOP(result)))
9189 /* if the result is a bit */
9190 if (AOP_TYPE(result) == AOP_CRY) {
9192 /* if the right size is a literal then
9193 we know what the value is */
9194 if (AOP_TYPE(right) == AOP_LIT) {
9196 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9197 popGet(AOP(result),0));
9199 if (((int) operandLitValue(right)))
9200 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9201 AOP(result)->aopu.aop_dir,
9202 AOP(result)->aopu.aop_dir);
9204 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9205 AOP(result)->aopu.aop_dir,
9206 AOP(result)->aopu.aop_dir);
9210 /* the right is also a bit variable */
9211 if (AOP_TYPE(right) == AOP_CRY) {
9212 emitpcode(POC_BCF, popGet(AOP(result),0));
9213 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9214 emitpcode(POC_BSF, popGet(AOP(result),0));
9216 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9217 AOP(result)->aopu.aop_dir,
9218 AOP(result)->aopu.aop_dir);
9219 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9220 AOP(right)->aopu.aop_dir,
9221 AOP(right)->aopu.aop_dir);
9222 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9223 AOP(result)->aopu.aop_dir,
9224 AOP(result)->aopu.aop_dir);
9229 emitpcode(POC_BCF, popGet(AOP(result),0));
9230 pic14_toBoolean(right);
9232 emitpcode(POC_BSF, popGet(AOP(result),0));
9233 //aopPut(AOP(result),"a",0);
9237 /* bit variables done */
9239 size = AOP_SIZE(result);
9241 if(AOP_TYPE(right) == AOP_LIT)
9242 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9244 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9246 if(aopIdx(AOP(result),0) == 4) {
9247 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9248 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9249 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9252 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9258 if(AOP_TYPE(right) == AOP_LIT) {
9260 if(know_W != (int)(lit&0xff))
9261 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9263 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9265 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9269 } else if (AOP_TYPE(right) == AOP_CRY) {
9270 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9272 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9273 emitpcode(POC_INCF, popGet(AOP(result),0));
9276 mov2w (AOP(right), offset);
9277 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9285 freeAsmop (right,NULL,ic,FALSE);
9286 freeAsmop (result,NULL,ic,TRUE);
9289 /*-----------------------------------------------------------------*/
9290 /* genJumpTab - genrates code for jump table */
9291 /*-----------------------------------------------------------------*/
9292 static void genJumpTab (iCode *ic)
9297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9299 aopOp(IC_JTCOND(ic),ic,FALSE);
9300 /* get the condition into accumulator */
9301 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9303 /* multiply by three */
9304 pic14_emitcode("add","a,acc");
9305 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9307 jtab = newiTempLabel(NULL);
9308 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9309 pic14_emitcode("jmp","@a+dptr");
9310 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9312 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9313 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9314 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9315 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9317 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9318 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9319 emitpLabel(jtab->key);
9321 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9323 /* now generate the jump labels */
9324 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9325 jtab = setNextItem(IC_JTLABELS(ic))) {
9326 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9327 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9333 /*-----------------------------------------------------------------*/
9334 /* genMixedOperation - gen code for operators between mixed types */
9335 /*-----------------------------------------------------------------*/
9337 TSD - Written for the PIC port - but this unfortunately is buggy.
9338 This routine is good in that it is able to efficiently promote
9339 types to different (larger) sizes. Unfortunately, the temporary
9340 variables that are optimized out by this routine are sometimes
9341 used in other places. So until I know how to really parse the
9342 iCode tree, I'm going to not be using this routine :(.
9344 static int genMixedOperation (iCode *ic)
9347 operand *result = IC_RESULT(ic);
9348 sym_link *ctype = operandType(IC_LEFT(ic));
9349 operand *right = IC_RIGHT(ic);
9355 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9357 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9363 nextright = IC_RIGHT(nextic);
9364 nextleft = IC_LEFT(nextic);
9365 nextresult = IC_RESULT(nextic);
9367 aopOp(right,ic,FALSE);
9368 aopOp(result,ic,FALSE);
9369 aopOp(nextright, nextic, FALSE);
9370 aopOp(nextleft, nextic, FALSE);
9371 aopOp(nextresult, nextic, FALSE);
9373 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9379 pic14_emitcode(";remove right +","");
9381 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9387 pic14_emitcode(";remove left +","");
9391 big = AOP_SIZE(nextleft);
9392 small = AOP_SIZE(nextright);
9394 switch(nextic->op) {
9397 pic14_emitcode(";optimize a +","");
9398 /* if unsigned or not an integral type */
9399 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9400 pic14_emitcode(";add a bit to something","");
9403 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9405 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9406 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9407 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9409 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9417 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9418 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9419 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9422 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9424 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9425 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9426 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9427 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9431 pic14_emitcode("rlf","known_zero,w");
9438 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9439 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9440 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9442 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9452 freeAsmop(right,NULL,ic,TRUE);
9453 freeAsmop(result,NULL,ic,TRUE);
9454 freeAsmop(nextright,NULL,ic,TRUE);
9455 freeAsmop(nextleft,NULL,ic,TRUE);
9457 nextic->generated = 1;
9464 /*-----------------------------------------------------------------*/
9465 /* genCast - gen code for casting */
9466 /*-----------------------------------------------------------------*/
9467 static void genCast (iCode *ic)
9469 operand *result = IC_RESULT(ic);
9470 sym_link *ctype = operandType(IC_LEFT(ic));
9471 sym_link *rtype = operandType(IC_RIGHT(ic));
9472 operand *right = IC_RIGHT(ic);
9475 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9476 /* if they are equivalent then do nothing */
9477 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9480 aopOp(right,ic,FALSE) ;
9481 aopOp(result,ic,FALSE);
9483 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9485 /* if the result is a bit */
9486 if (AOP_TYPE(result) == AOP_CRY) {
9487 /* if the right size is a literal then
9488 we know what the value is */
9489 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9490 if (AOP_TYPE(right) == AOP_LIT) {
9492 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9493 popGet(AOP(result),0));
9495 if (((int) operandLitValue(right)))
9496 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9497 AOP(result)->aopu.aop_dir,
9498 AOP(result)->aopu.aop_dir);
9500 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9501 AOP(result)->aopu.aop_dir,
9502 AOP(result)->aopu.aop_dir);
9507 /* the right is also a bit variable */
9508 if (AOP_TYPE(right) == AOP_CRY) {
9511 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9513 pic14_emitcode("clrc","");
9514 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9515 AOP(right)->aopu.aop_dir,
9516 AOP(right)->aopu.aop_dir);
9517 aopPut(AOP(result),"c",0);
9522 if (AOP_TYPE(right) == AOP_REG) {
9523 emitpcode(POC_BCF, popGet(AOP(result),0));
9524 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9525 emitpcode(POC_BSF, popGet(AOP(result),0));
9527 pic14_toBoolean(right);
9528 aopPut(AOP(result),"a",0);
9532 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9534 size = AOP_SIZE(result);
9536 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9538 emitpcode(POC_CLRF, popGet(AOP(result),0));
9539 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9540 emitpcode(POC_INCF, popGet(AOP(result),0));
9543 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9548 /* if they are the same size : or less */
9549 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9551 /* if they are in the same place */
9552 if (pic14_sameRegs(AOP(right),AOP(result)))
9555 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9556 if (IS_PTR_CONST(rtype))
9557 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9558 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9559 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9561 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9562 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9563 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9564 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9565 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9566 if(AOP_SIZE(result) <2)
9567 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9571 /* if they in different places then copy */
9572 size = AOP_SIZE(result);
9575 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9576 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9578 //aopPut(AOP(result),
9579 // aopGet(AOP(right),offset,FALSE,FALSE),
9589 /* if the result is of type pointer */
9590 if (IS_PTR(ctype)) {
9593 sym_link *type = operandType(right);
9594 sym_link *etype = getSpec(type);
9595 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9597 /* pointer to generic pointer */
9598 if (IS_GENPTR(ctype)) {
9602 p_type = DCL_TYPE(type);
9604 /* we have to go by the storage class */
9605 p_type = PTR_TYPE(SPEC_OCLS(etype));
9607 /* if (SPEC_OCLS(etype)->codesp ) */
9608 /* p_type = CPOINTER ; */
9610 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9611 /* p_type = FPOINTER ; */
9613 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9614 /* p_type = PPOINTER; */
9616 /* if (SPEC_OCLS(etype) == idata ) */
9617 /* p_type = IPOINTER ; */
9619 /* p_type = POINTER ; */
9622 /* the first two bytes are known */
9623 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9624 size = GPTRSIZE - 1;
9627 if(offset < AOP_SIZE(right)) {
9628 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9629 if ((AOP_TYPE(right) == AOP_PCODE) &&
9630 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9631 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9632 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9635 aopGet(AOP(right),offset,FALSE,FALSE),
9639 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9642 /* the last byte depending on type */
9646 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9649 pic14_emitcode(";BUG!? ","%d",__LINE__);
9653 pic14_emitcode(";BUG!? ","%d",__LINE__);
9657 pic14_emitcode(";BUG!? ","%d",__LINE__);
9662 /* this should never happen */
9663 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9664 "got unknown pointer type");
9667 //aopPut(AOP(result),l, GPTRSIZE - 1);
9671 /* just copy the pointers */
9672 size = AOP_SIZE(result);
9676 aopGet(AOP(right),offset,FALSE,FALSE),
9685 /* so we now know that the size of destination is greater
9686 than the size of the source.
9687 Now, if the next iCode is an operator then we might be
9688 able to optimize the operation without performing a cast.
9690 if(genMixedOperation(ic))
9693 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9695 /* we move to result for the size of source */
9696 size = AOP_SIZE(right);
9699 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9700 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9704 /* now depending on the sign of the destination */
9705 size = AOP_SIZE(result) - AOP_SIZE(right);
9706 /* if unsigned or not an integral type */
9707 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9709 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9711 /* we need to extend the sign :{ */
9714 /* Save one instruction of casting char to int */
9715 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9716 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9717 emitpcode(POC_DECF, popGet(AOP(result),offset));
9719 emitpcodeNULLop(POC_CLRW);
9722 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9724 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9726 emitpcode(POC_MOVLW, popGetLit(0xff));
9729 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9734 freeAsmop(right,NULL,ic,TRUE);
9735 freeAsmop(result,NULL,ic,TRUE);
9739 /*-----------------------------------------------------------------*/
9740 /* genDjnz - generate decrement & jump if not zero instrucion */
9741 /*-----------------------------------------------------------------*/
9742 static int genDjnz (iCode *ic, iCode *ifx)
9745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9750 /* if the if condition has a false label
9751 then we cannot save */
9755 /* if the minus is not of the form
9757 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9758 !IS_OP_LITERAL(IC_RIGHT(ic)))
9761 if (operandLitValue(IC_RIGHT(ic)) != 1)
9764 /* if the size of this greater than one then no
9766 if (getSize(operandType(IC_RESULT(ic))) > 1)
9769 /* otherwise we can save BIG */
9770 lbl = newiTempLabel(NULL);
9771 lbl1= newiTempLabel(NULL);
9773 aopOp(IC_RESULT(ic),ic,FALSE);
9775 if (IS_AOP_PREG(IC_RESULT(ic))) {
9776 pic14_emitcode("dec","%s",
9777 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9778 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9779 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9783 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9784 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9786 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9787 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9790 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9791 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9792 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9793 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9796 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9801 /*-----------------------------------------------------------------*/
9802 /* genReceive - generate code for a receive iCode */
9803 /*-----------------------------------------------------------------*/
9804 static void genReceive (iCode *ic)
9806 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9808 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9809 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9810 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9812 int size = getSize(operandType(IC_RESULT(ic)));
9813 int offset = fReturnSizePic - size;
9815 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9816 fReturn[fReturnSizePic - offset - 1] : "acc"));
9819 aopOp(IC_RESULT(ic),ic,FALSE);
9820 size = AOP_SIZE(IC_RESULT(ic));
9823 pic14_emitcode ("pop","acc");
9824 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9829 aopOp(IC_RESULT(ic),ic,FALSE);
9831 assignResultValue(IC_RESULT(ic));
9834 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9837 /*-----------------------------------------------------------------*/
9838 /* genDummyRead - generate code for dummy read of volatiles */
9839 /*-----------------------------------------------------------------*/
9841 genDummyRead (iCode * ic)
9843 pic14_emitcode ("; genDummyRead","");
9844 pic14_emitcode ("; not implemented","");
9849 /*-----------------------------------------------------------------*/
9850 /* genpic14Code - generate code for pic14 based controllers */
9851 /*-----------------------------------------------------------------*/
9853 * At this point, ralloc.c has gone through the iCode and attempted
9854 * to optimize in a way suitable for a PIC. Now we've got to generate
9855 * PIC instructions that correspond to the iCode.
9857 * Once the instructions are generated, we'll pass through both the
9858 * peep hole optimizer and the pCode optimizer.
9859 *-----------------------------------------------------------------*/
9861 void genpic14Code (iCode *lic)
9866 lineHead = lineCurr = NULL;
9868 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9871 /* if debug information required */
9872 if (options.debug && currFunc) {
9874 debugFile->writeFunction (currFunc, lic);
9879 for (ic = lic ; ic ; ic = ic->next ) {
9881 DEBUGpic14_emitcode(";ic","");
9882 if ( cln != ic->lineno ) {
9883 if ( options.debug ) {
9884 debugFile->writeCLine (ic);
9887 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9888 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9889 printCLine(ic->filename, ic->lineno));
9891 if (!options.noCcodeInAsm) {
9893 newpCodeCSource(ic->lineno,
9895 printCLine(ic->filename, ic->lineno)));
9901 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9903 /* if the result is marked as
9904 spilt and rematerializable or code for
9905 this has already been generated then
9907 if (resultRemat(ic) || ic->generated )
9910 /* depending on the operation */
9929 /* IPOP happens only when trying to restore a
9930 spilt live range, if there is an ifx statement
9931 following this pop then the if statement might
9932 be using some of the registers being popped which
9933 would destory the contents of the register so
9934 we need to check for this condition and handle it */
9936 ic->next->op == IFX &&
9937 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9938 genIfx (ic->next,ic);
9956 genEndFunction (ic);
9976 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9993 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9997 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10004 /* note these two are xlated by algebraic equivalence
10005 during parsing SDCC.y */
10006 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10007 "got '>=' or '<=' shouldn't have come here");
10011 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10023 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10027 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10031 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10055 genRightShift (ic);
10058 case GET_VALUE_AT_ADDRESS:
10063 if (POINTER_SET(ic))
10090 addSet(&_G.sendSet,ic);
10093 case DUMMY_READ_VOLATILE:
10103 /* now we are ready to call the
10104 peep hole optimizer */
10105 if (!options.nopeep) {
10106 peepHole (&lineHead);
10108 /* now do the actual printing */
10109 printLine (lineHead,codeOutFile);
10112 DFPRINTF((stderr,"printing pBlock\n\n"));
10113 printpBlock(stdout,pb);