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);
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69 /* this is the down and dirty file with all kinds of
70 kludgy & hacky stuff. This is what it is all about
71 CODE GENERATION for a specific MCU . some of the
72 routines may be reusable, will have to see */
74 static char *zero = "#0x00";
75 static char *one = "#0x01";
76 static char *spname = "sp";
78 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
79 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
80 static char **fReturn = fReturnpic14;
82 static char *accUse[] = {"a","b"};
84 //static short rbank = -1;
96 /* Resolved ifx structure. This structure stores information
97 about an iCode ifx that makes it easier to generate code.
99 typedef struct resolvedIfx {
100 symbol *lbl; /* pointer to a label */
101 int condition; /* true or false ifx */
102 int generated; /* set true when the code associated with the ifx
106 extern int pic14_ptrRegReq ;
107 extern int pic14_nRegs;
108 extern FILE *codeOutFile;
109 static void saverbank (int, iCode *,bool);
111 static lineNode *lineHead = NULL;
112 static lineNode *lineCurr = NULL;
114 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
115 0xE0, 0xC0, 0x80, 0x00};
116 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
117 0x07, 0x03, 0x01, 0x00};
121 /*-----------------------------------------------------------------*/
122 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
123 /* exponent of 2 is returned, otherwise -1 is */
125 /* note that this is similar to the function `powof2' in SDCCsymt */
129 /*-----------------------------------------------------------------*/
130 static int my_powof2 (unsigned long num)
133 if( (num & (num-1)) == 0) {
146 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
149 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
151 ((result) ? AopType(AOP_TYPE(result)) : "-"),
152 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
153 ((left) ? AopType(AOP_TYPE(left)) : "-"),
154 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
155 ((right) ? AopType(AOP_TYPE(right)) : "-"),
156 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
157 ((result) ? AOP_SIZE(result) : 0));
161 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
164 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
166 ((result) ? AopType(AOP_TYPE(result)) : "-"),
167 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
168 ((left) ? AopType(AOP_TYPE(left)) : "-"),
169 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
170 ((right) ? AopType(AOP_TYPE(right)) : "-"),
171 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
175 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
178 char lb[INITIAL_INLINEASM];
188 sprintf(lb,"%s\t",inst);
190 sprintf(lb,"%s",inst);
191 vsprintf(lb+(strlen(lb)),fmt,ap);
195 while (isspace(*lbp)) lbp++;
198 lineCurr = (lineCurr ?
199 connectLine(lineCurr,newLineNode(lb)) :
200 (lineHead = newLineNode(lb)));
201 lineCurr->isInline = _G.inLine;
202 lineCurr->isDebug = _G.debugLine;
204 addpCode2pBlock(pb,newpCodeCharP(lb));
210 void emitpLabel(int key)
212 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
215 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
218 addpCode2pBlock(pb,newpCode(poc,pcop));
220 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
223 void emitpcodeNULLop(PIC_OPCODE poc)
226 addpCode2pBlock(pb,newpCode(poc,NULL));
231 /*-----------------------------------------------------------------*/
232 /* pic14_emitcode - writes the code into a file : for now it is simple */
233 /*-----------------------------------------------------------------*/
234 void pic14_emitcode (char *inst,char *fmt, ...)
237 char lb[INITIAL_INLINEASM];
244 sprintf(lb,"%s\t",inst);
246 sprintf(lb,"%s",inst);
247 vsprintf(lb+(strlen(lb)),fmt,ap);
251 while (isspace(*lbp)) lbp++;
254 lineCurr = (lineCurr ?
255 connectLine(lineCurr,newLineNode(lb)) :
256 (lineHead = newLineNode(lb)));
257 lineCurr->isInline = _G.inLine;
258 lineCurr->isDebug = _G.debugLine;
261 addpCode2pBlock(pb,newpCodeCharP(lb));
266 /*-----------------------------------------------------------------*/
267 /* pic14_emitDebuggerSymbol - associate the current code location */
268 /* with a debugger symbol */
269 /*-----------------------------------------------------------------*/
271 pic14_emitDebuggerSymbol (char * debugSym)
274 pic14_emitcode ("", ";%s ==.", debugSym);
279 /*-----------------------------------------------------------------*/
280 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
281 /*-----------------------------------------------------------------*/
282 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
284 bool r0iu = FALSE , r1iu = FALSE;
285 bool r0ou = FALSE , r1ou = FALSE;
287 /* the logic: if r0 & r1 used in the instruction
288 then we are in trouble otherwise */
290 /* first check if r0 & r1 are used by this
291 instruction, in which case we are in trouble */
292 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
293 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
298 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
299 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
301 /* if no usage of r0 then return it */
302 if (!r0iu && !r0ou) {
303 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
304 (*aopp)->type = AOP_R0;
306 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
309 /* if no usage of r1 then return it */
310 if (!r1iu && !r1ou) {
311 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
312 (*aopp)->type = AOP_R1;
314 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
317 /* now we know they both have usage */
318 /* if r0 not used in this instruction */
320 /* push it if not already pushed */
322 //pic14_emitcode ("push","%s",
323 // pic14_regWithIdx(R0_IDX)->dname);
327 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
328 (*aopp)->type = AOP_R0;
330 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
333 /* if r1 not used then */
336 /* push it if not already pushed */
338 //pic14_emitcode ("push","%s",
339 // pic14_regWithIdx(R1_IDX)->dname);
343 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
344 (*aopp)->type = AOP_R1;
345 return pic14_regWithIdx(R1_IDX);
349 /* I said end of world but not quite end of world yet */
350 /* if this is a result then we can push it on the stack*/
352 (*aopp)->type = AOP_STK;
356 /* other wise this is true end of the world */
357 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
358 "getFreePtr should never reach here");
362 /*-----------------------------------------------------------------*/
363 /* newAsmop - creates a new asmOp */
364 /*-----------------------------------------------------------------*/
365 asmop *newAsmop (short type)
369 aop = Safe_calloc(1,sizeof(asmop));
374 static void genSetDPTR(int n)
378 pic14_emitcode(";", "Select standard DPTR");
379 pic14_emitcode("mov", "dps, #0x00");
383 pic14_emitcode(";", "Select alternate DPTR");
384 pic14_emitcode("mov", "dps, #0x01");
388 /*-----------------------------------------------------------------*/
389 /* resolveIfx - converts an iCode ifx into a form more useful for */
390 /* generating code */
391 /*-----------------------------------------------------------------*/
392 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
397 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
399 resIfx->condition = 1; /* assume that the ifx is true */
400 resIfx->generated = 0; /* indicate that the ifx has not been used */
403 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
405 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
406 __FUNCTION__,__LINE__,resIfx->lbl->key);
410 resIfx->lbl = IC_TRUE(ifx);
412 resIfx->lbl = IC_FALSE(ifx);
413 resIfx->condition = 0;
417 DEBUGpic14_emitcode("; ***","ifx true is non-null");
419 DEBUGpic14_emitcode("; ***","ifx false is non-null");
423 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
426 /*-----------------------------------------------------------------*/
427 /* pointerCode - returns the code for a pointer type */
428 /*-----------------------------------------------------------------*/
429 static int pointerCode (sym_link *etype)
432 return PTR_TYPE(SPEC_OCLS(etype));
436 /*-----------------------------------------------------------------*/
437 /* aopForSym - for a true symbol */
438 /*-----------------------------------------------------------------*/
439 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
442 memmap *space= SPEC_OCLS(sym->etype);
444 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
445 /* if already has one */
449 /* assign depending on the storage class */
450 /* if it is on the stack or indirectly addressable */
451 /* space we need to assign either r0 or r1 to it */
452 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
453 sym->aop = aop = newAsmop(0);
454 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
455 aop->size = getSize(sym->type);
457 /* now assign the address of the variable to
458 the pointer register */
459 if (aop->type != AOP_STK) {
463 pic14_emitcode("push","acc");
465 pic14_emitcode("mov","a,_bp");
466 pic14_emitcode("add","a,#0x%02x",
468 ((char)(sym->stack - _G.nRegsSaved )) :
469 ((char)sym->stack)) & 0xff);
470 pic14_emitcode("mov","%s,a",
471 aop->aopu.aop_ptr->name);
474 pic14_emitcode("pop","acc");
476 pic14_emitcode("mov","%s,#%s",
477 aop->aopu.aop_ptr->name,
479 aop->paged = space->paged;
481 aop->aopu.aop_stk = sym->stack;
485 if (sym->onStack && options.stack10bit)
487 /* It's on the 10 bit stack, which is located in
491 //DEBUGpic14_emitcode(";","%d",__LINE__);
494 pic14_emitcode("push","acc");
496 pic14_emitcode("mov","a,_bp");
497 pic14_emitcode("add","a,#0x%02x",
499 ((char)(sym->stack - _G.nRegsSaved )) :
500 ((char)sym->stack)) & 0xff);
503 pic14_emitcode ("mov","dpx1,#0x40");
504 pic14_emitcode ("mov","dph1,#0x00");
505 pic14_emitcode ("mov","dpl1, a");
509 pic14_emitcode("pop","acc");
511 sym->aop = aop = newAsmop(AOP_DPTR2);
512 aop->size = getSize(sym->type);
516 //DEBUGpic14_emitcode(";","%d",__LINE__);
517 /* if in bit space */
518 if (IN_BITSPACE(space)) {
519 sym->aop = aop = newAsmop (AOP_CRY);
520 aop->aopu.aop_dir = sym->rname ;
521 aop->size = getSize(sym->type);
522 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
525 /* if it is in direct space */
526 if (IN_DIRSPACE(space)) {
527 sym->aop = aop = newAsmop (AOP_DIR);
528 aop->aopu.aop_dir = sym->rname ;
529 aop->size = getSize(sym->type);
530 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
534 /* special case for a function */
535 if (IS_FUNC(sym->type)) {
537 sym->aop = aop = newAsmop(AOP_PCODE);
538 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
539 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
540 PCOI(aop->aopu.pcop)->_function = 1;
541 PCOI(aop->aopu.pcop)->index = 0;
542 aop->size = FPTRSIZE;
544 sym->aop = aop = newAsmop(AOP_IMMD);
545 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
546 strcpy(aop->aopu.aop_immd,sym->rname);
547 aop->size = FPTRSIZE;
549 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
554 /* only remaining is far space */
555 /* in which case DPTR gets the address */
556 sym->aop = aop = newAsmop(AOP_PCODE);
558 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
559 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
560 PCOI(aop->aopu.pcop)->index = 0;
562 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
563 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
565 allocDirReg (IC_LEFT(ic));
567 aop->size = FPTRSIZE;
569 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
570 sym->aop = aop = newAsmop(AOP_DPTR);
571 pic14_emitcode ("mov","dptr,#%s", sym->rname);
572 aop->size = getSize(sym->type);
574 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
577 /* if it is in code space */
578 if (IN_CODESPACE(space))
584 /*-----------------------------------------------------------------*/
585 /* aopForRemat - rematerialzes an object */
586 /*-----------------------------------------------------------------*/
587 static asmop *aopForRemat (operand *op) // x symbol *sym)
589 symbol *sym = OP_SYMBOL(op);
591 asmop *aop = newAsmop(AOP_PCODE);
595 ic = sym->rematiCode;
597 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
598 if(IS_OP_POINTER(op)) {
599 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
603 val += (int) operandLitValue(IC_RIGHT(ic));
604 } else if (ic->op == '-') {
605 val -= (int) operandLitValue(IC_RIGHT(ic));
609 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
612 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
613 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
614 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
615 PCOI(aop->aopu.pcop)->index = val;
617 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
618 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
619 val, IS_PTR_CONST(operandType(op)));
621 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
623 allocDirReg (IC_LEFT(ic));
628 int aopIdx (asmop *aop, int offset)
633 if(aop->type != AOP_REG)
636 return aop->aopu.aop_reg[offset]->rIdx;
639 /*-----------------------------------------------------------------*/
640 /* regsInCommon - two operands have some registers in common */
641 /*-----------------------------------------------------------------*/
642 static bool regsInCommon (operand *op1, operand *op2)
647 /* if they have registers in common */
648 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
651 sym1 = OP_SYMBOL(op1);
652 sym2 = OP_SYMBOL(op2);
654 if (sym1->nRegs == 0 || sym2->nRegs == 0)
657 for (i = 0 ; i < sym1->nRegs ; i++) {
662 for (j = 0 ; j < sym2->nRegs ;j++ ) {
666 if (sym2->regs[j] == sym1->regs[i])
674 /*-----------------------------------------------------------------*/
675 /* operandsEqu - equivalent */
676 /*-----------------------------------------------------------------*/
677 static bool operandsEqu ( operand *op1, operand *op2)
681 /* if they not symbols */
682 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
685 sym1 = OP_SYMBOL(op1);
686 sym2 = OP_SYMBOL(op2);
688 /* if both are itemps & one is spilt
689 and the other is not then false */
690 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
691 sym1->isspilt != sym2->isspilt )
694 /* if they are the same */
698 if (sym1->rname[0] && sym2->rname[0]
699 && strcmp (sym1->rname, sym2->rname) == 0)
703 /* if left is a tmp & right is not */
707 (sym1->usl.spillLoc == sym2))
714 (sym2->usl.spillLoc == sym1))
720 /*-----------------------------------------------------------------*/
721 /* pic14_sameRegs - two asmops have the same registers */
722 /*-----------------------------------------------------------------*/
723 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
730 if (aop1->type != AOP_REG ||
731 aop2->type != AOP_REG )
734 if (aop1->size != aop2->size )
737 for (i = 0 ; i < aop1->size ; i++ )
738 if (aop1->aopu.aop_reg[i] !=
739 aop2->aopu.aop_reg[i] )
745 /*-----------------------------------------------------------------*/
746 /* aopOp - allocates an asmop for an operand : */
747 /*-----------------------------------------------------------------*/
748 void aopOp (operand *op, iCode *ic, bool result)
757 /* if this a literal */
758 if (IS_OP_LITERAL(op)) {
759 op->aop = aop = newAsmop(AOP_LIT);
760 aop->aopu.aop_lit = op->operand.valOperand;
761 aop->size = getSize(operandType(op));
766 sym_link *type = operandType(op);
767 if(IS_PTR_CONST(type))
768 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
771 /* if already has a asmop then continue */
775 /* if the underlying symbol has a aop */
776 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
777 DEBUGpic14_emitcode(";","%d",__LINE__);
778 op->aop = OP_SYMBOL(op)->aop;
782 /* if this is a true symbol */
783 if (IS_TRUE_SYMOP(op)) {
784 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
785 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
789 /* this is a temporary : this has
795 e) can be a return use only */
800 /* if the type is a conditional */
801 if (sym->regType == REG_CND) {
802 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
807 /* if it is spilt then two situations
809 b) has a spill location */
810 if (sym->isspilt || sym->nRegs == 0) {
812 DEBUGpic14_emitcode(";","%d",__LINE__);
813 /* rematerialize it NOW */
816 sym->aop = op->aop = aop = aopForRemat (op);
817 aop->size = getSize(sym->type);
818 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
824 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825 aop->size = getSize(sym->type);
826 for ( i = 0 ; i < 2 ; i++ )
827 aop->aopu.aop_str[i] = accUse[i];
828 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
833 if(sym->isptr) { // && sym->uptr
834 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
835 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
837 //PCOI(aop->aopu.pcop)->_const = 0;
838 //PCOI(aop->aopu.pcop)->index = 0;
840 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
841 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
843 //allocDirReg (IC_LEFT(ic));
845 aop->size = getSize(sym->type);
846 DEBUGpic14_emitcode(";","%d",__LINE__);
853 aop = op->aop = sym->aop = newAsmop(AOP_STR);
854 aop->size = getSize(sym->type);
855 for ( i = 0 ; i < fReturnSizePic ; i++ )
856 aop->aopu.aop_str[i] = fReturn[i];
858 DEBUGpic14_emitcode(";","%d",__LINE__);
863 /* else spill location */
864 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
865 /* force a new aop if sizes differ */
866 sym->usl.spillLoc->aop = NULL;
868 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
869 __FUNCTION__,__LINE__,
870 sym->usl.spillLoc->rname,
871 sym->rname, sym->usl.spillLoc->offset);
873 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
874 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
875 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
877 sym->usl.spillLoc->offset);
878 aop->size = getSize(sym->type);
884 sym_link *type = operandType(op);
885 if(IS_PTR_CONST(type))
886 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
889 /* must be in a register */
890 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
891 sym->aop = op->aop = aop = newAsmop(AOP_REG);
892 aop->size = sym->nRegs;
893 for ( i = 0 ; i < sym->nRegs ;i++)
894 aop->aopu.aop_reg[i] = sym->regs[i];
897 /*-----------------------------------------------------------------*/
898 /* freeAsmop - free up the asmop given to an operand */
899 /*----------------------------------------------------------------*/
900 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
917 /* depending on the asmop type only three cases need work AOP_RO
918 , AOP_R1 && AOP_STK */
924 pic14_emitcode ("pop","ar0");
928 bitVectUnSetBit(ic->rUsed,R0_IDX);
934 pic14_emitcode ("pop","ar1");
938 bitVectUnSetBit(ic->rUsed,R1_IDX);
944 int stk = aop->aopu.aop_stk + aop->size;
945 bitVectUnSetBit(ic->rUsed,R0_IDX);
946 bitVectUnSetBit(ic->rUsed,R1_IDX);
948 getFreePtr(ic,&aop,FALSE);
950 if (options.stack10bit)
952 /* I'm not sure what to do here yet... */
955 "*** Warning: probably generating bad code for "
956 "10 bit stack mode.\n");
960 pic14_emitcode ("mov","a,_bp");
961 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
962 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
964 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
968 pic14_emitcode("pop","acc");
969 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
971 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
974 freeAsmop(op,NULL,ic,TRUE);
976 pic14_emitcode("pop","ar0");
981 pic14_emitcode("pop","ar1");
989 /* all other cases just dealloc */
993 OP_SYMBOL(op)->aop = NULL;
994 /* if the symbol has a spill */
996 SPIL_LOC(op)->aop = NULL;
1001 /*-----------------------------------------------------------------*/
1002 /* aopGet - for fetching value of the aop */
1003 /*-----------------------------------------------------------------*/
1004 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1009 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1010 /* offset is greater than
1012 if (offset > (aop->size - 1) &&
1013 aop->type != AOP_LIT)
1016 /* depending on type */
1017 switch (aop->type) {
1021 DEBUGpic14_emitcode(";","%d",__LINE__);
1022 /* if we need to increment it */
1023 while (offset > aop->coff) {
1024 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1028 while (offset < aop->coff) {
1029 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1033 aop->coff = offset ;
1035 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1036 return (dname ? "acc" : "a");
1038 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1039 rs = Safe_calloc(1,strlen(s)+1);
1045 DEBUGpic14_emitcode(";","%d",__LINE__);
1046 if (aop->type == AOP_DPTR2)
1051 while (offset > aop->coff) {
1052 pic14_emitcode ("inc","dptr");
1056 while (offset < aop->coff) {
1057 pic14_emitcode("lcall","__decdptr");
1063 pic14_emitcode("clr","a");
1064 pic14_emitcode("movc","a,@a+dptr");
1067 pic14_emitcode("movx","a,@dptr");
1070 if (aop->type == AOP_DPTR2)
1075 return (dname ? "acc" : "a");
1080 sprintf (s,"%s",aop->aopu.aop_immd);
1083 sprintf(s,"(%s >> %d)",
1088 aop->aopu.aop_immd);
1089 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1090 rs = Safe_calloc(1,strlen(s)+1);
1096 sprintf(s,"(%s + %d)",
1099 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1101 sprintf(s,"%s",aop->aopu.aop_dir);
1102 rs = Safe_calloc(1,strlen(s)+1);
1108 // return aop->aopu.aop_reg[offset]->dname;
1110 return aop->aopu.aop_reg[offset]->name;
1113 //pic14_emitcode(";","%d",__LINE__);
1114 return aop->aopu.aop_dir;
1117 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1118 return "AOP_accumulator_bug";
1121 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1122 rs = Safe_calloc(1,strlen(s)+1);
1127 aop->coff = offset ;
1128 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1131 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1133 return aop->aopu.aop_str[offset];
1137 pCodeOp *pcop = aop->aopu.pcop;
1138 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1141 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
1142 sprintf(s,"(%s+%d)", pcop->name,offset);
1144 DEBUGpic14_emitcode(";","%s",pcop->name);
1145 sprintf(s,"%s", pcop->name);
1148 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1151 rs = Safe_calloc(1,strlen(s)+1);
1157 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1158 "aopget got unsupported aop->type");
1163 /*-----------------------------------------------------------------*/
1164 /* popGetTempReg - create a new temporary pCodeOp */
1165 /*-----------------------------------------------------------------*/
1166 pCodeOp *popGetTempReg(void)
1171 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1172 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1173 PCOR(pcop)->r->wasUsed=1;
1174 PCOR(pcop)->r->isFree=0;
1180 /*-----------------------------------------------------------------*/
1181 /* popReleaseTempReg - create a new temporary pCodeOp */
1182 /*-----------------------------------------------------------------*/
1183 void popReleaseTempReg(pCodeOp *pcop)
1186 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1187 PCOR(pcop)->r->isFree = 1;
1190 /*-----------------------------------------------------------------*/
1191 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1192 /*-----------------------------------------------------------------*/
1193 pCodeOp *popGetLabel(unsigned int key)
1196 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1198 if(key>(unsigned int)max_key)
1201 return newpCodeOpLabel(NULL,key+100+labelOffset);
1204 /*-------------------------------------------------------------------*/
1205 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1206 /*-------------------------------------------------------------------*/
1207 pCodeOp *popGetHighLabel(unsigned int key)
1210 pcop = popGetLabel(key);
1211 PCOLAB(pcop)->offset = 1;
1215 /*-----------------------------------------------------------------*/
1216 /* popGetLit - asm operator to pcode operator conversion */
1217 /*-----------------------------------------------------------------*/
1218 pCodeOp *popGetLit(unsigned int lit)
1221 return newpCodeOpLit(lit);
1224 /*-----------------------------------------------------------------*/
1225 /* popGetImmd - asm operator to pcode immediate conversion */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1230 return newpCodeOpImmd(name, offset,index, 0, is_func);
1234 /*-----------------------------------------------------------------*/
1235 /* popGetWithString - asm operator to pcode operator conversion */
1236 /*-----------------------------------------------------------------*/
1237 pCodeOp *popGetWithString(char *str, int isExtern)
1243 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1247 pcop = newpCodeOp(str,PO_STR);
1248 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1253 /*-----------------------------------------------------------------*/
1254 /* popRegFromString - */
1255 /*-----------------------------------------------------------------*/
1256 pCodeOp *popRegFromString(char *str, int size, int offset)
1259 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1260 pcop->type = PO_DIR;
1262 DEBUGpic14_emitcode(";","%d",__LINE__);
1267 pcop->name = Safe_calloc(1,strlen(str)+1);
1268 strcpy(pcop->name,str);
1270 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1272 PCOR(pcop)->r = dirregWithName(pcop->name);
1273 if(PCOR(pcop)->r == NULL) {
1274 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1275 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1276 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1278 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1280 PCOR(pcop)->instance = offset;
1285 /*-----------------------------------------------------------------*/
1286 /*-----------------------------------------------------------------*/
1287 pCodeOp *popRegFromIdx(int rIdx)
1291 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1292 __FUNCTION__,__LINE__,rIdx);
1294 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1296 PCOR(pcop)->rIdx = rIdx;
1297 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1298 PCOR(pcop)->r->isFree = 0;
1299 PCOR(pcop)->r->wasUsed = 1;
1301 pcop->type = PCOR(pcop)->r->pc_type;
1307 /*-----------------------------------------------------------------*/
1308 /* popGet - asm operator to pcode operator conversion */
1309 /*-----------------------------------------------------------------*/
1310 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1312 //char *s = buffer ;
1317 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1318 /* offset is greater than
1321 if (offset > (aop->size - 1) &&
1322 aop->type != AOP_LIT)
1323 return NULL; //zero;
1325 /* depending on type */
1326 switch (aop->type) {
1333 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1337 DEBUGpic14_emitcode(";","%d",__LINE__);
1338 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1341 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1343 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1344 pcop->type = PO_DIR;
1346 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1347 strcpy(pcop->name,aop->aopu.aop_dir);
1348 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1349 if(PCOR(pcop)->r == NULL) {
1350 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1351 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1352 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1354 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1356 PCOR(pcop)->instance = offset;
1363 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1365 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1366 PCOR(pcop)->rIdx = rIdx;
1367 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1368 PCOR(pcop)->r->wasUsed=1;
1369 PCOR(pcop)->r->isFree=0;
1371 PCOR(pcop)->instance = offset;
1372 pcop->type = PCOR(pcop)->r->pc_type;
1373 //rs = aop->aopu.aop_reg[offset]->name;
1374 DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1379 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1380 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1381 //if(PCOR(pcop)->r == NULL)
1382 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1386 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1389 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1390 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1392 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1393 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1394 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1395 pcop->type = PCOR(pcop)->r->pc_type;
1396 pcop->name = PCOR(pcop)->r->name;
1402 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1404 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1405 pcop = pCodeOpCopy(aop->aopu.pcop);
1406 PCOI(pcop)->offset = offset;
1410 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1411 "popGet got unsupported aop->type");
1414 /*-----------------------------------------------------------------*/
1415 /* aopPut - puts a string for a aop */
1416 /*-----------------------------------------------------------------*/
1417 void aopPut (asmop *aop, char *s, int offset)
1422 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1424 if (aop->size && offset > ( aop->size - 1)) {
1425 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1426 "aopPut got offset > aop->size");
1430 /* will assign value to value */
1431 /* depending on where it is ofcourse */
1432 switch (aop->type) {
1435 sprintf(d,"(%s + %d)",
1436 aop->aopu.aop_dir,offset);
1437 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1440 sprintf(d,"%s",aop->aopu.aop_dir);
1443 DEBUGpic14_emitcode(";","%d",__LINE__);
1445 pic14_emitcode("movf","%s,w",s);
1446 pic14_emitcode("movwf","%s",d);
1449 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1450 if(offset >= aop->size) {
1451 emitpcode(POC_CLRF,popGet(aop,offset));
1454 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1457 emitpcode(POC_MOVWF,popGet(aop,offset));
1464 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1465 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1468 strcmp(s,"r0") == 0 ||
1469 strcmp(s,"r1") == 0 ||
1470 strcmp(s,"r2") == 0 ||
1471 strcmp(s,"r3") == 0 ||
1472 strcmp(s,"r4") == 0 ||
1473 strcmp(s,"r5") == 0 ||
1474 strcmp(s,"r6") == 0 ||
1475 strcmp(s,"r7") == 0 )
1476 pic14_emitcode("mov","%s,%s ; %d",
1477 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1481 if(strcmp(s,"W")==0 )
1482 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1484 pic14_emitcode("movwf","%s",
1485 aop->aopu.aop_reg[offset]->name);
1487 if(strcmp(s,zero)==0) {
1488 emitpcode(POC_CLRF,popGet(aop,offset));
1490 } else if(strcmp(s,"W")==0) {
1491 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1492 pcop->type = PO_GPR_REGISTER;
1494 PCOR(pcop)->rIdx = -1;
1495 PCOR(pcop)->r = NULL;
1497 DEBUGpic14_emitcode(";","%d",__LINE__);
1498 pcop->name = Safe_strdup(s);
1499 emitpcode(POC_MOVFW,pcop);
1500 emitpcode(POC_MOVWF,popGet(aop,offset));
1501 } else if(strcmp(s,one)==0) {
1502 emitpcode(POC_CLRF,popGet(aop,offset));
1503 emitpcode(POC_INCF,popGet(aop,offset));
1505 emitpcode(POC_MOVWF,popGet(aop,offset));
1513 if (aop->type == AOP_DPTR2)
1519 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1520 "aopPut writting to code space");
1524 while (offset > aop->coff) {
1526 pic14_emitcode ("inc","dptr");
1529 while (offset < aop->coff) {
1531 pic14_emitcode("lcall","__decdptr");
1536 /* if not in accumulater */
1539 pic14_emitcode ("movx","@dptr,a");
1541 if (aop->type == AOP_DPTR2)
1549 while (offset > aop->coff) {
1551 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1553 while (offset < aop->coff) {
1555 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1561 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1566 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1568 if (strcmp(s,"r0") == 0 ||
1569 strcmp(s,"r1") == 0 ||
1570 strcmp(s,"r2") == 0 ||
1571 strcmp(s,"r3") == 0 ||
1572 strcmp(s,"r4") == 0 ||
1573 strcmp(s,"r5") == 0 ||
1574 strcmp(s,"r6") == 0 ||
1575 strcmp(s,"r7") == 0 ) {
1577 sprintf(buffer,"a%s",s);
1578 pic14_emitcode("mov","@%s,%s",
1579 aop->aopu.aop_ptr->name,buffer);
1581 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1586 if (strcmp(s,"a") == 0)
1587 pic14_emitcode("push","acc");
1589 pic14_emitcode("push","%s",s);
1594 /* if bit variable */
1595 if (!aop->aopu.aop_dir) {
1596 pic14_emitcode("clr","a");
1597 pic14_emitcode("rlc","a");
1600 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1603 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1606 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1608 lbl = newiTempLabel(NULL);
1610 if (strcmp(s,"a")) {
1613 pic14_emitcode("clr","c");
1614 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1615 pic14_emitcode("cpl","c");
1616 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1617 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1624 if (strcmp(aop->aopu.aop_str[offset],s))
1625 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1630 if (!offset && (strcmp(s,"acc") == 0))
1633 if (strcmp(aop->aopu.aop_str[offset],s))
1634 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1638 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1639 "aopPut got unsupported aop->type");
1645 /*-----------------------------------------------------------------*/
1646 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1647 /*-----------------------------------------------------------------*/
1648 void mov2w (asmop *aop, int offset)
1654 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1656 if ( aop->type == AOP_PCODE ||
1657 aop->type == AOP_LIT ||
1658 aop->type == AOP_IMMD )
1659 emitpcode(POC_MOVLW,popGet(aop,offset));
1661 emitpcode(POC_MOVFW,popGet(aop,offset));
1665 /*-----------------------------------------------------------------*/
1666 /* reAdjustPreg - points a register back to where it should */
1667 /*-----------------------------------------------------------------*/
1668 static void reAdjustPreg (asmop *aop)
1672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1674 if ((size = aop->size) <= 1)
1677 switch (aop->type) {
1681 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1685 if (aop->type == AOP_DPTR2)
1691 pic14_emitcode("lcall","__decdptr");
1694 if (aop->type == AOP_DPTR2)
1706 /*-----------------------------------------------------------------*/
1707 /* opIsGptr: returns non-zero if the passed operand is */
1708 /* a generic pointer type. */
1709 /*-----------------------------------------------------------------*/
1710 static int opIsGptr(operand *op)
1712 sym_link *type = operandType(op);
1714 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1715 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1723 /*-----------------------------------------------------------------*/
1724 /* pic14_getDataSize - get the operand data size */
1725 /*-----------------------------------------------------------------*/
1726 int pic14_getDataSize(operand *op)
1728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1731 return AOP_SIZE(op);
1733 // tsd- in the pic port, the genptr size is 1, so this code here
1734 // fails. ( in the 8051 port, the size was 4).
1737 size = AOP_SIZE(op);
1738 if (size == GPTRSIZE)
1740 sym_link *type = operandType(op);
1741 if (IS_GENPTR(type))
1743 /* generic pointer; arithmetic operations
1744 * should ignore the high byte (pointer type).
1747 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1754 /*-----------------------------------------------------------------*/
1755 /* pic14_outAcc - output Acc */
1756 /*-----------------------------------------------------------------*/
1757 void pic14_outAcc(operand *result)
1760 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1761 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1764 size = pic14_getDataSize(result);
1766 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1769 /* unsigned or positive */
1771 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1776 /*-----------------------------------------------------------------*/
1777 /* pic14_outBitC - output a bit C */
1778 /*-----------------------------------------------------------------*/
1779 void pic14_outBitC(operand *result)
1782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1783 /* if the result is bit */
1784 if (AOP_TYPE(result) == AOP_CRY)
1785 aopPut(AOP(result),"c",0);
1787 pic14_emitcode("clr","a ; %d", __LINE__);
1788 pic14_emitcode("rlc","a");
1789 pic14_outAcc(result);
1793 /*-----------------------------------------------------------------*/
1794 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1795 /*-----------------------------------------------------------------*/
1796 void pic14_toBoolean(operand *oper)
1798 int size = AOP_SIZE(oper) - 1;
1801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1803 if ( AOP_TYPE(oper) != AOP_ACC) {
1804 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1807 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1812 /*-----------------------------------------------------------------*/
1813 /* genNot - generate code for ! operation */
1814 /*-----------------------------------------------------------------*/
1815 static void genNot (iCode *ic)
1820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1821 /* assign asmOps to operand & result */
1822 aopOp (IC_LEFT(ic),ic,FALSE);
1823 aopOp (IC_RESULT(ic),ic,TRUE);
1825 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1826 /* if in bit space then a special case */
1827 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1828 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1829 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1830 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1832 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1833 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1834 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1839 size = AOP_SIZE(IC_LEFT(ic));
1841 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1842 emitpcode(POC_ANDLW,popGetLit(1));
1843 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1846 pic14_toBoolean(IC_LEFT(ic));
1848 tlbl = newiTempLabel(NULL);
1849 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1850 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1851 pic14_outBitC(IC_RESULT(ic));
1854 /* release the aops */
1855 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1856 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1860 /*-----------------------------------------------------------------*/
1861 /* genCpl - generate code for complement */
1862 /*-----------------------------------------------------------------*/
1863 static void genCpl (iCode *ic)
1865 operand *left, *result;
1869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1870 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1871 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1873 /* if both are in bit space then
1875 if (AOP_TYPE(result) == AOP_CRY &&
1876 AOP_TYPE(left) == AOP_CRY ) {
1878 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1879 pic14_emitcode("cpl","c");
1880 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1884 size = AOP_SIZE(result);
1887 if(AOP_TYPE(left) == AOP_ACC)
1888 emitpcode(POC_XORLW, popGetLit(0xff));
1890 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1892 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1898 /* release the aops */
1899 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1900 freeAsmop(result,NULL,ic,TRUE);
1903 /*-----------------------------------------------------------------*/
1904 /* genUminusFloat - unary minus for floating points */
1905 /*-----------------------------------------------------------------*/
1906 static void genUminusFloat(operand *op,operand *result)
1908 int size ,offset =0 ;
1911 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 /* for this we just need to flip the
1913 first it then copy the rest in place */
1914 size = AOP_SIZE(op) - 1;
1915 l = aopGet(AOP(op),3,FALSE,FALSE);
1919 pic14_emitcode("cpl","acc.7");
1920 aopPut(AOP(result),"a",3);
1924 aopGet(AOP(op),offset,FALSE,FALSE),
1930 /*-----------------------------------------------------------------*/
1931 /* genUminus - unary minus code generation */
1932 /*-----------------------------------------------------------------*/
1933 static void genUminus (iCode *ic)
1936 sym_link *optype, *rtype;
1939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1941 aopOp(IC_LEFT(ic),ic,FALSE);
1942 aopOp(IC_RESULT(ic),ic,TRUE);
1944 /* if both in bit space then special
1946 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1947 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1949 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1950 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1951 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1956 optype = operandType(IC_LEFT(ic));
1957 rtype = operandType(IC_RESULT(ic));
1959 /* if float then do float stuff */
1960 if (IS_FLOAT(optype)) {
1961 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1965 /* otherwise subtract from zero by taking the 2's complement */
1966 size = AOP_SIZE(IC_LEFT(ic));
1968 for(i=0; i<size; i++) {
1969 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1970 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1972 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1973 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1977 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1978 for(i=1; i<size; i++) {
1980 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1984 /* release the aops */
1985 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1986 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1989 /*-----------------------------------------------------------------*/
1990 /* saveRegisters - will look for a call and save the registers */
1991 /*-----------------------------------------------------------------*/
1992 static void saveRegisters(iCode *lic)
1999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2001 for (ic = lic ; ic ; ic = ic->next)
2002 if (ic->op == CALL || ic->op == PCALL)
2006 fprintf(stderr,"found parameter push with no function call\n");
2010 /* if the registers have been saved already then
2012 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2015 /* find the registers in use at this time
2016 and push them away to safety */
2017 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2021 if (options.useXstack) {
2022 if (bitVectBitValue(rsave,R0_IDX))
2023 pic14_emitcode("mov","b,r0");
2024 pic14_emitcode("mov","r0,%s",spname);
2025 for (i = 0 ; i < pic14_nRegs ; i++) {
2026 if (bitVectBitValue(rsave,i)) {
2028 pic14_emitcode("mov","a,b");
2030 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2031 pic14_emitcode("movx","@r0,a");
2032 pic14_emitcode("inc","r0");
2035 pic14_emitcode("mov","%s,r0",spname);
2036 if (bitVectBitValue(rsave,R0_IDX))
2037 pic14_emitcode("mov","r0,b");
2039 //for (i = 0 ; i < pic14_nRegs ; i++) {
2040 // if (bitVectBitValue(rsave,i))
2041 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2044 dtype = operandType(IC_LEFT(ic));
2045 if (currFunc && dtype &&
2046 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2047 IFFUNC_ISISR(currFunc->type) &&
2050 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2053 /*-----------------------------------------------------------------*/
2054 /* unsaveRegisters - pop the pushed registers */
2055 /*-----------------------------------------------------------------*/
2056 static void unsaveRegisters (iCode *ic)
2061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2062 /* find the registers in use at this time
2063 and push them away to safety */
2064 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2067 if (options.useXstack) {
2068 pic14_emitcode("mov","r0,%s",spname);
2069 for (i = pic14_nRegs ; i >= 0 ; i--) {
2070 if (bitVectBitValue(rsave,i)) {
2071 pic14_emitcode("dec","r0");
2072 pic14_emitcode("movx","a,@r0");
2074 pic14_emitcode("mov","b,a");
2076 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2080 pic14_emitcode("mov","%s,r0",spname);
2081 if (bitVectBitValue(rsave,R0_IDX))
2082 pic14_emitcode("mov","r0,b");
2084 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2085 // if (bitVectBitValue(rsave,i))
2086 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2092 /*-----------------------------------------------------------------*/
2094 /*-----------------------------------------------------------------*/
2095 static void pushSide(operand * oper, int size)
2099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2101 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2102 if (AOP_TYPE(oper) != AOP_REG &&
2103 AOP_TYPE(oper) != AOP_DIR &&
2105 pic14_emitcode("mov","a,%s",l);
2106 pic14_emitcode("push","acc");
2108 pic14_emitcode("push","%s",l);
2113 /*-----------------------------------------------------------------*/
2114 /* assignResultValue - */
2115 /*-----------------------------------------------------------------*/
2116 static void assignResultValue(operand * oper)
2118 int size = AOP_SIZE(oper);
2120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2122 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2125 if (GpsuedoStkPtr++)
2126 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2127 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2132 /*-----------------------------------------------------------------*/
2133 /* genIpush - genrate code for pushing this gets a little complex */
2134 /*-----------------------------------------------------------------*/
2135 static void genIpush (iCode *ic)
2138 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2140 int size, offset = 0 ;
2144 /* if this is not a parm push : ie. it is spill push
2145 and spill push is always done on the local stack */
2146 if (!ic->parmPush) {
2148 /* and the item is spilt then do nothing */
2149 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2152 aopOp(IC_LEFT(ic),ic,FALSE);
2153 size = AOP_SIZE(IC_LEFT(ic));
2154 /* push it on the stack */
2156 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2161 pic14_emitcode("push","%s",l);
2166 /* this is a paramter push: in this case we call
2167 the routine to find the call and save those
2168 registers that need to be saved */
2171 /* then do the push */
2172 aopOp(IC_LEFT(ic),ic,FALSE);
2175 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2176 size = AOP_SIZE(IC_LEFT(ic));
2179 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2180 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2181 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2183 pic14_emitcode("mov","a,%s",l);
2184 pic14_emitcode("push","acc");
2186 pic14_emitcode("push","%s",l);
2189 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2193 /*-----------------------------------------------------------------*/
2194 /* genIpop - recover the registers: can happen only for spilling */
2195 /*-----------------------------------------------------------------*/
2196 static void genIpop (iCode *ic)
2198 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2203 /* if the temp was not pushed then */
2204 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2207 aopOp(IC_LEFT(ic),ic,FALSE);
2208 size = AOP_SIZE(IC_LEFT(ic));
2211 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2214 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2218 /*-----------------------------------------------------------------*/
2219 /* unsaverbank - restores the resgister bank from stack */
2220 /*-----------------------------------------------------------------*/
2221 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2223 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2231 if (options.useXstack) {
2233 r = getFreePtr(ic,&aop,FALSE);
2236 pic14_emitcode("mov","%s,_spx",r->name);
2237 pic14_emitcode("movx","a,@%s",r->name);
2238 pic14_emitcode("mov","psw,a");
2239 pic14_emitcode("dec","%s",r->name);
2242 pic14_emitcode ("pop","psw");
2245 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2246 if (options.useXstack) {
2247 pic14_emitcode("movx","a,@%s",r->name);
2248 //pic14_emitcode("mov","(%s+%d),a",
2249 // regspic14[i].base,8*bank+regspic14[i].offset);
2250 pic14_emitcode("dec","%s",r->name);
2253 pic14_emitcode("pop",""); //"(%s+%d)",
2254 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2257 if (options.useXstack) {
2259 pic14_emitcode("mov","_spx,%s",r->name);
2260 freeAsmop(NULL,aop,ic,TRUE);
2266 /*-----------------------------------------------------------------*/
2267 /* saverbank - saves an entire register bank on the stack */
2268 /*-----------------------------------------------------------------*/
2269 static void saverbank (int bank, iCode *ic, bool pushPsw)
2271 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2278 if (options.useXstack) {
2281 r = getFreePtr(ic,&aop,FALSE);
2282 pic14_emitcode("mov","%s,_spx",r->name);
2286 for (i = 0 ; i < pic14_nRegs ;i++) {
2287 if (options.useXstack) {
2288 pic14_emitcode("inc","%s",r->name);
2289 //pic14_emitcode("mov","a,(%s+%d)",
2290 // regspic14[i].base,8*bank+regspic14[i].offset);
2291 pic14_emitcode("movx","@%s,a",r->name);
2293 pic14_emitcode("push","");// "(%s+%d)",
2294 //regspic14[i].base,8*bank+regspic14[i].offset);
2298 if (options.useXstack) {
2299 pic14_emitcode("mov","a,psw");
2300 pic14_emitcode("movx","@%s,a",r->name);
2301 pic14_emitcode("inc","%s",r->name);
2302 pic14_emitcode("mov","_spx,%s",r->name);
2303 freeAsmop (NULL,aop,ic,TRUE);
2306 pic14_emitcode("push","psw");
2308 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2314 /*-----------------------------------------------------------------*/
2315 /* genCall - generates a call statement */
2316 /*-----------------------------------------------------------------*/
2317 static void genCall (iCode *ic)
2321 unsigned char *name;
2324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2326 /* if caller saves & we have not saved then */
2330 /* if we are calling a function that is not using
2331 the same register bank then we need to save the
2332 destination registers on the stack */
2333 dtype = operandType(IC_LEFT(ic));
2334 if (currFunc && dtype &&
2335 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2336 IFFUNC_ISISR(currFunc->type) &&
2339 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2341 /* if send set is not empty the assign */
2344 /* For the Pic port, there is no data stack.
2345 * So parameters passed to functions are stored
2346 * in registers. (The pCode optimizer will get
2347 * rid of most of these :).
2349 int psuedoStkPtr=-1;
2350 int firstTimeThruLoop = 1;
2352 _G.sendSet = reverseSet(_G.sendSet);
2354 /* First figure how many parameters are getting passed */
2355 for (sic = setFirstItem(_G.sendSet) ; sic ;
2356 sic = setNextItem(_G.sendSet)) {
2358 aopOp(IC_LEFT(sic),sic,FALSE);
2359 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2360 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2363 for (sic = setFirstItem(_G.sendSet) ; sic ;
2364 sic = setNextItem(_G.sendSet)) {
2365 int size, offset = 0;
2367 aopOp(IC_LEFT(sic),sic,FALSE);
2368 size = AOP_SIZE(IC_LEFT(sic));
2371 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2372 AopType(AOP_TYPE(IC_LEFT(sic))));
2374 if(!firstTimeThruLoop) {
2375 /* If this is not the first time we've been through the loop
2376 * then we need to save the parameter in a temporary
2377 * register. The last byte of the last parameter is
2379 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2382 firstTimeThruLoop=0;
2384 mov2w (AOP(IC_LEFT(sic)), offset);
2387 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2392 sym = OP_SYMBOL(IC_LEFT(ic));
2393 name = sym->rname[0] ? sym->rname : sym->name;
2394 isExtern = IS_EXTERN(sym->etype);
2396 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2398 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2400 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2403 /* if we need assign a result value */
2404 if ((IS_ITEMP(IC_RESULT(ic)) &&
2405 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2406 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2407 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2410 aopOp(IC_RESULT(ic),ic,FALSE);
2413 assignResultValue(IC_RESULT(ic));
2415 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2416 AopType(AOP_TYPE(IC_RESULT(ic))));
2418 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2421 /* adjust the stack for parameters if
2423 if (ic->parmBytes) {
2425 if (ic->parmBytes > 3) {
2426 pic14_emitcode("mov","a,%s",spname);
2427 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2428 pic14_emitcode("mov","%s,a",spname);
2430 for ( i = 0 ; i < ic->parmBytes ;i++)
2431 pic14_emitcode("dec","%s",spname);
2435 /* if register bank was saved then pop them */
2437 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2439 /* if we hade saved some registers then unsave them */
2440 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2441 unsaveRegisters (ic);
2446 /*-----------------------------------------------------------------*/
2447 /* genPcall - generates a call by pointer statement */
2448 /*-----------------------------------------------------------------*/
2449 static void genPcall (iCode *ic)
2452 symbol *albl = newiTempLabel(NULL);
2453 symbol *blbl = newiTempLabel(NULL);
2458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2459 /* if caller saves & we have not saved then */
2463 /* if we are calling a function that is not using
2464 the same register bank then we need to save the
2465 destination registers on the stack */
2466 dtype = operandType(IC_LEFT(ic));
2467 if (currFunc && dtype &&
2468 IFFUNC_ISISR(currFunc->type) &&
2469 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2470 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2473 aopOp(left,ic,FALSE);
2474 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2476 pushSide(IC_LEFT(ic), FPTRSIZE);
2478 /* if send set is not empty, assign parameters */
2481 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2482 /* no way to pass args - W always gets used to make the call */
2484 /* first idea - factor out a common helper function and call it.
2485 But don't know how to get it generated only once in its own block
2487 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2490 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2491 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2492 buffer = Safe_calloc(1,strlen(rname)+16);
2493 sprintf(buffer, "%s_goto_helper", rname);
2494 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2498 emitpcode(POC_CALL,popGetLabel(albl->key));
2499 pcop = popGetLabel(blbl->key);
2500 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2501 emitpcode(POC_GOTO,pcop);
2502 emitpLabel(albl->key);
2504 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2506 emitpcode(poc,popGet(AOP(left),1));
2507 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2508 emitpcode(poc,popGet(AOP(left),0));
2509 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2511 emitpLabel(blbl->key);
2513 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2515 /* if we need to assign a result value */
2516 if ((IS_ITEMP(IC_RESULT(ic)) &&
2517 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2518 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2519 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2522 aopOp(IC_RESULT(ic),ic,FALSE);
2525 assignResultValue(IC_RESULT(ic));
2527 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2530 /* if register bank was saved then unsave them */
2531 if (currFunc && dtype &&
2532 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2533 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2535 /* if we hade saved some registers then
2538 unsaveRegisters (ic);
2542 /*-----------------------------------------------------------------*/
2543 /* resultRemat - result is rematerializable */
2544 /*-----------------------------------------------------------------*/
2545 static int resultRemat (iCode *ic)
2547 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2548 if (SKIP_IC(ic) || ic->op == IFX)
2551 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2552 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2553 if (sym->remat && !POINTER_SET(ic))
2560 #if defined(__BORLANDC__) || defined(_MSC_VER)
2561 #define STRCASECMP stricmp
2563 #define STRCASECMP strcasecmp
2567 /*-----------------------------------------------------------------*/
2568 /* inExcludeList - return 1 if the string is in exclude Reg list */
2569 /*-----------------------------------------------------------------*/
2570 static bool inExcludeList(char *s)
2572 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2575 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2576 if (options.excludeRegs[i] &&
2577 STRCASECMP(options.excludeRegs[i],"none") == 0)
2580 for ( i = 0 ; options.excludeRegs[i]; i++) {
2581 if (options.excludeRegs[i] &&
2582 STRCASECMP(s,options.excludeRegs[i]) == 0)
2589 /*-----------------------------------------------------------------*/
2590 /* genFunction - generated code for function entry */
2591 /*-----------------------------------------------------------------*/
2592 static void genFunction (iCode *ic)
2597 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2599 labelOffset += (max_key+4);
2603 /* create the function header */
2604 pic14_emitcode(";","-----------------------------------------");
2605 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2606 pic14_emitcode(";","-----------------------------------------");
2608 pic14_emitcode("","%s:",sym->rname);
2609 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2611 ftype = operandType(IC_LEFT(ic));
2613 /* if critical function then turn interrupts off */
2614 if (IFFUNC_ISCRITICAL(ftype))
2615 pic14_emitcode("clr","ea");
2617 /* here we need to generate the equates for the
2618 register bank if required */
2620 if (FUNC_REGBANK(ftype) != rbank) {
2623 rbank = FUNC_REGBANK(ftype);
2624 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2625 if (strcmp(regspic14[i].base,"0") == 0)
2626 pic14_emitcode("","%s = 0x%02x",
2628 8*rbank+regspic14[i].offset);
2630 pic14_emitcode ("","%s = %s + 0x%02x",
2633 8*rbank+regspic14[i].offset);
2638 /* if this is an interrupt service routine */
2639 if (IFFUNC_ISISR(sym->type)) {
2640 /* already done in pic14createInterruptVect() - delete me
2641 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2642 emitpcodeNULLop(POC_NOP);
2643 emitpcodeNULLop(POC_NOP);
2644 emitpcodeNULLop(POC_NOP);
2646 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2647 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2648 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2649 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2650 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2651 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2652 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2654 pBlockConvert2ISR(pb);
2656 if (!inExcludeList("acc"))
2657 pic14_emitcode ("push","acc");
2658 if (!inExcludeList("b"))
2659 pic14_emitcode ("push","b");
2660 if (!inExcludeList("dpl"))
2661 pic14_emitcode ("push","dpl");
2662 if (!inExcludeList("dph"))
2663 pic14_emitcode ("push","dph");
2664 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2666 pic14_emitcode ("push", "dpx");
2667 /* Make sure we're using standard DPTR */
2668 pic14_emitcode ("push", "dps");
2669 pic14_emitcode ("mov", "dps, #0x00");
2670 if (options.stack10bit)
2672 /* This ISR could conceivably use DPTR2. Better save it. */
2673 pic14_emitcode ("push", "dpl1");
2674 pic14_emitcode ("push", "dph1");
2675 pic14_emitcode ("push", "dpx1");
2678 /* if this isr has no bank i.e. is going to
2679 run with bank 0 , then we need to save more
2681 if (!FUNC_REGBANK(sym->type)) {
2683 /* if this function does not call any other
2684 function then we can be economical and
2685 save only those registers that are used */
2686 if (! IFFUNC_HASFCALL(sym->type)) {
2689 /* if any registers used */
2690 if (sym->regsUsed) {
2691 /* save the registers used */
2692 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2693 if (bitVectBitValue(sym->regsUsed,i) ||
2694 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2695 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2700 /* this function has a function call cannot
2701 determines register usage so we will have the
2703 saverbank(0,ic,FALSE);
2708 /* if callee-save to be used for this function
2709 then save the registers being used in this function */
2710 if (IFFUNC_CALLEESAVES(sym->type)) {
2713 /* if any registers used */
2714 if (sym->regsUsed) {
2715 /* save the registers used */
2716 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2717 if (bitVectBitValue(sym->regsUsed,i) ||
2718 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2719 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2727 /* set the register bank to the desired value */
2728 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2729 pic14_emitcode("push","psw");
2730 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2733 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2735 if (options.useXstack) {
2736 pic14_emitcode("mov","r0,%s",spname);
2737 pic14_emitcode("mov","a,_bp");
2738 pic14_emitcode("movx","@r0,a");
2739 pic14_emitcode("inc","%s",spname);
2743 /* set up the stack */
2744 pic14_emitcode ("push","_bp"); /* save the callers stack */
2746 pic14_emitcode ("mov","_bp,%s",spname);
2749 /* adjust the stack for the function */
2754 werror(W_STACK_OVERFLOW,sym->name);
2756 if (i > 3 && sym->recvSize < 4) {
2758 pic14_emitcode ("mov","a,sp");
2759 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2760 pic14_emitcode ("mov","sp,a");
2765 pic14_emitcode("inc","sp");
2770 pic14_emitcode ("mov","a,_spx");
2771 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2772 pic14_emitcode ("mov","_spx,a");
2777 /*-----------------------------------------------------------------*/
2778 /* genEndFunction - generates epilogue for functions */
2779 /*-----------------------------------------------------------------*/
2780 static void genEndFunction (iCode *ic)
2782 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2784 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2786 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2788 pic14_emitcode ("mov","%s,_bp",spname);
2791 /* if use external stack but some variables were
2792 added to the local stack then decrement the
2794 if (options.useXstack && sym->stack) {
2795 pic14_emitcode("mov","a,sp");
2796 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2797 pic14_emitcode("mov","sp,a");
2801 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2802 if (options.useXstack) {
2803 pic14_emitcode("mov","r0,%s",spname);
2804 pic14_emitcode("movx","a,@r0");
2805 pic14_emitcode("mov","_bp,a");
2806 pic14_emitcode("dec","%s",spname);
2810 pic14_emitcode ("pop","_bp");
2814 /* restore the register bank */
2815 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2816 pic14_emitcode ("pop","psw");
2818 if (IFFUNC_ISISR(sym->type)) {
2820 /* now we need to restore the registers */
2821 /* if this isr has no bank i.e. is going to
2822 run with bank 0 , then we need to save more
2824 if (!FUNC_REGBANK(sym->type)) {
2826 /* if this function does not call any other
2827 function then we can be economical and
2828 save only those registers that are used */
2829 if (! IFFUNC_HASFCALL(sym->type)) {
2832 /* if any registers used */
2833 if (sym->regsUsed) {
2834 /* save the registers used */
2835 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2836 if (bitVectBitValue(sym->regsUsed,i) ||
2837 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2838 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2843 /* this function has a function call cannot
2844 determines register usage so we will have the
2846 unsaverbank(0,ic,FALSE);
2850 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2852 if (options.stack10bit)
2854 pic14_emitcode ("pop", "dpx1");
2855 pic14_emitcode ("pop", "dph1");
2856 pic14_emitcode ("pop", "dpl1");
2858 pic14_emitcode ("pop", "dps");
2859 pic14_emitcode ("pop", "dpx");
2861 if (!inExcludeList("dph"))
2862 pic14_emitcode ("pop","dph");
2863 if (!inExcludeList("dpl"))
2864 pic14_emitcode ("pop","dpl");
2865 if (!inExcludeList("b"))
2866 pic14_emitcode ("pop","b");
2867 if (!inExcludeList("acc"))
2868 pic14_emitcode ("pop","acc");
2870 if (IFFUNC_ISCRITICAL(sym->type))
2871 pic14_emitcode("setb","ea");
2874 /* if debug then send end of function */
2875 /* if (options.debug && currFunc) { */
2877 debugFile->writeEndFunction (currFunc, ic, 1);
2880 pic14_emitcode ("reti","");
2881 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2882 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2883 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2884 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2885 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2886 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2887 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2888 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2889 emitpcodeNULLop(POC_RETFIE);
2892 if (IFFUNC_ISCRITICAL(sym->type))
2893 pic14_emitcode("setb","ea");
2895 if (IFFUNC_CALLEESAVES(sym->type)) {
2898 /* if any registers used */
2899 if (sym->regsUsed) {
2900 /* save the registers used */
2901 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2902 if (bitVectBitValue(sym->regsUsed,i) ||
2903 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2904 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2910 /* if debug then send end of function */
2912 debugFile->writeEndFunction (currFunc, ic, 1);
2915 pic14_emitcode ("return","");
2916 emitpcodeNULLop(POC_RETURN);
2918 /* Mark the end of a function */
2919 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2924 /*-----------------------------------------------------------------*/
2925 /* genRet - generate code for return statement */
2926 /*-----------------------------------------------------------------*/
2927 static void genRet (iCode *ic)
2929 int size,offset = 0 , pushed = 0;
2931 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2932 /* if we have no return value then
2933 just generate the "ret" */
2937 /* we have something to return then
2938 move the return value into place */
2939 aopOp(IC_LEFT(ic),ic,FALSE);
2940 size = AOP_SIZE(IC_LEFT(ic));
2944 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2946 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2948 pic14_emitcode("push","%s",l);
2951 l = aopGet(AOP(IC_LEFT(ic)),offset,
2953 if (strcmp(fReturn[offset],l)) {
2954 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2955 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2956 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2957 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2958 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2960 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2963 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2973 if (strcmp(fReturn[pushed],"a"))
2974 pic14_emitcode("pop",fReturn[pushed]);
2976 pic14_emitcode("pop","acc");
2979 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2982 /* generate a jump to the return label
2983 if the next is not the return statement */
2984 if (!(ic->next && ic->next->op == LABEL &&
2985 IC_LABEL(ic->next) == returnLabel)) {
2987 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2988 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2993 /*-----------------------------------------------------------------*/
2994 /* genLabel - generates a label */
2995 /*-----------------------------------------------------------------*/
2996 static void genLabel (iCode *ic)
2998 /* special case never generate */
2999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3000 if (IC_LABEL(ic) == entryLabel)
3003 emitpLabel(IC_LABEL(ic)->key);
3004 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3007 /*-----------------------------------------------------------------*/
3008 /* genGoto - generates a goto */
3009 /*-----------------------------------------------------------------*/
3011 static void genGoto (iCode *ic)
3013 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3014 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3018 /*-----------------------------------------------------------------*/
3019 /* genMultbits :- multiplication of bits */
3020 /*-----------------------------------------------------------------*/
3021 static void genMultbits (operand *left,
3025 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3027 if(!pic14_sameRegs(AOP(result),AOP(right)))
3028 emitpcode(POC_BSF, popGet(AOP(result),0));
3030 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3031 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3032 emitpcode(POC_BCF, popGet(AOP(result),0));
3037 /*-----------------------------------------------------------------*/
3038 /* genMultOneByte : 8 bit multiplication & division */
3039 /*-----------------------------------------------------------------*/
3040 static void genMultOneByte (operand *left,
3044 sym_link *opetype = operandType(result);
3049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3050 DEBUGpic14_AopType(__LINE__,left,right,result);
3051 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3053 /* (if two literals, the value is computed before) */
3054 /* if one literal, literal on the right */
3055 if (AOP_TYPE(left) == AOP_LIT){
3061 size = AOP_SIZE(result);
3064 if (AOP_TYPE(right) == AOP_LIT){
3065 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3066 aopGet(AOP(right),0,FALSE,FALSE),
3067 aopGet(AOP(left),0,FALSE,FALSE),
3068 aopGet(AOP(result),0,FALSE,FALSE));
3069 pic14_emitcode("call","genMultLit");
3071 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3072 aopGet(AOP(right),0,FALSE,FALSE),
3073 aopGet(AOP(left),0,FALSE,FALSE),
3074 aopGet(AOP(result),0,FALSE,FALSE));
3075 pic14_emitcode("call","genMult8X8_8");
3078 genMult8X8_8 (left, right,result);
3081 /* signed or unsigned */
3082 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3083 //l = aopGet(AOP(left),0,FALSE,FALSE);
3085 //pic14_emitcode("mul","ab");
3086 /* if result size = 1, mul signed = mul unsigned */
3087 //aopPut(AOP(result),"a",0);
3089 } else { // (size > 1)
3091 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3092 aopGet(AOP(right),0,FALSE,FALSE),
3093 aopGet(AOP(left),0,FALSE,FALSE),
3094 aopGet(AOP(result),0,FALSE,FALSE));
3096 if (SPEC_USIGN(opetype)){
3097 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3098 genUMult8X8_16 (left, right, result, NULL);
3101 /* for filling the MSBs */
3102 emitpcode(POC_CLRF, popGet(AOP(result),2));
3103 emitpcode(POC_CLRF, popGet(AOP(result),3));
3107 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3109 pic14_emitcode("mov","a,b");
3111 /* adjust the MSB if left or right neg */
3113 /* if one literal */
3114 if (AOP_TYPE(right) == AOP_LIT){
3115 pic14_emitcode("multiply ","right is a lit");
3116 /* AND literal negative */
3117 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3118 /* adjust MSB (c==0 after mul) */
3119 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3123 genSMult8X8_16 (left, right, result, NULL);
3127 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3129 pic14_emitcode("rlc","a");
3130 pic14_emitcode("subb","a,acc");
3138 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3139 //aopPut(AOP(result),"a",offset++);
3143 /*-----------------------------------------------------------------*/
3144 /* genMult - generates code for multiplication */
3145 /*-----------------------------------------------------------------*/
3146 static void genMult (iCode *ic)
3148 operand *left = IC_LEFT(ic);
3149 operand *right = IC_RIGHT(ic);
3150 operand *result= IC_RESULT(ic);
3152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3153 /* assign the amsops */
3154 aopOp (left,ic,FALSE);
3155 aopOp (right,ic,FALSE);
3156 aopOp (result,ic,TRUE);
3158 DEBUGpic14_AopType(__LINE__,left,right,result);
3160 /* special cases first */
3162 if (AOP_TYPE(left) == AOP_CRY &&
3163 AOP_TYPE(right)== AOP_CRY) {
3164 genMultbits(left,right,result);
3168 /* if both are of size == 1 */
3169 if (AOP_SIZE(left) == 1 &&
3170 AOP_SIZE(right) == 1 ) {
3171 genMultOneByte(left,right,result);
3175 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3177 /* should have been converted to function call */
3181 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3183 freeAsmop(result,NULL,ic,TRUE);
3186 /*-----------------------------------------------------------------*/
3187 /* genDivbits :- division of bits */
3188 /*-----------------------------------------------------------------*/
3189 static void genDivbits (operand *left,
3196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3197 /* the result must be bit */
3198 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3199 l = aopGet(AOP(left),0,FALSE,FALSE);
3203 pic14_emitcode("div","ab");
3204 pic14_emitcode("rrc","a");
3205 aopPut(AOP(result),"c",0);
3208 /*-----------------------------------------------------------------*/
3209 /* genDivOneByte : 8 bit division */
3210 /*-----------------------------------------------------------------*/
3211 static void genDivOneByte (operand *left,
3215 sym_link *opetype = operandType(result);
3220 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3221 size = AOP_SIZE(result) - 1;
3223 /* signed or unsigned */
3224 if (SPEC_USIGN(opetype)) {
3225 /* unsigned is easy */
3226 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3227 l = aopGet(AOP(left),0,FALSE,FALSE);
3229 pic14_emitcode("div","ab");
3230 aopPut(AOP(result),"a",0);
3232 aopPut(AOP(result),zero,offset++);
3236 /* signed is a little bit more difficult */
3238 /* save the signs of the operands */
3239 l = aopGet(AOP(left),0,FALSE,FALSE);
3241 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3242 pic14_emitcode("push","acc"); /* save it on the stack */
3244 /* now sign adjust for both left & right */
3245 l = aopGet(AOP(right),0,FALSE,FALSE);
3247 lbl = newiTempLabel(NULL);
3248 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3249 pic14_emitcode("cpl","a");
3250 pic14_emitcode("inc","a");
3251 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3252 pic14_emitcode("mov","b,a");
3254 /* sign adjust left side */
3255 l = aopGet(AOP(left),0,FALSE,FALSE);
3258 lbl = newiTempLabel(NULL);
3259 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3260 pic14_emitcode("cpl","a");
3261 pic14_emitcode("inc","a");
3262 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3264 /* now the division */
3265 pic14_emitcode("div","ab");
3266 /* we are interested in the lower order
3268 pic14_emitcode("mov","b,a");
3269 lbl = newiTempLabel(NULL);
3270 pic14_emitcode("pop","acc");
3271 /* if there was an over flow we don't
3272 adjust the sign of the result */
3273 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3274 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3276 pic14_emitcode("clr","a");
3277 pic14_emitcode("subb","a,b");
3278 pic14_emitcode("mov","b,a");
3279 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3281 /* now we are done */
3282 aopPut(AOP(result),"b",0);
3284 pic14_emitcode("mov","c,b.7");
3285 pic14_emitcode("subb","a,acc");
3288 aopPut(AOP(result),"a",offset++);
3292 /*-----------------------------------------------------------------*/
3293 /* genDiv - generates code for division */
3294 /*-----------------------------------------------------------------*/
3295 static void genDiv (iCode *ic)
3297 operand *left = IC_LEFT(ic);
3298 operand *right = IC_RIGHT(ic);
3299 operand *result= IC_RESULT(ic);
3301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3302 /* assign the amsops */
3303 aopOp (left,ic,FALSE);
3304 aopOp (right,ic,FALSE);
3305 aopOp (result,ic,TRUE);
3307 /* special cases first */
3309 if (AOP_TYPE(left) == AOP_CRY &&
3310 AOP_TYPE(right)== AOP_CRY) {
3311 genDivbits(left,right,result);
3315 /* if both are of size == 1 */
3316 if (AOP_SIZE(left) == 1 &&
3317 AOP_SIZE(right) == 1 ) {
3318 genDivOneByte(left,right,result);
3322 /* should have been converted to function call */
3325 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3326 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3327 freeAsmop(result,NULL,ic,TRUE);
3330 /*-----------------------------------------------------------------*/
3331 /* genModbits :- modulus of bits */
3332 /*-----------------------------------------------------------------*/
3333 static void genModbits (operand *left,
3340 /* the result must be bit */
3341 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3342 l = aopGet(AOP(left),0,FALSE,FALSE);
3346 pic14_emitcode("div","ab");
3347 pic14_emitcode("mov","a,b");
3348 pic14_emitcode("rrc","a");
3349 aopPut(AOP(result),"c",0);
3352 /*-----------------------------------------------------------------*/
3353 /* genModOneByte : 8 bit modulus */
3354 /*-----------------------------------------------------------------*/
3355 static void genModOneByte (operand *left,
3359 sym_link *opetype = operandType(result);
3363 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3364 /* signed or unsigned */
3365 if (SPEC_USIGN(opetype)) {
3366 /* unsigned is easy */
3367 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3368 l = aopGet(AOP(left),0,FALSE,FALSE);
3370 pic14_emitcode("div","ab");
3371 aopPut(AOP(result),"b",0);
3375 /* signed is a little bit more difficult */
3377 /* save the signs of the operands */
3378 l = aopGet(AOP(left),0,FALSE,FALSE);
3381 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3382 pic14_emitcode("push","acc"); /* save it on the stack */
3384 /* now sign adjust for both left & right */
3385 l = aopGet(AOP(right),0,FALSE,FALSE);
3388 lbl = newiTempLabel(NULL);
3389 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3390 pic14_emitcode("cpl","a");
3391 pic14_emitcode("inc","a");
3392 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3393 pic14_emitcode("mov","b,a");
3395 /* sign adjust left side */
3396 l = aopGet(AOP(left),0,FALSE,FALSE);
3399 lbl = newiTempLabel(NULL);
3400 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3401 pic14_emitcode("cpl","a");
3402 pic14_emitcode("inc","a");
3403 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3405 /* now the multiplication */
3406 pic14_emitcode("div","ab");
3407 /* we are interested in the lower order
3409 lbl = newiTempLabel(NULL);
3410 pic14_emitcode("pop","acc");
3411 /* if there was an over flow we don't
3412 adjust the sign of the result */
3413 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3414 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3416 pic14_emitcode("clr","a");
3417 pic14_emitcode("subb","a,b");
3418 pic14_emitcode("mov","b,a");
3419 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3421 /* now we are done */
3422 aopPut(AOP(result),"b",0);
3426 /*-----------------------------------------------------------------*/
3427 /* genMod - generates code for division */
3428 /*-----------------------------------------------------------------*/
3429 static void genMod (iCode *ic)
3431 operand *left = IC_LEFT(ic);
3432 operand *right = IC_RIGHT(ic);
3433 operand *result= IC_RESULT(ic);
3435 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3436 /* assign the amsops */
3437 aopOp (left,ic,FALSE);
3438 aopOp (right,ic,FALSE);
3439 aopOp (result,ic,TRUE);
3441 /* special cases first */
3443 if (AOP_TYPE(left) == AOP_CRY &&
3444 AOP_TYPE(right)== AOP_CRY) {
3445 genModbits(left,right,result);
3449 /* if both are of size == 1 */
3450 if (AOP_SIZE(left) == 1 &&
3451 AOP_SIZE(right) == 1 ) {
3452 genModOneByte(left,right,result);
3456 /* should have been converted to function call */
3460 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3461 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3462 freeAsmop(result,NULL,ic,TRUE);
3465 /*-----------------------------------------------------------------*/
3466 /* genIfxJump :- will create a jump depending on the ifx */
3467 /*-----------------------------------------------------------------*/
3469 note: May need to add parameter to indicate when a variable is in bit space.
3471 static void genIfxJump (iCode *ic, char *jval)
3474 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3475 /* if true label then we jump if condition
3477 if ( IC_TRUE(ic) ) {
3479 if(strcmp(jval,"a") == 0)
3481 else if (strcmp(jval,"c") == 0)
3484 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3485 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3488 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3489 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3493 /* false label is present */
3494 if(strcmp(jval,"a") == 0)
3496 else if (strcmp(jval,"c") == 0)
3499 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3500 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3503 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3504 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3509 /* mark the icode as generated */
3513 /*-----------------------------------------------------------------*/
3515 /*-----------------------------------------------------------------*/
3516 static void genSkip(iCode *ifx,int status_bit)
3521 if ( IC_TRUE(ifx) ) {
3522 switch(status_bit) {
3537 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3538 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3542 switch(status_bit) {
3556 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3557 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3563 /*-----------------------------------------------------------------*/
3565 /*-----------------------------------------------------------------*/
3566 static void genSkipc(resolvedIfx *rifx)
3576 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3577 rifx->generated = 1;
3580 /*-----------------------------------------------------------------*/
3582 /*-----------------------------------------------------------------*/
3583 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3588 if( (rifx->condition ^ invert_condition) & 1)
3593 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3594 rifx->generated = 1;
3597 /*-----------------------------------------------------------------*/
3599 /*-----------------------------------------------------------------*/
3600 static void genSkipz(iCode *ifx, int condition)
3611 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3613 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3616 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3618 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3621 /*-----------------------------------------------------------------*/
3623 /*-----------------------------------------------------------------*/
3624 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3630 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3632 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3635 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3636 rifx->generated = 1;
3640 /*-----------------------------------------------------------------*/
3641 /* genChkZeroes :- greater or less than comparison */
3642 /* For each byte in a literal that is zero, inclusive or the */
3643 /* the corresponding byte in the operand with W */
3644 /* returns true if any of the bytes are zero */
3645 /*-----------------------------------------------------------------*/
3646 static int genChkZeroes(operand *op, int lit, int size)
3653 i = (lit >> (size*8)) & 0xff;
3657 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3659 emitpcode(POC_IORFW, popGet(AOP(op),size));
3668 /*-----------------------------------------------------------------*/
3669 /* genCmp :- greater or less than comparison */
3670 /*-----------------------------------------------------------------*/
3671 static void genCmp (operand *left,operand *right,
3672 operand *result, iCode *ifx, int sign)
3674 int size; //, offset = 0 ;
3675 unsigned long lit = 0L,i = 0;
3676 resolvedIfx rFalseIfx;
3677 // resolvedIfx rTrueIfx;
3679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3682 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3683 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3687 resolveIfx(&rFalseIfx,ifx);
3688 truelbl = newiTempLabel(NULL);
3689 size = max(AOP_SIZE(left),AOP_SIZE(right));
3691 DEBUGpic14_AopType(__LINE__,left,right,result);
3695 /* if literal is on the right then swap with left */
3696 if ((AOP_TYPE(right) == AOP_LIT)) {
3697 operand *tmp = right ;
3698 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3699 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3702 lit = (lit - 1) & mask;
3705 rFalseIfx.condition ^= 1;
3708 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3709 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3713 //if(IC_TRUE(ifx) == NULL)
3714 /* if left & right are bit variables */
3715 if (AOP_TYPE(left) == AOP_CRY &&
3716 AOP_TYPE(right) == AOP_CRY ) {
3717 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3718 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3720 /* subtract right from left if at the
3721 end the carry flag is set then we know that
3722 left is greater than right */
3724 symbol *lbl = newiTempLabel(NULL);
3727 if(AOP_TYPE(right) == AOP_LIT) {
3729 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3731 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3738 genSkipCond(&rFalseIfx,left,size-1,7);
3740 /* no need to compare to 0...*/
3741 /* NOTE: this is a de-generate compare that most certainly
3742 * creates some dead code. */
3743 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3745 if(ifx) ifx->generated = 1;
3752 //i = (lit >> (size*8)) & 0xff;
3753 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3755 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3757 i = ((0-lit) & 0xff);
3760 /* lit is 0x7f, all signed chars are less than
3761 * this except for 0x7f itself */
3762 emitpcode(POC_XORLW, popGetLit(0x7f));
3763 genSkipz2(&rFalseIfx,0);
3765 emitpcode(POC_ADDLW, popGetLit(0x80));
3766 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3767 genSkipc(&rFalseIfx);
3772 genSkipz2(&rFalseIfx,1);
3774 emitpcode(POC_ADDLW, popGetLit(i));
3775 genSkipc(&rFalseIfx);
3779 if(ifx) ifx->generated = 1;
3783 /* chars are out of the way. now do ints and longs */
3786 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3793 genSkipCond(&rFalseIfx,left,size,7);
3794 if(ifx) ifx->generated = 1;
3799 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3801 //rFalseIfx.condition ^= 1;
3802 //genSkipCond(&rFalseIfx,left,size,7);
3803 //rFalseIfx.condition ^= 1;
3805 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3806 if(rFalseIfx.condition)
3807 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3809 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3811 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3812 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3813 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3816 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3818 if(rFalseIfx.condition) {
3820 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3826 genSkipc(&rFalseIfx);
3827 emitpLabel(truelbl->key);
3828 if(ifx) ifx->generated = 1;
3835 if( (lit & 0xff) == 0) {
3836 /* lower byte is zero */
3837 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3838 i = ((lit >> 8) & 0xff) ^0x80;
3839 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3840 emitpcode(POC_ADDLW, popGetLit( 0x80));
3841 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3842 genSkipc(&rFalseIfx);
3845 if(ifx) ifx->generated = 1;
3850 /* Special cases for signed longs */
3851 if( (lit & 0xffffff) == 0) {
3852 /* lower byte is zero */
3853 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3854 i = ((lit >> 8*3) & 0xff) ^0x80;
3855 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3856 emitpcode(POC_ADDLW, popGetLit( 0x80));
3857 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3858 genSkipc(&rFalseIfx);
3861 if(ifx) ifx->generated = 1;
3869 if(lit & (0x80 << (size*8))) {
3870 /* lit is negative */
3871 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3873 //genSkipCond(&rFalseIfx,left,size,7);
3875 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3877 if(rFalseIfx.condition)
3878 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3880 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3884 /* lit is positive */
3885 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3886 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3887 if(rFalseIfx.condition)
3888 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3890 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3894 /* There are no more special cases, so perform a general compare */
3896 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3897 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3901 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3903 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3905 //rFalseIfx.condition ^= 1;
3906 genSkipc(&rFalseIfx);
3908 emitpLabel(truelbl->key);
3910 if(ifx) ifx->generated = 1;
3917 /* sign is out of the way. So now do an unsigned compare */
3918 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3921 /* General case - compare to an unsigned literal on the right.*/
3923 i = (lit >> (size*8)) & 0xff;
3924 emitpcode(POC_MOVLW, popGetLit(i));
3925 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3927 i = (lit >> (size*8)) & 0xff;
3930 emitpcode(POC_MOVLW, popGetLit(i));
3932 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3934 /* this byte of the lit is zero,
3935 *if it's not the last then OR in the variable */
3937 emitpcode(POC_IORFW, popGet(AOP(left),size));
3942 emitpLabel(lbl->key);
3943 //if(emitFinalCheck)
3944 genSkipc(&rFalseIfx);
3946 emitpLabel(truelbl->key);
3948 if(ifx) ifx->generated = 1;
3955 if(AOP_TYPE(left) == AOP_LIT) {
3956 //symbol *lbl = newiTempLabel(NULL);
3958 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3961 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3964 if((lit == 0) && (sign == 0)){
3967 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3969 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3971 genSkipz2(&rFalseIfx,0);
3972 if(ifx) ifx->generated = 1;
3979 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3980 /* degenerate compare can never be true */
3981 if(rFalseIfx.condition == 0)
3982 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3984 if(ifx) ifx->generated = 1;
3989 /* signed comparisons to a literal byte */
3991 int lp1 = (lit+1) & 0xff;
3993 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3996 rFalseIfx.condition ^= 1;
3997 genSkipCond(&rFalseIfx,right,0,7);
4000 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4001 emitpcode(POC_XORLW, popGetLit(0x7f));
4002 genSkipz2(&rFalseIfx,1);
4005 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4006 emitpcode(POC_ADDLW, popGetLit(0x80));
4007 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4008 rFalseIfx.condition ^= 1;
4009 genSkipc(&rFalseIfx);
4012 if(ifx) ifx->generated = 1;
4014 /* unsigned comparisons to a literal byte */
4016 switch(lit & 0xff ) {
4018 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4019 genSkipz2(&rFalseIfx,0);
4020 if(ifx) ifx->generated = 1;
4023 genSkipCond(&rFalseIfx,right,0,7);
4024 if(ifx) ifx->generated = 1;
4028 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4029 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4031 rFalseIfx.condition ^= 1;
4032 if (AOP_TYPE(result) == AOP_CRY) {
4033 genSkipc(&rFalseIfx);
4034 if(ifx) ifx->generated = 1;
4036 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4037 emitpcode(POC_CLRF, popGet(AOP(result),0));
4038 emitpcode(POC_RLF, popGet(AOP(result),0));
4039 emitpcode(POC_MOVLW, popGetLit(0x01));
4040 emitpcode(POC_XORWF, popGet(AOP(result),0));
4051 /* Size is greater than 1 */
4059 /* this means lit = 0xffffffff, or -1 */
4062 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4063 rFalseIfx.condition ^= 1;
4064 genSkipCond(&rFalseIfx,right,size,7);
4065 if(ifx) ifx->generated = 1;
4072 if(rFalseIfx.condition) {
4073 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4074 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4077 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4079 emitpcode(POC_IORFW, popGet(AOP(right),size));
4083 if(rFalseIfx.condition) {
4084 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4085 emitpLabel(truelbl->key);
4087 rFalseIfx.condition ^= 1;
4088 genSkipCond(&rFalseIfx,right,s,7);
4091 if(ifx) ifx->generated = 1;
4095 if((size == 1) && (0 == (lp1&0xff))) {
4096 /* lower byte of signed word is zero */
4097 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4098 i = ((lp1 >> 8) & 0xff) ^0x80;
4099 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4100 emitpcode(POC_ADDLW, popGetLit( 0x80));
4101 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4102 rFalseIfx.condition ^= 1;
4103 genSkipc(&rFalseIfx);
4106 if(ifx) ifx->generated = 1;
4110 if(lit & (0x80 << (size*8))) {
4111 /* Lit is less than zero */
4112 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4113 //rFalseIfx.condition ^= 1;
4114 //genSkipCond(&rFalseIfx,left,size,7);
4115 //rFalseIfx.condition ^= 1;
4116 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4117 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4119 if(rFalseIfx.condition)
4120 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4122 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4126 /* Lit is greater than or equal to zero */
4127 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4128 //rFalseIfx.condition ^= 1;
4129 //genSkipCond(&rFalseIfx,right,size,7);
4130 //rFalseIfx.condition ^= 1;
4132 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4133 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4135 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4136 if(rFalseIfx.condition)
4137 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4139 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4144 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4145 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4149 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4151 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4153 rFalseIfx.condition ^= 1;
4154 //rFalseIfx.condition = 1;
4155 genSkipc(&rFalseIfx);
4157 emitpLabel(truelbl->key);
4159 if(ifx) ifx->generated = 1;
4164 /* compare word or long to an unsigned literal on the right.*/
4169 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4172 break; /* handled above */
4175 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4177 emitpcode(POC_IORFW, popGet(AOP(right),size));
4178 genSkipz2(&rFalseIfx,0);
4182 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4184 emitpcode(POC_IORFW, popGet(AOP(right),size));
4187 if(rFalseIfx.condition)
4188 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4190 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4193 emitpcode(POC_MOVLW, popGetLit(lit+1));
4194 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4196 rFalseIfx.condition ^= 1;
4197 genSkipc(&rFalseIfx);
4200 emitpLabel(truelbl->key);
4202 if(ifx) ifx->generated = 1;
4208 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4209 i = (lit >> (size*8)) & 0xff;
4211 emitpcode(POC_MOVLW, popGetLit(i));
4212 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4215 i = (lit >> (size*8)) & 0xff;
4218 emitpcode(POC_MOVLW, popGetLit(i));
4220 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4222 /* this byte of the lit is zero,
4223 *if it's not the last then OR in the variable */
4225 emitpcode(POC_IORFW, popGet(AOP(right),size));
4230 emitpLabel(lbl->key);
4232 rFalseIfx.condition ^= 1;
4233 genSkipc(&rFalseIfx);
4237 emitpLabel(truelbl->key);
4238 if(ifx) ifx->generated = 1;
4242 /* Compare two variables */
4244 DEBUGpic14_emitcode(";sign","%d",sign);
4248 /* Sigh. thus sucks... */
4250 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4251 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4252 emitpcode(POC_MOVLW, popGetLit(0x80));
4253 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4254 emitpcode(POC_XORFW, popGet(AOP(right),size));
4255 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4257 /* Signed char comparison */
4258 /* Special thanks to Nikolai Golovchenko for this snippet */
4259 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4260 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4261 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4262 emitpcode(POC_XORFW, popGet(AOP(left),0));
4263 emitpcode(POC_XORFW, popGet(AOP(right),0));
4264 emitpcode(POC_ADDLW, popGetLit(0x80));
4266 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4267 genSkipc(&rFalseIfx);
4269 if(ifx) ifx->generated = 1;
4275 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4276 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4280 /* The rest of the bytes of a multi-byte compare */
4284 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4287 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4288 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4293 emitpLabel(lbl->key);
4295 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4296 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4297 (AOP_TYPE(result) == AOP_REG)) {
4298 emitpcode(POC_CLRF, popGet(AOP(result),0));
4299 emitpcode(POC_RLF, popGet(AOP(result),0));
4301 genSkipc(&rFalseIfx);
4303 //genSkipc(&rFalseIfx);
4304 if(ifx) ifx->generated = 1;
4311 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4313 pic14_outBitC(result);
4315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4316 /* if the result is used in the next
4317 ifx conditional branch then generate
4318 code a little differently */
4320 genIfxJump (ifx,"c");
4322 pic14_outBitC(result);
4323 /* leave the result in acc */
4328 /*-----------------------------------------------------------------*/
4329 /* genCmpGt :- greater than comparison */
4330 /*-----------------------------------------------------------------*/
4331 static void genCmpGt (iCode *ic, iCode *ifx)
4333 operand *left, *right, *result;
4334 sym_link *letype , *retype;
4337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4339 right= IC_RIGHT(ic);
4340 result = IC_RESULT(ic);
4342 letype = getSpec(operandType(left));
4343 retype =getSpec(operandType(right));
4344 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4345 /* assign the amsops */
4346 aopOp (left,ic,FALSE);
4347 aopOp (right,ic,FALSE);
4348 aopOp (result,ic,TRUE);
4350 genCmp(right, left, result, ifx, sign);
4352 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4353 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4354 freeAsmop(result,NULL,ic,TRUE);
4357 /*-----------------------------------------------------------------*/
4358 /* genCmpLt - less than comparisons */
4359 /*-----------------------------------------------------------------*/
4360 static void genCmpLt (iCode *ic, iCode *ifx)
4362 operand *left, *right, *result;
4363 sym_link *letype , *retype;
4366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4368 right= IC_RIGHT(ic);
4369 result = IC_RESULT(ic);
4371 letype = getSpec(operandType(left));
4372 retype =getSpec(operandType(right));
4373 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4375 /* assign the amsops */
4376 aopOp (left,ic,FALSE);
4377 aopOp (right,ic,FALSE);
4378 aopOp (result,ic,TRUE);
4380 genCmp(left, right, result, ifx, sign);
4382 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4383 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4384 freeAsmop(result,NULL,ic,TRUE);
4387 /*-----------------------------------------------------------------*/
4388 /* genc16bit2lit - compare a 16 bit value to a literal */
4389 /*-----------------------------------------------------------------*/
4390 static void genc16bit2lit(operand *op, int lit, int offset)
4394 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4395 if( (lit&0xff) == 0)
4400 switch( BYTEofLONG(lit,i)) {
4402 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4405 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4408 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4411 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4412 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4417 switch( BYTEofLONG(lit,i)) {
4419 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4423 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4427 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4430 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4432 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4438 /*-----------------------------------------------------------------*/
4439 /* gencjneshort - compare and jump if not equal */
4440 /*-----------------------------------------------------------------*/
4441 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4443 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4445 int res_offset = 0; /* the result may be a different size then left or right */
4446 int res_size = AOP_SIZE(result);
4450 unsigned long lit = 0L;
4451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4452 DEBUGpic14_AopType(__LINE__,left,right,result);
4454 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4455 resolveIfx(&rIfx,ifx);
4456 lbl = newiTempLabel(NULL);
4459 /* if the left side is a literal or
4460 if the right is in a pointer register and left
4462 if ((AOP_TYPE(left) == AOP_LIT) ||
4463 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4468 if(AOP_TYPE(right) == AOP_LIT)
4469 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4471 /* if the right side is a literal then anything goes */
4472 if (AOP_TYPE(right) == AOP_LIT &&
4473 AOP_TYPE(left) != AOP_DIR ) {
4476 genc16bit2lit(left, lit, 0);
4478 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4483 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4484 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4486 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4490 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4492 if(res_offset < res_size-1)
4500 /* if the right side is in a register or in direct space or
4501 if the left is a pointer register & right is not */
4502 else if (AOP_TYPE(right) == AOP_REG ||
4503 AOP_TYPE(right) == AOP_DIR ||
4504 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4505 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4506 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4507 int lbl_key = lbl->key;
4510 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4511 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4513 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4514 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4515 __FUNCTION__,__LINE__);
4519 /* switch(size) { */
4521 /* genc16bit2lit(left, lit, 0); */
4523 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4528 if((AOP_TYPE(left) == AOP_DIR) &&
4529 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4531 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4532 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4534 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4536 switch (lit & 0xff) {
4538 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4541 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4542 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4543 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4547 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4548 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4549 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4550 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4554 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4555 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4560 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4563 if(AOP_TYPE(result) == AOP_CRY) {
4564 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4569 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4571 /* fix me. probably need to check result size too */
4572 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4577 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4578 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4585 if(res_offset < res_size-1)
4590 } else if(AOP_TYPE(right) == AOP_REG &&
4591 AOP_TYPE(left) != AOP_DIR){
4594 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4595 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4596 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4601 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4603 if(res_offset < res_size-1)
4608 /* right is a pointer reg need both a & b */
4610 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4612 pic14_emitcode("mov","b,%s",l);
4613 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4614 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4619 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4621 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4623 emitpLabel(lbl->key);
4625 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4632 /*-----------------------------------------------------------------*/
4633 /* gencjne - compare and jump if not equal */
4634 /*-----------------------------------------------------------------*/
4635 static void gencjne(operand *left, operand *right, iCode *ifx)
4637 symbol *tlbl = newiTempLabel(NULL);
4639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4640 gencjneshort(left, right, lbl);
4642 pic14_emitcode("mov","a,%s",one);
4643 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4644 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4645 pic14_emitcode("clr","a");
4646 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4648 emitpLabel(lbl->key);
4649 emitpLabel(tlbl->key);
4654 /*-----------------------------------------------------------------*/
4655 /* genCmpEq - generates code for equal to */
4656 /*-----------------------------------------------------------------*/
4657 static void genCmpEq (iCode *ic, iCode *ifx)
4659 operand *left, *right, *result;
4660 unsigned long lit = 0L;
4663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4666 DEBUGpic14_emitcode ("; ifx is non-null","");
4668 DEBUGpic14_emitcode ("; ifx is null","");
4670 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4671 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4672 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4674 size = max(AOP_SIZE(left),AOP_SIZE(right));
4676 DEBUGpic14_AopType(__LINE__,left,right,result);
4678 /* if literal, literal on the right or
4679 if the right is in a pointer register and left
4681 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4682 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4683 operand *tmp = right ;
4689 if(ifx && !AOP_SIZE(result)){
4691 /* if they are both bit variables */
4692 if (AOP_TYPE(left) == AOP_CRY &&
4693 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4694 if(AOP_TYPE(right) == AOP_LIT){
4695 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4697 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4698 pic14_emitcode("cpl","c");
4699 } else if(lit == 1L) {
4700 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4702 pic14_emitcode("clr","c");
4704 /* AOP_TYPE(right) == AOP_CRY */
4706 symbol *lbl = newiTempLabel(NULL);
4707 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4708 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4709 pic14_emitcode("cpl","c");
4710 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4712 /* if true label then we jump if condition
4714 tlbl = newiTempLabel(NULL);
4715 if ( IC_TRUE(ifx) ) {
4716 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4717 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4719 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4720 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4722 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4725 /* left and right are both bit variables, result is carry */
4728 resolveIfx(&rIfx,ifx);
4730 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4731 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4732 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4733 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4738 /* They're not both bit variables. Is the right a literal? */
4739 if(AOP_TYPE(right) == AOP_LIT) {
4740 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4745 switch(lit & 0xff) {
4747 if ( IC_TRUE(ifx) ) {
4748 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4750 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4752 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4753 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4757 if ( IC_TRUE(ifx) ) {
4758 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4760 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4762 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4763 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4767 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4769 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4774 /* end of size == 1 */
4778 genc16bit2lit(left,lit,offset);
4781 /* end of size == 2 */
4786 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4787 emitpcode(POC_IORFW,popGet(AOP(left),1));
4788 emitpcode(POC_IORFW,popGet(AOP(left),2));
4789 emitpcode(POC_IORFW,popGet(AOP(left),3));
4793 /* search for patterns that can be optimized */
4795 genc16bit2lit(left,lit,0);
4798 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4800 genc16bit2lit(left,lit,2);
4802 emitpcode(POC_IORFW,popGet(AOP(left),2));
4803 emitpcode(POC_IORFW,popGet(AOP(left),3));
4816 } else if(AOP_TYPE(right) == AOP_CRY ) {
4817 /* we know the left is not a bit, but that the right is */
4818 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4819 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4820 popGet(AOP(right),offset));
4821 emitpcode(POC_XORLW,popGetLit(1));
4823 /* if the two are equal, then W will be 0 and the Z bit is set
4824 * we could test Z now, or go ahead and check the high order bytes if
4825 * the variable we're comparing is larger than a byte. */
4828 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4830 if ( IC_TRUE(ifx) ) {
4832 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4833 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4836 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4837 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4841 /* They're both variables that are larger than bits */
4844 tlbl = newiTempLabel(NULL);
4847 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4848 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4850 if ( IC_TRUE(ifx) ) {
4853 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4854 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4857 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4858 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4862 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4863 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4867 if(s>1 && IC_TRUE(ifx)) {
4868 emitpLabel(tlbl->key);
4869 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4873 /* mark the icode as generated */
4878 /* if they are both bit variables */
4879 if (AOP_TYPE(left) == AOP_CRY &&
4880 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4881 if(AOP_TYPE(right) == AOP_LIT){
4882 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4884 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4885 pic14_emitcode("cpl","c");
4886 } else if(lit == 1L) {
4887 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4889 pic14_emitcode("clr","c");
4891 /* AOP_TYPE(right) == AOP_CRY */
4893 symbol *lbl = newiTempLabel(NULL);
4894 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4895 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4896 pic14_emitcode("cpl","c");
4897 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4900 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4901 pic14_outBitC(result);
4905 genIfxJump (ifx,"c");
4908 /* if the result is used in an arithmetic operation
4909 then put the result in place */
4910 pic14_outBitC(result);
4913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4914 gencjne(left,right,result,ifx);
4917 gencjne(left,right,newiTempLabel(NULL));
4919 if(IC_TRUE(ifx)->key)
4920 gencjne(left,right,IC_TRUE(ifx)->key);
4922 gencjne(left,right,IC_FALSE(ifx)->key);
4926 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4927 aopPut(AOP(result),"a",0);
4932 genIfxJump (ifx,"a");
4936 /* if the result is used in an arithmetic operation
4937 then put the result in place */
4939 if (AOP_TYPE(result) != AOP_CRY)
4940 pic14_outAcc(result);
4942 /* leave the result in acc */
4946 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4947 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4948 freeAsmop(result,NULL,ic,TRUE);
4951 /*-----------------------------------------------------------------*/
4952 /* ifxForOp - returns the icode containing the ifx for operand */
4953 /*-----------------------------------------------------------------*/
4954 static iCode *ifxForOp ( operand *op, iCode *ic )
4956 /* if true symbol then needs to be assigned */
4957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4958 if (IS_TRUE_SYMOP(op))
4961 /* if this has register type condition and
4962 the next instruction is ifx with the same operand
4963 and live to of the operand is upto the ifx only then */
4965 ic->next->op == IFX &&
4966 IC_COND(ic->next)->key == op->key &&
4967 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4971 ic->next->op == IFX &&
4972 IC_COND(ic->next)->key == op->key) {
4973 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4977 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4979 ic->next->op == IFX)
4980 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4983 ic->next->op == IFX &&
4984 IC_COND(ic->next)->key == op->key) {
4985 DEBUGpic14_emitcode ("; "," key is okay");
4986 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4987 OP_SYMBOL(op)->liveTo,
4994 /*-----------------------------------------------------------------*/
4995 /* genAndOp - for && operation */
4996 /*-----------------------------------------------------------------*/
4997 static void genAndOp (iCode *ic)
4999 operand *left,*right, *result;
5002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5003 /* note here that && operations that are in an
5004 if statement are taken away by backPatchLabels
5005 only those used in arthmetic operations remain */
5006 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5007 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5008 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5010 DEBUGpic14_AopType(__LINE__,left,right,result);
5012 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5013 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5014 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5016 /* if both are bit variables */
5017 /* if (AOP_TYPE(left) == AOP_CRY && */
5018 /* AOP_TYPE(right) == AOP_CRY ) { */
5019 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5020 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5021 /* pic14_outBitC(result); */
5023 /* tlbl = newiTempLabel(NULL); */
5024 /* pic14_toBoolean(left); */
5025 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5026 /* pic14_toBoolean(right); */
5027 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5028 /* pic14_outBitAcc(result); */
5031 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5033 freeAsmop(result,NULL,ic,TRUE);
5037 /*-----------------------------------------------------------------*/
5038 /* genOrOp - for || operation */
5039 /*-----------------------------------------------------------------*/
5042 modified this code, but it doesn't appear to ever get called
5045 static void genOrOp (iCode *ic)
5047 operand *left,*right, *result;
5050 /* note here that || operations that are in an
5051 if statement are taken away by backPatchLabels
5052 only those used in arthmetic operations remain */
5053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5054 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5055 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5056 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5058 DEBUGpic14_AopType(__LINE__,left,right,result);
5060 /* if both are bit variables */
5061 if (AOP_TYPE(left) == AOP_CRY &&
5062 AOP_TYPE(right) == AOP_CRY ) {
5063 pic14_emitcode("clrc","");
5064 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5065 AOP(left)->aopu.aop_dir,
5066 AOP(left)->aopu.aop_dir);
5067 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5068 AOP(right)->aopu.aop_dir,
5069 AOP(right)->aopu.aop_dir);
5070 pic14_emitcode("setc","");
5073 tlbl = newiTempLabel(NULL);
5074 pic14_toBoolean(left);
5076 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5077 pic14_toBoolean(right);
5078 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5080 pic14_outBitAcc(result);
5083 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5085 freeAsmop(result,NULL,ic,TRUE);
5088 /*-----------------------------------------------------------------*/
5089 /* isLiteralBit - test if lit == 2^n */
5090 /*-----------------------------------------------------------------*/
5091 static int isLiteralBit(unsigned long lit)
5093 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5094 0x100L,0x200L,0x400L,0x800L,
5095 0x1000L,0x2000L,0x4000L,0x8000L,
5096 0x10000L,0x20000L,0x40000L,0x80000L,
5097 0x100000L,0x200000L,0x400000L,0x800000L,
5098 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5099 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5102 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5103 for(idx = 0; idx < 32; idx++)
5109 /*-----------------------------------------------------------------*/
5110 /* continueIfTrue - */
5111 /*-----------------------------------------------------------------*/
5112 static void continueIfTrue (iCode *ic)
5114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5116 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5120 /*-----------------------------------------------------------------*/
5122 /*-----------------------------------------------------------------*/
5123 static void jumpIfTrue (iCode *ic)
5125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5127 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5131 /*-----------------------------------------------------------------*/
5132 /* jmpTrueOrFalse - */
5133 /*-----------------------------------------------------------------*/
5134 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5136 // ugly but optimized by peephole
5137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5139 symbol *nlbl = newiTempLabel(NULL);
5140 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5141 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5142 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5143 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5146 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5147 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5152 /*-----------------------------------------------------------------*/
5153 /* genAnd - code for and */
5154 /*-----------------------------------------------------------------*/
5155 static void genAnd (iCode *ic, iCode *ifx)
5157 operand *left, *right, *result;
5159 unsigned long lit = 0L;
5164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5165 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5166 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5167 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5169 resolveIfx(&rIfx,ifx);
5171 /* if left is a literal & right is not then exchange them */
5172 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5173 AOP_NEEDSACC(left)) {
5174 operand *tmp = right ;
5179 /* if result = right then exchange them */
5180 if(pic14_sameRegs(AOP(result),AOP(right))){
5181 operand *tmp = right ;
5186 /* if right is bit then exchange them */
5187 if (AOP_TYPE(right) == AOP_CRY &&
5188 AOP_TYPE(left) != AOP_CRY){
5189 operand *tmp = right ;
5193 if(AOP_TYPE(right) == AOP_LIT)
5194 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5196 size = AOP_SIZE(result);
5198 DEBUGpic14_AopType(__LINE__,left,right,result);
5201 // result = bit & yy;
5202 if (AOP_TYPE(left) == AOP_CRY){
5203 // c = bit & literal;
5204 if(AOP_TYPE(right) == AOP_LIT){
5206 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5209 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5212 if(size && (AOP_TYPE(result) == AOP_CRY)){
5213 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5216 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5220 pic14_emitcode("clr","c");
5223 if (AOP_TYPE(right) == AOP_CRY){
5225 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5226 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5229 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5231 pic14_emitcode("rrc","a");
5232 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5238 pic14_outBitC(result);
5240 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5241 genIfxJump(ifx, "c");
5245 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5246 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5247 if((AOP_TYPE(right) == AOP_LIT) &&
5248 (AOP_TYPE(result) == AOP_CRY) &&
5249 (AOP_TYPE(left) != AOP_CRY)){
5250 int posbit = isLiteralBit(lit);
5254 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5257 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5262 while (posbit > 7) {
5266 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5267 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5268 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5275 symbol *tlbl = newiTempLabel(NULL);
5276 int sizel = AOP_SIZE(left);
5278 pic14_emitcode("setb","c");
5280 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5281 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5283 if((posbit = isLiteralBit(bytelit)) != 0)
5284 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5286 if(bytelit != 0x0FFL)
5287 pic14_emitcode("anl","a,%s",
5288 aopGet(AOP(right),offset,FALSE,TRUE));
5289 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5294 // bit = left & literal
5296 pic14_emitcode("clr","c");
5297 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5299 // if(left & literal)
5302 jmpTrueOrFalse(ifx, tlbl);
5306 pic14_outBitC(result);
5310 /* if left is same as result */
5311 if(pic14_sameRegs(AOP(result),AOP(left))){
5313 for(;size--; offset++,lit>>=8) {
5314 if(AOP_TYPE(right) == AOP_LIT){
5315 switch(lit & 0xff) {
5317 /* and'ing with 0 has clears the result */
5318 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5321 /* and'ing with 0xff is a nop when the result and left are the same */
5326 int p = my_powof2( (~lit) & 0xff );
5328 /* only one bit is set in the literal, so use a bcf instruction */
5329 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5332 if(know_W != (int)(lit&0xff))
5333 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5335 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5340 if (AOP_TYPE(left) == AOP_ACC) {
5341 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5343 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5344 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5351 // left & result in different registers
5352 if(AOP_TYPE(result) == AOP_CRY){
5354 // if(size), result in bit
5355 // if(!size && ifx), conditional oper: if(left & right)
5356 symbol *tlbl = newiTempLabel(NULL);
5357 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5359 pic14_emitcode("setb","c");
5361 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5362 pic14_emitcode("anl","a,%s",
5363 aopGet(AOP(left),offset,FALSE,FALSE));
5364 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5369 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5370 pic14_outBitC(result);
5372 jmpTrueOrFalse(ifx, tlbl);
5374 for(;(size--);offset++) {
5376 // result = left & right
5377 if(AOP_TYPE(right) == AOP_LIT){
5378 int t = (lit >> (offset*8)) & 0x0FFL;
5381 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5384 if(AOP_TYPE(left) != AOP_ACC) {
5385 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5387 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5390 if(AOP_TYPE(left) == AOP_ACC) {
5391 emitpcode(POC_ANDLW, popGetLit(t));
5393 emitpcode(POC_MOVLW, popGetLit(t));
5394 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5396 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5401 if (AOP_TYPE(left) == AOP_ACC) {
5402 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5404 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5405 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5407 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5413 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5414 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5415 freeAsmop(result,NULL,ic,TRUE);
5418 /*-----------------------------------------------------------------*/
5419 /* genOr - code for or */
5420 /*-----------------------------------------------------------------*/
5421 static void genOr (iCode *ic, iCode *ifx)
5423 operand *left, *right, *result;
5425 unsigned long lit = 0L;
5427 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5429 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5430 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5431 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5433 DEBUGpic14_AopType(__LINE__,left,right,result);
5435 /* if left is a literal & right is not then exchange them */
5436 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5437 AOP_NEEDSACC(left)) {
5438 operand *tmp = right ;
5443 /* if result = right then exchange them */
5444 if(pic14_sameRegs(AOP(result),AOP(right))){
5445 operand *tmp = right ;
5450 /* if right is bit then exchange them */
5451 if (AOP_TYPE(right) == AOP_CRY &&
5452 AOP_TYPE(left) != AOP_CRY){
5453 operand *tmp = right ;
5458 DEBUGpic14_AopType(__LINE__,left,right,result);
5460 if(AOP_TYPE(right) == AOP_LIT)
5461 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5463 size = AOP_SIZE(result);
5467 if (AOP_TYPE(left) == AOP_CRY){
5468 if(AOP_TYPE(right) == AOP_LIT){
5469 // c = bit & literal;
5471 // lit != 0 => result = 1
5472 if(AOP_TYPE(result) == AOP_CRY){
5474 emitpcode(POC_BSF, popGet(AOP(result),0));
5475 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5476 // AOP(result)->aopu.aop_dir,
5477 // AOP(result)->aopu.aop_dir);
5479 continueIfTrue(ifx);
5483 // lit == 0 => result = left
5484 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5486 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5489 if (AOP_TYPE(right) == AOP_CRY){
5490 if(pic14_sameRegs(AOP(result),AOP(left))){
5492 emitpcode(POC_BCF, popGet(AOP(result),0));
5493 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5494 emitpcode(POC_BSF, popGet(AOP(result),0));
5496 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5497 AOP(result)->aopu.aop_dir,
5498 AOP(result)->aopu.aop_dir);
5499 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5500 AOP(right)->aopu.aop_dir,
5501 AOP(right)->aopu.aop_dir);
5502 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5503 AOP(result)->aopu.aop_dir,
5504 AOP(result)->aopu.aop_dir);
5506 if( AOP_TYPE(result) == AOP_ACC) {
5507 emitpcode(POC_MOVLW, popGetLit(0));
5508 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5509 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5510 emitpcode(POC_MOVLW, popGetLit(1));
5514 emitpcode(POC_BCF, popGet(AOP(result),0));
5515 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5516 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5517 emitpcode(POC_BSF, popGet(AOP(result),0));
5519 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5520 AOP(result)->aopu.aop_dir,
5521 AOP(result)->aopu.aop_dir);
5522 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5523 AOP(right)->aopu.aop_dir,
5524 AOP(right)->aopu.aop_dir);
5525 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5526 AOP(left)->aopu.aop_dir,
5527 AOP(left)->aopu.aop_dir);
5528 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5529 AOP(result)->aopu.aop_dir,
5530 AOP(result)->aopu.aop_dir);
5535 symbol *tlbl = newiTempLabel(NULL);
5536 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5539 emitpcode(POC_BCF, popGet(AOP(result),0));
5540 if( AOP_TYPE(right) == AOP_ACC) {
5541 emitpcode(POC_IORLW, popGetLit(0));
5543 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5544 emitpcode(POC_BSF, popGet(AOP(result),0));
5549 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5550 pic14_emitcode(";XXX setb","c");
5551 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5552 AOP(left)->aopu.aop_dir,tlbl->key+100);
5553 pic14_toBoolean(right);
5554 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5555 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5556 jmpTrueOrFalse(ifx, tlbl);
5560 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5567 pic14_outBitC(result);
5569 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5570 genIfxJump(ifx, "c");
5574 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5575 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5576 if((AOP_TYPE(right) == AOP_LIT) &&
5577 (AOP_TYPE(result) == AOP_CRY) &&
5578 (AOP_TYPE(left) != AOP_CRY)){
5580 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5583 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5585 continueIfTrue(ifx);
5588 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5589 // lit = 0, result = boolean(left)
5591 pic14_emitcode(";XXX setb","c");
5592 pic14_toBoolean(right);
5594 symbol *tlbl = newiTempLabel(NULL);
5595 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5597 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5599 genIfxJump (ifx,"a");
5603 pic14_outBitC(result);
5607 /* if left is same as result */
5608 if(pic14_sameRegs(AOP(result),AOP(left))){
5610 for(;size--; offset++,lit>>=8) {
5611 if(AOP_TYPE(right) == AOP_LIT){
5612 if((lit & 0xff) == 0)
5613 /* or'ing with 0 has no effect */
5616 int p = my_powof2(lit & 0xff);
5618 /* only one bit is set in the literal, so use a bsf instruction */
5620 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5622 if(know_W != (int)(lit & 0xff))
5623 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5624 know_W = lit & 0xff;
5625 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5630 if (AOP_TYPE(left) == AOP_ACC) {
5631 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5632 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5634 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5635 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5637 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5638 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5644 // left & result in different registers
5645 if(AOP_TYPE(result) == AOP_CRY){
5647 // if(size), result in bit
5648 // if(!size && ifx), conditional oper: if(left | right)
5649 symbol *tlbl = newiTempLabel(NULL);
5650 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5651 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5655 pic14_emitcode(";XXX setb","c");
5657 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5658 pic14_emitcode(";XXX orl","a,%s",
5659 aopGet(AOP(left),offset,FALSE,FALSE));
5660 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5665 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5666 pic14_outBitC(result);
5668 jmpTrueOrFalse(ifx, tlbl);
5669 } else for(;(size--);offset++){
5671 // result = left & right
5672 if(AOP_TYPE(right) == AOP_LIT){
5673 int t = (lit >> (offset*8)) & 0x0FFL;
5676 if (AOP_TYPE(left) != AOP_ACC) {
5677 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5679 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5683 if (AOP_TYPE(left) == AOP_ACC) {
5684 emitpcode(POC_IORLW, popGetLit(t));
5686 emitpcode(POC_MOVLW, popGetLit(t));
5687 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5689 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5694 // faster than result <- left, anl result,right
5695 // and better if result is SFR
5696 if (AOP_TYPE(left) == AOP_ACC) {
5697 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5698 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5700 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5701 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5703 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5704 pic14_emitcode("iorwf","%s,w",
5705 aopGet(AOP(left),offset,FALSE,FALSE));
5707 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5708 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5713 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5714 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5715 freeAsmop(result,NULL,ic,TRUE);
5718 /*-----------------------------------------------------------------*/
5719 /* genXor - code for xclusive or */
5720 /*-----------------------------------------------------------------*/
5721 static void genXor (iCode *ic, iCode *ifx)
5723 operand *left, *right, *result;
5725 unsigned long lit = 0L;
5727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5729 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5730 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5731 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5733 /* if left is a literal & right is not ||
5734 if left needs acc & right does not */
5735 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5736 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5737 operand *tmp = right ;
5742 /* if result = right then exchange them */
5743 if(pic14_sameRegs(AOP(result),AOP(right))){
5744 operand *tmp = right ;
5749 /* if right is bit then exchange them */
5750 if (AOP_TYPE(right) == AOP_CRY &&
5751 AOP_TYPE(left) != AOP_CRY){
5752 operand *tmp = right ;
5756 if(AOP_TYPE(right) == AOP_LIT)
5757 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5759 size = AOP_SIZE(result);
5763 if (AOP_TYPE(left) == AOP_CRY){
5764 if(AOP_TYPE(right) == AOP_LIT){
5765 // c = bit & literal;
5767 // lit>>1 != 0 => result = 1
5768 if(AOP_TYPE(result) == AOP_CRY){
5770 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5771 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5773 continueIfTrue(ifx);
5776 pic14_emitcode("setb","c");
5780 // lit == 0, result = left
5781 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5783 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5785 // lit == 1, result = not(left)
5786 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5787 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5788 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5789 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5792 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5793 pic14_emitcode("cpl","c");
5800 symbol *tlbl = newiTempLabel(NULL);
5801 if (AOP_TYPE(right) == AOP_CRY){
5803 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5806 int sizer = AOP_SIZE(right);
5808 // if val>>1 != 0, result = 1
5809 pic14_emitcode("setb","c");
5811 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5813 // test the msb of the lsb
5814 pic14_emitcode("anl","a,#0xfe");
5815 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5819 pic14_emitcode("rrc","a");
5821 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5822 pic14_emitcode("cpl","c");
5823 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5828 pic14_outBitC(result);
5830 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5831 genIfxJump(ifx, "c");
5835 if(pic14_sameRegs(AOP(result),AOP(left))){
5836 /* if left is same as result */
5837 for(;size--; offset++) {
5838 if(AOP_TYPE(right) == AOP_LIT){
5839 int t = (lit >> (offset*8)) & 0x0FFL;
5843 if (IS_AOP_PREG(left)) {
5844 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5845 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5846 aopPut(AOP(result),"a",offset);
5848 emitpcode(POC_MOVLW, popGetLit(t));
5849 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5850 pic14_emitcode("xrl","%s,%s",
5851 aopGet(AOP(left),offset,FALSE,TRUE),
5852 aopGet(AOP(right),offset,FALSE,FALSE));
5855 if (AOP_TYPE(left) == AOP_ACC)
5856 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5858 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5859 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5861 if (IS_AOP_PREG(left)) {
5862 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5863 aopPut(AOP(result),"a",offset);
5865 pic14_emitcode("xrl","%s,a",
5866 aopGet(AOP(left),offset,FALSE,TRUE));
5872 // left & result in different registers
5873 if(AOP_TYPE(result) == AOP_CRY){
5875 // if(size), result in bit
5876 // if(!size && ifx), conditional oper: if(left ^ right)
5877 symbol *tlbl = newiTempLabel(NULL);
5878 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5880 pic14_emitcode("setb","c");
5882 if((AOP_TYPE(right) == AOP_LIT) &&
5883 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5884 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5886 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5887 pic14_emitcode("xrl","a,%s",
5888 aopGet(AOP(left),offset,FALSE,FALSE));
5890 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5895 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5896 pic14_outBitC(result);
5898 jmpTrueOrFalse(ifx, tlbl);
5899 } else for(;(size--);offset++){
5901 // result = left & right
5902 if(AOP_TYPE(right) == AOP_LIT){
5903 int t = (lit >> (offset*8)) & 0x0FFL;
5906 if (AOP_TYPE(left) != AOP_ACC) {
5907 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5909 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5910 pic14_emitcode("movf","%s,w",
5911 aopGet(AOP(left),offset,FALSE,FALSE));
5912 pic14_emitcode("movwf","%s",
5913 aopGet(AOP(result),offset,FALSE,FALSE));
5916 if (AOP_TYPE(left) == AOP_ACC) {
5917 emitpcode(POC_XORLW, popGetLit(t));
5919 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5921 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5924 if (AOP_TYPE(left) == AOP_ACC) {
5925 emitpcode(POC_XORLW, popGetLit(t));
5927 emitpcode(POC_MOVLW, popGetLit(t));
5928 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5930 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5931 pic14_emitcode("movlw","0x%x",t);
5932 pic14_emitcode("xorwf","%s,w",
5933 aopGet(AOP(left),offset,FALSE,FALSE));
5934 pic14_emitcode("movwf","%s",
5935 aopGet(AOP(result),offset,FALSE,FALSE));
5941 // faster than result <- left, anl result,right
5942 // and better if result is SFR
5943 if (AOP_TYPE(left) == AOP_ACC) {
5944 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5945 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5947 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5948 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5949 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5950 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5952 if ( AOP_TYPE(result) != AOP_ACC){
5953 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5954 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5960 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5961 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5962 freeAsmop(result,NULL,ic,TRUE);
5965 /*-----------------------------------------------------------------*/
5966 /* genInline - write the inline code out */
5967 /*-----------------------------------------------------------------*/
5968 static void genInline (iCode *ic)
5970 char *buffer, *bp, *bp1;
5972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5974 _G.inLine += (!options.asmpeep);
5976 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5977 strcpy(buffer,IC_INLINE(ic));
5979 /* emit each line as a code */
5985 addpCode2pBlock(pb,AssembleLine(bp1));
5992 pic14_emitcode(bp1,"");
5998 if ((bp1 != bp) && *bp1)
5999 addpCode2pBlock(pb,AssembleLine(bp1));
6003 _G.inLine -= (!options.asmpeep);
6006 /*-----------------------------------------------------------------*/
6007 /* genRRC - rotate right with carry */
6008 /*-----------------------------------------------------------------*/
6009 static void genRRC (iCode *ic)
6011 operand *left , *result ;
6012 int size, offset = 0, same;
6014 /* rotate right with carry */
6016 result=IC_RESULT(ic);
6017 aopOp (left,ic,FALSE);
6018 aopOp (result,ic,FALSE);
6020 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6022 same = pic14_sameRegs(AOP(result),AOP(left));
6024 size = AOP_SIZE(result);
6026 /* get the lsb and put it into the carry */
6027 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6034 emitpcode(POC_RRF, popGet(AOP(left),offset));
6036 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6037 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6043 freeAsmop(left,NULL,ic,TRUE);
6044 freeAsmop(result,NULL,ic,TRUE);
6047 /*-----------------------------------------------------------------*/
6048 /* genRLC - generate code for rotate left with carry */
6049 /*-----------------------------------------------------------------*/
6050 static void genRLC (iCode *ic)
6052 operand *left , *result ;
6053 int size, offset = 0;
6056 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6057 /* rotate right with carry */
6059 result=IC_RESULT(ic);
6060 aopOp (left,ic,FALSE);
6061 aopOp (result,ic,FALSE);
6063 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6065 same = pic14_sameRegs(AOP(result),AOP(left));
6067 /* move it to the result */
6068 size = AOP_SIZE(result);
6070 /* get the msb and put it into the carry */
6071 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6078 emitpcode(POC_RLF, popGet(AOP(left),offset));
6080 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6081 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6088 freeAsmop(left,NULL,ic,TRUE);
6089 freeAsmop(result,NULL,ic,TRUE);
6092 /*-----------------------------------------------------------------*/
6093 /* genGetHbit - generates code get highest order bit */
6094 /*-----------------------------------------------------------------*/
6095 static void genGetHbit (iCode *ic)
6097 operand *left, *result;
6099 result=IC_RESULT(ic);
6100 aopOp (left,ic,FALSE);
6101 aopOp (result,ic,FALSE);
6103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6104 /* get the highest order byte into a */
6105 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6106 if(AOP_TYPE(result) == AOP_CRY){
6107 pic14_emitcode("rlc","a");
6108 pic14_outBitC(result);
6111 pic14_emitcode("rl","a");
6112 pic14_emitcode("anl","a,#0x01");
6113 pic14_outAcc(result);
6117 freeAsmop(left,NULL,ic,TRUE);
6118 freeAsmop(result,NULL,ic,TRUE);
6121 /*-----------------------------------------------------------------*/
6122 /* AccRol - rotate left accumulator by known count */
6123 /*-----------------------------------------------------------------*/
6124 static void AccRol (operand *op,int offset,int shCount)
6126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6127 shCount &= 0x0007; // shCount : 0..7
6132 pic14_emitcode("rl","a");
6133 emitpcode(POC_RLF,popGet(AOP(op),offset));
6136 pic14_emitcode("rl","a");
6137 pic14_emitcode("rl","a");
6138 emitpcode(POC_RLF,popGet(AOP(op),offset));
6139 emitpcode(POC_RLF,popGet(AOP(op),offset));
6142 pic14_emitcode("swap","a");
6143 pic14_emitcode("rr","a");
6144 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6145 emitpcode(POC_RRF,popGet(AOP(op),offset));
6148 pic14_emitcode("swap","a");
6149 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6152 pic14_emitcode("swap","a");
6153 pic14_emitcode("rl","a");
6154 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6155 emitpcode(POC_RLF,popGet(AOP(op),offset));
6158 pic14_emitcode("rr","a");
6159 pic14_emitcode("rr","a");
6160 emitpcode(POC_RRF,popGet(AOP(op),offset));
6161 emitpcode(POC_RRF,popGet(AOP(op),offset));
6164 pic14_emitcode("rr","a");
6165 emitpcode(POC_RRF,popGet(AOP(op),offset));
6170 /*-----------------------------------------------------------------*/
6171 /* AccLsh - left shift accumulator by known count */
6172 /*-----------------------------------------------------------------*/
6173 static void AccLsh (operand *op,int offset,int shCount)
6175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6179 pic14_emitcode("add","a,acc");
6181 emitpcode(POC_RLF,popGet(AOP(op),offset));
6184 pic14_emitcode("add","a,acc");
6186 emitpcode(POC_RLF,popGet(AOP(op),offset));
6187 pic14_emitcode("add","a,acc");
6189 emitpcode(POC_RLF,popGet(AOP(op),offset));
6194 /* rotate left accumulator */
6195 AccRol(op,offset,shCount);
6196 /* and kill the lower order bits */
6197 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6198 emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
6204 /*-----------------------------------------------------------------*/
6205 /* AccRsh - right shift accumulator by known count */
6206 /*-----------------------------------------------------------------*/
6207 static void AccRsh (operand *op,int offset,int shCount)
6209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6213 pic14_emitcode("rrc","a");
6215 /* rotate right accumulator */
6216 AccRol(op,offset,8 - shCount);
6217 /* and kill the higher order bits */
6218 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6224 /*-----------------------------------------------------------------*/
6225 /* AccSRsh - signed right shift accumulator by known count */
6226 /*-----------------------------------------------------------------*/
6227 static void AccSRsh (int shCount)
6230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6233 pic14_emitcode("mov","c,acc.7");
6234 pic14_emitcode("rrc","a");
6235 } else if(shCount == 2){
6236 pic14_emitcode("mov","c,acc.7");
6237 pic14_emitcode("rrc","a");
6238 pic14_emitcode("mov","c,acc.7");
6239 pic14_emitcode("rrc","a");
6241 tlbl = newiTempLabel(NULL);
6242 /* rotate right accumulator */
6243 AccRol(8 - shCount);
6244 /* and kill the higher order bits */
6245 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6246 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6247 pic14_emitcode("orl","a,#0x%02x",
6248 (unsigned char)~SRMask[shCount]);
6249 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6254 /*-----------------------------------------------------------------*/
6255 /* shiftR1Left2Result - shift right one byte from left to result */
6256 /*-----------------------------------------------------------------*/
6257 static void shiftR1Left2ResultSigned (operand *left, int offl,
6258 operand *result, int offr,
6263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6265 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6269 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6271 emitpcode(POC_RRF, popGet(AOP(result),offr));
6273 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6274 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6280 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6282 emitpcode(POC_RRF, popGet(AOP(result),offr));
6284 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6285 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6287 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6288 emitpcode(POC_RRF, popGet(AOP(result),offr));
6294 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6296 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6297 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6300 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6301 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6302 emitpcode(POC_ANDLW, popGetLit(0x1f));
6304 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6305 emitpcode(POC_IORLW, popGetLit(0xe0));
6307 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6311 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6312 emitpcode(POC_ANDLW, popGetLit(0x0f));
6313 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6314 emitpcode(POC_IORLW, popGetLit(0xf0));
6315 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6319 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6321 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6322 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6324 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6325 emitpcode(POC_ANDLW, popGetLit(0x07));
6326 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6327 emitpcode(POC_IORLW, popGetLit(0xf8));
6328 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6333 emitpcode(POC_MOVLW, popGetLit(0x00));
6334 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6335 emitpcode(POC_MOVLW, popGetLit(0xfe));
6336 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6337 emitpcode(POC_IORLW, popGetLit(0x01));
6338 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6340 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6341 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6342 emitpcode(POC_DECF, popGet(AOP(result),offr));
6343 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6344 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6350 emitpcode(POC_MOVLW, popGetLit(0x00));
6351 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6352 emitpcode(POC_MOVLW, popGetLit(0xff));
6353 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6355 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6356 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6357 emitpcode(POC_DECF, popGet(AOP(result),offr));
6365 /*-----------------------------------------------------------------*/
6366 /* shiftR1Left2Result - shift right one byte from left to result */
6367 /*-----------------------------------------------------------------*/
6368 static void shiftR1Left2Result (operand *left, int offl,
6369 operand *result, int offr,
6370 int shCount, int sign)
6374 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6376 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6378 /* Copy the msb into the carry if signed. */
6380 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6390 emitpcode(POC_RRF, popGet(AOP(result),offr));
6392 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6393 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6399 emitpcode(POC_RRF, popGet(AOP(result),offr));
6401 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6402 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6405 emitpcode(POC_RRF, popGet(AOP(result),offr));
6410 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6412 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6413 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6417 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6418 emitpcode(POC_ANDLW, popGetLit(0x1f));
6419 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6424 emitpcode(POC_ANDLW, popGetLit(0x0f));
6425 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6429 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6430 emitpcode(POC_ANDLW, popGetLit(0x0f));
6431 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6433 emitpcode(POC_RRF, popGet(AOP(result),offr));
6438 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6439 emitpcode(POC_ANDLW, popGetLit(0x80));
6440 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6441 emitpcode(POC_RLF, popGet(AOP(result),offr));
6442 emitpcode(POC_RLF, popGet(AOP(result),offr));
6447 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6448 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6449 emitpcode(POC_RLF, popGet(AOP(result),offr));
6458 /*-----------------------------------------------------------------*/
6459 /* shiftL1Left2Result - shift left one byte from left to result */
6460 /*-----------------------------------------------------------------*/
6461 static void shiftL1Left2Result (operand *left, int offl,
6462 operand *result, int offr, int shCount)
6467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6469 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6470 DEBUGpic14_emitcode ("; ***","same = %d",same);
6471 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6473 /* shift left accumulator */
6474 //AccLsh(shCount); // don't comment out just yet...
6475 // aopPut(AOP(result),"a",offr);
6479 /* Shift left 1 bit position */
6480 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6482 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6484 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6485 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6489 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6490 emitpcode(POC_ANDLW,popGetLit(0x7e));
6491 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6492 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6495 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6496 emitpcode(POC_ANDLW,popGetLit(0x3e));
6497 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6498 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6499 emitpcode(POC_RLF, popGet(AOP(result),offr));
6502 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6503 emitpcode(POC_ANDLW, popGetLit(0xf0));
6504 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6507 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6508 emitpcode(POC_ANDLW, popGetLit(0xf0));
6509 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6510 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6513 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6514 emitpcode(POC_ANDLW, popGetLit(0x30));
6515 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6516 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6517 emitpcode(POC_RLF, popGet(AOP(result),offr));
6520 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6521 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6522 emitpcode(POC_RRF, popGet(AOP(result),offr));
6526 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6531 /*-----------------------------------------------------------------*/
6532 /* movLeft2Result - move byte from left to result */
6533 /*-----------------------------------------------------------------*/
6534 static void movLeft2Result (operand *left, int offl,
6535 operand *result, int offr)
6538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6539 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6540 l = aopGet(AOP(left),offl,FALSE,FALSE);
6542 if (*l == '@' && (IS_AOP_PREG(result))) {
6543 pic14_emitcode("mov","a,%s",l);
6544 aopPut(AOP(result),"a",offr);
6546 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6547 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6552 /*-----------------------------------------------------------------*/
6553 /* shiftL2Left2Result - shift left two bytes from left to result */
6554 /*-----------------------------------------------------------------*/
6555 static void shiftL2Left2Result (operand *left, int offl,
6556 operand *result, int offr, int shCount)
6560 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6562 if(pic14_sameRegs(AOP(result), AOP(left))) {
6570 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6571 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6572 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6576 emitpcode(POC_RLF, popGet(AOP(result),offr));
6577 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_MOVLW, popGetLit(0x0f));
6584 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6585 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6586 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6587 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6588 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6589 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6591 emitpcode(POC_RLF, popGet(AOP(result),offr));
6592 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6596 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6597 emitpcode(POC_RRF, popGet(AOP(result),offr));
6598 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6599 emitpcode(POC_RRF, popGet(AOP(result),offr));
6600 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_ANDLW,popGetLit(0xc0));
6602 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6603 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6604 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6605 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6609 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6610 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6611 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6612 emitpcode(POC_RRF, popGet(AOP(result),offr));
6622 /* note, use a mov/add for the shift since the mov has a
6623 chance of getting optimized out */
6624 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6625 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6626 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6627 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6628 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6632 emitpcode(POC_RLF, popGet(AOP(result),offr));
6633 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6639 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6640 emitpcode(POC_ANDLW, popGetLit(0xF0));
6641 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6642 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6643 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6644 emitpcode(POC_ANDLW, popGetLit(0xF0));
6645 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6646 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6650 emitpcode(POC_RLF, popGet(AOP(result),offr));
6651 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6655 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6656 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6657 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6658 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6660 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6661 emitpcode(POC_RRF, popGet(AOP(result),offr));
6662 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6663 emitpcode(POC_ANDLW,popGetLit(0xc0));
6664 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6665 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6666 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6667 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6671 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6672 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6673 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6674 emitpcode(POC_RRF, popGet(AOP(result),offr));
6679 /*-----------------------------------------------------------------*/
6680 /* shiftR2Left2Result - shift right two bytes from left to result */
6681 /*-----------------------------------------------------------------*/
6682 static void shiftR2Left2Result (operand *left, int offl,
6683 operand *result, int offr,
6684 int shCount, int sign)
6688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6689 same = pic14_sameRegs(AOP(result), AOP(left));
6691 if(same && ((offl + MSB16) == offr)){
6693 /* don't crash result[offr] */
6694 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6695 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6698 movLeft2Result(left,offl, result, offr);
6699 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6702 /* a:x >> shCount (x = lsb(result))*/
6705 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6707 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6716 emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6721 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6722 emitpcode(POC_RRF,popGet(AOP(result),offr));
6724 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6725 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6726 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6727 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6732 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRF,popGet(AOP(result),offr));
6743 emitpcode(POC_MOVLW, popGetLit(0xf0));
6744 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6745 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6747 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6748 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6749 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6752 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6753 emitpcode(POC_ANDLW, popGetLit(0x0f));
6754 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6756 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6757 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_ANDLW, popGetLit(0xf0));
6759 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6760 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6764 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6765 emitpcode(POC_RRF, popGet(AOP(result),offr));
6769 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6770 emitpcode(POC_BTFSC,
6771 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6772 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6780 emitpcode(POC_RLF, popGet(AOP(result),offr));
6781 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6783 emitpcode(POC_RLF, popGet(AOP(result),offr));
6784 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6785 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6786 emitpcode(POC_ANDLW,popGetLit(0x03));
6788 emitpcode(POC_BTFSC,
6789 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6790 emitpcode(POC_IORLW,popGetLit(0xfc));
6792 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6793 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6797 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6798 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6799 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6800 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6801 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_RLF, popGet(AOP(result),offr));
6803 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6804 emitpcode(POC_ANDLW,popGetLit(0x03));
6806 emitpcode(POC_BTFSC,
6807 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6808 emitpcode(POC_IORLW,popGetLit(0xfc));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6811 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6818 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6819 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6820 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6821 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6824 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6826 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6831 /*-----------------------------------------------------------------*/
6832 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6833 /*-----------------------------------------------------------------*/
6834 static void shiftLLeftOrResult (operand *left, int offl,
6835 operand *result, int offr, int shCount)
6837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6838 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6839 /* shift left accumulator */
6840 AccLsh(left,offl,shCount);
6841 /* or with result */
6842 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6843 /* back to result */
6844 aopPut(AOP(result),"a",offr);
6847 /*-----------------------------------------------------------------*/
6848 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6849 /*-----------------------------------------------------------------*/
6850 static void shiftRLeftOrResult (operand *left, int offl,
6851 operand *result, int offr, int shCount)
6853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6854 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6855 /* shift right accumulator */
6856 AccRsh(left,offl,shCount);
6857 /* or with result */
6858 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6859 /* back to result */
6860 aopPut(AOP(result),"a",offr);
6863 /*-----------------------------------------------------------------*/
6864 /* genlshOne - left shift a one byte quantity by known count */
6865 /*-----------------------------------------------------------------*/
6866 static void genlshOne (operand *result, operand *left, int shCount)
6868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6869 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6872 /*-----------------------------------------------------------------*/
6873 /* genlshTwo - left shift two bytes by known amount != 0 */
6874 /*-----------------------------------------------------------------*/
6875 static void genlshTwo (operand *result,operand *left, int shCount)
6879 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6880 size = pic14_getDataSize(result);
6882 /* if shCount >= 8 */
6888 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6890 movLeft2Result(left, LSB, result, MSB16);
6892 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6895 /* 1 <= shCount <= 7 */
6898 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6900 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6904 /*-----------------------------------------------------------------*/
6905 /* shiftLLong - shift left one long from left to result */
6906 /* offl = LSB or MSB16 */
6907 /*-----------------------------------------------------------------*/
6908 static void shiftLLong (operand *left, operand *result, int offr )
6911 int size = AOP_SIZE(result);
6913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6914 if(size >= LSB+offr){
6915 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6917 pic14_emitcode("add","a,acc");
6918 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6919 size >= MSB16+offr && offr != LSB )
6920 pic14_emitcode("xch","a,%s",
6921 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6923 aopPut(AOP(result),"a",LSB+offr);
6926 if(size >= MSB16+offr){
6927 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6928 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6931 pic14_emitcode("rlc","a");
6932 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6933 size >= MSB24+offr && offr != LSB)
6934 pic14_emitcode("xch","a,%s",
6935 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6937 aopPut(AOP(result),"a",MSB16+offr);
6940 if(size >= MSB24+offr){
6941 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6942 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6945 pic14_emitcode("rlc","a");
6946 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6947 size >= MSB32+offr && offr != LSB )
6948 pic14_emitcode("xch","a,%s",
6949 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6951 aopPut(AOP(result),"a",MSB24+offr);
6954 if(size > MSB32+offr){
6955 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6956 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6959 pic14_emitcode("rlc","a");
6960 aopPut(AOP(result),"a",MSB32+offr);
6963 aopPut(AOP(result),zero,LSB);
6966 /*-----------------------------------------------------------------*/
6967 /* genlshFour - shift four byte by a known amount != 0 */
6968 /*-----------------------------------------------------------------*/
6969 static void genlshFour (operand *result, operand *left, int shCount)
6973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6974 size = AOP_SIZE(result);
6976 /* if shifting more that 3 bytes */
6977 if (shCount >= 24 ) {
6980 /* lowest order of left goes to the highest
6981 order of the destination */
6982 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6984 movLeft2Result(left, LSB, result, MSB32);
6985 aopPut(AOP(result),zero,LSB);
6986 aopPut(AOP(result),zero,MSB16);
6987 aopPut(AOP(result),zero,MSB32);
6991 /* more than two bytes */
6992 else if ( shCount >= 16 ) {
6993 /* lower order two bytes goes to higher order two bytes */
6995 /* if some more remaining */
6997 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6999 movLeft2Result(left, MSB16, result, MSB32);
7000 movLeft2Result(left, LSB, result, MSB24);
7002 aopPut(AOP(result),zero,MSB16);
7003 aopPut(AOP(result),zero,LSB);
7007 /* if more than 1 byte */
7008 else if ( shCount >= 8 ) {
7009 /* lower order three bytes goes to higher order three bytes */
7013 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7015 movLeft2Result(left, LSB, result, MSB16);
7017 else{ /* size = 4 */
7019 movLeft2Result(left, MSB24, result, MSB32);
7020 movLeft2Result(left, MSB16, result, MSB24);
7021 movLeft2Result(left, LSB, result, MSB16);
7022 aopPut(AOP(result),zero,LSB);
7024 else if(shCount == 1)
7025 shiftLLong(left, result, MSB16);
7027 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7028 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7029 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7030 aopPut(AOP(result),zero,LSB);
7035 /* 1 <= shCount <= 7 */
7036 else if(shCount <= 2){
7037 shiftLLong(left, result, LSB);
7039 shiftLLong(result, result, LSB);
7041 /* 3 <= shCount <= 7, optimize */
7043 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7044 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7045 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7049 /*-----------------------------------------------------------------*/
7050 /* genLeftShiftLiteral - left shifting by known count */
7051 /*-----------------------------------------------------------------*/
7052 static void genLeftShiftLiteral (operand *left,
7057 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7061 freeAsmop(right,NULL,ic,TRUE);
7063 aopOp(left,ic,FALSE);
7064 aopOp(result,ic,FALSE);
7066 size = getSize(operandType(result));
7069 pic14_emitcode("; shift left ","result %d, left %d",size,
7073 /* I suppose that the left size >= result size */
7076 movLeft2Result(left, size, result, size);
7080 else if(shCount >= (size * 8))
7082 aopPut(AOP(result),zero,size);
7086 genlshOne (result,left,shCount);
7091 genlshTwo (result,left,shCount);
7095 genlshFour (result,left,shCount);
7099 freeAsmop(left,NULL,ic,TRUE);
7100 freeAsmop(result,NULL,ic,TRUE);
7103 /*-----------------------------------------------------------------*
7104 * genMultiAsm - repeat assembly instruction for size of register.
7105 * if endian == 1, then the high byte (i.e base address + size of
7106 * register) is used first else the low byte is used first;
7107 *-----------------------------------------------------------------*/
7108 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7126 emitpcode(poc, popGet(AOP(reg),offset));
7131 /*-----------------------------------------------------------------*/
7132 /* genLeftShift - generates code for left shifting */
7133 /*-----------------------------------------------------------------*/
7134 static void genLeftShift (iCode *ic)
7136 operand *left,*right, *result;
7139 symbol *tlbl , *tlbl1;
7142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7144 right = IC_RIGHT(ic);
7146 result = IC_RESULT(ic);
7148 aopOp(right,ic,FALSE);
7150 /* if the shift count is known then do it
7151 as efficiently as possible */
7152 if (AOP_TYPE(right) == AOP_LIT) {
7153 genLeftShiftLiteral (left,right,result,ic);
7157 /* shift count is unknown then we have to form
7158 a loop get the loop count in B : Note: we take
7159 only the lower order byte since shifting
7160 more that 32 bits make no sense anyway, ( the
7161 largest size of an object can be only 32 bits ) */
7164 aopOp(left,ic,FALSE);
7165 aopOp(result,ic,FALSE);
7167 /* now move the left to the result if they are not the
7169 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7170 AOP_SIZE(result) > 1) {
7172 size = AOP_SIZE(result);
7175 l = aopGet(AOP(left),offset,FALSE,TRUE);
7176 if (*l == '@' && (IS_AOP_PREG(result))) {
7178 pic14_emitcode("mov","a,%s",l);
7179 aopPut(AOP(result),"a",offset);
7181 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7182 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7183 //aopPut(AOP(result),l,offset);
7189 size = AOP_SIZE(result);
7191 /* if it is only one byte then */
7193 if(optimized_for_speed) {
7194 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7195 emitpcode(POC_ANDLW, popGetLit(0xf0));
7196 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7197 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7198 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7199 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7200 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7201 emitpcode(POC_RLFW, popGet(AOP(result),0));
7202 emitpcode(POC_ANDLW, popGetLit(0xfe));
7203 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7204 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7205 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7208 tlbl = newiTempLabel(NULL);
7209 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7210 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7211 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7214 emitpcode(POC_COMFW, popGet(AOP(right),0));
7215 emitpcode(POC_RRF, popGet(AOP(result),0));
7216 emitpLabel(tlbl->key);
7217 emitpcode(POC_RLF, popGet(AOP(result),0));
7218 emitpcode(POC_ADDLW, popGetLit(1));
7220 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7225 if (pic14_sameRegs(AOP(left),AOP(result))) {
7227 tlbl = newiTempLabel(NULL);
7228 emitpcode(POC_COMFW, popGet(AOP(right),0));
7229 genMultiAsm(POC_RRF, result, size,1);
7230 emitpLabel(tlbl->key);
7231 genMultiAsm(POC_RLF, result, size,0);
7232 emitpcode(POC_ADDLW, popGetLit(1));
7234 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7238 //tlbl = newiTempLabel(NULL);
7240 //tlbl1 = newiTempLabel(NULL);
7242 //reAdjustPreg(AOP(result));
7244 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7245 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7246 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7248 //pic14_emitcode("add","a,acc");
7249 //aopPut(AOP(result),"a",offset++);
7251 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7253 // pic14_emitcode("rlc","a");
7254 // aopPut(AOP(result),"a",offset++);
7256 //reAdjustPreg(AOP(result));
7258 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7259 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7262 tlbl = newiTempLabel(NULL);
7263 tlbl1= newiTempLabel(NULL);
7265 size = AOP_SIZE(result);
7268 pctemp = popGetTempReg(); /* grab a temporary working register. */
7270 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7272 /* offset should be 0, 1 or 3 */
7273 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7275 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7277 emitpcode(POC_MOVWF, pctemp);
7280 emitpLabel(tlbl->key);
7283 emitpcode(POC_RLF, popGet(AOP(result),0));
7285 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7287 emitpcode(POC_DECFSZ, pctemp);
7288 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7289 emitpLabel(tlbl1->key);
7291 popReleaseTempReg(pctemp);
7295 freeAsmop (right,NULL,ic,TRUE);
7296 freeAsmop(left,NULL,ic,TRUE);
7297 freeAsmop(result,NULL,ic,TRUE);
7300 /*-----------------------------------------------------------------*/
7301 /* genrshOne - right shift a one byte quantity by known count */
7302 /*-----------------------------------------------------------------*/
7303 static void genrshOne (operand *result, operand *left,
7304 int shCount, int sign)
7306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7307 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7310 /*-----------------------------------------------------------------*/
7311 /* genrshTwo - right shift two bytes by known amount != 0 */
7312 /*-----------------------------------------------------------------*/
7313 static void genrshTwo (operand *result,operand *left,
7314 int shCount, int sign)
7316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7317 /* if shCount >= 8 */
7321 shiftR1Left2Result(left, MSB16, result, LSB,
7324 movLeft2Result(left, MSB16, result, LSB);
7326 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7329 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7330 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7334 /* 1 <= shCount <= 7 */
7336 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7339 /*-----------------------------------------------------------------*/
7340 /* shiftRLong - shift right one long from left to result */
7341 /* offl = LSB or MSB16 */
7342 /*-----------------------------------------------------------------*/
7343 static void shiftRLong (operand *left, int offl,
7344 operand *result, int sign)
7346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7348 pic14_emitcode("clr","c");
7349 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7351 pic14_emitcode("mov","c,acc.7");
7352 pic14_emitcode("rrc","a");
7353 aopPut(AOP(result),"a",MSB32-offl);
7355 /* add sign of "a" */
7356 addSign(result, MSB32, sign);
7358 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7359 pic14_emitcode("rrc","a");
7360 aopPut(AOP(result),"a",MSB24-offl);
7362 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7363 pic14_emitcode("rrc","a");
7364 aopPut(AOP(result),"a",MSB16-offl);
7367 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7368 pic14_emitcode("rrc","a");
7369 aopPut(AOP(result),"a",LSB);
7373 /*-----------------------------------------------------------------*/
7374 /* genrshFour - shift four byte by a known amount != 0 */
7375 /*-----------------------------------------------------------------*/
7376 static void genrshFour (operand *result, operand *left,
7377 int shCount, int sign)
7379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7380 /* if shifting more that 3 bytes */
7381 if(shCount >= 24 ) {
7384 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7386 movLeft2Result(left, MSB32, result, LSB);
7388 addSign(result, MSB16, sign);
7390 else if(shCount >= 16){
7393 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7395 movLeft2Result(left, MSB24, result, LSB);
7396 movLeft2Result(left, MSB32, result, MSB16);
7398 addSign(result, MSB24, sign);
7400 else if(shCount >= 8){
7403 shiftRLong(left, MSB16, result, sign);
7404 else if(shCount == 0){
7405 movLeft2Result(left, MSB16, result, LSB);
7406 movLeft2Result(left, MSB24, result, MSB16);
7407 movLeft2Result(left, MSB32, result, MSB24);
7408 addSign(result, MSB32, sign);
7411 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7412 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7413 /* the last shift is signed */
7414 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7415 addSign(result, MSB32, sign);
7418 else{ /* 1 <= shCount <= 7 */
7420 shiftRLong(left, LSB, result, sign);
7422 shiftRLong(result, LSB, result, sign);
7425 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7426 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7427 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7432 /*-----------------------------------------------------------------*/
7433 /* genRightShiftLiteral - right shifting by known count */
7434 /*-----------------------------------------------------------------*/
7435 static void genRightShiftLiteral (operand *left,
7441 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7445 freeAsmop(right,NULL,ic,TRUE);
7447 aopOp(left,ic,FALSE);
7448 aopOp(result,ic,FALSE);
7451 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7455 lsize = pic14_getDataSize(left);
7456 res_size = pic14_getDataSize(result);
7457 /* test the LEFT size !!! */
7459 /* I suppose that the left size >= result size */
7462 movLeft2Result(left, lsize, result, res_size);
7465 else if(shCount >= (lsize * 8)){
7468 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7470 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7471 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7476 emitpcode(POC_MOVLW, popGetLit(0));
7477 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7478 emitpcode(POC_MOVLW, popGetLit(0xff));
7480 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7485 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7492 genrshOne (result,left,shCount,sign);
7496 genrshTwo (result,left,shCount,sign);
7500 genrshFour (result,left,shCount,sign);
7508 freeAsmop(left,NULL,ic,TRUE);
7509 freeAsmop(result,NULL,ic,TRUE);
7512 /*-----------------------------------------------------------------*/
7513 /* genSignedRightShift - right shift of signed number */
7514 /*-----------------------------------------------------------------*/
7515 static void genSignedRightShift (iCode *ic)
7517 operand *right, *left, *result;
7520 symbol *tlbl, *tlbl1 ;
7523 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7525 /* we do it the hard way put the shift count in b
7526 and loop thru preserving the sign */
7527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7529 right = IC_RIGHT(ic);
7531 result = IC_RESULT(ic);
7533 aopOp(right,ic,FALSE);
7534 aopOp(left,ic,FALSE);
7535 aopOp(result,ic,FALSE);
7538 if ( AOP_TYPE(right) == AOP_LIT) {
7539 genRightShiftLiteral (left,right,result,ic,1);
7542 /* shift count is unknown then we have to form
7543 a loop get the loop count in B : Note: we take
7544 only the lower order byte since shifting
7545 more that 32 bits make no sense anyway, ( the
7546 largest size of an object can be only 32 bits ) */
7548 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7549 //pic14_emitcode("inc","b");
7550 //freeAsmop (right,NULL,ic,TRUE);
7551 //aopOp(left,ic,FALSE);
7552 //aopOp(result,ic,FALSE);
7554 /* now move the left to the result if they are not the
7556 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7557 AOP_SIZE(result) > 1) {
7559 size = AOP_SIZE(result);
7563 l = aopGet(AOP(left),offset,FALSE,TRUE);
7564 if (*l == '@' && IS_AOP_PREG(result)) {
7565 pic14_emitcode("mov","a,%s",l);
7566 aopPut(AOP(result),"a",offset);
7568 aopPut(AOP(result),l,offset);
7570 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7571 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7577 /* mov the highest order bit to OVR */
7578 tlbl = newiTempLabel(NULL);
7579 tlbl1= newiTempLabel(NULL);
7581 size = AOP_SIZE(result);
7584 pctemp = popGetTempReg(); /* grab a temporary working register. */
7586 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7588 /* offset should be 0, 1 or 3 */
7589 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7591 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7593 emitpcode(POC_MOVWF, pctemp);
7596 emitpLabel(tlbl->key);
7598 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7599 emitpcode(POC_RRF, popGet(AOP(result),offset));
7602 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7605 emitpcode(POC_DECFSZ, pctemp);
7606 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7607 emitpLabel(tlbl1->key);
7609 popReleaseTempReg(pctemp);
7611 size = AOP_SIZE(result);
7613 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7614 pic14_emitcode("rlc","a");
7615 pic14_emitcode("mov","ov,c");
7616 /* if it is only one byte then */
7618 l = aopGet(AOP(left),0,FALSE,FALSE);
7620 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7621 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7622 pic14_emitcode("mov","c,ov");
7623 pic14_emitcode("rrc","a");
7624 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7625 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7626 aopPut(AOP(result),"a",0);
7630 reAdjustPreg(AOP(result));
7631 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7632 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7633 pic14_emitcode("mov","c,ov");
7635 l = aopGet(AOP(result),offset,FALSE,FALSE);
7637 pic14_emitcode("rrc","a");
7638 aopPut(AOP(result),"a",offset--);
7640 reAdjustPreg(AOP(result));
7641 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7642 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7647 freeAsmop(left,NULL,ic,TRUE);
7648 freeAsmop(result,NULL,ic,TRUE);
7649 freeAsmop(right,NULL,ic,TRUE);
7652 /*-----------------------------------------------------------------*/
7653 /* genRightShift - generate code for right shifting */
7654 /*-----------------------------------------------------------------*/
7655 static void genRightShift (iCode *ic)
7657 operand *right, *left, *result;
7661 symbol *tlbl, *tlbl1 ;
7663 /* if signed then we do it the hard way preserve the
7664 sign bit moving it inwards */
7665 retype = getSpec(operandType(IC_RESULT(ic)));
7666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7668 if (!SPEC_USIGN(retype)) {
7669 genSignedRightShift (ic);
7673 /* signed & unsigned types are treated the same : i.e. the
7674 signed is NOT propagated inwards : quoting from the
7675 ANSI - standard : "for E1 >> E2, is equivalent to division
7676 by 2**E2 if unsigned or if it has a non-negative value,
7677 otherwise the result is implementation defined ", MY definition
7678 is that the sign does not get propagated */
7680 right = IC_RIGHT(ic);
7682 result = IC_RESULT(ic);
7684 aopOp(right,ic,FALSE);
7686 /* if the shift count is known then do it
7687 as efficiently as possible */
7688 if (AOP_TYPE(right) == AOP_LIT) {
7689 genRightShiftLiteral (left,right,result,ic, 0);
7693 /* shift count is unknown then we have to form
7694 a loop get the loop count in B : Note: we take
7695 only the lower order byte since shifting
7696 more that 32 bits make no sense anyway, ( the
7697 largest size of an object can be only 32 bits ) */
7699 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7700 pic14_emitcode("inc","b");
7701 aopOp(left,ic,FALSE);
7702 aopOp(result,ic,FALSE);
7704 /* now move the left to the result if they are not the
7706 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7707 AOP_SIZE(result) > 1) {
7709 size = AOP_SIZE(result);
7712 l = aopGet(AOP(left),offset,FALSE,TRUE);
7713 if (*l == '@' && IS_AOP_PREG(result)) {
7715 pic14_emitcode("mov","a,%s",l);
7716 aopPut(AOP(result),"a",offset);
7718 aopPut(AOP(result),l,offset);
7723 tlbl = newiTempLabel(NULL);
7724 tlbl1= newiTempLabel(NULL);
7725 size = AOP_SIZE(result);
7728 /* if it is only one byte then */
7731 tlbl = newiTempLabel(NULL);
7732 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7733 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7734 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7737 emitpcode(POC_COMFW, popGet(AOP(right),0));
7738 emitpcode(POC_RLF, popGet(AOP(result),0));
7739 emitpLabel(tlbl->key);
7740 emitpcode(POC_RRF, popGet(AOP(result),0));
7741 emitpcode(POC_ADDLW, popGetLit(1));
7743 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7748 reAdjustPreg(AOP(result));
7749 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7750 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7753 l = aopGet(AOP(result),offset,FALSE,FALSE);
7755 pic14_emitcode("rrc","a");
7756 aopPut(AOP(result),"a",offset--);
7758 reAdjustPreg(AOP(result));
7760 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7761 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7764 freeAsmop(left,NULL,ic,TRUE);
7765 freeAsmop (right,NULL,ic,TRUE);
7766 freeAsmop(result,NULL,ic,TRUE);
7769 /*-----------------------------------------------------------------*/
7770 /* genUnpackBits - generates code for unpacking bits */
7771 /*-----------------------------------------------------------------*/
7772 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
7775 int offset = 0; /* result byte offset */
7776 int rsize; /* result size */
7777 int rlen = 0; /* remaining bitfield length */
7778 sym_link *etype; /* bitfield type information */
7779 int blen; /* bitfield length */
7780 int bstr; /* bitfield starting bit within byte */
7782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7783 etype = getSpec(operandType(result));
7784 rsize = getSize (operandType (result));
7785 blen = SPEC_BLEN (etype);
7786 bstr = SPEC_BSTR (etype);
7788 /* single bit field case */
7790 if (ifx) { /* that is for an if statement */
7793 resolveIfx(&rIfx,ifx);
7794 if (ptype == -1) /* direct */
7795 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7797 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7798 emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
7799 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
7803 if (ptype == -1) /* direct */
7804 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7806 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7807 emitpcode(POC_BTFSC,pcop);
7808 emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7810 if (ptype == -1) /* direct */
7811 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7813 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7814 emitpcode(POC_BTFSS,pcop);
7815 emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7820 /* read the first byte */
7825 // pic14_emitcode("mov","a,@%s",rname);
7826 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
7830 pic14_emitcode("movx","a,@%s",rname);
7834 pic14_emitcode("movx","a,@dptr");
7838 pic14_emitcode("clr","a");
7839 pic14_emitcode("movc","a","@a+dptr");
7843 pic14_emitcode("lcall","__gptrget");
7847 /* if we have bitdisplacement then it fits */
7848 /* into this byte completely or if length is */
7849 /* less than a byte */
7850 if ((shCnt = SPEC_BSTR(etype)) || blen <= 8) {
7852 /* shift right acc */
7853 AccRsh(left,0,shCnt);
7855 pic14_emitcode("anl","a,#0x%02x",
7856 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7857 aopPut(AOP(result),"a",offset);
7861 /* bit field did not fit in a byte */
7862 rlen = SPEC_BLEN(etype) - 8;
7863 aopPut(AOP(result),"a",offset++);
7870 pic14_emitcode("inc","%s",rname);
7871 pic14_emitcode("mov","a,@%s",rname);
7875 pic14_emitcode("inc","%s",rname);
7876 pic14_emitcode("movx","a,@%s",rname);
7880 pic14_emitcode("inc","dptr");
7881 pic14_emitcode("movx","a,@dptr");
7885 pic14_emitcode("clr","a");
7886 pic14_emitcode("inc","dptr");
7887 pic14_emitcode("movc","a","@a+dptr");
7891 pic14_emitcode("inc","dptr");
7892 pic14_emitcode("lcall","__gptrget");
7897 /* if we are done */
7901 aopPut(AOP(result),"a",offset++);
7906 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7907 aopPut(AOP(result),"a",offset);
7914 /*-----------------------------------------------------------------*/
7915 /* genDataPointerGet - generates code when ptr offset is known */
7916 /*-----------------------------------------------------------------*/
7917 static void genDataPointerGet (operand *left,
7921 int size , offset = 0;
7924 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7927 /* optimization - most of the time, left and result are the same
7928 * address, but different types. for the pic code, we could omit
7932 aopOp(result,ic,TRUE);
7934 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7936 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7938 size = AOP_SIZE(result);
7941 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7945 freeAsmop(left,NULL,ic,TRUE);
7946 freeAsmop(result,NULL,ic,TRUE);
7949 /*-----------------------------------------------------------------*/
7950 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7951 /*-----------------------------------------------------------------*/
7952 static void genNearPointerGet (operand *left,
7957 sym_link *ltype = operandType(left);
7958 sym_link *rtype = operandType(result);
7959 sym_link *retype= getSpec(rtype); /* bitfield type information */
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 aopOp(left,ic,FALSE);
7968 /* if left is rematerialisable and
7969 result is not bit variable type and
7970 the left is pointer to data space i.e
7971 lower 128 bytes of space */
7972 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7973 !IS_BITVAR(retype) &&
7974 DCL_TYPE(ltype) == POINTER) {
7975 //genDataPointerGet (left,result,ic);
7979 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7980 aopOp (result,ic,FALSE);
7982 /* Check if can access directly instead of via a pointer */
7983 if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
7987 /* If the pointer value is not in a the FSR then need to put it in */
7988 if (!AOP_INPREG(AOP(left)) && !direct) {
7989 /* otherwise get a free pointer register */
7990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7991 if (PCOP(AOP(result))->type == PO_LITERAL)
7992 emitpcode(POC_MOVLW, popGet(AOP(left),0));
7994 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7995 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8000 /* if bitfield then unpack the bits */
8001 if (IS_BITFIELD(retype))
8002 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8004 /* we have can just get the values */
8005 int size = AOP_SIZE(result);
8008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8012 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8014 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8015 if (AOP_TYPE(result) == AOP_LIT) {
8016 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8018 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8020 if (size && !direct)
8021 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8026 /* now some housekeeping stuff */
8028 /* we had to allocate for this iCode */
8029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8030 freeAsmop(NULL,aop,ic,TRUE);
8032 /* we did not allocate which means left
8033 already in a pointer register, then
8034 if size > 0 && this could be used again
8035 we have to point it back to where it
8037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8038 if (AOP_SIZE(result) > 1 &&
8039 !OP_SYMBOL(left)->remat &&
8040 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8042 int size = AOP_SIZE(result) - 1;
8044 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8049 freeAsmop(left,NULL,ic,TRUE);
8050 freeAsmop(result,NULL,ic,TRUE);
8054 /*-----------------------------------------------------------------*/
8055 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8056 /*-----------------------------------------------------------------*/
8057 static void genPagedPointerGet (operand *left,
8064 sym_link *rtype, *retype;
8066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8068 rtype = operandType(result);
8069 retype= getSpec(rtype);
8071 aopOp(left,ic,FALSE);
8073 /* if the value is already in a pointer register
8074 then don't need anything more */
8075 if (!AOP_INPREG(AOP(left))) {
8076 /* otherwise get a free pointer register */
8078 preg = getFreePtr(ic,&aop,FALSE);
8079 pic14_emitcode("mov","%s,%s",
8081 aopGet(AOP(left),0,FALSE,TRUE));
8082 rname = preg->name ;
8084 rname = aopGet(AOP(left),0,FALSE,FALSE);
8086 freeAsmop(left,NULL,ic,TRUE);
8087 aopOp (result,ic,FALSE);
8089 /* if bitfield then unpack the bits */
8090 if (IS_BITFIELD(retype))
8091 genUnpackBits (result,left,rname,PPOINTER,0);
8093 /* we have can just get the values */
8094 int size = AOP_SIZE(result);
8099 pic14_emitcode("movx","a,@%s",rname);
8100 aopPut(AOP(result),"a",offset);
8105 pic14_emitcode("inc","%s",rname);
8109 /* now some housekeeping stuff */
8111 /* we had to allocate for this iCode */
8112 freeAsmop(NULL,aop,ic,TRUE);
8114 /* we did not allocate which means left
8115 already in a pointer register, then
8116 if size > 0 && this could be used again
8117 we have to point it back to where it
8119 if (AOP_SIZE(result) > 1 &&
8120 !OP_SYMBOL(left)->remat &&
8121 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8123 int size = AOP_SIZE(result) - 1;
8125 pic14_emitcode("dec","%s",rname);
8130 freeAsmop(result,NULL,ic,TRUE);
8135 /*-----------------------------------------------------------------*/
8136 /* genFarPointerGet - gget value from far space */
8137 /*-----------------------------------------------------------------*/
8138 static void genFarPointerGet (operand *left,
8139 operand *result, iCode *ic)
8142 sym_link *retype = getSpec(operandType(result));
8144 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8146 aopOp(left,ic,FALSE);
8148 /* if the operand is already in dptr
8149 then we do nothing else we move the value to dptr */
8150 if (AOP_TYPE(left) != AOP_STR) {
8151 /* if this is remateriazable */
8152 if (AOP_TYPE(left) == AOP_IMMD)
8153 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8154 else { /* we need to get it byte by byte */
8155 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8156 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8157 if (options.model == MODEL_FLAT24)
8159 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8163 /* so dptr know contains the address */
8164 freeAsmop(left,NULL,ic,TRUE);
8165 aopOp(result,ic,FALSE);
8167 /* if bit then unpack */
8168 if (IS_BITFIELD(retype))
8169 genUnpackBits(result,left,"dptr",FPOINTER,0);
8171 size = AOP_SIZE(result);
8175 pic14_emitcode("movx","a,@dptr");
8176 aopPut(AOP(result),"a",offset++);
8178 pic14_emitcode("inc","dptr");
8182 freeAsmop(result,NULL,ic,TRUE);
8185 /*-----------------------------------------------------------------*/
8186 /* genCodePointerGet - get value from code space */
8187 /*-----------------------------------------------------------------*/
8188 static void genCodePointerGet (operand *left,
8189 operand *result, iCode *ic)
8192 sym_link *retype = getSpec(operandType(result));
8194 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8196 aopOp(left,ic,FALSE);
8198 /* if the operand is already in dptr
8199 then we do nothing else we move the value to dptr */
8200 if (AOP_TYPE(left) != AOP_STR) {
8201 /* if this is remateriazable */
8202 if (AOP_TYPE(left) == AOP_IMMD)
8203 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8204 else { /* we need to get it byte by byte */
8205 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8206 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8207 if (options.model == MODEL_FLAT24)
8209 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8213 /* so dptr know contains the address */
8214 freeAsmop(left,NULL,ic,TRUE);
8215 aopOp(result,ic,FALSE);
8217 /* if bit then unpack */
8218 if (IS_BITFIELD(retype))
8219 genUnpackBits(result,left,"dptr",CPOINTER,0);
8221 size = AOP_SIZE(result);
8225 pic14_emitcode("clr","a");
8226 pic14_emitcode("movc","a,@a+dptr");
8227 aopPut(AOP(result),"a",offset++);
8229 pic14_emitcode("inc","dptr");
8233 freeAsmop(result,NULL,ic,TRUE);
8236 /*-----------------------------------------------------------------*/
8237 /* genGenPointerGet - gget value from generic pointer space */
8238 /*-----------------------------------------------------------------*/
8239 static void genGenPointerGet (operand *left,
8240 operand *result, iCode *ic)
8243 sym_link *retype = getSpec(operandType(result));
8245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8246 aopOp(left,ic,FALSE);
8247 aopOp(result,ic,FALSE);
8250 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8252 /* if the operand is already in dptr
8253 then we do nothing else we move the value to dptr */
8254 // if (AOP_TYPE(left) != AOP_STR) {
8255 /* if this is remateriazable */
8256 if (AOP_TYPE(left) == AOP_IMMD) {
8257 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8258 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8260 else { /* we need to get it byte by byte */
8262 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8263 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8265 size = AOP_SIZE(result);
8269 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8270 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8272 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8277 /* so dptr know contains the address */
8279 /* if bit then unpack */
8280 //if (IS_BITFIELD(retype))
8281 // genUnpackBits(result,"dptr",GPOINTER);
8284 freeAsmop(left,NULL,ic,TRUE);
8285 freeAsmop(result,NULL,ic,TRUE);
8289 /*-----------------------------------------------------------------*/
8290 /* genConstPointerGet - get value from const generic pointer space */
8291 /*-----------------------------------------------------------------*/
8292 static void genConstPointerGet (operand *left,
8293 operand *result, iCode *ic)
8295 //sym_link *retype = getSpec(operandType(result));
8296 symbol *albl = newiTempLabel(NULL);
8297 symbol *blbl = newiTempLabel(NULL);
8301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8302 aopOp(left,ic,FALSE);
8303 aopOp(result,ic,FALSE);
8306 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8308 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8310 emitpcode(POC_CALL,popGetLabel(albl->key));
8311 pcop = popGetLabel(blbl->key);
8312 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8313 emitpcode(POC_GOTO,pcop);
8314 emitpLabel(albl->key);
8316 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8318 emitpcode(poc,popGet(AOP(left),1));
8319 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8320 emitpcode(poc,popGet(AOP(left),0));
8321 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8323 emitpLabel(blbl->key);
8325 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8328 freeAsmop(left,NULL,ic,TRUE);
8329 freeAsmop(result,NULL,ic,TRUE);
8332 /*-----------------------------------------------------------------*/
8333 /* genPointerGet - generate code for pointer get */
8334 /*-----------------------------------------------------------------*/
8335 static void genPointerGet (iCode *ic)
8337 operand *left, *result ;
8338 sym_link *type, *etype;
8341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8344 result = IC_RESULT(ic) ;
8346 /* depending on the type of pointer we need to
8347 move it to the correct pointer register */
8348 type = operandType(left);
8349 etype = getSpec(type);
8351 if (IS_PTR_CONST(type))
8352 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8354 /* if left is of type of pointer then it is simple */
8355 if (IS_PTR(type) && !IS_FUNC(type->next))
8356 p_type = DCL_TYPE(type);
8358 /* we have to go by the storage class */
8359 p_type = PTR_TYPE(SPEC_OCLS(etype));
8361 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8363 if (SPEC_OCLS(etype)->codesp ) {
8364 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8365 //p_type = CPOINTER ;
8368 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8369 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8370 /*p_type = FPOINTER ;*/
8372 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8373 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8374 /* p_type = PPOINTER; */
8376 if (SPEC_OCLS(etype) == idata )
8377 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8378 /* p_type = IPOINTER; */
8380 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8381 /* p_type = POINTER ; */
8384 /* now that we have the pointer type we assign
8385 the pointer values */
8390 genNearPointerGet (left,result,ic);
8394 genPagedPointerGet(left,result,ic);
8398 genFarPointerGet (left,result,ic);
8402 genConstPointerGet (left,result,ic);
8403 //pic14_emitcodePointerGet (left,result,ic);
8407 if (IS_PTR_CONST(type))
8408 genConstPointerGet (left,result,ic);
8410 genGenPointerGet (left,result,ic);
8416 /*-----------------------------------------------------------------*/
8417 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into */
8418 /* A through a pointer register (R0, R1, or DPTR). The original */
8419 /* value of A can be preserved in B. */
8420 /* PIC has to use INDF register. */
8421 /*-----------------------------------------------------------------*/
8423 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8430 pic14_emitcode ("mov", "b,a");
8431 // pic14_emitcode ("mov", "a,@%s", rname);
8432 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8437 pic14_emitcode ("mov", "b,a");
8438 pic14_emitcode ("movx", "a,@%s", rname);
8443 pic14_emitcode ("mov", "b,a");
8444 pic14_emitcode ("movx", "a,@dptr");
8449 pic14_emitcode ("mov", "b,a");
8450 pic14_emitcode ("clr", "a");
8451 pic14_emitcode ("movc", "a,@a+dptr");
8457 pic14_emitcode ("push", "b");
8458 pic14_emitcode ("push", "acc");
8460 pic14_emitcode ("lcall", "__gptrget");
8462 pic14_emitcode ("pop", "b");
8467 /*-----------------------------------------------------------------*/
8468 /* emitPtrByteSet - emits code to set a byte from src through a */
8469 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR). */
8470 /*-----------------------------------------------------------------*/
8472 emitPtrByteSet (char *rname, int p_type, char *src)
8481 pic14_emitcode ("mov", "@%s,a", rname);
8484 // pic14_emitcode ("mov", "@%s,%s", rname, src);
8485 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8490 pic14_emitcode ("movx", "@%s,a", rname);
8495 pic14_emitcode ("movx", "@dptr,a");
8500 pic14_emitcode ("lcall", "__gptrput");
8505 /*-----------------------------------------------------------------*/
8506 /* genPackBits - generates code for packed bit storage */
8507 /*-----------------------------------------------------------------*/
8508 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8510 int offset = 0; /* source byte offset */
8511 int rlen = 0; /* remaining bitfield length */
8512 int blen; /* bitfield length */
8513 int bstr; /* bitfield starting bit within byte */
8514 int litval; /* source literal value (if AOP_LIT) */
8515 unsigned char mask; /* bitmask within current byte */
8517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8519 blen = SPEC_BLEN (etype);
8520 bstr = SPEC_BSTR (etype);
8522 /* If the bitfield length is less than a byte */
8525 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8526 (unsigned char) (0xFF >> (8 - bstr)));
8528 if (AOP_TYPE (right) == AOP_LIT)
8530 /* Case with a bitfield length <8 and literal source
8532 int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8536 if (AOP(result)->type == AOP_PCODE)
8537 pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
8539 pcop = popGet(AOP(result),0);
8540 emitpcode(lit?POC_BSF:POC_BCF,pcop);
8542 emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8546 litval = lit << bstr;
8547 litval &= (~mask) & 0xff;
8549 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8551 emitPtrByteGet (rname, p_type, FALSE);
8552 if ((mask|litval)!=0xff)
8553 emitpcode(POC_ANDLW,popGetLit(mask));
8555 emitpcode(POC_IORLW,popGetLit(litval));
8562 /* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
8563 emitpcode(POC_RLF,popGet(AOP(right),0));
8565 emitpcode(POC_BCF,popGet(AOP(result),0));
8567 emitpcode(POC_BSF,popGet(AOP(result),0));
8568 } else if (p_type!=GPOINTER) {
8569 /* Case with a bitfield length == 1 and no generic pointer
8571 if (AOP_TYPE (right) == AOP_CRY)
8572 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
8575 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8576 pic14_emitcode ("rrc","a");
8578 emitPtrByteGet (rname, p_type, FALSE);
8579 pic14_emitcode ("mov","acc.%d,c",bstr);
8585 /* Case with a bitfield length < 8 and arbitrary source
8587 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8588 /* shift and mask source value */
8589 AccLsh (right,0,bstr);
8590 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8591 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
8593 //pushedB = pushB ();
8595 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8597 emitPtrByteGet (rname, p_type, TRUE);
8599 pic14_emitcode ("anl", "a,#0x%02x", mask);
8600 pic14_emitcode ("orl", "a,b");
8601 emitpcode(POC_ANDLW,popGetLit(mask));
8602 emitpcode(POC_IORFW,popGet(AOP(right),0));
8603 if (p_type == GPOINTER)
8604 pic14_emitcode ("pop", "b");
8611 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8613 emitPtrByteSet (rname, p_type, "a");
8617 /* Bit length is greater than 7 bits. In this case, copy */
8618 /* all except the partial byte at the end */
8619 for (rlen=blen;rlen>=8;rlen-=8)
8621 emitPtrByteSet (rname, p_type,
8622 aopGet (AOP (right), offset++, FALSE, TRUE) );
8624 pic14_emitcode ("inc", "%s", rname);
8627 /* If there was a partial byte at the end */
8630 mask = (((unsigned char) -1 << rlen) & 0xff);
8632 if (AOP_TYPE (right) == AOP_LIT)
8634 /* Case with partial byte and literal source
8636 litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8637 litval >>= (blen-rlen);
8638 litval &= (~mask) & 0xff;
8639 emitPtrByteGet (rname, p_type, FALSE);
8640 if ((mask|litval)!=0xff)
8641 pic14_emitcode ("anl","a,#0x%02x", mask);
8643 pic14_emitcode ("orl","a,#0x%02x", litval);
8648 /* Case with partial byte and arbitrary source
8650 MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
8651 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8653 //pushedB = pushB ();
8654 /* transfer A to B and get next byte */
8655 emitPtrByteGet (rname, p_type, TRUE);
8657 pic14_emitcode ("anl", "a,#0x%02x", mask);
8658 pic14_emitcode ("orl", "a,b");
8659 if (p_type == GPOINTER)
8660 pic14_emitcode ("pop", "b");
8664 emitPtrByteSet (rname, p_type, "a");
8669 /*-----------------------------------------------------------------*/
8670 /* SetIrp - Set IRP bit */
8671 /*-----------------------------------------------------------------*/
8672 void SetIrp(operand *result) {
8673 if (AOP_TYPE(result) == AOP_LIT) {
8674 unsigned lit = (unsigned)operandLitValue(result);
8675 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8677 if (PCOP(AOP(result))->type == PO_LITERAL) {
8678 int addrs = PCOL(AOP(result))->lit;
8679 emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8681 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
8682 if(AOP_SIZE(result) > 1) {
8683 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8684 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8690 /*-----------------------------------------------------------------*/
8691 /* genDataPointerSet - remat pointer to data space */
8692 /*-----------------------------------------------------------------*/
8693 static void genDataPointerSet(operand *right,
8697 int size, offset = 0 ;
8698 char *l, buffer[256];
8700 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8701 aopOp(right,ic,FALSE);
8703 l = aopGet(AOP(result),0,FALSE,TRUE);
8704 size = AOP_SIZE(right);
8706 if ( AOP_TYPE(result) == AOP_PCODE) {
8707 fprintf(stderr,"genDataPointerSet %s, %d\n",
8708 AOP(result)->aopu.pcop->name,
8709 PCOI(AOP(result)->aopu.pcop)->offset);
8713 // tsd, was l+1 - the underline `_' prefix was being stripped
8716 sprintf(buffer,"(%s + %d)",l,offset);
8717 fprintf(stderr,"oops %s\n",buffer);
8719 sprintf(buffer,"%s",l);
8721 if (AOP_TYPE(right) == AOP_LIT) {
8722 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8723 lit = lit >> (8*offset);
8725 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8726 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8728 emitpcode(POC_CLRF, popGet(AOP(result),0));
8731 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8732 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8738 freeAsmop(right,NULL,ic,TRUE);
8739 freeAsmop(result,NULL,ic,TRUE);
8742 /*-----------------------------------------------------------------*/
8743 /* genNearPointerSet - pic14_emitcode for near pointer put */
8744 /*-----------------------------------------------------------------*/
8745 static void genNearPointerSet (operand *right,
8750 sym_link *ptype = operandType(result);
8751 sym_link *retype = getSpec(operandType(right));
8752 sym_link *letype = getSpec(ptype);
8756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8757 aopOp(result,ic,FALSE);
8760 /* if the result is rematerializable &
8761 in data space & not a bit variable */
8762 //if (AOP_TYPE(result) == AOP_IMMD &&
8763 if (AOP_TYPE(result) == AOP_PCODE &&
8764 DCL_TYPE(ptype) == POINTER &&
8765 !IS_BITVAR (retype) &&
8766 !IS_BITVAR (letype)) {
8767 genDataPointerSet (right,result,ic);
8768 freeAsmop(result,NULL,ic,TRUE);
8772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8773 aopOp(right,ic,FALSE);
8774 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8776 /* Check if can access directly instead of via a pointer */
8777 if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
8781 /* If the pointer value is not in a the FSR then need to put it in */
8782 if (!AOP_INPREG(AOP(result)) && !direct) {
8783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8784 if (PCOP(AOP(result))->type == PO_LITERAL)
8785 emitpcode(POC_MOVLW, popGet(AOP(result),0));
8787 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8788 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8791 /* Must set/reset IRP bit for use with FSR. */
8792 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
8796 /* if bitfield then unpack the bits */
8797 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
8798 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
8800 /* we have can just get the values */
8801 int size = AOP_SIZE(right);
8804 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8806 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
8808 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8810 if (AOP_TYPE(right) == AOP_LIT) {
8811 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
8813 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
8816 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8818 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8820 if (size && !direct)
8821 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8826 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8827 /* now some housekeeping stuff */
8829 /* we had to allocate for this iCode */
8830 freeAsmop(NULL,aop,ic,TRUE);
8832 /* we did not allocate which means left
8833 already in a pointer register, then
8834 if size > 0 && this could be used again
8835 we have to point it back to where it
8837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8838 if (AOP_SIZE(right) > 1 &&
8839 !OP_SYMBOL(result)->remat &&
8840 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8842 int size = AOP_SIZE(right) - 1;
8844 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8848 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8851 freeAsmop(right,NULL,ic,TRUE);
8852 freeAsmop(result,NULL,ic,TRUE);
8855 /*-----------------------------------------------------------------*/
8856 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8857 /*-----------------------------------------------------------------*/
8858 static void genPagedPointerSet (operand *right,
8867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8869 retype= getSpec(operandType(right));
8871 aopOp(result,ic,FALSE);
8873 /* if the value is already in a pointer register
8874 then don't need anything more */
8875 if (!AOP_INPREG(AOP(result))) {
8876 /* otherwise get a free pointer register */
8878 preg = getFreePtr(ic,&aop,FALSE);
8879 pic14_emitcode("mov","%s,%s",
8881 aopGet(AOP(result),0,FALSE,TRUE));
8882 rname = preg->name ;
8884 rname = aopGet(AOP(result),0,FALSE,FALSE);
8886 freeAsmop(result,NULL,ic,TRUE);
8887 aopOp (right,ic,FALSE);
8889 /* if bitfield then unpack the bits */
8890 if (IS_BITFIELD(retype))
8891 genPackBits (retype,result,right,rname,PPOINTER);
8893 /* we have can just get the values */
8894 int size = AOP_SIZE(right);
8898 l = aopGet(AOP(right),offset,FALSE,TRUE);
8901 pic14_emitcode("movx","@%s,a",rname);
8904 pic14_emitcode("inc","%s",rname);
8910 /* now some housekeeping stuff */
8912 /* we had to allocate for this iCode */
8913 freeAsmop(NULL,aop,ic,TRUE);
8915 /* we did not allocate which means left
8916 already in a pointer register, then
8917 if size > 0 && this could be used again
8918 we have to point it back to where it
8920 if (AOP_SIZE(right) > 1 &&
8921 !OP_SYMBOL(result)->remat &&
8922 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8924 int size = AOP_SIZE(right) - 1;
8926 pic14_emitcode("dec","%s",rname);
8931 freeAsmop(right,NULL,ic,TRUE);
8936 /*-----------------------------------------------------------------*/
8937 /* genFarPointerSet - set value from far space */
8938 /*-----------------------------------------------------------------*/
8939 static void genFarPointerSet (operand *right,
8940 operand *result, iCode *ic)
8943 sym_link *retype = getSpec(operandType(right));
8945 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8946 aopOp(result,ic,FALSE);
8948 /* if the operand is already in dptr
8949 then we do nothing else we move the value to dptr */
8950 if (AOP_TYPE(result) != AOP_STR) {
8951 /* if this is remateriazable */
8952 if (AOP_TYPE(result) == AOP_IMMD)
8953 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8954 else { /* we need to get it byte by byte */
8955 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8956 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8957 if (options.model == MODEL_FLAT24)
8959 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8963 /* so dptr know contains the address */
8964 freeAsmop(result,NULL,ic,TRUE);
8965 aopOp(right,ic,FALSE);
8967 /* if bit then unpack */
8968 if (IS_BITFIELD(retype))
8969 genPackBits(retype,result,right,"dptr",FPOINTER);
8971 size = AOP_SIZE(right);
8975 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8977 pic14_emitcode("movx","@dptr,a");
8979 pic14_emitcode("inc","dptr");
8983 freeAsmop(right,NULL,ic,TRUE);
8986 /*-----------------------------------------------------------------*/
8987 /* genGenPointerSet - set value from generic pointer space */
8988 /*-----------------------------------------------------------------*/
8989 static void genGenPointerSet (operand *right,
8990 operand *result, iCode *ic)
8992 sym_link *ptype = operandType(result);
8993 sym_link *retype = getSpec(operandType(right));
8994 sym_link *letype = getSpec (ptype);
8996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8998 aopOp(result,ic,FALSE);
8999 aopOp(right,ic,FALSE);
9001 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9003 /* if the operand is already in dptr
9004 then we do nothing else we move the value to dptr */
9005 if (AOP_TYPE(result) != AOP_STR) {
9006 /* if this is remateriazable */
9007 if (AOP_TYPE(result) == AOP_IMMD) {
9008 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9009 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9012 emitpcode(POC_MOVFW,popGet(AOP(result),0));
9013 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9015 /* Must set/reset IRP bit for use with FSR. */
9016 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9021 /* if bitfield then unpack the bits */
9022 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9023 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9025 /* we have can just get the values */
9026 int size = AOP_SIZE(right);
9029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9031 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9033 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9035 if (AOP_TYPE(right) == AOP_LIT) {
9036 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9038 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9040 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9043 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9048 freeAsmop(right,NULL,ic,TRUE);
9049 freeAsmop(result,NULL,ic,TRUE);
9052 /*-----------------------------------------------------------------*/
9053 /* genPointerSet - stores the value into a pointer location */
9054 /*-----------------------------------------------------------------*/
9055 static void genPointerSet (iCode *ic)
9057 operand *right, *result ;
9058 sym_link *type, *etype;
9061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9063 right = IC_RIGHT(ic);
9064 result = IC_RESULT(ic) ;
9066 /* depending on the type of pointer we need to
9067 move it to the correct pointer register */
9068 type = operandType(result);
9069 etype = getSpec(type);
9070 /* if left is of type of pointer then it is simple */
9071 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9072 p_type = DCL_TYPE(type);
9075 /* we have to go by the storage class */
9076 p_type = PTR_TYPE(SPEC_OCLS(etype));
9078 /* if (SPEC_OCLS(etype)->codesp ) { */
9079 /* p_type = CPOINTER ; */
9082 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9083 /* p_type = FPOINTER ; */
9085 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9086 /* p_type = PPOINTER ; */
9088 /* if (SPEC_OCLS(etype) == idata ) */
9089 /* p_type = IPOINTER ; */
9091 /* p_type = POINTER ; */
9094 /* now that we have the pointer type we assign
9095 the pointer values */
9100 genNearPointerSet (right,result,ic);
9104 genPagedPointerSet (right,result,ic);
9108 genFarPointerSet (right,result,ic);
9112 genGenPointerSet (right,result,ic);
9116 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9117 "genPointerSet: illegal pointer type");
9121 /*-----------------------------------------------------------------*/
9122 /* genIfx - generate code for Ifx statement */
9123 /*-----------------------------------------------------------------*/
9124 static void genIfx (iCode *ic, iCode *popIc)
9126 operand *cond = IC_COND(ic);
9129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9131 aopOp(cond,ic,FALSE);
9133 /* get the value into acc */
9134 if (AOP_TYPE(cond) != AOP_CRY)
9135 pic14_toBoolean(cond);
9138 /* the result is now in the accumulator */
9139 freeAsmop(cond,NULL,ic,TRUE);
9141 /* if there was something to be popped then do it */
9145 /* if the condition is a bit variable */
9146 if (isbit && IS_ITEMP(cond) &&
9148 genIfxJump(ic,SPIL_LOC(cond)->rname);
9149 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9152 if (isbit && !IS_ITEMP(cond))
9153 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9161 /*-----------------------------------------------------------------*/
9162 /* genAddrOf - generates code for address of */
9163 /*-----------------------------------------------------------------*/
9164 static void genAddrOf (iCode *ic)
9166 operand *right, *result, *left;
9169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9172 //aopOp(IC_RESULT(ic),ic,FALSE);
9174 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9175 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9176 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9178 DEBUGpic14_AopType(__LINE__,left,right,result);
9180 size = AOP_SIZE(IC_RESULT(ic));
9184 /* fixing bug #863624, reported from (errolv) */
9185 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9186 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9189 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9190 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9195 freeAsmop(left,NULL,ic,FALSE);
9196 freeAsmop(result,NULL,ic,TRUE);
9201 /*-----------------------------------------------------------------*/
9202 /* genFarFarAssign - assignment when both are in far space */
9203 /*-----------------------------------------------------------------*/
9204 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9206 int size = AOP_SIZE(right);
9209 /* first push the right side on to the stack */
9211 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9213 pic14_emitcode ("push","acc");
9216 freeAsmop(right,NULL,ic,FALSE);
9217 /* now assign DPTR to result */
9218 aopOp(result,ic,FALSE);
9219 size = AOP_SIZE(result);
9221 pic14_emitcode ("pop","acc");
9222 aopPut(AOP(result),"a",--offset);
9224 freeAsmop(result,NULL,ic,FALSE);
9229 /*-----------------------------------------------------------------*/
9230 /* genAssign - generate code for assignment */
9231 /*-----------------------------------------------------------------*/
9232 static void genAssign (iCode *ic)
9234 operand *result, *right;
9235 int size, offset,know_W;
9236 unsigned long lit = 0L;
9238 result = IC_RESULT(ic);
9239 right = IC_RIGHT(ic) ;
9241 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9243 /* if they are the same */
9244 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9247 aopOp(right,ic,FALSE);
9248 aopOp(result,ic,TRUE);
9250 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9252 /* if they are the same registers */
9253 if (pic14_sameRegs(AOP(right),AOP(result)))
9256 /* if the result is a bit */
9257 if (AOP_TYPE(result) == AOP_CRY) {
9259 /* if the right size is a literal then
9260 we know what the value is */
9261 if (AOP_TYPE(right) == AOP_LIT) {
9263 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9264 popGet(AOP(result),0));
9266 if (((int) operandLitValue(right)))
9267 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9268 AOP(result)->aopu.aop_dir,
9269 AOP(result)->aopu.aop_dir);
9271 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9272 AOP(result)->aopu.aop_dir,
9273 AOP(result)->aopu.aop_dir);
9277 /* the right is also a bit variable */
9278 if (AOP_TYPE(right) == AOP_CRY) {
9279 emitpcode(POC_BCF, popGet(AOP(result),0));
9280 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9281 emitpcode(POC_BSF, popGet(AOP(result),0));
9283 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9284 AOP(result)->aopu.aop_dir,
9285 AOP(result)->aopu.aop_dir);
9286 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9287 AOP(right)->aopu.aop_dir,
9288 AOP(right)->aopu.aop_dir);
9289 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9290 AOP(result)->aopu.aop_dir,
9291 AOP(result)->aopu.aop_dir);
9296 emitpcode(POC_BCF, popGet(AOP(result),0));
9297 pic14_toBoolean(right);
9299 emitpcode(POC_BSF, popGet(AOP(result),0));
9300 //aopPut(AOP(result),"a",0);
9304 /* bit variables done */
9306 size = AOP_SIZE(result);
9308 if(AOP_TYPE(right) == AOP_LIT)
9309 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9311 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9313 if(aopIdx(AOP(result),0) == 4) {
9314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9315 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9316 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9319 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9325 if(AOP_TYPE(right) == AOP_LIT) {
9327 if(know_W != (int)(lit&0xff))
9328 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9330 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9332 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9336 } else if (AOP_TYPE(right) == AOP_CRY) {
9337 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9339 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9340 emitpcode(POC_INCF, popGet(AOP(result),0));
9343 mov2w (AOP(right), offset);
9344 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9352 freeAsmop (right,NULL,ic,FALSE);
9353 freeAsmop (result,NULL,ic,TRUE);
9356 /*-----------------------------------------------------------------*/
9357 /* genJumpTab - genrates code for jump table */
9358 /*-----------------------------------------------------------------*/
9359 static void genJumpTab (iCode *ic)
9364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9366 aopOp(IC_JTCOND(ic),ic,FALSE);
9367 /* get the condition into accumulator */
9368 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9370 /* multiply by three */
9371 pic14_emitcode("add","a,acc");
9372 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9374 jtab = newiTempLabel(NULL);
9375 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9376 pic14_emitcode("jmp","@a+dptr");
9377 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9379 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9380 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9381 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9382 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9384 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9385 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9386 emitpLabel(jtab->key);
9388 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9390 /* now generate the jump labels */
9391 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9392 jtab = setNextItem(IC_JTLABELS(ic))) {
9393 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9394 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9400 /*-----------------------------------------------------------------*/
9401 /* genMixedOperation - gen code for operators between mixed types */
9402 /*-----------------------------------------------------------------*/
9404 TSD - Written for the PIC port - but this unfortunately is buggy.
9405 This routine is good in that it is able to efficiently promote
9406 types to different (larger) sizes. Unfortunately, the temporary
9407 variables that are optimized out by this routine are sometimes
9408 used in other places. So until I know how to really parse the
9409 iCode tree, I'm going to not be using this routine :(.
9411 static int genMixedOperation (iCode *ic)
9414 operand *result = IC_RESULT(ic);
9415 sym_link *ctype = operandType(IC_LEFT(ic));
9416 operand *right = IC_RIGHT(ic);
9422 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9424 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9430 nextright = IC_RIGHT(nextic);
9431 nextleft = IC_LEFT(nextic);
9432 nextresult = IC_RESULT(nextic);
9434 aopOp(right,ic,FALSE);
9435 aopOp(result,ic,FALSE);
9436 aopOp(nextright, nextic, FALSE);
9437 aopOp(nextleft, nextic, FALSE);
9438 aopOp(nextresult, nextic, FALSE);
9440 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9446 pic14_emitcode(";remove right +","");
9448 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9454 pic14_emitcode(";remove left +","");
9458 big = AOP_SIZE(nextleft);
9459 small = AOP_SIZE(nextright);
9461 switch(nextic->op) {
9464 pic14_emitcode(";optimize a +","");
9465 /* if unsigned or not an integral type */
9466 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9467 pic14_emitcode(";add a bit to something","");
9470 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9472 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9473 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9474 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9476 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9484 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9485 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9486 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9489 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9491 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9492 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9493 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9494 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9495 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9498 pic14_emitcode("rlf","known_zero,w");
9505 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9506 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9507 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9509 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9519 freeAsmop(right,NULL,ic,TRUE);
9520 freeAsmop(result,NULL,ic,TRUE);
9521 freeAsmop(nextright,NULL,ic,TRUE);
9522 freeAsmop(nextleft,NULL,ic,TRUE);
9524 nextic->generated = 1;
9531 /*-----------------------------------------------------------------*/
9532 /* genCast - gen code for casting */
9533 /*-----------------------------------------------------------------*/
9534 static void genCast (iCode *ic)
9536 operand *result = IC_RESULT(ic);
9537 sym_link *ctype = operandType(IC_LEFT(ic));
9538 sym_link *rtype = operandType(IC_RIGHT(ic));
9539 operand *right = IC_RIGHT(ic);
9542 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9543 /* if they are equivalent then do nothing */
9544 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9547 aopOp(right,ic,FALSE) ;
9548 aopOp(result,ic,FALSE);
9550 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9552 /* if the result is a bit */
9553 if (AOP_TYPE(result) == AOP_CRY) {
9554 /* if the right size is a literal then
9555 we know what the value is */
9556 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9557 if (AOP_TYPE(right) == AOP_LIT) {
9559 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9560 popGet(AOP(result),0));
9562 if (((int) operandLitValue(right)))
9563 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9564 AOP(result)->aopu.aop_dir,
9565 AOP(result)->aopu.aop_dir);
9567 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9568 AOP(result)->aopu.aop_dir,
9569 AOP(result)->aopu.aop_dir);
9574 /* the right is also a bit variable */
9575 if (AOP_TYPE(right) == AOP_CRY) {
9578 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9580 pic14_emitcode("clrc","");
9581 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9582 AOP(right)->aopu.aop_dir,
9583 AOP(right)->aopu.aop_dir);
9584 aopPut(AOP(result),"c",0);
9589 if (AOP_TYPE(right) == AOP_REG) {
9590 emitpcode(POC_BCF, popGet(AOP(result),0));
9591 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9592 emitpcode(POC_BSF, popGet(AOP(result),0));
9594 pic14_toBoolean(right);
9595 aopPut(AOP(result),"a",0);
9599 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9601 size = AOP_SIZE(result);
9603 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9605 emitpcode(POC_CLRF, popGet(AOP(result),0));
9606 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9607 emitpcode(POC_INCF, popGet(AOP(result),0));
9610 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9615 /* if they are the same size : or less */
9616 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9618 /* if they are in the same place */
9619 if (pic14_sameRegs(AOP(right),AOP(result)))
9622 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9623 if (IS_PTR_CONST(rtype))
9624 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9625 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9626 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9628 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9629 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9630 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9631 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9632 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9633 if(AOP_SIZE(result) <2)
9634 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9638 /* if they in different places then copy */
9639 size = AOP_SIZE(result);
9642 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9643 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9645 //aopPut(AOP(result),
9646 // aopGet(AOP(right),offset,FALSE,FALSE),
9656 /* if the result is of type pointer */
9657 if (IS_PTR(ctype)) {
9660 sym_link *type = operandType(right);
9661 sym_link *etype = getSpec(type);
9662 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9664 /* pointer to generic pointer */
9665 if (IS_GENPTR(ctype)) {
9669 p_type = DCL_TYPE(type);
9671 /* we have to go by the storage class */
9672 p_type = PTR_TYPE(SPEC_OCLS(etype));
9674 /* if (SPEC_OCLS(etype)->codesp ) */
9675 /* p_type = CPOINTER ; */
9677 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9678 /* p_type = FPOINTER ; */
9680 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9681 /* p_type = PPOINTER; */
9683 /* if (SPEC_OCLS(etype) == idata ) */
9684 /* p_type = IPOINTER ; */
9686 /* p_type = POINTER ; */
9689 /* the first two bytes are known */
9690 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9691 size = GPTRSIZE - 1;
9694 if(offset < AOP_SIZE(right)) {
9695 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9696 if ((AOP_TYPE(right) == AOP_PCODE) &&
9697 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9698 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9699 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9702 aopGet(AOP(right),offset,FALSE,FALSE),
9706 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9709 /* the last byte depending on type */
9713 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9716 pic14_emitcode(";BUG!? ","%d",__LINE__);
9720 pic14_emitcode(";BUG!? ","%d",__LINE__);
9724 pic14_emitcode(";BUG!? ","%d",__LINE__);
9729 /* this should never happen */
9730 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9731 "got unknown pointer type");
9734 //aopPut(AOP(result),l, GPTRSIZE - 1);
9738 /* just copy the pointers */
9739 size = AOP_SIZE(result);
9743 aopGet(AOP(right),offset,FALSE,FALSE),
9752 /* so we now know that the size of destination is greater
9753 than the size of the source.
9754 Now, if the next iCode is an operator then we might be
9755 able to optimize the operation without performing a cast.
9757 if(genMixedOperation(ic))
9760 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9762 /* we move to result for the size of source */
9763 size = AOP_SIZE(right);
9766 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9767 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9771 /* now depending on the sign of the destination */
9772 size = AOP_SIZE(result) - AOP_SIZE(right);
9773 /* if unsigned or not an integral type */
9774 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9776 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9778 /* we need to extend the sign :{ */
9781 /* Save one instruction of casting char to int */
9782 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9783 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9784 emitpcode(POC_DECF, popGet(AOP(result),offset));
9786 emitpcodeNULLop(POC_CLRW);
9789 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9791 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9793 emitpcode(POC_MOVLW, popGetLit(0xff));
9796 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9801 freeAsmop(right,NULL,ic,TRUE);
9802 freeAsmop(result,NULL,ic,TRUE);
9806 /*-----------------------------------------------------------------*/
9807 /* genDjnz - generate decrement & jump if not zero instrucion */
9808 /*-----------------------------------------------------------------*/
9809 static int genDjnz (iCode *ic, iCode *ifx)
9812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9817 /* if the if condition has a false label
9818 then we cannot save */
9822 /* if the minus is not of the form
9824 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9825 !IS_OP_LITERAL(IC_RIGHT(ic)))
9828 if (operandLitValue(IC_RIGHT(ic)) != 1)
9831 /* if the size of this greater than one then no
9833 if (getSize(operandType(IC_RESULT(ic))) > 1)
9836 /* otherwise we can save BIG */
9837 lbl = newiTempLabel(NULL);
9838 lbl1= newiTempLabel(NULL);
9840 aopOp(IC_RESULT(ic),ic,FALSE);
9842 if (IS_AOP_PREG(IC_RESULT(ic))) {
9843 pic14_emitcode("dec","%s",
9844 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9845 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9846 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9850 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9851 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9853 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9854 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9857 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9858 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9859 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9860 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9863 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9868 /*-----------------------------------------------------------------*/
9869 /* genReceive - generate code for a receive iCode */
9870 /*-----------------------------------------------------------------*/
9871 static void genReceive (iCode *ic)
9873 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9875 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9876 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9877 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9879 int size = getSize(operandType(IC_RESULT(ic)));
9880 int offset = fReturnSizePic - size;
9882 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9883 fReturn[fReturnSizePic - offset - 1] : "acc"));
9886 aopOp(IC_RESULT(ic),ic,FALSE);
9887 size = AOP_SIZE(IC_RESULT(ic));
9890 pic14_emitcode ("pop","acc");
9891 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9896 aopOp(IC_RESULT(ic),ic,FALSE);
9898 assignResultValue(IC_RESULT(ic));
9901 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9904 /*-----------------------------------------------------------------*/
9905 /* genDummyRead - generate code for dummy read of volatiles */
9906 /*-----------------------------------------------------------------*/
9908 genDummyRead (iCode * ic)
9910 pic14_emitcode ("; genDummyRead","");
9911 pic14_emitcode ("; not implemented","");
9916 /*-----------------------------------------------------------------*/
9917 /* genpic14Code - generate code for pic14 based controllers */
9918 /*-----------------------------------------------------------------*/
9920 * At this point, ralloc.c has gone through the iCode and attempted
9921 * to optimize in a way suitable for a PIC. Now we've got to generate
9922 * PIC instructions that correspond to the iCode.
9924 * Once the instructions are generated, we'll pass through both the
9925 * peep hole optimizer and the pCode optimizer.
9926 *-----------------------------------------------------------------*/
9928 void genpic14Code (iCode *lic)
9933 lineHead = lineCurr = NULL;
9935 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9938 /* if debug information required */
9939 if (options.debug && currFunc) {
9941 debugFile->writeFunction (currFunc, lic);
9946 for (ic = lic ; ic ; ic = ic->next ) {
9948 DEBUGpic14_emitcode(";ic","");
9949 if ( cln != ic->lineno ) {
9950 if ( options.debug ) {
9951 debugFile->writeCLine (ic);
9954 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9955 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9956 printCLine(ic->filename, ic->lineno));
9958 if (!options.noCcodeInAsm) {
9960 newpCodeCSource(ic->lineno,
9962 printCLine(ic->filename, ic->lineno)));
9968 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9970 /* if the result is marked as
9971 spilt and rematerializable or code for
9972 this has already been generated then
9974 if (resultRemat(ic) || ic->generated )
9977 /* depending on the operation */
9996 /* IPOP happens only when trying to restore a
9997 spilt live range, if there is an ifx statement
9998 following this pop then the if statement might
9999 be using some of the registers being popped which
10000 would destory the contents of the register so
10001 we need to check for this condition and handle it */
10003 ic->next->op == IFX &&
10004 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10005 genIfx (ic->next,ic);
10023 genEndFunction (ic);
10043 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10060 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10064 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10071 /* note these two are xlated by algebraic equivalence
10072 during parsing SDCC.y */
10073 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10074 "got '>=' or '<=' shouldn't have come here");
10078 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10090 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10094 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10098 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10122 genRightShift (ic);
10125 case GET_VALUE_AT_ADDRESS:
10130 if (POINTER_SET(ic))
10157 addSet(&_G.sendSet,ic);
10160 case DUMMY_READ_VOLATILE:
10170 /* now we are ready to call the
10171 peep hole optimizer */
10172 if (!options.nopeep) {
10173 peepHole (&lineHead);
10175 /* now do the actual printing */
10176 printLine (lineHead,codeOutFile);
10179 DFPRINTF((stderr,"printing pBlock\n\n"));
10180 printpBlock(stdout,pb);