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_IORFW,popGet(AOP(right),offset));
5699 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5700 emitpcode(POC_IORFW,popGet(AOP(left),offset));
5702 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5707 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5708 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5709 freeAsmop(result,NULL,ic,TRUE);
5712 /*-----------------------------------------------------------------*/
5713 /* genXor - code for xclusive or */
5714 /*-----------------------------------------------------------------*/
5715 static void genXor (iCode *ic, iCode *ifx)
5717 operand *left, *right, *result;
5719 unsigned long lit = 0L;
5721 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5723 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5724 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5725 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5727 /* if left is a literal & right is not ||
5728 if left needs acc & right does not */
5729 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5730 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5731 operand *tmp = right ;
5736 /* if result = right then exchange them */
5737 if(pic14_sameRegs(AOP(result),AOP(right))){
5738 operand *tmp = right ;
5743 /* if right is bit then exchange them */
5744 if (AOP_TYPE(right) == AOP_CRY &&
5745 AOP_TYPE(left) != AOP_CRY){
5746 operand *tmp = right ;
5750 if(AOP_TYPE(right) == AOP_LIT)
5751 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5753 size = AOP_SIZE(result);
5757 if (AOP_TYPE(left) == AOP_CRY){
5758 if(AOP_TYPE(right) == AOP_LIT){
5759 // c = bit & literal;
5761 // lit>>1 != 0 => result = 1
5762 if(AOP_TYPE(result) == AOP_CRY){
5764 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5765 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5767 continueIfTrue(ifx);
5770 pic14_emitcode("setb","c");
5774 // lit == 0, result = left
5775 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5777 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5779 // lit == 1, result = not(left)
5780 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5781 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5782 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5783 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5786 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5787 pic14_emitcode("cpl","c");
5794 symbol *tlbl = newiTempLabel(NULL);
5795 if (AOP_TYPE(right) == AOP_CRY){
5797 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5800 int sizer = AOP_SIZE(right);
5802 // if val>>1 != 0, result = 1
5803 pic14_emitcode("setb","c");
5805 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5807 // test the msb of the lsb
5808 pic14_emitcode("anl","a,#0xfe");
5809 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5813 pic14_emitcode("rrc","a");
5815 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5816 pic14_emitcode("cpl","c");
5817 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5822 pic14_outBitC(result);
5824 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5825 genIfxJump(ifx, "c");
5829 if(pic14_sameRegs(AOP(result),AOP(left))){
5830 /* if left is same as result */
5831 for(;size--; offset++) {
5832 if(AOP_TYPE(right) == AOP_LIT){
5833 int t = (lit >> (offset*8)) & 0x0FFL;
5837 if (IS_AOP_PREG(left)) {
5838 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5839 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5840 aopPut(AOP(result),"a",offset);
5842 emitpcode(POC_MOVLW, popGetLit(t));
5843 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5844 pic14_emitcode("xrl","%s,%s",
5845 aopGet(AOP(left),offset,FALSE,TRUE),
5846 aopGet(AOP(right),offset,FALSE,FALSE));
5849 if (AOP_TYPE(left) == AOP_ACC)
5850 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5852 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5853 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5855 if (IS_AOP_PREG(left)) {
5856 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5857 aopPut(AOP(result),"a",offset);
5859 pic14_emitcode("xrl","%s,a",
5860 aopGet(AOP(left),offset,FALSE,TRUE));
5866 // left & result in different registers
5867 if(AOP_TYPE(result) == AOP_CRY){
5869 // if(size), result in bit
5870 // if(!size && ifx), conditional oper: if(left ^ right)
5871 symbol *tlbl = newiTempLabel(NULL);
5872 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5874 pic14_emitcode("setb","c");
5876 if((AOP_TYPE(right) == AOP_LIT) &&
5877 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5878 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5880 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5881 pic14_emitcode("xrl","a,%s",
5882 aopGet(AOP(left),offset,FALSE,FALSE));
5884 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5889 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5890 pic14_outBitC(result);
5892 jmpTrueOrFalse(ifx, tlbl);
5893 } else for(;(size--);offset++){
5895 // result = left & right
5896 if(AOP_TYPE(right) == AOP_LIT){
5897 int t = (lit >> (offset*8)) & 0x0FFL;
5900 if (AOP_TYPE(left) != AOP_ACC) {
5901 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5903 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5904 pic14_emitcode("movf","%s,w",
5905 aopGet(AOP(left),offset,FALSE,FALSE));
5906 pic14_emitcode("movwf","%s",
5907 aopGet(AOP(result),offset,FALSE,FALSE));
5910 if (AOP_TYPE(left) == AOP_ACC) {
5911 emitpcode(POC_XORLW, popGetLit(t));
5913 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5915 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5918 if (AOP_TYPE(left) == AOP_ACC) {
5919 emitpcode(POC_XORLW, popGetLit(t));
5921 emitpcode(POC_MOVLW, popGetLit(t));
5922 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5924 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5925 pic14_emitcode("movlw","0x%x",t);
5926 pic14_emitcode("xorwf","%s,w",
5927 aopGet(AOP(left),offset,FALSE,FALSE));
5928 pic14_emitcode("movwf","%s",
5929 aopGet(AOP(result),offset,FALSE,FALSE));
5935 // faster than result <- left, anl result,right
5936 // and better if result is SFR
5937 if (AOP_TYPE(left) == AOP_ACC) {
5938 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5940 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5941 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5943 if ( AOP_TYPE(result) != AOP_ACC){
5944 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5950 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5951 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5952 freeAsmop(result,NULL,ic,TRUE);
5955 /*-----------------------------------------------------------------*/
5956 /* genInline - write the inline code out */
5957 /*-----------------------------------------------------------------*/
5958 static void genInline (iCode *ic)
5960 char *buffer, *bp, *bp1;
5962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5964 _G.inLine += (!options.asmpeep);
5966 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5967 strcpy(buffer,IC_INLINE(ic));
5969 /* emit each line as a code */
5975 addpCode2pBlock(pb,AssembleLine(bp1));
5982 pic14_emitcode(bp1,"");
5988 if ((bp1 != bp) && *bp1)
5989 addpCode2pBlock(pb,AssembleLine(bp1));
5993 _G.inLine -= (!options.asmpeep);
5996 /*-----------------------------------------------------------------*/
5997 /* genRRC - rotate right with carry */
5998 /*-----------------------------------------------------------------*/
5999 static void genRRC (iCode *ic)
6001 operand *left , *result ;
6002 int size, offset = 0, same;
6004 /* rotate right with carry */
6006 result=IC_RESULT(ic);
6007 aopOp (left,ic,FALSE);
6008 aopOp (result,ic,FALSE);
6010 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6012 same = pic14_sameRegs(AOP(result),AOP(left));
6014 size = AOP_SIZE(result);
6016 /* get the lsb and put it into the carry */
6017 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6024 emitpcode(POC_RRF, popGet(AOP(left),offset));
6026 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6027 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6033 freeAsmop(left,NULL,ic,TRUE);
6034 freeAsmop(result,NULL,ic,TRUE);
6037 /*-----------------------------------------------------------------*/
6038 /* genRLC - generate code for rotate left with carry */
6039 /*-----------------------------------------------------------------*/
6040 static void genRLC (iCode *ic)
6042 operand *left , *result ;
6043 int size, offset = 0;
6046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6047 /* rotate right with carry */
6049 result=IC_RESULT(ic);
6050 aopOp (left,ic,FALSE);
6051 aopOp (result,ic,FALSE);
6053 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6055 same = pic14_sameRegs(AOP(result),AOP(left));
6057 /* move it to the result */
6058 size = AOP_SIZE(result);
6060 /* get the msb and put it into the carry */
6061 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6068 emitpcode(POC_RLF, popGet(AOP(left),offset));
6070 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6071 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6078 freeAsmop(left,NULL,ic,TRUE);
6079 freeAsmop(result,NULL,ic,TRUE);
6082 /*-----------------------------------------------------------------*/
6083 /* genGetHbit - generates code get highest order bit */
6084 /*-----------------------------------------------------------------*/
6085 static void genGetHbit (iCode *ic)
6087 operand *left, *result;
6089 result=IC_RESULT(ic);
6090 aopOp (left,ic,FALSE);
6091 aopOp (result,ic,FALSE);
6093 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6094 /* get the highest order byte into a */
6095 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6096 if(AOP_TYPE(result) == AOP_CRY){
6097 pic14_emitcode("rlc","a");
6098 pic14_outBitC(result);
6101 pic14_emitcode("rl","a");
6102 pic14_emitcode("anl","a,#0x01");
6103 pic14_outAcc(result);
6107 freeAsmop(left,NULL,ic,TRUE);
6108 freeAsmop(result,NULL,ic,TRUE);
6111 /*-----------------------------------------------------------------*/
6112 /* AccRol - rotate left accumulator by known count */
6113 /*-----------------------------------------------------------------*/
6114 static void AccRol (operand *op,int offset,int shCount)
6116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6117 shCount &= 0x0007; // shCount : 0..7
6122 pic14_emitcode("rl","a");
6123 emitpcode(POC_RLF,popGet(AOP(op),offset));
6126 pic14_emitcode("rl","a");
6127 pic14_emitcode("rl","a");
6128 emitpcode(POC_RLF,popGet(AOP(op),offset));
6129 emitpcode(POC_RLF,popGet(AOP(op),offset));
6132 pic14_emitcode("swap","a");
6133 pic14_emitcode("rr","a");
6134 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6135 emitpcode(POC_RRF,popGet(AOP(op),offset));
6138 pic14_emitcode("swap","a");
6139 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6142 pic14_emitcode("swap","a");
6143 pic14_emitcode("rl","a");
6144 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6145 emitpcode(POC_RLF,popGet(AOP(op),offset));
6148 pic14_emitcode("rr","a");
6149 pic14_emitcode("rr","a");
6150 emitpcode(POC_RRF,popGet(AOP(op),offset));
6151 emitpcode(POC_RRF,popGet(AOP(op),offset));
6154 pic14_emitcode("rr","a");
6155 emitpcode(POC_RRF,popGet(AOP(op),offset));
6160 /*-----------------------------------------------------------------*/
6161 /* AccLsh - left shift accumulator by known count */
6162 /*-----------------------------------------------------------------*/
6163 static void AccLsh (operand *op,int offset,int shCount)
6165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6169 pic14_emitcode("add","a,acc");
6171 emitpcode(POC_RLF,popGet(AOP(op),offset));
6174 pic14_emitcode("add","a,acc");
6176 emitpcode(POC_RLF,popGet(AOP(op),offset));
6177 pic14_emitcode("add","a,acc");
6179 emitpcode(POC_RLF,popGet(AOP(op),offset));
6184 /* rotate left accumulator */
6185 AccRol(op,offset,shCount);
6186 /* and kill the lower order bits */
6187 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6188 emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
6194 /*-----------------------------------------------------------------*/
6195 /* AccRsh - right shift accumulator by known count */
6196 /*-----------------------------------------------------------------*/
6197 static void AccRsh (operand *op,int offset,int shCount)
6199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6203 pic14_emitcode("rrc","a");
6205 /* rotate right accumulator */
6206 AccRol(op,offset,8 - shCount);
6207 /* and kill the higher order bits */
6208 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6214 /*-----------------------------------------------------------------*/
6215 /* AccSRsh - signed right shift accumulator by known count */
6216 /*-----------------------------------------------------------------*/
6217 static void AccSRsh (int shCount)
6220 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6223 pic14_emitcode("mov","c,acc.7");
6224 pic14_emitcode("rrc","a");
6225 } else if(shCount == 2){
6226 pic14_emitcode("mov","c,acc.7");
6227 pic14_emitcode("rrc","a");
6228 pic14_emitcode("mov","c,acc.7");
6229 pic14_emitcode("rrc","a");
6231 tlbl = newiTempLabel(NULL);
6232 /* rotate right accumulator */
6233 AccRol(8 - shCount);
6234 /* and kill the higher order bits */
6235 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6236 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6237 pic14_emitcode("orl","a,#0x%02x",
6238 (unsigned char)~SRMask[shCount]);
6239 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6244 /*-----------------------------------------------------------------*/
6245 /* shiftR1Left2Result - shift right one byte from left to result */
6246 /*-----------------------------------------------------------------*/
6247 static void shiftR1Left2ResultSigned (operand *left, int offl,
6248 operand *result, int offr,
6253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6255 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6259 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6261 emitpcode(POC_RRF, popGet(AOP(result),offr));
6263 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6264 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6270 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6272 emitpcode(POC_RRF, popGet(AOP(result),offr));
6274 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6275 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6277 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6278 emitpcode(POC_RRF, popGet(AOP(result),offr));
6284 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6286 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6287 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6290 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6291 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6292 emitpcode(POC_ANDLW, popGetLit(0x1f));
6294 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6295 emitpcode(POC_IORLW, popGetLit(0xe0));
6297 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6301 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6302 emitpcode(POC_ANDLW, popGetLit(0x0f));
6303 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6304 emitpcode(POC_IORLW, popGetLit(0xf0));
6305 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6309 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6311 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6312 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6314 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6315 emitpcode(POC_ANDLW, popGetLit(0x07));
6316 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6317 emitpcode(POC_IORLW, popGetLit(0xf8));
6318 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6323 emitpcode(POC_MOVLW, popGetLit(0x00));
6324 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6325 emitpcode(POC_MOVLW, popGetLit(0xfe));
6326 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6327 emitpcode(POC_IORLW, popGetLit(0x01));
6328 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6330 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6331 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6332 emitpcode(POC_DECF, popGet(AOP(result),offr));
6333 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6334 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6340 emitpcode(POC_MOVLW, popGetLit(0x00));
6341 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6342 emitpcode(POC_MOVLW, popGetLit(0xff));
6343 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6345 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6346 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6347 emitpcode(POC_DECF, popGet(AOP(result),offr));
6355 /*-----------------------------------------------------------------*/
6356 /* shiftR1Left2Result - shift right one byte from left to result */
6357 /*-----------------------------------------------------------------*/
6358 static void shiftR1Left2Result (operand *left, int offl,
6359 operand *result, int offr,
6360 int shCount, int sign)
6364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6366 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6368 /* Copy the msb into the carry if signed. */
6370 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6380 emitpcode(POC_RRF, popGet(AOP(result),offr));
6382 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6383 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6389 emitpcode(POC_RRF, popGet(AOP(result),offr));
6391 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6392 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6395 emitpcode(POC_RRF, popGet(AOP(result),offr));
6400 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6402 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6403 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6407 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6408 emitpcode(POC_ANDLW, popGetLit(0x1f));
6409 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6414 emitpcode(POC_ANDLW, popGetLit(0x0f));
6415 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6419 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6420 emitpcode(POC_ANDLW, popGetLit(0x0f));
6421 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423 emitpcode(POC_RRF, popGet(AOP(result),offr));
6428 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6429 emitpcode(POC_ANDLW, popGetLit(0x80));
6430 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6431 emitpcode(POC_RLF, popGet(AOP(result),offr));
6432 emitpcode(POC_RLF, popGet(AOP(result),offr));
6437 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6438 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6439 emitpcode(POC_RLF, popGet(AOP(result),offr));
6448 /*-----------------------------------------------------------------*/
6449 /* shiftL1Left2Result - shift left one byte from left to result */
6450 /*-----------------------------------------------------------------*/
6451 static void shiftL1Left2Result (operand *left, int offl,
6452 operand *result, int offr, int shCount)
6457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6459 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6460 DEBUGpic14_emitcode ("; ***","same = %d",same);
6461 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6463 /* shift left accumulator */
6464 //AccLsh(shCount); // don't comment out just yet...
6465 // aopPut(AOP(result),"a",offr);
6469 /* Shift left 1 bit position */
6470 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6472 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6474 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6475 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6479 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6480 emitpcode(POC_ANDLW,popGetLit(0x7e));
6481 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6482 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6485 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6486 emitpcode(POC_ANDLW,popGetLit(0x3e));
6487 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6488 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6489 emitpcode(POC_RLF, popGet(AOP(result),offr));
6492 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6493 emitpcode(POC_ANDLW, popGetLit(0xf0));
6494 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6497 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6498 emitpcode(POC_ANDLW, popGetLit(0xf0));
6499 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6500 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6503 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6504 emitpcode(POC_ANDLW, popGetLit(0x30));
6505 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6506 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6507 emitpcode(POC_RLF, popGet(AOP(result),offr));
6510 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6511 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6512 emitpcode(POC_RRF, popGet(AOP(result),offr));
6516 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6521 /*-----------------------------------------------------------------*/
6522 /* movLeft2Result - move byte from left to result */
6523 /*-----------------------------------------------------------------*/
6524 static void movLeft2Result (operand *left, int offl,
6525 operand *result, int offr)
6528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6529 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6530 l = aopGet(AOP(left),offl,FALSE,FALSE);
6532 if (*l == '@' && (IS_AOP_PREG(result))) {
6533 pic14_emitcode("mov","a,%s",l);
6534 aopPut(AOP(result),"a",offr);
6536 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6537 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6542 /*-----------------------------------------------------------------*/
6543 /* shiftL2Left2Result - shift left two bytes from left to result */
6544 /*-----------------------------------------------------------------*/
6545 static void shiftL2Left2Result (operand *left, int offl,
6546 operand *result, int offr, int shCount)
6550 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6552 if(pic14_sameRegs(AOP(result), AOP(left))) {
6560 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6561 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6562 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6566 emitpcode(POC_RLF, popGet(AOP(result),offr));
6567 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6573 emitpcode(POC_MOVLW, popGetLit(0x0f));
6574 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6575 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6576 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6577 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6578 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6579 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6581 emitpcode(POC_RLF, popGet(AOP(result),offr));
6582 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6586 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6587 emitpcode(POC_RRF, popGet(AOP(result),offr));
6588 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6589 emitpcode(POC_RRF, popGet(AOP(result),offr));
6590 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6591 emitpcode(POC_ANDLW,popGetLit(0xc0));
6592 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6593 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6594 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6595 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6598 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6599 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6600 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6602 emitpcode(POC_RRF, popGet(AOP(result),offr));
6612 /* note, use a mov/add for the shift since the mov has a
6613 chance of getting optimized out */
6614 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6615 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6616 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6617 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6618 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6622 emitpcode(POC_RLF, popGet(AOP(result),offr));
6623 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6629 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6630 emitpcode(POC_ANDLW, popGetLit(0xF0));
6631 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6632 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6633 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6634 emitpcode(POC_ANDLW, popGetLit(0xF0));
6635 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6636 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6640 emitpcode(POC_RLF, popGet(AOP(result),offr));
6641 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6645 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6646 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6647 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6648 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6650 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6651 emitpcode(POC_RRF, popGet(AOP(result),offr));
6652 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6653 emitpcode(POC_ANDLW,popGetLit(0xc0));
6654 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6655 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6656 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6657 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6660 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6661 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6662 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6663 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6664 emitpcode(POC_RRF, popGet(AOP(result),offr));
6669 /*-----------------------------------------------------------------*/
6670 /* shiftR2Left2Result - shift right two bytes from left to result */
6671 /*-----------------------------------------------------------------*/
6672 static void shiftR2Left2Result (operand *left, int offl,
6673 operand *result, int offr,
6674 int shCount, int sign)
6678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6679 same = pic14_sameRegs(AOP(result), AOP(left));
6681 if(same && ((offl + MSB16) == offr)){
6683 /* don't crash result[offr] */
6684 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6685 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6688 movLeft2Result(left,offl, result, offr);
6689 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6692 /* a:x >> shCount (x = lsb(result))*/
6695 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6697 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6706 emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6711 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6712 emitpcode(POC_RRF,popGet(AOP(result),offr));
6714 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6715 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6716 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6717 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6722 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6725 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6726 emitpcode(POC_RRF,popGet(AOP(result),offr));
6733 emitpcode(POC_MOVLW, popGetLit(0xf0));
6734 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6735 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6737 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6738 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6740 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6742 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6743 emitpcode(POC_ANDLW, popGetLit(0x0f));
6744 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6746 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6747 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6748 emitpcode(POC_ANDLW, popGetLit(0xf0));
6749 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6754 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_RRF, popGet(AOP(result),offr));
6759 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6760 emitpcode(POC_BTFSC,
6761 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6762 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6770 emitpcode(POC_RLF, popGet(AOP(result),offr));
6771 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_RLF, popGet(AOP(result),offr));
6774 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6776 emitpcode(POC_ANDLW,popGetLit(0x03));
6778 emitpcode(POC_BTFSC,
6779 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6780 emitpcode(POC_IORLW,popGetLit(0xfc));
6782 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6783 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6784 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6785 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6787 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6788 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6789 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6790 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6791 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6792 emitpcode(POC_RLF, popGet(AOP(result),offr));
6793 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_ANDLW,popGetLit(0x03));
6796 emitpcode(POC_BTFSC,
6797 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6798 emitpcode(POC_IORLW,popGetLit(0xfc));
6800 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6801 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6808 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6809 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6811 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6814 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6821 /*-----------------------------------------------------------------*/
6822 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6823 /*-----------------------------------------------------------------*/
6824 static void shiftLLeftOrResult (operand *left, int offl,
6825 operand *result, int offr, int shCount)
6827 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6828 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6829 /* shift left accumulator */
6830 AccLsh(left,offl,shCount);
6831 /* or with result */
6832 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6833 /* back to result */
6834 aopPut(AOP(result),"a",offr);
6837 /*-----------------------------------------------------------------*/
6838 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6839 /*-----------------------------------------------------------------*/
6840 static void shiftRLeftOrResult (operand *left, int offl,
6841 operand *result, int offr, int shCount)
6843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6844 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6845 /* shift right accumulator */
6846 AccRsh(left,offl,shCount);
6847 /* or with result */
6848 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6849 /* back to result */
6850 aopPut(AOP(result),"a",offr);
6853 /*-----------------------------------------------------------------*/
6854 /* genlshOne - left shift a one byte quantity by known count */
6855 /*-----------------------------------------------------------------*/
6856 static void genlshOne (operand *result, operand *left, int shCount)
6858 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6859 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6862 /*-----------------------------------------------------------------*/
6863 /* genlshTwo - left shift two bytes by known amount != 0 */
6864 /*-----------------------------------------------------------------*/
6865 static void genlshTwo (operand *result,operand *left, int shCount)
6869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6870 size = pic14_getDataSize(result);
6872 /* if shCount >= 8 */
6878 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6880 movLeft2Result(left, LSB, result, MSB16);
6882 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6885 /* 1 <= shCount <= 7 */
6888 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6890 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6894 /*-----------------------------------------------------------------*/
6895 /* shiftLLong - shift left one long from left to result */
6896 /* offl = LSB or MSB16 */
6897 /*-----------------------------------------------------------------*/
6898 static void shiftLLong (operand *left, operand *result, int offr )
6901 int size = AOP_SIZE(result);
6903 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6904 if(size >= LSB+offr){
6905 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6907 pic14_emitcode("add","a,acc");
6908 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6909 size >= MSB16+offr && offr != LSB )
6910 pic14_emitcode("xch","a,%s",
6911 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6913 aopPut(AOP(result),"a",LSB+offr);
6916 if(size >= MSB16+offr){
6917 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6918 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6921 pic14_emitcode("rlc","a");
6922 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6923 size >= MSB24+offr && offr != LSB)
6924 pic14_emitcode("xch","a,%s",
6925 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6927 aopPut(AOP(result),"a",MSB16+offr);
6930 if(size >= MSB24+offr){
6931 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6932 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6935 pic14_emitcode("rlc","a");
6936 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6937 size >= MSB32+offr && offr != LSB )
6938 pic14_emitcode("xch","a,%s",
6939 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6941 aopPut(AOP(result),"a",MSB24+offr);
6944 if(size > MSB32+offr){
6945 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6946 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6949 pic14_emitcode("rlc","a");
6950 aopPut(AOP(result),"a",MSB32+offr);
6953 aopPut(AOP(result),zero,LSB);
6956 /*-----------------------------------------------------------------*/
6957 /* genlshFour - shift four byte by a known amount != 0 */
6958 /*-----------------------------------------------------------------*/
6959 static void genlshFour (operand *result, operand *left, int shCount)
6963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6964 size = AOP_SIZE(result);
6966 /* if shifting more that 3 bytes */
6967 if (shCount >= 24 ) {
6970 /* lowest order of left goes to the highest
6971 order of the destination */
6972 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6974 movLeft2Result(left, LSB, result, MSB32);
6975 aopPut(AOP(result),zero,LSB);
6976 aopPut(AOP(result),zero,MSB16);
6977 aopPut(AOP(result),zero,MSB32);
6981 /* more than two bytes */
6982 else if ( shCount >= 16 ) {
6983 /* lower order two bytes goes to higher order two bytes */
6985 /* if some more remaining */
6987 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6989 movLeft2Result(left, MSB16, result, MSB32);
6990 movLeft2Result(left, LSB, result, MSB24);
6992 aopPut(AOP(result),zero,MSB16);
6993 aopPut(AOP(result),zero,LSB);
6997 /* if more than 1 byte */
6998 else if ( shCount >= 8 ) {
6999 /* lower order three bytes goes to higher order three bytes */
7003 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7005 movLeft2Result(left, LSB, result, MSB16);
7007 else{ /* size = 4 */
7009 movLeft2Result(left, MSB24, result, MSB32);
7010 movLeft2Result(left, MSB16, result, MSB24);
7011 movLeft2Result(left, LSB, result, MSB16);
7012 aopPut(AOP(result),zero,LSB);
7014 else if(shCount == 1)
7015 shiftLLong(left, result, MSB16);
7017 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7018 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7019 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7020 aopPut(AOP(result),zero,LSB);
7025 /* 1 <= shCount <= 7 */
7026 else if(shCount <= 2){
7027 shiftLLong(left, result, LSB);
7029 shiftLLong(result, result, LSB);
7031 /* 3 <= shCount <= 7, optimize */
7033 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7034 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7035 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7039 /*-----------------------------------------------------------------*/
7040 /* genLeftShiftLiteral - left shifting by known count */
7041 /*-----------------------------------------------------------------*/
7042 static void genLeftShiftLiteral (operand *left,
7047 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7051 freeAsmop(right,NULL,ic,TRUE);
7053 aopOp(left,ic,FALSE);
7054 aopOp(result,ic,FALSE);
7056 size = getSize(operandType(result));
7059 pic14_emitcode("; shift left ","result %d, left %d",size,
7063 /* I suppose that the left size >= result size */
7066 movLeft2Result(left, size, result, size);
7070 else if(shCount >= (size * 8))
7072 aopPut(AOP(result),zero,size);
7076 genlshOne (result,left,shCount);
7081 genlshTwo (result,left,shCount);
7085 genlshFour (result,left,shCount);
7089 freeAsmop(left,NULL,ic,TRUE);
7090 freeAsmop(result,NULL,ic,TRUE);
7093 /*-----------------------------------------------------------------*
7094 * genMultiAsm - repeat assembly instruction for size of register.
7095 * if endian == 1, then the high byte (i.e base address + size of
7096 * register) is used first else the low byte is used first;
7097 *-----------------------------------------------------------------*/
7098 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7116 emitpcode(poc, popGet(AOP(reg),offset));
7121 /*-----------------------------------------------------------------*/
7122 /* genLeftShift - generates code for left shifting */
7123 /*-----------------------------------------------------------------*/
7124 static void genLeftShift (iCode *ic)
7126 operand *left,*right, *result;
7128 unsigned long lit = 0L;
7130 symbol *tlbl , *tlbl1;
7133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7135 right = IC_RIGHT(ic);
7137 result = IC_RESULT(ic);
7139 aopOp(right,ic,FALSE);
7141 /* if the shift count is known then do it
7142 as efficiently as possible */
7143 if (AOP_TYPE(right) == AOP_LIT) {
7144 genLeftShiftLiteral (left,right,result,ic);
7148 /* shift count is unknown then we have to form
7149 a loop get the loop count in B : Note: we take
7150 only the lower order byte since shifting
7151 more that 32 bits make no sense anyway, ( the
7152 largest size of an object can be only 32 bits ) */
7155 aopOp(left,ic,FALSE);
7156 aopOp(result,ic,FALSE);
7158 /* now move the left to the result if they are not the
7160 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7161 AOP_SIZE(result) > 1) {
7163 size = AOP_SIZE(result);
7166 l = aopGet(AOP(left),offset,FALSE,TRUE);
7167 if (*l == '@' && (IS_AOP_PREG(result))) {
7169 pic14_emitcode("mov","a,%s",l);
7170 aopPut(AOP(result),"a",offset);
7172 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7173 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7174 //aopPut(AOP(result),l,offset);
7180 if(AOP_TYPE(left) == AOP_LIT)
7181 lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
7183 size = AOP_SIZE(result);
7185 /* if it is only one byte then */
7187 if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
7188 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7189 emitpcode(POC_ANDLW, popGetLit(0xf0));
7190 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7191 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7192 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7193 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7194 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7195 emitpcode(POC_RLFW, popGet(AOP(result),0));
7196 emitpcode(POC_ANDLW, popGetLit(0xfe));
7197 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7198 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7199 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7202 tlbl = newiTempLabel(NULL);
7203 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7204 if (AOP_TYPE(left) == AOP_LIT)
7205 emitpcode(POC_MOVLW, popGetLit(lit));
7207 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7208 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7211 emitpcode(POC_COMFW, popGet(AOP(right),0));
7212 emitpcode(POC_RRF, popGet(AOP(result),0));
7213 emitpLabel(tlbl->key);
7214 emitpcode(POC_RLF, popGet(AOP(result),0));
7215 emitpcode(POC_ADDLW, popGetLit(1));
7217 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7222 if (pic14_sameRegs(AOP(left),AOP(result))) {
7224 tlbl = newiTempLabel(NULL);
7225 emitpcode(POC_COMFW, popGet(AOP(right),0));
7226 genMultiAsm(POC_RRF, result, size,1);
7227 emitpLabel(tlbl->key);
7228 genMultiAsm(POC_RLF, result, size,0);
7229 emitpcode(POC_ADDLW, popGetLit(1));
7231 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7235 //tlbl = newiTempLabel(NULL);
7237 //tlbl1 = newiTempLabel(NULL);
7239 //reAdjustPreg(AOP(result));
7241 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7242 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7243 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7245 //pic14_emitcode("add","a,acc");
7246 //aopPut(AOP(result),"a",offset++);
7248 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7250 // pic14_emitcode("rlc","a");
7251 // aopPut(AOP(result),"a",offset++);
7253 //reAdjustPreg(AOP(result));
7255 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7256 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7259 tlbl = newiTempLabel(NULL);
7260 tlbl1= newiTempLabel(NULL);
7262 size = AOP_SIZE(result);
7265 pctemp = popGetTempReg(); /* grab a temporary working register. */
7267 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7269 /* offset should be 0, 1 or 3 */
7270 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7272 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7274 emitpcode(POC_MOVWF, pctemp);
7277 emitpLabel(tlbl->key);
7280 emitpcode(POC_RLF, popGet(AOP(result),0));
7282 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7284 emitpcode(POC_DECFSZ, pctemp);
7285 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7286 emitpLabel(tlbl1->key);
7288 popReleaseTempReg(pctemp);
7292 freeAsmop (right,NULL,ic,TRUE);
7293 freeAsmop(left,NULL,ic,TRUE);
7294 freeAsmop(result,NULL,ic,TRUE);
7297 /*-----------------------------------------------------------------*/
7298 /* genrshOne - right shift a one byte quantity by known count */
7299 /*-----------------------------------------------------------------*/
7300 static void genrshOne (operand *result, operand *left,
7301 int shCount, int sign)
7303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7304 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7307 /*-----------------------------------------------------------------*/
7308 /* genrshTwo - right shift two bytes by known amount != 0 */
7309 /*-----------------------------------------------------------------*/
7310 static void genrshTwo (operand *result,operand *left,
7311 int shCount, int sign)
7313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7314 /* if shCount >= 8 */
7318 shiftR1Left2Result(left, MSB16, result, LSB,
7321 movLeft2Result(left, MSB16, result, LSB);
7323 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7326 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7327 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7331 /* 1 <= shCount <= 7 */
7333 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7336 /*-----------------------------------------------------------------*/
7337 /* shiftRLong - shift right one long from left to result */
7338 /* offl = LSB or MSB16 */
7339 /*-----------------------------------------------------------------*/
7340 static void shiftRLong (operand *left, int offl,
7341 operand *result, int sign)
7343 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7345 pic14_emitcode("clr","c");
7346 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7348 pic14_emitcode("mov","c,acc.7");
7349 pic14_emitcode("rrc","a");
7350 aopPut(AOP(result),"a",MSB32-offl);
7352 /* add sign of "a" */
7353 addSign(result, MSB32, sign);
7355 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7356 pic14_emitcode("rrc","a");
7357 aopPut(AOP(result),"a",MSB24-offl);
7359 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7360 pic14_emitcode("rrc","a");
7361 aopPut(AOP(result),"a",MSB16-offl);
7364 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7365 pic14_emitcode("rrc","a");
7366 aopPut(AOP(result),"a",LSB);
7370 /*-----------------------------------------------------------------*/
7371 /* genrshFour - shift four byte by a known amount != 0 */
7372 /*-----------------------------------------------------------------*/
7373 static void genrshFour (operand *result, operand *left,
7374 int shCount, int sign)
7376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7377 /* if shifting more that 3 bytes */
7378 if(shCount >= 24 ) {
7381 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7383 movLeft2Result(left, MSB32, result, LSB);
7385 addSign(result, MSB16, sign);
7387 else if(shCount >= 16){
7390 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7392 movLeft2Result(left, MSB24, result, LSB);
7393 movLeft2Result(left, MSB32, result, MSB16);
7395 addSign(result, MSB24, sign);
7397 else if(shCount >= 8){
7400 shiftRLong(left, MSB16, result, sign);
7401 else if(shCount == 0){
7402 movLeft2Result(left, MSB16, result, LSB);
7403 movLeft2Result(left, MSB24, result, MSB16);
7404 movLeft2Result(left, MSB32, result, MSB24);
7405 addSign(result, MSB32, sign);
7408 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7409 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7410 /* the last shift is signed */
7411 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7412 addSign(result, MSB32, sign);
7415 else{ /* 1 <= shCount <= 7 */
7417 shiftRLong(left, LSB, result, sign);
7419 shiftRLong(result, LSB, result, sign);
7422 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7423 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7424 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7429 /*-----------------------------------------------------------------*/
7430 /* genRightShiftLiteral - right shifting by known count */
7431 /*-----------------------------------------------------------------*/
7432 static void genRightShiftLiteral (operand *left,
7438 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7441 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7442 freeAsmop(right,NULL,ic,TRUE);
7444 aopOp(left,ic,FALSE);
7445 aopOp(result,ic,FALSE);
7448 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7452 lsize = pic14_getDataSize(left);
7453 res_size = pic14_getDataSize(result);
7454 /* test the LEFT size !!! */
7456 /* I suppose that the left size >= result size */
7459 movLeft2Result(left, lsize, result, res_size);
7462 else if(shCount >= (lsize * 8)){
7465 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7467 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7468 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7473 emitpcode(POC_MOVLW, popGetLit(0));
7474 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7475 emitpcode(POC_MOVLW, popGetLit(0xff));
7477 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7482 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7489 genrshOne (result,left,shCount,sign);
7493 genrshTwo (result,left,shCount,sign);
7497 genrshFour (result,left,shCount,sign);
7505 freeAsmop(left,NULL,ic,TRUE);
7506 freeAsmop(result,NULL,ic,TRUE);
7509 /*-----------------------------------------------------------------*/
7510 /* genSignedRightShift - right shift of signed number */
7511 /*-----------------------------------------------------------------*/
7512 static void genSignedRightShift (iCode *ic)
7514 operand *right, *left, *result;
7517 symbol *tlbl, *tlbl1 ;
7520 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7522 /* we do it the hard way put the shift count in b
7523 and loop thru preserving the sign */
7524 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7526 right = IC_RIGHT(ic);
7528 result = IC_RESULT(ic);
7530 aopOp(right,ic,FALSE);
7531 aopOp(left,ic,FALSE);
7532 aopOp(result,ic,FALSE);
7535 if ( AOP_TYPE(right) == AOP_LIT) {
7536 genRightShiftLiteral (left,right,result,ic,1);
7539 /* shift count is unknown then we have to form
7540 a loop get the loop count in B : Note: we take
7541 only the lower order byte since shifting
7542 more that 32 bits make no sense anyway, ( the
7543 largest size of an object can be only 32 bits ) */
7545 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7546 //pic14_emitcode("inc","b");
7547 //freeAsmop (right,NULL,ic,TRUE);
7548 //aopOp(left,ic,FALSE);
7549 //aopOp(result,ic,FALSE);
7551 /* now move the left to the result if they are not the
7553 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7554 AOP_SIZE(result) > 1) {
7556 size = AOP_SIZE(result);
7560 l = aopGet(AOP(left),offset,FALSE,TRUE);
7561 if (*l == '@' && IS_AOP_PREG(result)) {
7562 pic14_emitcode("mov","a,%s",l);
7563 aopPut(AOP(result),"a",offset);
7565 aopPut(AOP(result),l,offset);
7567 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7568 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7574 /* mov the highest order bit to OVR */
7575 tlbl = newiTempLabel(NULL);
7576 tlbl1= newiTempLabel(NULL);
7578 size = AOP_SIZE(result);
7581 pctemp = popGetTempReg(); /* grab a temporary working register. */
7583 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7585 /* offset should be 0, 1 or 3 */
7586 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7588 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7590 emitpcode(POC_MOVWF, pctemp);
7593 emitpLabel(tlbl->key);
7595 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7596 emitpcode(POC_RRF, popGet(AOP(result),offset));
7599 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7602 emitpcode(POC_DECFSZ, pctemp);
7603 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7604 emitpLabel(tlbl1->key);
7606 popReleaseTempReg(pctemp);
7608 size = AOP_SIZE(result);
7610 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7611 pic14_emitcode("rlc","a");
7612 pic14_emitcode("mov","ov,c");
7613 /* if it is only one byte then */
7615 l = aopGet(AOP(left),0,FALSE,FALSE);
7617 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7618 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7619 pic14_emitcode("mov","c,ov");
7620 pic14_emitcode("rrc","a");
7621 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7622 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7623 aopPut(AOP(result),"a",0);
7627 reAdjustPreg(AOP(result));
7628 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7629 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7630 pic14_emitcode("mov","c,ov");
7632 l = aopGet(AOP(result),offset,FALSE,FALSE);
7634 pic14_emitcode("rrc","a");
7635 aopPut(AOP(result),"a",offset--);
7637 reAdjustPreg(AOP(result));
7638 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7639 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7644 freeAsmop(left,NULL,ic,TRUE);
7645 freeAsmop(result,NULL,ic,TRUE);
7646 freeAsmop(right,NULL,ic,TRUE);
7649 /*-----------------------------------------------------------------*/
7650 /* genRightShift - generate code for right shifting */
7651 /*-----------------------------------------------------------------*/
7652 static void genRightShift (iCode *ic)
7654 operand *right, *left, *result;
7658 symbol *tlbl, *tlbl1 ;
7660 /* if signed then we do it the hard way preserve the
7661 sign bit moving it inwards */
7662 retype = getSpec(operandType(IC_RESULT(ic)));
7663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7665 if (!SPEC_USIGN(retype)) {
7666 genSignedRightShift (ic);
7670 /* signed & unsigned types are treated the same : i.e. the
7671 signed is NOT propagated inwards : quoting from the
7672 ANSI - standard : "for E1 >> E2, is equivalent to division
7673 by 2**E2 if unsigned or if it has a non-negative value,
7674 otherwise the result is implementation defined ", MY definition
7675 is that the sign does not get propagated */
7677 right = IC_RIGHT(ic);
7679 result = IC_RESULT(ic);
7681 aopOp(right,ic,FALSE);
7683 /* if the shift count is known then do it
7684 as efficiently as possible */
7685 if (AOP_TYPE(right) == AOP_LIT) {
7686 genRightShiftLiteral (left,right,result,ic, 0);
7690 /* shift count is unknown then we have to form
7691 a loop get the loop count in B : Note: we take
7692 only the lower order byte since shifting
7693 more that 32 bits make no sense anyway, ( the
7694 largest size of an object can be only 32 bits ) */
7696 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7697 pic14_emitcode("inc","b");
7698 aopOp(left,ic,FALSE);
7699 aopOp(result,ic,FALSE);
7701 /* now move the left to the result if they are not the
7703 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7704 AOP_SIZE(result) > 1) {
7706 size = AOP_SIZE(result);
7709 l = aopGet(AOP(left),offset,FALSE,TRUE);
7710 if (*l == '@' && IS_AOP_PREG(result)) {
7712 pic14_emitcode("mov","a,%s",l);
7713 aopPut(AOP(result),"a",offset);
7715 aopPut(AOP(result),l,offset);
7720 tlbl = newiTempLabel(NULL);
7721 tlbl1= newiTempLabel(NULL);
7722 size = AOP_SIZE(result);
7725 /* if it is only one byte then */
7728 tlbl = newiTempLabel(NULL);
7729 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7730 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7731 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7734 emitpcode(POC_COMFW, popGet(AOP(right),0));
7735 emitpcode(POC_RLF, popGet(AOP(result),0));
7736 emitpLabel(tlbl->key);
7737 emitpcode(POC_RRF, popGet(AOP(result),0));
7738 emitpcode(POC_ADDLW, popGetLit(1));
7740 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7745 reAdjustPreg(AOP(result));
7746 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7747 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7750 l = aopGet(AOP(result),offset,FALSE,FALSE);
7752 pic14_emitcode("rrc","a");
7753 aopPut(AOP(result),"a",offset--);
7755 reAdjustPreg(AOP(result));
7757 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7758 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7761 freeAsmop(left,NULL,ic,TRUE);
7762 freeAsmop (right,NULL,ic,TRUE);
7763 freeAsmop(result,NULL,ic,TRUE);
7766 /*-----------------------------------------------------------------*/
7767 /* genUnpackBits - generates code for unpacking bits */
7768 /*-----------------------------------------------------------------*/
7769 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
7772 int offset = 0; /* result byte offset */
7773 int rsize; /* result size */
7774 int rlen = 0; /* remaining bitfield length */
7775 sym_link *etype; /* bitfield type information */
7776 int blen; /* bitfield length */
7777 int bstr; /* bitfield starting bit within byte */
7779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7780 etype = getSpec(operandType(result));
7781 rsize = getSize (operandType (result));
7782 blen = SPEC_BLEN (etype);
7783 bstr = SPEC_BSTR (etype);
7785 /* single bit field case */
7787 if (ifx) { /* that is for an if statement */
7790 resolveIfx(&rIfx,ifx);
7791 if (ptype == -1) /* direct */
7792 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7794 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7795 emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
7796 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
7800 if (ptype == -1) /* direct */
7801 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7803 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7804 emitpcode(POC_BTFSC,pcop);
7805 emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7807 if (ptype == -1) /* direct */
7808 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7810 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7811 emitpcode(POC_BTFSS,pcop);
7812 emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7817 /* read the first byte */
7822 // pic14_emitcode("mov","a,@%s",rname);
7823 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
7827 pic14_emitcode("movx","a,@%s",rname);
7831 pic14_emitcode("movx","a,@dptr");
7835 pic14_emitcode("clr","a");
7836 pic14_emitcode("movc","a","@a+dptr");
7840 pic14_emitcode("lcall","__gptrget");
7844 /* if we have bitdisplacement then it fits */
7845 /* into this byte completely or if length is */
7846 /* less than a byte */
7847 if ((shCnt = SPEC_BSTR(etype)) || blen <= 8) {
7849 /* shift right acc */
7850 AccRsh(left,0,shCnt);
7852 pic14_emitcode("anl","a,#0x%02x",
7853 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7854 aopPut(AOP(result),"a",offset);
7858 /* bit field did not fit in a byte */
7859 rlen = SPEC_BLEN(etype) - 8;
7860 aopPut(AOP(result),"a",offset++);
7867 pic14_emitcode("inc","%s",rname);
7868 pic14_emitcode("mov","a,@%s",rname);
7872 pic14_emitcode("inc","%s",rname);
7873 pic14_emitcode("movx","a,@%s",rname);
7877 pic14_emitcode("inc","dptr");
7878 pic14_emitcode("movx","a,@dptr");
7882 pic14_emitcode("clr","a");
7883 pic14_emitcode("inc","dptr");
7884 pic14_emitcode("movc","a","@a+dptr");
7888 pic14_emitcode("inc","dptr");
7889 pic14_emitcode("lcall","__gptrget");
7894 /* if we are done */
7898 aopPut(AOP(result),"a",offset++);
7903 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7904 aopPut(AOP(result),"a",offset);
7911 /*-----------------------------------------------------------------*/
7912 /* genDataPointerGet - generates code when ptr offset is known */
7913 /*-----------------------------------------------------------------*/
7914 static void genDataPointerGet (operand *left,
7918 int size , offset = 0;
7921 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7924 /* optimization - most of the time, left and result are the same
7925 * address, but different types. for the pic code, we could omit
7929 aopOp(result,ic,TRUE);
7931 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7933 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7935 size = AOP_SIZE(result);
7938 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7942 freeAsmop(left,NULL,ic,TRUE);
7943 freeAsmop(result,NULL,ic,TRUE);
7946 /*-----------------------------------------------------------------*/
7947 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7948 /*-----------------------------------------------------------------*/
7949 static void genNearPointerGet (operand *left,
7954 sym_link *ltype = operandType(left);
7955 sym_link *rtype = operandType(result);
7956 sym_link *retype= getSpec(rtype); /* bitfield type information */
7960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 aopOp(left,ic,FALSE);
7965 /* if left is rematerialisable and
7966 result is not bit variable type and
7967 the left is pointer to data space i.e
7968 lower 128 bytes of space */
7969 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7970 !IS_BITVAR(retype) &&
7971 DCL_TYPE(ltype) == POINTER) {
7972 //genDataPointerGet (left,result,ic);
7976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7977 aopOp (result,ic,FALSE);
7979 /* Check if can access directly instead of via a pointer */
7980 if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
7984 /* If the pointer value is not in a the FSR then need to put it in */
7985 if (!AOP_INPREG(AOP(left)) && !direct) {
7986 /* otherwise get a free pointer register */
7987 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7988 if (PCOP(AOP(result))->type == PO_LITERAL)
7989 emitpcode(POC_MOVLW, popGet(AOP(left),0));
7991 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7992 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
7997 /* if bitfield then unpack the bits */
7998 if (IS_BITFIELD(retype))
7999 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8001 /* we have can just get the values */
8002 int size = AOP_SIZE(result);
8005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8009 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8011 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8012 if (AOP_TYPE(result) == AOP_LIT) {
8013 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8015 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8017 if (size && !direct)
8018 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8023 /* now some housekeeping stuff */
8025 /* we had to allocate for this iCode */
8026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8027 freeAsmop(NULL,aop,ic,TRUE);
8029 /* we did not allocate which means left
8030 already in a pointer register, then
8031 if size > 0 && this could be used again
8032 we have to point it back to where it
8034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8035 if (AOP_SIZE(result) > 1 &&
8036 !OP_SYMBOL(left)->remat &&
8037 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8039 int size = AOP_SIZE(result) - 1;
8041 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8046 freeAsmop(left,NULL,ic,TRUE);
8047 freeAsmop(result,NULL,ic,TRUE);
8051 /*-----------------------------------------------------------------*/
8052 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8053 /*-----------------------------------------------------------------*/
8054 static void genPagedPointerGet (operand *left,
8061 sym_link *rtype, *retype;
8063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8065 rtype = operandType(result);
8066 retype= getSpec(rtype);
8068 aopOp(left,ic,FALSE);
8070 /* if the value is already in a pointer register
8071 then don't need anything more */
8072 if (!AOP_INPREG(AOP(left))) {
8073 /* otherwise get a free pointer register */
8075 preg = getFreePtr(ic,&aop,FALSE);
8076 pic14_emitcode("mov","%s,%s",
8078 aopGet(AOP(left),0,FALSE,TRUE));
8079 rname = preg->name ;
8081 rname = aopGet(AOP(left),0,FALSE,FALSE);
8083 freeAsmop(left,NULL,ic,TRUE);
8084 aopOp (result,ic,FALSE);
8086 /* if bitfield then unpack the bits */
8087 if (IS_BITFIELD(retype))
8088 genUnpackBits (result,left,rname,PPOINTER,0);
8090 /* we have can just get the values */
8091 int size = AOP_SIZE(result);
8096 pic14_emitcode("movx","a,@%s",rname);
8097 aopPut(AOP(result),"a",offset);
8102 pic14_emitcode("inc","%s",rname);
8106 /* now some housekeeping stuff */
8108 /* we had to allocate for this iCode */
8109 freeAsmop(NULL,aop,ic,TRUE);
8111 /* we did not allocate which means left
8112 already in a pointer register, then
8113 if size > 0 && this could be used again
8114 we have to point it back to where it
8116 if (AOP_SIZE(result) > 1 &&
8117 !OP_SYMBOL(left)->remat &&
8118 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8120 int size = AOP_SIZE(result) - 1;
8122 pic14_emitcode("dec","%s",rname);
8127 freeAsmop(result,NULL,ic,TRUE);
8132 /*-----------------------------------------------------------------*/
8133 /* genFarPointerGet - gget value from far space */
8134 /*-----------------------------------------------------------------*/
8135 static void genFarPointerGet (operand *left,
8136 operand *result, iCode *ic)
8139 sym_link *retype = getSpec(operandType(result));
8141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8143 aopOp(left,ic,FALSE);
8145 /* if the operand is already in dptr
8146 then we do nothing else we move the value to dptr */
8147 if (AOP_TYPE(left) != AOP_STR) {
8148 /* if this is remateriazable */
8149 if (AOP_TYPE(left) == AOP_IMMD)
8150 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8151 else { /* we need to get it byte by byte */
8152 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8153 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8154 if (options.model == MODEL_FLAT24)
8156 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8160 /* so dptr know contains the address */
8161 freeAsmop(left,NULL,ic,TRUE);
8162 aopOp(result,ic,FALSE);
8164 /* if bit then unpack */
8165 if (IS_BITFIELD(retype))
8166 genUnpackBits(result,left,"dptr",FPOINTER,0);
8168 size = AOP_SIZE(result);
8172 pic14_emitcode("movx","a,@dptr");
8173 aopPut(AOP(result),"a",offset++);
8175 pic14_emitcode("inc","dptr");
8179 freeAsmop(result,NULL,ic,TRUE);
8182 /*-----------------------------------------------------------------*/
8183 /* genCodePointerGet - get value from code space */
8184 /*-----------------------------------------------------------------*/
8185 static void genCodePointerGet (operand *left,
8186 operand *result, iCode *ic)
8189 sym_link *retype = getSpec(operandType(result));
8191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8193 aopOp(left,ic,FALSE);
8195 /* if the operand is already in dptr
8196 then we do nothing else we move the value to dptr */
8197 if (AOP_TYPE(left) != AOP_STR) {
8198 /* if this is remateriazable */
8199 if (AOP_TYPE(left) == AOP_IMMD)
8200 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8201 else { /* we need to get it byte by byte */
8202 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8203 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8204 if (options.model == MODEL_FLAT24)
8206 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8210 /* so dptr know contains the address */
8211 freeAsmop(left,NULL,ic,TRUE);
8212 aopOp(result,ic,FALSE);
8214 /* if bit then unpack */
8215 if (IS_BITFIELD(retype))
8216 genUnpackBits(result,left,"dptr",CPOINTER,0);
8218 size = AOP_SIZE(result);
8222 pic14_emitcode("clr","a");
8223 pic14_emitcode("movc","a,@a+dptr");
8224 aopPut(AOP(result),"a",offset++);
8226 pic14_emitcode("inc","dptr");
8230 freeAsmop(result,NULL,ic,TRUE);
8233 /*-----------------------------------------------------------------*/
8234 /* genGenPointerGet - gget value from generic pointer space */
8235 /*-----------------------------------------------------------------*/
8236 static void genGenPointerGet (operand *left,
8237 operand *result, iCode *ic)
8240 sym_link *retype = getSpec(operandType(result));
8242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8243 aopOp(left,ic,FALSE);
8244 aopOp(result,ic,FALSE);
8247 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8249 /* if the operand is already in dptr
8250 then we do nothing else we move the value to dptr */
8251 // if (AOP_TYPE(left) != AOP_STR) {
8252 /* if this is remateriazable */
8253 if (AOP_TYPE(left) == AOP_IMMD) {
8254 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8255 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8257 else { /* we need to get it byte by byte */
8259 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8260 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8262 size = AOP_SIZE(result);
8266 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8267 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8269 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8274 /* so dptr know contains the address */
8276 /* if bit then unpack */
8277 //if (IS_BITFIELD(retype))
8278 // genUnpackBits(result,"dptr",GPOINTER);
8281 freeAsmop(left,NULL,ic,TRUE);
8282 freeAsmop(result,NULL,ic,TRUE);
8286 /*-----------------------------------------------------------------*/
8287 /* genConstPointerGet - get value from const generic pointer space */
8288 /*-----------------------------------------------------------------*/
8289 static void genConstPointerGet (operand *left,
8290 operand *result, iCode *ic)
8292 //sym_link *retype = getSpec(operandType(result));
8293 symbol *albl = newiTempLabel(NULL);
8294 symbol *blbl = newiTempLabel(NULL);
8298 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8299 aopOp(left,ic,FALSE);
8300 aopOp(result,ic,FALSE);
8303 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8305 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8307 emitpcode(POC_CALL,popGetLabel(albl->key));
8308 pcop = popGetLabel(blbl->key);
8309 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8310 emitpcode(POC_GOTO,pcop);
8311 emitpLabel(albl->key);
8313 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8315 emitpcode(poc,popGet(AOP(left),1));
8316 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8317 emitpcode(poc,popGet(AOP(left),0));
8318 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8320 emitpLabel(blbl->key);
8322 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8325 freeAsmop(left,NULL,ic,TRUE);
8326 freeAsmop(result,NULL,ic,TRUE);
8329 /*-----------------------------------------------------------------*/
8330 /* genPointerGet - generate code for pointer get */
8331 /*-----------------------------------------------------------------*/
8332 static void genPointerGet (iCode *ic)
8334 operand *left, *result ;
8335 sym_link *type, *etype;
8338 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8341 result = IC_RESULT(ic) ;
8343 /* depending on the type of pointer we need to
8344 move it to the correct pointer register */
8345 type = operandType(left);
8346 etype = getSpec(type);
8348 if (IS_PTR_CONST(type))
8349 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8351 /* if left is of type of pointer then it is simple */
8352 if (IS_PTR(type) && !IS_FUNC(type->next))
8353 p_type = DCL_TYPE(type);
8355 /* we have to go by the storage class */
8356 p_type = PTR_TYPE(SPEC_OCLS(etype));
8358 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8360 if (SPEC_OCLS(etype)->codesp ) {
8361 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8362 //p_type = CPOINTER ;
8365 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8366 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8367 /*p_type = FPOINTER ;*/
8369 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8370 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8371 /* p_type = PPOINTER; */
8373 if (SPEC_OCLS(etype) == idata )
8374 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8375 /* p_type = IPOINTER; */
8377 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8378 /* p_type = POINTER ; */
8381 /* now that we have the pointer type we assign
8382 the pointer values */
8387 genNearPointerGet (left,result,ic);
8391 genPagedPointerGet(left,result,ic);
8395 genFarPointerGet (left,result,ic);
8399 genConstPointerGet (left,result,ic);
8400 //pic14_emitcodePointerGet (left,result,ic);
8404 if (IS_PTR_CONST(type))
8405 genConstPointerGet (left,result,ic);
8407 genGenPointerGet (left,result,ic);
8413 /*-----------------------------------------------------------------*/
8414 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into */
8415 /* A through a pointer register (R0, R1, or DPTR). The original */
8416 /* value of A can be preserved in B. */
8417 /* PIC has to use INDF register. */
8418 /*-----------------------------------------------------------------*/
8420 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8427 pic14_emitcode ("mov", "b,a");
8428 // pic14_emitcode ("mov", "a,@%s", rname);
8429 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8434 pic14_emitcode ("mov", "b,a");
8435 pic14_emitcode ("movx", "a,@%s", rname);
8440 pic14_emitcode ("mov", "b,a");
8441 pic14_emitcode ("movx", "a,@dptr");
8446 pic14_emitcode ("mov", "b,a");
8447 pic14_emitcode ("clr", "a");
8448 pic14_emitcode ("movc", "a,@a+dptr");
8454 pic14_emitcode ("push", "b");
8455 pic14_emitcode ("push", "acc");
8457 pic14_emitcode ("lcall", "__gptrget");
8459 pic14_emitcode ("pop", "b");
8464 /*-----------------------------------------------------------------*/
8465 /* emitPtrByteSet - emits code to set a byte from src through a */
8466 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR). */
8467 /*-----------------------------------------------------------------*/
8469 emitPtrByteSet (char *rname, int p_type, char *src)
8478 pic14_emitcode ("mov", "@%s,a", rname);
8481 // pic14_emitcode ("mov", "@%s,%s", rname, src);
8482 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8487 pic14_emitcode ("movx", "@%s,a", rname);
8492 pic14_emitcode ("movx", "@dptr,a");
8497 pic14_emitcode ("lcall", "__gptrput");
8502 /*-----------------------------------------------------------------*/
8503 /* genPackBits - generates code for packed bit storage */
8504 /*-----------------------------------------------------------------*/
8505 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8507 int offset = 0; /* source byte offset */
8508 int rlen = 0; /* remaining bitfield length */
8509 int blen; /* bitfield length */
8510 int bstr; /* bitfield starting bit within byte */
8511 int litval; /* source literal value (if AOP_LIT) */
8512 unsigned char mask; /* bitmask within current byte */
8514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8516 blen = SPEC_BLEN (etype);
8517 bstr = SPEC_BSTR (etype);
8519 /* If the bitfield length is less than a byte */
8522 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8523 (unsigned char) (0xFF >> (8 - bstr)));
8525 if (AOP_TYPE (right) == AOP_LIT)
8527 /* Case with a bitfield length <8 and literal source
8529 int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8533 if (AOP(result)->type == AOP_PCODE)
8534 pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
8536 pcop = popGet(AOP(result),0);
8537 emitpcode(lit?POC_BSF:POC_BCF,pcop);
8539 emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8543 litval = lit << bstr;
8544 litval &= (~mask) & 0xff;
8546 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8548 emitPtrByteGet (rname, p_type, FALSE);
8549 if ((mask|litval)!=0xff)
8550 emitpcode(POC_ANDLW,popGetLit(mask));
8552 emitpcode(POC_IORLW,popGetLit(litval));
8559 /* 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 */
8560 emitpcode(POC_RLF,popGet(AOP(right),0));
8562 emitpcode(POC_BCF,popGet(AOP(result),0));
8564 emitpcode(POC_BSF,popGet(AOP(result),0));
8565 } else if (p_type!=GPOINTER) {
8566 /* Case with a bitfield length == 1 and no generic pointer
8568 if (AOP_TYPE (right) == AOP_CRY)
8569 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
8572 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8573 pic14_emitcode ("rrc","a");
8575 emitPtrByteGet (rname, p_type, FALSE);
8576 pic14_emitcode ("mov","acc.%d,c",bstr);
8582 /* Case with a bitfield length < 8 and arbitrary source
8584 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8585 /* shift and mask source value */
8586 AccLsh (right,0,bstr);
8587 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8588 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
8590 //pushedB = pushB ();
8592 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8594 emitPtrByteGet (rname, p_type, TRUE);
8596 pic14_emitcode ("anl", "a,#0x%02x", mask);
8597 pic14_emitcode ("orl", "a,b");
8598 emitpcode(POC_ANDLW,popGetLit(mask));
8599 emitpcode(POC_IORFW,popGet(AOP(right),0));
8600 if (p_type == GPOINTER)
8601 pic14_emitcode ("pop", "b");
8608 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8610 emitPtrByteSet (rname, p_type, "a");
8614 /* Bit length is greater than 7 bits. In this case, copy */
8615 /* all except the partial byte at the end */
8616 for (rlen=blen;rlen>=8;rlen-=8)
8618 emitPtrByteSet (rname, p_type,
8619 aopGet (AOP (right), offset++, FALSE, TRUE) );
8621 pic14_emitcode ("inc", "%s", rname);
8624 /* If there was a partial byte at the end */
8627 mask = (((unsigned char) -1 << rlen) & 0xff);
8629 if (AOP_TYPE (right) == AOP_LIT)
8631 /* Case with partial byte and literal source
8633 litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8634 litval >>= (blen-rlen);
8635 litval &= (~mask) & 0xff;
8636 emitPtrByteGet (rname, p_type, FALSE);
8637 if ((mask|litval)!=0xff)
8638 pic14_emitcode ("anl","a,#0x%02x", mask);
8640 pic14_emitcode ("orl","a,#0x%02x", litval);
8645 /* Case with partial byte and arbitrary source
8647 MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
8648 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8650 //pushedB = pushB ();
8651 /* transfer A to B and get next byte */
8652 emitPtrByteGet (rname, p_type, TRUE);
8654 pic14_emitcode ("anl", "a,#0x%02x", mask);
8655 pic14_emitcode ("orl", "a,b");
8656 if (p_type == GPOINTER)
8657 pic14_emitcode ("pop", "b");
8661 emitPtrByteSet (rname, p_type, "a");
8666 /*-----------------------------------------------------------------*/
8667 /* SetIrp - Set IRP bit */
8668 /*-----------------------------------------------------------------*/
8669 void SetIrp(operand *result) {
8670 if (AOP_TYPE(result) == AOP_LIT) {
8671 unsigned lit = (unsigned)operandLitValue(result);
8672 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8674 if (PCOP(AOP(result))->type == PO_LITERAL) {
8675 int addrs = PCOL(AOP(result))->lit;
8676 emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8678 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
8679 if(AOP_SIZE(result) > 1) {
8680 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8681 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8687 /*-----------------------------------------------------------------*/
8688 /* genDataPointerSet - remat pointer to data space */
8689 /*-----------------------------------------------------------------*/
8690 static void genDataPointerSet(operand *right,
8694 int size, offset = 0 ;
8695 char *l, buffer[256];
8697 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8698 aopOp(right,ic,FALSE);
8700 l = aopGet(AOP(result),0,FALSE,TRUE);
8701 size = AOP_SIZE(right);
8703 if ( AOP_TYPE(result) == AOP_PCODE) {
8704 fprintf(stderr,"genDataPointerSet %s, %d\n",
8705 AOP(result)->aopu.pcop->name,
8706 PCOI(AOP(result)->aopu.pcop)->offset);
8710 // tsd, was l+1 - the underline `_' prefix was being stripped
8713 sprintf(buffer,"(%s + %d)",l,offset);
8714 fprintf(stderr,"oops %s\n",buffer);
8716 sprintf(buffer,"%s",l);
8718 if (AOP_TYPE(right) == AOP_LIT) {
8719 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8720 lit = lit >> (8*offset);
8722 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8723 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8725 emitpcode(POC_CLRF, popGet(AOP(result),0));
8728 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8729 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8735 freeAsmop(right,NULL,ic,TRUE);
8736 freeAsmop(result,NULL,ic,TRUE);
8739 /*-----------------------------------------------------------------*/
8740 /* genNearPointerSet - pic14_emitcode for near pointer put */
8741 /*-----------------------------------------------------------------*/
8742 static void genNearPointerSet (operand *right,
8747 sym_link *ptype = operandType(result);
8748 sym_link *retype = getSpec(operandType(right));
8749 sym_link *letype = getSpec(ptype);
8753 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8754 aopOp(result,ic,FALSE);
8757 /* if the result is rematerializable &
8758 in data space & not a bit variable */
8759 //if (AOP_TYPE(result) == AOP_IMMD &&
8760 if (AOP_TYPE(result) == AOP_PCODE &&
8761 DCL_TYPE(ptype) == POINTER &&
8762 !IS_BITVAR (retype) &&
8763 !IS_BITVAR (letype)) {
8764 genDataPointerSet (right,result,ic);
8765 freeAsmop(result,NULL,ic,TRUE);
8769 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8770 aopOp(right,ic,FALSE);
8771 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8773 /* Check if can access directly instead of via a pointer */
8774 if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
8778 /* If the pointer value is not in a the FSR then need to put it in */
8779 if (!AOP_INPREG(AOP(result)) && !direct) {
8780 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8781 if (PCOP(AOP(result))->type == PO_LITERAL)
8782 emitpcode(POC_MOVLW, popGet(AOP(result),0));
8784 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8785 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8788 /* Must set/reset IRP bit for use with FSR. */
8789 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
8793 /* if bitfield then unpack the bits */
8794 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
8795 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
8797 /* we have can just get the values */
8798 int size = AOP_SIZE(right);
8801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8803 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
8805 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8807 if (AOP_TYPE(right) == AOP_LIT) {
8808 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
8810 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
8813 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8815 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8817 if (size && !direct)
8818 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8824 /* now some housekeeping stuff */
8826 /* we had to allocate for this iCode */
8827 freeAsmop(NULL,aop,ic,TRUE);
8829 /* we did not allocate which means left
8830 already in a pointer register, then
8831 if size > 0 && this could be used again
8832 we have to point it back to where it
8834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8835 if (AOP_SIZE(right) > 1 &&
8836 !OP_SYMBOL(result)->remat &&
8837 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8839 int size = AOP_SIZE(right) - 1;
8841 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8845 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8848 freeAsmop(right,NULL,ic,TRUE);
8849 freeAsmop(result,NULL,ic,TRUE);
8852 /*-----------------------------------------------------------------*/
8853 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8854 /*-----------------------------------------------------------------*/
8855 static void genPagedPointerSet (operand *right,
8864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8866 retype= getSpec(operandType(right));
8868 aopOp(result,ic,FALSE);
8870 /* if the value is already in a pointer register
8871 then don't need anything more */
8872 if (!AOP_INPREG(AOP(result))) {
8873 /* otherwise get a free pointer register */
8875 preg = getFreePtr(ic,&aop,FALSE);
8876 pic14_emitcode("mov","%s,%s",
8878 aopGet(AOP(result),0,FALSE,TRUE));
8879 rname = preg->name ;
8881 rname = aopGet(AOP(result),0,FALSE,FALSE);
8883 freeAsmop(result,NULL,ic,TRUE);
8884 aopOp (right,ic,FALSE);
8886 /* if bitfield then unpack the bits */
8887 if (IS_BITFIELD(retype))
8888 genPackBits (retype,result,right,rname,PPOINTER);
8890 /* we have can just get the values */
8891 int size = AOP_SIZE(right);
8895 l = aopGet(AOP(right),offset,FALSE,TRUE);
8898 pic14_emitcode("movx","@%s,a",rname);
8901 pic14_emitcode("inc","%s",rname);
8907 /* now some housekeeping stuff */
8909 /* we had to allocate for this iCode */
8910 freeAsmop(NULL,aop,ic,TRUE);
8912 /* we did not allocate which means left
8913 already in a pointer register, then
8914 if size > 0 && this could be used again
8915 we have to point it back to where it
8917 if (AOP_SIZE(right) > 1 &&
8918 !OP_SYMBOL(result)->remat &&
8919 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8921 int size = AOP_SIZE(right) - 1;
8923 pic14_emitcode("dec","%s",rname);
8928 freeAsmop(right,NULL,ic,TRUE);
8933 /*-----------------------------------------------------------------*/
8934 /* genFarPointerSet - set value from far space */
8935 /*-----------------------------------------------------------------*/
8936 static void genFarPointerSet (operand *right,
8937 operand *result, iCode *ic)
8940 sym_link *retype = getSpec(operandType(right));
8942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8943 aopOp(result,ic,FALSE);
8945 /* if the operand is already in dptr
8946 then we do nothing else we move the value to dptr */
8947 if (AOP_TYPE(result) != AOP_STR) {
8948 /* if this is remateriazable */
8949 if (AOP_TYPE(result) == AOP_IMMD)
8950 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8951 else { /* we need to get it byte by byte */
8952 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8953 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8954 if (options.model == MODEL_FLAT24)
8956 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8960 /* so dptr know contains the address */
8961 freeAsmop(result,NULL,ic,TRUE);
8962 aopOp(right,ic,FALSE);
8964 /* if bit then unpack */
8965 if (IS_BITFIELD(retype))
8966 genPackBits(retype,result,right,"dptr",FPOINTER);
8968 size = AOP_SIZE(right);
8972 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8974 pic14_emitcode("movx","@dptr,a");
8976 pic14_emitcode("inc","dptr");
8980 freeAsmop(right,NULL,ic,TRUE);
8983 /*-----------------------------------------------------------------*/
8984 /* genGenPointerSet - set value from generic pointer space */
8985 /*-----------------------------------------------------------------*/
8986 static void genGenPointerSet (operand *right,
8987 operand *result, iCode *ic)
8989 sym_link *ptype = operandType(result);
8990 sym_link *retype = getSpec(operandType(right));
8991 sym_link *letype = getSpec (ptype);
8993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8995 aopOp(result,ic,FALSE);
8996 aopOp(right,ic,FALSE);
8998 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9000 /* if the operand is already in dptr
9001 then we do nothing else we move the value to dptr */
9002 if (AOP_TYPE(result) != AOP_STR) {
9003 /* if this is remateriazable */
9004 if (AOP_TYPE(result) == AOP_IMMD) {
9005 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9006 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9009 emitpcode(POC_MOVFW,popGet(AOP(result),0));
9010 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9012 /* Must set/reset IRP bit for use with FSR. */
9013 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9018 /* if bitfield then unpack the bits */
9019 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9020 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9022 /* we have can just get the values */
9023 int size = AOP_SIZE(right);
9026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9028 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9030 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9032 if (AOP_TYPE(right) == AOP_LIT) {
9033 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9035 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9037 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9040 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9045 freeAsmop(right,NULL,ic,TRUE);
9046 freeAsmop(result,NULL,ic,TRUE);
9049 /*-----------------------------------------------------------------*/
9050 /* genPointerSet - stores the value into a pointer location */
9051 /*-----------------------------------------------------------------*/
9052 static void genPointerSet (iCode *ic)
9054 operand *right, *result ;
9055 sym_link *type, *etype;
9058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9060 right = IC_RIGHT(ic);
9061 result = IC_RESULT(ic) ;
9063 /* depending on the type of pointer we need to
9064 move it to the correct pointer register */
9065 type = operandType(result);
9066 etype = getSpec(type);
9067 /* if left is of type of pointer then it is simple */
9068 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9069 p_type = DCL_TYPE(type);
9072 /* we have to go by the storage class */
9073 p_type = PTR_TYPE(SPEC_OCLS(etype));
9075 /* if (SPEC_OCLS(etype)->codesp ) { */
9076 /* p_type = CPOINTER ; */
9079 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9080 /* p_type = FPOINTER ; */
9082 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9083 /* p_type = PPOINTER ; */
9085 /* if (SPEC_OCLS(etype) == idata ) */
9086 /* p_type = IPOINTER ; */
9088 /* p_type = POINTER ; */
9091 /* now that we have the pointer type we assign
9092 the pointer values */
9097 genNearPointerSet (right,result,ic);
9101 genPagedPointerSet (right,result,ic);
9105 genFarPointerSet (right,result,ic);
9109 genGenPointerSet (right,result,ic);
9113 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9114 "genPointerSet: illegal pointer type");
9118 /*-----------------------------------------------------------------*/
9119 /* genIfx - generate code for Ifx statement */
9120 /*-----------------------------------------------------------------*/
9121 static void genIfx (iCode *ic, iCode *popIc)
9123 operand *cond = IC_COND(ic);
9126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9128 aopOp(cond,ic,FALSE);
9130 /* get the value into acc */
9131 if (AOP_TYPE(cond) != AOP_CRY)
9132 pic14_toBoolean(cond);
9135 /* the result is now in the accumulator */
9136 freeAsmop(cond,NULL,ic,TRUE);
9138 /* if there was something to be popped then do it */
9142 /* if the condition is a bit variable */
9143 if (isbit && IS_ITEMP(cond) &&
9145 genIfxJump(ic,SPIL_LOC(cond)->rname);
9146 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9149 if (isbit && !IS_ITEMP(cond))
9150 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9158 /*-----------------------------------------------------------------*/
9159 /* genAddrOf - generates code for address of */
9160 /*-----------------------------------------------------------------*/
9161 static void genAddrOf (iCode *ic)
9163 operand *right, *result, *left;
9166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9169 //aopOp(IC_RESULT(ic),ic,FALSE);
9171 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9172 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9173 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9175 DEBUGpic14_AopType(__LINE__,left,right,result);
9177 size = AOP_SIZE(IC_RESULT(ic));
9181 /* fixing bug #863624, reported from (errolv) */
9182 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9183 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9186 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9187 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9192 freeAsmop(left,NULL,ic,FALSE);
9193 freeAsmop(result,NULL,ic,TRUE);
9198 /*-----------------------------------------------------------------*/
9199 /* genFarFarAssign - assignment when both are in far space */
9200 /*-----------------------------------------------------------------*/
9201 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9203 int size = AOP_SIZE(right);
9206 /* first push the right side on to the stack */
9208 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9210 pic14_emitcode ("push","acc");
9213 freeAsmop(right,NULL,ic,FALSE);
9214 /* now assign DPTR to result */
9215 aopOp(result,ic,FALSE);
9216 size = AOP_SIZE(result);
9218 pic14_emitcode ("pop","acc");
9219 aopPut(AOP(result),"a",--offset);
9221 freeAsmop(result,NULL,ic,FALSE);
9226 /*-----------------------------------------------------------------*/
9227 /* genAssign - generate code for assignment */
9228 /*-----------------------------------------------------------------*/
9229 static void genAssign (iCode *ic)
9231 operand *result, *right;
9232 int size, offset,know_W;
9233 unsigned long lit = 0L;
9235 result = IC_RESULT(ic);
9236 right = IC_RIGHT(ic) ;
9238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9240 /* if they are the same */
9241 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9244 aopOp(right,ic,FALSE);
9245 aopOp(result,ic,TRUE);
9247 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9249 /* if they are the same registers */
9250 if (pic14_sameRegs(AOP(right),AOP(result)))
9253 /* if the result is a bit */
9254 if (AOP_TYPE(result) == AOP_CRY) {
9256 /* if the right size is a literal then
9257 we know what the value is */
9258 if (AOP_TYPE(right) == AOP_LIT) {
9260 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9261 popGet(AOP(result),0));
9263 if (((int) operandLitValue(right)))
9264 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9265 AOP(result)->aopu.aop_dir,
9266 AOP(result)->aopu.aop_dir);
9268 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9269 AOP(result)->aopu.aop_dir,
9270 AOP(result)->aopu.aop_dir);
9274 /* the right is also a bit variable */
9275 if (AOP_TYPE(right) == AOP_CRY) {
9276 emitpcode(POC_BCF, popGet(AOP(result),0));
9277 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9278 emitpcode(POC_BSF, popGet(AOP(result),0));
9280 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9281 AOP(result)->aopu.aop_dir,
9282 AOP(result)->aopu.aop_dir);
9283 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9284 AOP(right)->aopu.aop_dir,
9285 AOP(right)->aopu.aop_dir);
9286 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9287 AOP(result)->aopu.aop_dir,
9288 AOP(result)->aopu.aop_dir);
9293 emitpcode(POC_BCF, popGet(AOP(result),0));
9294 pic14_toBoolean(right);
9296 emitpcode(POC_BSF, popGet(AOP(result),0));
9297 //aopPut(AOP(result),"a",0);
9301 /* bit variables done */
9303 size = AOP_SIZE(result);
9305 if(AOP_TYPE(right) == AOP_LIT)
9306 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9308 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9310 if(aopIdx(AOP(result),0) == 4) {
9311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9312 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9313 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9316 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9322 if(AOP_TYPE(right) == AOP_LIT) {
9324 if(know_W != (int)(lit&0xff))
9325 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9327 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9329 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9333 } else if (AOP_TYPE(right) == AOP_CRY) {
9334 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9336 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9337 emitpcode(POC_INCF, popGet(AOP(result),0));
9340 mov2w (AOP(right), offset);
9341 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9349 freeAsmop (right,NULL,ic,FALSE);
9350 freeAsmop (result,NULL,ic,TRUE);
9353 /*-----------------------------------------------------------------*/
9354 /* genJumpTab - genrates code for jump table */
9355 /*-----------------------------------------------------------------*/
9356 static void genJumpTab (iCode *ic)
9361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9363 aopOp(IC_JTCOND(ic),ic,FALSE);
9364 /* get the condition into accumulator */
9365 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9367 /* multiply by three */
9368 pic14_emitcode("add","a,acc");
9369 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9371 jtab = newiTempLabel(NULL);
9372 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9373 pic14_emitcode("jmp","@a+dptr");
9374 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9376 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9377 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9378 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9379 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9381 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9382 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9383 emitpLabel(jtab->key);
9385 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9387 /* now generate the jump labels */
9388 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9389 jtab = setNextItem(IC_JTLABELS(ic))) {
9390 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9391 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9397 /*-----------------------------------------------------------------*/
9398 /* genMixedOperation - gen code for operators between mixed types */
9399 /*-----------------------------------------------------------------*/
9401 TSD - Written for the PIC port - but this unfortunately is buggy.
9402 This routine is good in that it is able to efficiently promote
9403 types to different (larger) sizes. Unfortunately, the temporary
9404 variables that are optimized out by this routine are sometimes
9405 used in other places. So until I know how to really parse the
9406 iCode tree, I'm going to not be using this routine :(.
9408 static int genMixedOperation (iCode *ic)
9411 operand *result = IC_RESULT(ic);
9412 sym_link *ctype = operandType(IC_LEFT(ic));
9413 operand *right = IC_RIGHT(ic);
9419 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9421 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9427 nextright = IC_RIGHT(nextic);
9428 nextleft = IC_LEFT(nextic);
9429 nextresult = IC_RESULT(nextic);
9431 aopOp(right,ic,FALSE);
9432 aopOp(result,ic,FALSE);
9433 aopOp(nextright, nextic, FALSE);
9434 aopOp(nextleft, nextic, FALSE);
9435 aopOp(nextresult, nextic, FALSE);
9437 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9443 pic14_emitcode(";remove right +","");
9445 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9451 pic14_emitcode(";remove left +","");
9455 big = AOP_SIZE(nextleft);
9456 small = AOP_SIZE(nextright);
9458 switch(nextic->op) {
9461 pic14_emitcode(";optimize a +","");
9462 /* if unsigned or not an integral type */
9463 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9464 pic14_emitcode(";add a bit to something","");
9467 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9469 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9470 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9471 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9473 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9481 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9482 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9483 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9486 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9488 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9489 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9490 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9491 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9492 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9495 pic14_emitcode("rlf","known_zero,w");
9502 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9503 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9504 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9506 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9516 freeAsmop(right,NULL,ic,TRUE);
9517 freeAsmop(result,NULL,ic,TRUE);
9518 freeAsmop(nextright,NULL,ic,TRUE);
9519 freeAsmop(nextleft,NULL,ic,TRUE);
9521 nextic->generated = 1;
9528 /*-----------------------------------------------------------------*/
9529 /* genCast - gen code for casting */
9530 /*-----------------------------------------------------------------*/
9531 static void genCast (iCode *ic)
9533 operand *result = IC_RESULT(ic);
9534 sym_link *ctype = operandType(IC_LEFT(ic));
9535 sym_link *rtype = operandType(IC_RIGHT(ic));
9536 operand *right = IC_RIGHT(ic);
9539 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9540 /* if they are equivalent then do nothing */
9541 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9544 aopOp(right,ic,FALSE) ;
9545 aopOp(result,ic,FALSE);
9547 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9549 /* if the result is a bit */
9550 if (AOP_TYPE(result) == AOP_CRY) {
9551 /* if the right size is a literal then
9552 we know what the value is */
9553 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9554 if (AOP_TYPE(right) == AOP_LIT) {
9556 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9557 popGet(AOP(result),0));
9559 if (((int) operandLitValue(right)))
9560 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9561 AOP(result)->aopu.aop_dir,
9562 AOP(result)->aopu.aop_dir);
9564 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9565 AOP(result)->aopu.aop_dir,
9566 AOP(result)->aopu.aop_dir);
9571 /* the right is also a bit variable */
9572 if (AOP_TYPE(right) == AOP_CRY) {
9575 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9577 pic14_emitcode("clrc","");
9578 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9579 AOP(right)->aopu.aop_dir,
9580 AOP(right)->aopu.aop_dir);
9581 aopPut(AOP(result),"c",0);
9586 if (AOP_TYPE(right) == AOP_REG) {
9587 emitpcode(POC_BCF, popGet(AOP(result),0));
9588 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9589 emitpcode(POC_BSF, popGet(AOP(result),0));
9591 pic14_toBoolean(right);
9592 aopPut(AOP(result),"a",0);
9596 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9598 size = AOP_SIZE(result);
9600 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9602 emitpcode(POC_CLRF, popGet(AOP(result),0));
9603 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9604 emitpcode(POC_INCF, popGet(AOP(result),0));
9607 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9612 /* if they are the same size : or less */
9613 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9615 /* if they are in the same place */
9616 if (pic14_sameRegs(AOP(right),AOP(result)))
9619 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9620 if (IS_PTR_CONST(rtype))
9621 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9622 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9623 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9625 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9626 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9627 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9628 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9629 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9630 if(AOP_SIZE(result) <2)
9631 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9635 /* if they in different places then copy */
9636 size = AOP_SIZE(result);
9639 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9640 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9642 //aopPut(AOP(result),
9643 // aopGet(AOP(right),offset,FALSE,FALSE),
9653 /* if the result is of type pointer */
9654 if (IS_PTR(ctype)) {
9657 sym_link *type = operandType(right);
9658 sym_link *etype = getSpec(type);
9659 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9661 /* pointer to generic pointer */
9662 if (IS_GENPTR(ctype)) {
9666 p_type = DCL_TYPE(type);
9668 /* we have to go by the storage class */
9669 p_type = PTR_TYPE(SPEC_OCLS(etype));
9671 /* if (SPEC_OCLS(etype)->codesp ) */
9672 /* p_type = CPOINTER ; */
9674 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9675 /* p_type = FPOINTER ; */
9677 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9678 /* p_type = PPOINTER; */
9680 /* if (SPEC_OCLS(etype) == idata ) */
9681 /* p_type = IPOINTER ; */
9683 /* p_type = POINTER ; */
9686 /* the first two bytes are known */
9687 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9688 size = GPTRSIZE - 1;
9691 if(offset < AOP_SIZE(right)) {
9692 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9693 if ((AOP_TYPE(right) == AOP_PCODE) &&
9694 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9695 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9696 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9699 aopGet(AOP(right),offset,FALSE,FALSE),
9703 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9706 /* the last byte depending on type */
9710 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9713 pic14_emitcode(";BUG!? ","%d",__LINE__);
9717 pic14_emitcode(";BUG!? ","%d",__LINE__);
9721 pic14_emitcode(";BUG!? ","%d",__LINE__);
9726 /* this should never happen */
9727 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9728 "got unknown pointer type");
9731 //aopPut(AOP(result),l, GPTRSIZE - 1);
9735 /* just copy the pointers */
9736 size = AOP_SIZE(result);
9740 aopGet(AOP(right),offset,FALSE,FALSE),
9749 /* so we now know that the size of destination is greater
9750 than the size of the source.
9751 Now, if the next iCode is an operator then we might be
9752 able to optimize the operation without performing a cast.
9754 if(genMixedOperation(ic))
9757 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9759 /* we move to result for the size of source */
9760 size = AOP_SIZE(right);
9763 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9764 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9768 /* now depending on the sign of the destination */
9769 size = AOP_SIZE(result) - AOP_SIZE(right);
9770 /* if unsigned or not an integral type */
9771 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9773 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9775 /* we need to extend the sign :{ */
9778 /* Save one instruction of casting char to int */
9779 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9780 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9781 emitpcode(POC_DECF, popGet(AOP(result),offset));
9783 emitpcodeNULLop(POC_CLRW);
9786 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9788 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9790 emitpcode(POC_MOVLW, popGetLit(0xff));
9793 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9798 freeAsmop(right,NULL,ic,TRUE);
9799 freeAsmop(result,NULL,ic,TRUE);
9803 /*-----------------------------------------------------------------*/
9804 /* genDjnz - generate decrement & jump if not zero instrucion */
9805 /*-----------------------------------------------------------------*/
9806 static int genDjnz (iCode *ic, iCode *ifx)
9809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9814 /* if the if condition has a false label
9815 then we cannot save */
9819 /* if the minus is not of the form
9821 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9822 !IS_OP_LITERAL(IC_RIGHT(ic)))
9825 if (operandLitValue(IC_RIGHT(ic)) != 1)
9828 /* if the size of this greater than one then no
9830 if (getSize(operandType(IC_RESULT(ic))) > 1)
9833 /* otherwise we can save BIG */
9834 lbl = newiTempLabel(NULL);
9835 lbl1= newiTempLabel(NULL);
9837 aopOp(IC_RESULT(ic),ic,FALSE);
9839 if (IS_AOP_PREG(IC_RESULT(ic))) {
9840 pic14_emitcode("dec","%s",
9841 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9842 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9847 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9848 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9850 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9851 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9854 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9855 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9856 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9857 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9860 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9865 /*-----------------------------------------------------------------*/
9866 /* genReceive - generate code for a receive iCode */
9867 /*-----------------------------------------------------------------*/
9868 static void genReceive (iCode *ic)
9870 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9872 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9873 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9874 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9876 int size = getSize(operandType(IC_RESULT(ic)));
9877 int offset = fReturnSizePic - size;
9879 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9880 fReturn[fReturnSizePic - offset - 1] : "acc"));
9883 aopOp(IC_RESULT(ic),ic,FALSE);
9884 size = AOP_SIZE(IC_RESULT(ic));
9887 pic14_emitcode ("pop","acc");
9888 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9893 aopOp(IC_RESULT(ic),ic,FALSE);
9895 assignResultValue(IC_RESULT(ic));
9898 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9901 /*-----------------------------------------------------------------*/
9902 /* genDummyRead - generate code for dummy read of volatiles */
9903 /*-----------------------------------------------------------------*/
9905 genDummyRead (iCode * ic)
9907 pic14_emitcode ("; genDummyRead","");
9908 pic14_emitcode ("; not implemented","");
9913 /*-----------------------------------------------------------------*/
9914 /* genpic14Code - generate code for pic14 based controllers */
9915 /*-----------------------------------------------------------------*/
9917 * At this point, ralloc.c has gone through the iCode and attempted
9918 * to optimize in a way suitable for a PIC. Now we've got to generate
9919 * PIC instructions that correspond to the iCode.
9921 * Once the instructions are generated, we'll pass through both the
9922 * peep hole optimizer and the pCode optimizer.
9923 *-----------------------------------------------------------------*/
9925 void genpic14Code (iCode *lic)
9930 lineHead = lineCurr = NULL;
9932 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9935 /* if debug information required */
9936 if (options.debug && currFunc) {
9938 debugFile->writeFunction (currFunc, lic);
9943 for (ic = lic ; ic ; ic = ic->next ) {
9945 DEBUGpic14_emitcode(";ic","");
9946 if ( cln != ic->lineno ) {
9947 if ( options.debug ) {
9948 debugFile->writeCLine (ic);
9951 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9952 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9953 printCLine(ic->filename, ic->lineno));
9955 if (!options.noCcodeInAsm) {
9957 newpCodeCSource(ic->lineno,
9959 printCLine(ic->filename, ic->lineno)));
9965 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9967 /* if the result is marked as
9968 spilt and rematerializable or code for
9969 this has already been generated then
9971 if (resultRemat(ic) || ic->generated )
9974 /* depending on the operation */
9993 /* IPOP happens only when trying to restore a
9994 spilt live range, if there is an ifx statement
9995 following this pop then the if statement might
9996 be using some of the registers being popped which
9997 would destory the contents of the register so
9998 we need to check for this condition and handle it */
10000 ic->next->op == IFX &&
10001 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10002 genIfx (ic->next,ic);
10020 genEndFunction (ic);
10040 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10057 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10061 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10068 /* note these two are xlated by algebraic equivalence
10069 during parsing SDCC.y */
10070 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10071 "got '>=' or '<=' shouldn't have come here");
10075 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10087 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10091 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10095 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10119 genRightShift (ic);
10122 case GET_VALUE_AT_ADDRESS:
10127 if (POINTER_SET(ic))
10154 addSet(&_G.sendSet,ic);
10157 case DUMMY_READ_VOLATILE:
10167 /* now we are ready to call the
10168 peep hole optimizer */
10169 if (!options.nopeep) {
10170 peepHole (&lineHead);
10172 /* now do the actual printing */
10173 printLine (lineHead,codeOutFile);
10176 DFPRINTF((stderr,"printing pBlock\n\n"));
10177 printpBlock(stdout,pb);