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"
45 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
46 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 void genMult8X8_8 (operand *, operand *,operand *);
48 extern void printpBlock(FILE *of, pBlock *pb);
50 static int labelOffset=0;
51 extern int debug_verbose;
52 static int optimized_for_speed = 0;
54 /* max_key keeps track of the largest label number used in
55 a function. This is then used to adjust the label offset
56 for the next function.
59 static int GpsuedoStkPtr=0;
61 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
62 unsigned int pic14aopLiteral (value *val, int offset);
63 const char *AopType(short type);
65 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff)
67 /* this is the down and dirty file with all kinds of
68 kludgy & hacky stuff. This is what it is all about
69 CODE GENERATION for a specific MCU . some of the
70 routines may be reusable, will have to see */
72 static char *zero = "#0x00";
73 static char *one = "#0x01";
74 static char *spname = "sp";
76 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
77 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
78 static char **fReturn = fReturnpic14;
80 static char *accUse[] = {"a","b"};
82 //static short rbank = -1;
94 /* Resolved ifx structure. This structure stores information
95 about an iCode ifx that makes it easier to generate code.
97 typedef struct resolvedIfx {
98 symbol *lbl; /* pointer to a label */
99 int condition; /* true or false ifx */
100 int generated; /* set true when the code associated with the ifx
104 extern int pic14_ptrRegReq ;
105 extern int pic14_nRegs;
106 extern FILE *codeOutFile;
107 static void saverbank (int, iCode *,bool);
109 static lineNode *lineHead = NULL;
110 static lineNode *lineCurr = NULL;
112 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
113 0xE0, 0xC0, 0x80, 0x00};
114 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
115 0x07, 0x03, 0x01, 0x00};
119 /*-----------------------------------------------------------------*/
120 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
121 /* exponent of 2 is returned, otherwise -1 is */
123 /* note that this is similar to the function `powof2' in SDCCsymt */
127 /*-----------------------------------------------------------------*/
128 static int my_powof2 (unsigned long num)
131 if( (num & (num-1)) == 0) {
144 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
147 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
149 ((result) ? AopType(AOP_TYPE(result)) : "-"),
150 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
151 ((left) ? AopType(AOP_TYPE(left)) : "-"),
152 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
153 ((right) ? AopType(AOP_TYPE(right)) : "-"),
154 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
155 ((result) ? AOP_SIZE(result) : 0));
159 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
162 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
164 ((result) ? AopType(AOP_TYPE(result)) : "-"),
165 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
166 ((left) ? AopType(AOP_TYPE(left)) : "-"),
167 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
168 ((right) ? AopType(AOP_TYPE(right)) : "-"),
169 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 char lb[INITIAL_INLINEASM];
179 if(!debug_verbose && !options.debug)
186 sprintf(lb,"%s\t",inst);
188 sprintf(lb,"%s",inst);
189 vsprintf(lb+(strlen(lb)),fmt,ap);
193 while (isspace(*lbp)) lbp++;
196 lineCurr = (lineCurr ?
197 connectLine(lineCurr,newLineNode(lb)) :
198 (lineHead = newLineNode(lb)));
199 lineCurr->isInline = _G.inLine;
200 lineCurr->isDebug = _G.debugLine;
202 addpCode2pBlock(pb,newpCodeCharP(lb));
207 static void Safe_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
209 #if defined (HAVE_VSNPRINTF)
210 vsnprintf (buf, size, fmt, ap);
211 #elif defined (HAVE_VSPRINTF)
212 vsprintf (buf, size, fmt, ap);
213 if (strlen (buf) >= size)
215 fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
217 #elif defined (HAVE_SNPRINTF)
218 snprintf (buf, size, "vs(n)printf required");
219 #elif defined (HAVE_SRINTF)
220 sprintf (buf, "vs(n)printf required");
221 if (strlen (buf) >= size)
223 fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
226 assert ( !"neither vsnprintf nor vsprintf is present -- unable to proceed" );
230 void emitpComment (const char *fmt, ...)
237 Safe_vsnprintf (buffer, 4096, fmt, va);
238 //fprintf (stderr, "%s\n" ,buffer);
239 addpCode2pBlock (pb, newpCodeCharP (buffer));
244 void emitpLabel(int key)
246 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
249 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
252 addpCode2pBlock(pb,newpCode(poc,pcop));
254 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
257 void emitpcodeNULLop(PIC_OPCODE poc)
260 addpCode2pBlock(pb,newpCode(poc,NULL));
265 /*-----------------------------------------------------------------*/
266 /* pic14_emitcode - writes the code into a file : for now it is simple */
267 /*-----------------------------------------------------------------*/
268 void pic14_emitcode (char *inst,char *fmt, ...)
271 char lb[INITIAL_INLINEASM];
278 sprintf(lb,"%s\t",inst);
280 sprintf(lb,"%s",inst);
281 vsprintf(lb+(strlen(lb)),fmt,ap);
285 while (isspace(*lbp)) lbp++;
288 lineCurr = (lineCurr ?
289 connectLine(lineCurr,newLineNode(lb)) :
290 (lineHead = newLineNode(lb)));
291 lineCurr->isInline = _G.inLine;
292 lineCurr->isDebug = _G.debugLine;
295 addpCode2pBlock(pb,newpCodeCharP(lb));
300 /*-----------------------------------------------------------------*/
301 /* pic14_emitDebuggerSymbol - associate the current code location */
302 /* with a debugger symbol */
303 /*-----------------------------------------------------------------*/
305 pic14_emitDebuggerSymbol (char * debugSym)
308 pic14_emitcode ("", ";%s ==.", debugSym);
313 /*-----------------------------------------------------------------*/
314 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
315 /*-----------------------------------------------------------------*/
316 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
318 bool r0iu = FALSE , r1iu = FALSE;
319 bool r0ou = FALSE , r1ou = FALSE;
321 /* the logic: if r0 & r1 used in the instruction
322 then we are in trouble otherwise */
324 /* first check if r0 & r1 are used by this
325 instruction, in which case we are in trouble */
326 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
327 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
332 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
333 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
335 /* if no usage of r0 then return it */
336 if (!r0iu && !r0ou) {
337 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
338 (*aopp)->type = AOP_R0;
340 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
343 /* if no usage of r1 then return it */
344 if (!r1iu && !r1ou) {
345 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
346 (*aopp)->type = AOP_R1;
348 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
351 /* now we know they both have usage */
352 /* if r0 not used in this instruction */
354 /* push it if not already pushed */
356 //pic14_emitcode ("push","%s",
357 // pic14_regWithIdx(R0_IDX)->dname);
361 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
362 (*aopp)->type = AOP_R0;
364 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
367 /* if r1 not used then */
370 /* push it if not already pushed */
372 //pic14_emitcode ("push","%s",
373 // pic14_regWithIdx(R1_IDX)->dname);
377 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
378 (*aopp)->type = AOP_R1;
379 return pic14_regWithIdx(R1_IDX);
383 /* I said end of world but not quite end of world yet */
384 /* if this is a result then we can push it on the stack*/
386 (*aopp)->type = AOP_STK;
390 /* other wise this is true end of the world */
391 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
392 "getFreePtr should never reach here");
396 /*-----------------------------------------------------------------*/
397 /* newAsmop - creates a new asmOp */
398 /*-----------------------------------------------------------------*/
399 asmop *newAsmop (short type)
403 aop = Safe_calloc(1,sizeof(asmop));
408 static void genSetDPTR(int n)
412 pic14_emitcode(";", "Select standard DPTR");
413 pic14_emitcode("mov", "dps, #0x00");
417 pic14_emitcode(";", "Select alternate DPTR");
418 pic14_emitcode("mov", "dps, #0x01");
422 /*-----------------------------------------------------------------*/
423 /* resolveIfx - converts an iCode ifx into a form more useful for */
424 /* generating code */
425 /*-----------------------------------------------------------------*/
426 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
431 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
433 resIfx->condition = 1; /* assume that the ifx is true */
434 resIfx->generated = 0; /* indicate that the ifx has not been used */
437 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
439 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
440 __FUNCTION__,__LINE__,resIfx->lbl->key);
444 resIfx->lbl = IC_TRUE(ifx);
446 resIfx->lbl = IC_FALSE(ifx);
447 resIfx->condition = 0;
451 DEBUGpic14_emitcode("; ***","ifx true is non-null");
453 DEBUGpic14_emitcode("; ***","ifx false is non-null");
457 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
460 /*-----------------------------------------------------------------*/
461 /* pointerCode - returns the code for a pointer type */
462 /*-----------------------------------------------------------------*/
463 static int pointerCode (sym_link *etype)
466 return PTR_TYPE(SPEC_OCLS(etype));
470 /*-----------------------------------------------------------------*/
471 /* aopForSym - for a true symbol */
472 /*-----------------------------------------------------------------*/
473 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
476 memmap *space= SPEC_OCLS(sym->etype);
478 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
479 /* if already has one */
483 /* assign depending on the storage class */
484 /* if it is on the stack or indirectly addressable */
485 /* space we need to assign either r0 or r1 to it */
486 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
487 sym->aop = aop = newAsmop(0);
488 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
489 aop->size = getSize(sym->type);
491 /* now assign the address of the variable to
492 the pointer register */
493 if (aop->type != AOP_STK) {
497 pic14_emitcode("push","acc");
499 pic14_emitcode("mov","a,_bp");
500 pic14_emitcode("add","a,#0x%02x",
502 ((char)(sym->stack - _G.nRegsSaved )) :
503 ((char)sym->stack)) & 0xff);
504 pic14_emitcode("mov","%s,a",
505 aop->aopu.aop_ptr->name);
508 pic14_emitcode("pop","acc");
510 pic14_emitcode("mov","%s,#%s",
511 aop->aopu.aop_ptr->name,
513 aop->paged = space->paged;
515 aop->aopu.aop_stk = sym->stack;
519 if (sym->onStack && options.stack10bit)
521 /* It's on the 10 bit stack, which is located in
525 //DEBUGpic14_emitcode(";","%d",__LINE__);
528 pic14_emitcode("push","acc");
530 pic14_emitcode("mov","a,_bp");
531 pic14_emitcode("add","a,#0x%02x",
533 ((char)(sym->stack - _G.nRegsSaved )) :
534 ((char)sym->stack)) & 0xff);
537 pic14_emitcode ("mov","dpx1,#0x40");
538 pic14_emitcode ("mov","dph1,#0x00");
539 pic14_emitcode ("mov","dpl1, a");
543 pic14_emitcode("pop","acc");
545 sym->aop = aop = newAsmop(AOP_DPTR2);
546 aop->size = getSize(sym->type);
550 //DEBUGpic14_emitcode(";","%d",__LINE__);
551 /* if in bit space */
552 if (IN_BITSPACE(space)) {
553 sym->aop = aop = newAsmop (AOP_CRY);
554 aop->aopu.aop_dir = sym->rname ;
555 aop->size = getSize(sym->type);
556 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
559 /* if it is in direct space */
560 if (IN_DIRSPACE(space)) {
561 sym->aop = aop = newAsmop (AOP_DIR);
562 aop->aopu.aop_dir = sym->rname ;
563 aop->size = getSize(sym->type);
564 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
568 /* special case for a function */
569 if (IS_FUNC(sym->type)) {
571 sym->aop = aop = newAsmop(AOP_PCODE);
572 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
573 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
574 PCOI(aop->aopu.pcop)->_function = 1;
575 PCOI(aop->aopu.pcop)->index = 0;
576 aop->size = FPTRSIZE;
578 sym->aop = aop = newAsmop(AOP_IMMD);
579 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
580 strcpy(aop->aopu.aop_immd,sym->rname);
581 aop->size = FPTRSIZE;
583 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
588 /* only remaining is far space */
589 /* in which case DPTR gets the address */
590 sym->aop = aop = newAsmop(AOP_PCODE);
592 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
593 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
594 PCOI(aop->aopu.pcop)->index = 0;
596 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
597 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
599 allocDirReg (IC_LEFT(ic));
601 aop->size = FPTRSIZE;
603 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
604 sym->aop = aop = newAsmop(AOP_DPTR);
605 pic14_emitcode ("mov","dptr,#%s", sym->rname);
606 aop->size = getSize(sym->type);
608 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
611 /* if it is in code space */
612 if (IN_CODESPACE(space))
618 /*-----------------------------------------------------------------*/
619 /* aopForRemat - rematerialzes an object */
620 /*-----------------------------------------------------------------*/
621 static asmop *aopForRemat (operand *op) // x symbol *sym)
623 symbol *sym = OP_SYMBOL(op);
625 asmop *aop = newAsmop(AOP_PCODE);
629 ic = sym->rematiCode;
631 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
632 if(IS_OP_POINTER(op)) {
633 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
637 val += (int) operandLitValue(IC_RIGHT(ic));
638 } else if (ic->op == '-') {
639 val -= (int) operandLitValue(IC_RIGHT(ic));
643 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
646 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
647 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
648 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
649 PCOI(aop->aopu.pcop)->index = val;
651 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
652 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
653 val, IS_PTR_CONST(operandType(op)));
655 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
657 allocDirReg (IC_LEFT(ic));
662 int aopIdx (asmop *aop, int offset)
667 if(aop->type != AOP_REG)
670 return aop->aopu.aop_reg[offset]->rIdx;
673 /*-----------------------------------------------------------------*/
674 /* regsInCommon - two operands have some registers in common */
675 /*-----------------------------------------------------------------*/
676 static bool regsInCommon (operand *op1, operand *op2)
681 /* if they have registers in common */
682 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
685 sym1 = OP_SYMBOL(op1);
686 sym2 = OP_SYMBOL(op2);
688 if (sym1->nRegs == 0 || sym2->nRegs == 0)
691 for (i = 0 ; i < sym1->nRegs ; i++) {
696 for (j = 0 ; j < sym2->nRegs ;j++ ) {
700 if (sym2->regs[j] == sym1->regs[i])
708 /*-----------------------------------------------------------------*/
709 /* operandsEqu - equivalent */
710 /*-----------------------------------------------------------------*/
711 static bool operandsEqu ( operand *op1, operand *op2)
715 /* if they not symbols */
716 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
719 sym1 = OP_SYMBOL(op1);
720 sym2 = OP_SYMBOL(op2);
722 /* if both are itemps & one is spilt
723 and the other is not then false */
724 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
725 sym1->isspilt != sym2->isspilt )
728 /* if they are the same */
732 if (sym1->rname[0] && sym2->rname[0]
733 && strcmp (sym1->rname, sym2->rname) == 0)
737 /* if left is a tmp & right is not */
741 (sym1->usl.spillLoc == sym2))
748 (sym2->usl.spillLoc == sym1))
754 /*-----------------------------------------------------------------*/
755 /* pic14_sameRegs - two asmops have the same registers */
756 /*-----------------------------------------------------------------*/
757 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
764 if (aop1->type != AOP_REG ||
765 aop2->type != AOP_REG )
768 if (aop1->size != aop2->size )
771 for (i = 0 ; i < aop1->size ; i++ )
772 if (aop1->aopu.aop_reg[i] !=
773 aop2->aopu.aop_reg[i] )
779 /*-----------------------------------------------------------------*/
780 /* aopOp - allocates an asmop for an operand : */
781 /*-----------------------------------------------------------------*/
782 void aopOp (operand *op, iCode *ic, bool result)
791 /* if this a literal */
792 if (IS_OP_LITERAL(op)) {
793 op->aop = aop = newAsmop(AOP_LIT);
794 aop->aopu.aop_lit = op->operand.valOperand;
795 aop->size = getSize(operandType(op));
800 sym_link *type = operandType(op);
801 if(IS_PTR_CONST(type))
802 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
805 /* if already has a asmop then continue */
809 /* if the underlying symbol has a aop */
810 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
811 DEBUGpic14_emitcode(";","%d",__LINE__);
812 op->aop = OP_SYMBOL(op)->aop;
816 /* if this is a true symbol */
817 if (IS_TRUE_SYMOP(op)) {
818 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
819 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
823 /* this is a temporary : this has
829 e) can be a return use only */
834 /* if the type is a conditional */
835 if (sym->regType == REG_CND) {
836 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
841 /* if it is spilt then two situations
843 b) has a spill location */
844 if (sym->isspilt || sym->nRegs == 0) {
846 DEBUGpic14_emitcode(";","%d",__LINE__);
847 /* rematerialize it NOW */
850 sym->aop = op->aop = aop = aopForRemat (op);
851 aop->size = getSize(sym->type);
852 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
858 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
859 aop->size = getSize(sym->type);
860 for ( i = 0 ; i < 2 ; i++ )
861 aop->aopu.aop_str[i] = accUse[i];
862 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
867 if(sym->isptr) { // && sym->uptr
868 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
869 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
871 //PCOI(aop->aopu.pcop)->_const = 0;
872 //PCOI(aop->aopu.pcop)->index = 0;
874 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
875 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
877 //allocDirReg (IC_LEFT(ic));
879 aop->size = getSize(sym->type);
880 DEBUGpic14_emitcode(";","%d",__LINE__);
887 aop = op->aop = sym->aop = newAsmop(AOP_STR);
888 aop->size = getSize(sym->type);
889 for ( i = 0 ; i < fReturnSizePic ; i++ )
890 aop->aopu.aop_str[i] = fReturn[i];
892 DEBUGpic14_emitcode(";","%d",__LINE__);
897 /* else spill location */
898 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
899 /* force a new aop if sizes differ */
900 sym->usl.spillLoc->aop = NULL;
902 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
903 __FUNCTION__,__LINE__,
904 sym->usl.spillLoc->rname,
905 sym->rname, sym->usl.spillLoc->offset);
907 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
908 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
909 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
911 sym->usl.spillLoc->offset);
912 aop->size = getSize(sym->type);
918 sym_link *type = operandType(op);
919 if(IS_PTR_CONST(type))
920 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
923 /* must be in a register */
924 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
925 sym->aop = op->aop = aop = newAsmop(AOP_REG);
926 aop->size = sym->nRegs;
927 for ( i = 0 ; i < sym->nRegs ;i++)
928 aop->aopu.aop_reg[i] = sym->regs[i];
931 /*-----------------------------------------------------------------*/
932 /* freeAsmop - free up the asmop given to an operand */
933 /*----------------------------------------------------------------*/
934 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
951 /* depending on the asmop type only three cases need work AOP_RO
952 , AOP_R1 && AOP_STK */
958 pic14_emitcode ("pop","ar0");
962 bitVectUnSetBit(ic->rUsed,R0_IDX);
968 pic14_emitcode ("pop","ar1");
972 bitVectUnSetBit(ic->rUsed,R1_IDX);
978 int stk = aop->aopu.aop_stk + aop->size;
979 bitVectUnSetBit(ic->rUsed,R0_IDX);
980 bitVectUnSetBit(ic->rUsed,R1_IDX);
982 getFreePtr(ic,&aop,FALSE);
984 if (options.stack10bit)
986 /* I'm not sure what to do here yet... */
989 "*** Warning: probably generating bad code for "
990 "10 bit stack mode.\n");
994 pic14_emitcode ("mov","a,_bp");
995 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
996 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
998 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1002 pic14_emitcode("pop","acc");
1003 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1005 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1008 freeAsmop(op,NULL,ic,TRUE);
1010 pic14_emitcode("pop","ar0");
1015 pic14_emitcode("pop","ar1");
1023 /* all other cases just dealloc */
1027 OP_SYMBOL(op)->aop = NULL;
1028 /* if the symbol has a spill */
1030 SPIL_LOC(op)->aop = NULL;
1035 /*-----------------------------------------------------------------*/
1036 /* aopGet - for fetching value of the aop */
1037 /*-----------------------------------------------------------------*/
1038 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1043 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1044 /* offset is greater than
1046 if (offset > (aop->size - 1) &&
1047 aop->type != AOP_LIT)
1050 /* depending on type */
1051 switch (aop->type) {
1055 DEBUGpic14_emitcode(";","%d",__LINE__);
1056 /* if we need to increment it */
1057 while (offset > aop->coff) {
1058 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1062 while (offset < aop->coff) {
1063 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1067 aop->coff = offset ;
1069 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1070 return (dname ? "acc" : "a");
1072 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1073 rs = Safe_calloc(1,strlen(s)+1);
1079 DEBUGpic14_emitcode(";","%d",__LINE__);
1080 if (aop->type == AOP_DPTR2)
1085 while (offset > aop->coff) {
1086 pic14_emitcode ("inc","dptr");
1090 while (offset < aop->coff) {
1091 pic14_emitcode("lcall","__decdptr");
1097 pic14_emitcode("clr","a");
1098 pic14_emitcode("movc","a,@a+dptr");
1101 pic14_emitcode("movx","a,@dptr");
1104 if (aop->type == AOP_DPTR2)
1109 return (dname ? "acc" : "a");
1114 sprintf (s,"%s",aop->aopu.aop_immd);
1117 sprintf(s,"(%s >> %d)",
1122 aop->aopu.aop_immd);
1123 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1124 rs = Safe_calloc(1,strlen(s)+1);
1130 sprintf(s,"(%s + %d)",
1133 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1135 sprintf(s,"%s",aop->aopu.aop_dir);
1136 rs = Safe_calloc(1,strlen(s)+1);
1142 // return aop->aopu.aop_reg[offset]->dname;
1144 return aop->aopu.aop_reg[offset]->name;
1147 //pic14_emitcode(";","%d",__LINE__);
1148 return aop->aopu.aop_dir;
1151 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1152 return "AOP_accumulator_bug";
1155 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1156 rs = Safe_calloc(1,strlen(s)+1);
1161 aop->coff = offset ;
1162 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1165 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1167 return aop->aopu.aop_str[offset];
1171 pCodeOp *pcop = aop->aopu.pcop;
1172 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1175 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
1176 sprintf(s,"(%s+%d)", pcop->name,offset);
1178 DEBUGpic14_emitcode(";","%s",pcop->name);
1179 sprintf(s,"%s", pcop->name);
1182 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1185 rs = Safe_calloc(1,strlen(s)+1);
1191 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1192 "aopget got unsupported aop->type");
1197 /*-----------------------------------------------------------------*/
1198 /* popGetTempReg - create a new temporary pCodeOp */
1199 /*-----------------------------------------------------------------*/
1200 pCodeOp *popGetTempReg(void)
1205 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1206 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1207 PCOR(pcop)->r->wasUsed=1;
1208 PCOR(pcop)->r->isFree=0;
1214 /*-----------------------------------------------------------------*/
1215 /* popReleaseTempReg - create a new temporary pCodeOp */
1216 /*-----------------------------------------------------------------*/
1217 void popReleaseTempReg(pCodeOp *pcop)
1220 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1221 PCOR(pcop)->r->isFree = 1;
1224 /*-----------------------------------------------------------------*/
1225 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetLabel(unsigned int key)
1230 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1232 if(key>(unsigned int)max_key)
1235 return newpCodeOpLabel(NULL,key+100+labelOffset);
1238 /*-------------------------------------------------------------------*/
1239 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1240 /*-------------------------------------------------------------------*/
1241 pCodeOp *popGetHighLabel(unsigned int key)
1244 pcop = popGetLabel(key);
1245 PCOLAB(pcop)->offset = 1;
1249 /*-----------------------------------------------------------------*/
1250 /* popGetLit - asm operator to pcode operator conversion */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popGetLit(unsigned int lit)
1255 return newpCodeOpLit(lit);
1258 /*-----------------------------------------------------------------*/
1259 /* popGetImmd - asm operator to pcode immediate conversion */
1260 /*-----------------------------------------------------------------*/
1261 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1264 return newpCodeOpImmd(name, offset,index, 0, is_func);
1268 /*-----------------------------------------------------------------*/
1269 /* popGetWithString - asm operator to pcode operator conversion */
1270 /*-----------------------------------------------------------------*/
1271 pCodeOp *popGetWithString(char *str, int isExtern)
1277 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1281 pcop = newpCodeOp(str,PO_STR);
1282 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1287 /*-----------------------------------------------------------------*/
1288 /* popRegFromString - */
1289 /*-----------------------------------------------------------------*/
1290 pCodeOp *popRegFromString(char *str, int size, int offset)
1293 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1294 pcop->type = PO_DIR;
1296 DEBUGpic14_emitcode(";","%d",__LINE__);
1301 pcop->name = Safe_calloc(1,strlen(str)+1);
1302 strcpy(pcop->name,str);
1304 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1306 PCOR(pcop)->r = dirregWithName(pcop->name);
1307 if(PCOR(pcop)->r == NULL) {
1308 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1309 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1310 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1312 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1314 PCOR(pcop)->instance = offset;
1319 /*-----------------------------------------------------------------*/
1320 /*-----------------------------------------------------------------*/
1321 pCodeOp *popRegFromIdx(int rIdx)
1325 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1326 __FUNCTION__,__LINE__,rIdx);
1328 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1330 PCOR(pcop)->rIdx = rIdx;
1331 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1332 PCOR(pcop)->r->isFree = 0;
1333 PCOR(pcop)->r->wasUsed = 1;
1335 pcop->type = PCOR(pcop)->r->pc_type;
1341 /*-----------------------------------------------------------------*/
1342 /* popGet - asm operator to pcode operator conversion */
1343 /*-----------------------------------------------------------------*/
1344 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1346 //char *s = buffer ;
1351 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1352 /* offset is greater than
1355 assert (offset >= 0 && offset < aop->size);
1357 if (offset > (aop->size - 1) &&
1358 aop->type != AOP_LIT)
1359 return NULL; //zero;
1361 /* depending on type */
1362 switch (aop->type) {
1369 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1373 DEBUGpic14_emitcode(";","%d",__LINE__);
1374 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1377 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1379 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1380 pcop->type = PO_DIR;
1382 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1383 strcpy(pcop->name,aop->aopu.aop_dir);
1384 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1385 if(PCOR(pcop)->r == NULL) {
1386 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1387 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1388 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1390 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1392 PCOR(pcop)->instance = offset;
1399 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1401 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1402 PCOR(pcop)->rIdx = rIdx;
1403 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1404 PCOR(pcop)->r->wasUsed=1;
1405 PCOR(pcop)->r->isFree=0;
1407 PCOR(pcop)->instance = offset;
1408 pcop->type = PCOR(pcop)->r->pc_type;
1409 //rs = aop->aopu.aop_reg[offset]->name;
1410 DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1415 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1416 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1417 //if(PCOR(pcop)->r == NULL)
1418 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1422 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1425 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1426 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1428 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1429 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1430 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1431 pcop->type = PCOR(pcop)->r->pc_type;
1432 pcop->name = PCOR(pcop)->r->name;
1439 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
1441 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1442 emitpComment ("popGet; name %s, offset: %i\n", aop->aopu.pcop->name, offset);
1443 switch (aop->aopu.pcop->type)
1446 pcop = pCodeOpCopy (aop->aopu.pcop);
1447 /* usually we want to access the memory at "<symbol> + offset" (using ->index),
1448 * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
1449 PCOI(pcop)->index += offset;
1450 //PCOI(pcop)->offset = 0;
1453 pcop = pCodeOpCopy (aop->aopu.pcop);
1454 PCOR(pcop)->instance = offset;
1457 assert ( !"unhandled pCode type" );
1463 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1464 "popGet got unsupported aop->type");
1468 /*-----------------------------------------------------------------*/
1469 /* popGetAddr - access the low/high word of a symbol (immediate) */
1470 /* (for non-PO_IMMEDIATEs this is the same as poGet) */
1471 /*-----------------------------------------------------------------*/
1472 pCodeOp *popGetAddr (asmop *aop, int offset)
1474 if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
1476 pCodeOp *pcop = aop->aopu.pcop;
1477 emitpComment ("popGet; name %s, offset: %i\n", pcop->name, offset);
1478 pcop = pCodeOpCopy (pcop);
1479 /* usually we want to access the memory at "<symbol> + offset" (using ->index),
1480 * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
1481 PCOI(pcop)->offset += offset;
1484 return popGet (aop, offset);
1488 /*-----------------------------------------------------------------*/
1489 /* aopPut - puts a string for a aop */
1490 /*-----------------------------------------------------------------*/
1491 void aopPut (asmop *aop, char *s, int offset)
1496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1498 if (aop->size && offset > ( aop->size - 1)) {
1499 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1500 "aopPut got offset > aop->size");
1504 /* will assign value to value */
1505 /* depending on where it is ofcourse */
1506 switch (aop->type) {
1509 sprintf(d,"(%s + %d)",
1510 aop->aopu.aop_dir,offset);
1511 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1514 sprintf(d,"%s",aop->aopu.aop_dir);
1517 DEBUGpic14_emitcode(";","%d",__LINE__);
1519 pic14_emitcode("movf","%s,w",s);
1520 pic14_emitcode("movwf","%s",d);
1523 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1524 if(offset >= aop->size) {
1525 emitpcode(POC_CLRF,popGet(aop,offset));
1528 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1531 emitpcode(POC_MOVWF,popGet(aop,offset));
1538 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1539 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1542 strcmp(s,"r0") == 0 ||
1543 strcmp(s,"r1") == 0 ||
1544 strcmp(s,"r2") == 0 ||
1545 strcmp(s,"r3") == 0 ||
1546 strcmp(s,"r4") == 0 ||
1547 strcmp(s,"r5") == 0 ||
1548 strcmp(s,"r6") == 0 ||
1549 strcmp(s,"r7") == 0 )
1550 pic14_emitcode("mov","%s,%s ; %d",
1551 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1555 if(strcmp(s,"W")==0 )
1556 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1558 pic14_emitcode("movwf","%s",
1559 aop->aopu.aop_reg[offset]->name);
1561 if(strcmp(s,zero)==0) {
1562 emitpcode(POC_CLRF,popGet(aop,offset));
1564 } else if(strcmp(s,"W")==0) {
1565 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1566 pcop->type = PO_GPR_REGISTER;
1568 PCOR(pcop)->rIdx = -1;
1569 PCOR(pcop)->r = NULL;
1571 DEBUGpic14_emitcode(";","%d",__LINE__);
1572 pcop->name = Safe_strdup(s);
1573 emitpcode(POC_MOVFW,pcop);
1574 emitpcode(POC_MOVWF,popGet(aop,offset));
1575 } else if(strcmp(s,one)==0) {
1576 emitpcode(POC_CLRF,popGet(aop,offset));
1577 emitpcode(POC_INCF,popGet(aop,offset));
1579 emitpcode(POC_MOVWF,popGet(aop,offset));
1587 if (aop->type == AOP_DPTR2)
1593 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1594 "aopPut writting to code space");
1598 while (offset > aop->coff) {
1600 pic14_emitcode ("inc","dptr");
1603 while (offset < aop->coff) {
1605 pic14_emitcode("lcall","__decdptr");
1610 /* if not in accumulater */
1613 pic14_emitcode ("movx","@dptr,a");
1615 if (aop->type == AOP_DPTR2)
1623 while (offset > aop->coff) {
1625 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1627 while (offset < aop->coff) {
1629 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1635 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1640 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1642 if (strcmp(s,"r0") == 0 ||
1643 strcmp(s,"r1") == 0 ||
1644 strcmp(s,"r2") == 0 ||
1645 strcmp(s,"r3") == 0 ||
1646 strcmp(s,"r4") == 0 ||
1647 strcmp(s,"r5") == 0 ||
1648 strcmp(s,"r6") == 0 ||
1649 strcmp(s,"r7") == 0 ) {
1651 sprintf(buffer,"a%s",s);
1652 pic14_emitcode("mov","@%s,%s",
1653 aop->aopu.aop_ptr->name,buffer);
1655 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1660 if (strcmp(s,"a") == 0)
1661 pic14_emitcode("push","acc");
1663 pic14_emitcode("push","%s",s);
1668 /* if bit variable */
1669 if (!aop->aopu.aop_dir) {
1670 pic14_emitcode("clr","a");
1671 pic14_emitcode("rlc","a");
1674 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1677 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1680 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1682 lbl = newiTempLabel(NULL);
1684 if (strcmp(s,"a")) {
1687 pic14_emitcode("clr","c");
1688 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1689 pic14_emitcode("cpl","c");
1690 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1691 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1698 if (strcmp(aop->aopu.aop_str[offset],s))
1699 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1704 if (!offset && (strcmp(s,"acc") == 0))
1707 if (strcmp(aop->aopu.aop_str[offset],s))
1708 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1712 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1713 "aopPut got unsupported aop->type");
1719 /*-----------------------------------------------------------------*/
1720 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1721 /*-----------------------------------------------------------------*/
1722 void mov2w (asmop *aop, int offset)
1728 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1730 if ( aop->type == AOP_PCODE ||
1731 aop->type == AOP_LIT ||
1732 aop->type == AOP_IMMD )
1733 emitpcode(POC_MOVLW,popGet(aop,offset));
1735 emitpcode(POC_MOVFW,popGet(aop,offset));
1739 /*-----------------------------------------------------------------*/
1740 /* reAdjustPreg - points a register back to where it should */
1741 /*-----------------------------------------------------------------*/
1742 static void reAdjustPreg (asmop *aop)
1746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1748 if ((size = aop->size) <= 1)
1751 switch (aop->type) {
1755 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1759 if (aop->type == AOP_DPTR2)
1765 pic14_emitcode("lcall","__decdptr");
1768 if (aop->type == AOP_DPTR2)
1780 /*-----------------------------------------------------------------*/
1781 /* opIsGptr: returns non-zero if the passed operand is */
1782 /* a generic pointer type. */
1783 /*-----------------------------------------------------------------*/
1784 static int opIsGptr(operand *op)
1786 sym_link *type = operandType(op);
1788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1789 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1797 /*-----------------------------------------------------------------*/
1798 /* pic14_getDataSize - get the operand data size */
1799 /*-----------------------------------------------------------------*/
1800 int pic14_getDataSize(operand *op)
1802 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1805 return AOP_SIZE(op);
1807 // tsd- in the pic port, the genptr size is 1, so this code here
1808 // fails. ( in the 8051 port, the size was 4).
1811 size = AOP_SIZE(op);
1812 if (size == GPTRSIZE)
1814 sym_link *type = operandType(op);
1815 if (IS_GENPTR(type))
1817 /* generic pointer; arithmetic operations
1818 * should ignore the high byte (pointer type).
1821 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1828 /*-----------------------------------------------------------------*/
1829 /* pic14_outAcc - output Acc */
1830 /*-----------------------------------------------------------------*/
1831 void pic14_outAcc(operand *result)
1834 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1835 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1838 size = pic14_getDataSize(result);
1840 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1843 /* unsigned or positive */
1845 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1850 /*-----------------------------------------------------------------*/
1851 /* pic14_outBitC - output a bit C */
1852 /*-----------------------------------------------------------------*/
1853 void pic14_outBitC(operand *result)
1856 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1857 /* if the result is bit */
1858 if (AOP_TYPE(result) == AOP_CRY)
1859 aopPut(AOP(result),"c",0);
1861 pic14_emitcode("clr","a ; %d", __LINE__);
1862 pic14_emitcode("rlc","a");
1863 pic14_outAcc(result);
1867 /*-----------------------------------------------------------------*/
1868 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1869 /*-----------------------------------------------------------------*/
1870 void pic14_toBoolean(operand *oper)
1872 int size = AOP_SIZE(oper) - 1;
1875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1877 if ( AOP_TYPE(oper) != AOP_ACC) {
1878 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1881 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1886 /*-----------------------------------------------------------------*/
1887 /* genNot - generate code for ! operation */
1888 /*-----------------------------------------------------------------*/
1889 static void genNot (iCode *ic)
1896 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1897 /* assign asmOps to operand & result */
1898 aopOp (IC_LEFT(ic),ic,FALSE);
1899 aopOp (IC_RESULT(ic),ic,TRUE);
1901 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1902 /* if in bit space then a special case */
1903 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1904 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1905 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1906 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1908 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1909 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1910 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1915 size = AOP_SIZE(IC_LEFT(ic));
1917 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1918 emitpcode(POC_ANDLW,popGetLit(1));
1919 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1922 pic14_toBoolean(IC_LEFT(ic));
1924 tlbl = newiTempLabel(NULL);
1925 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1926 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1927 pic14_outBitC(IC_RESULT(ic));
1930 /* release the aops */
1931 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1932 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1936 /*-----------------------------------------------------------------*/
1937 /* genCpl - generate code for complement */
1938 /*-----------------------------------------------------------------*/
1939 static void genCpl (iCode *ic)
1941 operand *left, *result;
1946 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1947 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1948 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1950 /* if both are in bit space then
1952 if (AOP_TYPE(result) == AOP_CRY &&
1953 AOP_TYPE(left) == AOP_CRY ) {
1955 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1956 pic14_emitcode("cpl","c");
1957 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1961 size = AOP_SIZE(result);
1964 if(AOP_TYPE(left) == AOP_ACC)
1965 emitpcode(POC_XORLW, popGetLit(0xff));
1967 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1969 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1975 /* release the aops */
1976 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1977 freeAsmop(result,NULL,ic,TRUE);
1980 /*-----------------------------------------------------------------*/
1981 /* genUminusFloat - unary minus for floating points */
1982 /*-----------------------------------------------------------------*/
1983 static void genUminusFloat(operand *op,operand *result)
1985 int size ,offset =0 ;
1990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1991 /* for this we just need to flip the
1992 first it then copy the rest in place */
1993 size = AOP_SIZE(op) - 1;
1994 l = aopGet(AOP(op),3,FALSE,FALSE);
1998 pic14_emitcode("cpl","acc.7");
1999 aopPut(AOP(result),"a",3);
2003 aopGet(AOP(op),offset,FALSE,FALSE),
2009 /*-----------------------------------------------------------------*/
2010 /* genUminus - unary minus code generation */
2011 /*-----------------------------------------------------------------*/
2012 static void genUminus (iCode *ic)
2015 sym_link *optype, *rtype;
2019 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2021 aopOp(IC_LEFT(ic),ic,FALSE);
2022 aopOp(IC_RESULT(ic),ic,TRUE);
2024 /* if both in bit space then special
2026 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2027 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2029 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
2030 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
2031 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
2036 optype = operandType(IC_LEFT(ic));
2037 rtype = operandType(IC_RESULT(ic));
2039 /* if float then do float stuff */
2040 if (IS_FLOAT(optype)) {
2041 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2045 /* otherwise subtract from zero by taking the 2's complement */
2046 size = AOP_SIZE(IC_LEFT(ic));
2048 for(i=0; i<size; i++) {
2049 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2050 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2052 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2053 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2057 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2058 for(i=1; i<size; i++) {
2060 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2064 /* release the aops */
2065 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2066 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2069 /*-----------------------------------------------------------------*/
2070 /* saveRegisters - will look for a call and save the registers */
2071 /*-----------------------------------------------------------------*/
2072 static void saveRegisters(iCode *lic)
2081 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2083 for (ic = lic ; ic ; ic = ic->next)
2084 if (ic->op == CALL || ic->op == PCALL)
2088 fprintf(stderr,"found parameter push with no function call\n");
2092 /* if the registers have been saved already then
2094 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2097 /* find the registers in use at this time
2098 and push them away to safety */
2099 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2103 if (options.useXstack) {
2104 if (bitVectBitValue(rsave,R0_IDX))
2105 pic14_emitcode("mov","b,r0");
2106 pic14_emitcode("mov","r0,%s",spname);
2107 for (i = 0 ; i < pic14_nRegs ; i++) {
2108 if (bitVectBitValue(rsave,i)) {
2110 pic14_emitcode("mov","a,b");
2112 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2113 pic14_emitcode("movx","@r0,a");
2114 pic14_emitcode("inc","r0");
2117 pic14_emitcode("mov","%s,r0",spname);
2118 if (bitVectBitValue(rsave,R0_IDX))
2119 pic14_emitcode("mov","r0,b");
2121 //for (i = 0 ; i < pic14_nRegs ; i++) {
2122 // if (bitVectBitValue(rsave,i))
2123 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2126 dtype = operandType(IC_LEFT(ic));
2127 if (currFunc && dtype &&
2128 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2129 IFFUNC_ISISR(currFunc->type) &&
2132 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2135 /*-----------------------------------------------------------------*/
2136 /* unsaveRegisters - pop the pushed registers */
2137 /*-----------------------------------------------------------------*/
2138 static void unsaveRegisters (iCode *ic)
2145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2146 /* find the registers in use at this time
2147 and push them away to safety */
2148 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2151 if (options.useXstack) {
2152 pic14_emitcode("mov","r0,%s",spname);
2153 for (i = pic14_nRegs ; i >= 0 ; i--) {
2154 if (bitVectBitValue(rsave,i)) {
2155 pic14_emitcode("dec","r0");
2156 pic14_emitcode("movx","a,@r0");
2158 pic14_emitcode("mov","b,a");
2160 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2164 pic14_emitcode("mov","%s,r0",spname);
2165 if (bitVectBitValue(rsave,R0_IDX))
2166 pic14_emitcode("mov","r0,b");
2168 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2169 // if (bitVectBitValue(rsave,i))
2170 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2176 /*-----------------------------------------------------------------*/
2178 /*-----------------------------------------------------------------*/
2179 static void pushSide(operand * oper, int size)
2183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2185 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2186 if (AOP_TYPE(oper) != AOP_REG &&
2187 AOP_TYPE(oper) != AOP_DIR &&
2189 pic14_emitcode("mov","a,%s",l);
2190 pic14_emitcode("push","acc");
2192 pic14_emitcode("push","%s",l);
2197 /*-----------------------------------------------------------------*/
2198 /* assignResultValue - */
2199 /*-----------------------------------------------------------------*/
2200 static void assignResultValue(operand * oper)
2202 int size = AOP_SIZE(oper);
2206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2208 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2211 if (GpsuedoStkPtr++)
2212 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2213 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2218 /*-----------------------------------------------------------------*/
2219 /* genIpush - genrate code for pushing this gets a little complex */
2220 /*-----------------------------------------------------------------*/
2221 static void genIpush (iCode *ic)
2225 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2227 int size, offset = 0 ;
2231 /* if this is not a parm push : ie. it is spill push
2232 and spill push is always done on the local stack */
2233 if (!ic->parmPush) {
2235 /* and the item is spilt then do nothing */
2236 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2239 aopOp(IC_LEFT(ic),ic,FALSE);
2240 size = AOP_SIZE(IC_LEFT(ic));
2241 /* push it on the stack */
2243 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2248 pic14_emitcode("push","%s",l);
2253 /* this is a paramter push: in this case we call
2254 the routine to find the call and save those
2255 registers that need to be saved */
2258 /* then do the push */
2259 aopOp(IC_LEFT(ic),ic,FALSE);
2262 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2263 size = AOP_SIZE(IC_LEFT(ic));
2266 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2267 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2268 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2270 pic14_emitcode("mov","a,%s",l);
2271 pic14_emitcode("push","acc");
2273 pic14_emitcode("push","%s",l);
2276 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2280 /*-----------------------------------------------------------------*/
2281 /* genIpop - recover the registers: can happen only for spilling */
2282 /*-----------------------------------------------------------------*/
2283 static void genIpop (iCode *ic)
2287 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2292 /* if the temp was not pushed then */
2293 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2296 aopOp(IC_LEFT(ic),ic,FALSE);
2297 size = AOP_SIZE(IC_LEFT(ic));
2300 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2303 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2307 /*-----------------------------------------------------------------*/
2308 /* unsaverbank - restores the resgister bank from stack */
2309 /*-----------------------------------------------------------------*/
2310 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2314 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2322 if (options.useXstack) {
2324 r = getFreePtr(ic,&aop,FALSE);
2327 pic14_emitcode("mov","%s,_spx",r->name);
2328 pic14_emitcode("movx","a,@%s",r->name);
2329 pic14_emitcode("mov","psw,a");
2330 pic14_emitcode("dec","%s",r->name);
2333 pic14_emitcode ("pop","psw");
2336 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2337 if (options.useXstack) {
2338 pic14_emitcode("movx","a,@%s",r->name);
2339 //pic14_emitcode("mov","(%s+%d),a",
2340 // regspic14[i].base,8*bank+regspic14[i].offset);
2341 pic14_emitcode("dec","%s",r->name);
2344 pic14_emitcode("pop",""); //"(%s+%d)",
2345 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2348 if (options.useXstack) {
2350 pic14_emitcode("mov","_spx,%s",r->name);
2351 freeAsmop(NULL,aop,ic,TRUE);
2357 /*-----------------------------------------------------------------*/
2358 /* saverbank - saves an entire register bank on the stack */
2359 /*-----------------------------------------------------------------*/
2360 static void saverbank (int bank, iCode *ic, bool pushPsw)
2364 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2371 if (options.useXstack) {
2374 r = getFreePtr(ic,&aop,FALSE);
2375 pic14_emitcode("mov","%s,_spx",r->name);
2379 for (i = 0 ; i < pic14_nRegs ;i++) {
2380 if (options.useXstack) {
2381 pic14_emitcode("inc","%s",r->name);
2382 //pic14_emitcode("mov","a,(%s+%d)",
2383 // regspic14[i].base,8*bank+regspic14[i].offset);
2384 pic14_emitcode("movx","@%s,a",r->name);
2386 pic14_emitcode("push","");// "(%s+%d)",
2387 //regspic14[i].base,8*bank+regspic14[i].offset);
2391 if (options.useXstack) {
2392 pic14_emitcode("mov","a,psw");
2393 pic14_emitcode("movx","@%s,a",r->name);
2394 pic14_emitcode("inc","%s",r->name);
2395 pic14_emitcode("mov","_spx,%s",r->name);
2396 freeAsmop (NULL,aop,ic,TRUE);
2399 pic14_emitcode("push","psw");
2401 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2407 /*-----------------------------------------------------------------*/
2408 /* genCall - generates a call statement */
2409 /*-----------------------------------------------------------------*/
2410 static void genCall (iCode *ic)
2414 unsigned char *name;
2419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2421 /* if caller saves & we have not saved then */
2425 /* if we are calling a function that is not using
2426 the same register bank then we need to save the
2427 destination registers on the stack */
2428 dtype = operandType(IC_LEFT(ic));
2429 if (currFunc && dtype &&
2430 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2431 IFFUNC_ISISR(currFunc->type) &&
2434 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2436 /* if send set is not empty the assign */
2439 /* For the Pic port, there is no data stack.
2440 * So parameters passed to functions are stored
2441 * in registers. (The pCode optimizer will get
2442 * rid of most of these :).
2444 int psuedoStkPtr=-1;
2445 int firstTimeThruLoop = 1;
2447 _G.sendSet = reverseSet(_G.sendSet);
2449 /* First figure how many parameters are getting passed */
2450 for (sic = setFirstItem(_G.sendSet) ; sic ;
2451 sic = setNextItem(_G.sendSet)) {
2453 aopOp(IC_LEFT(sic),sic,FALSE);
2454 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2455 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2458 for (sic = setFirstItem(_G.sendSet) ; sic ;
2459 sic = setNextItem(_G.sendSet)) {
2460 int size, offset = 0;
2462 aopOp(IC_LEFT(sic),sic,FALSE);
2463 size = AOP_SIZE(IC_LEFT(sic));
2466 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2467 AopType(AOP_TYPE(IC_LEFT(sic))));
2469 if(!firstTimeThruLoop) {
2470 /* If this is not the first time we've been through the loop
2471 * then we need to save the parameter in a temporary
2472 * register. The last byte of the last parameter is
2474 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2477 firstTimeThruLoop=0;
2479 mov2w (AOP(IC_LEFT(sic)), offset);
2482 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2487 sym = OP_SYMBOL(IC_LEFT(ic));
2488 name = sym->rname[0] ? sym->rname : sym->name;
2489 isExtern = IS_EXTERN(sym->etype);
2491 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2493 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2495 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2498 /* if we need assign a result value */
2499 if ((IS_ITEMP(IC_RESULT(ic)) &&
2500 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2501 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2502 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2505 aopOp(IC_RESULT(ic),ic,FALSE);
2508 assignResultValue(IC_RESULT(ic));
2510 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2511 AopType(AOP_TYPE(IC_RESULT(ic))));
2513 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2516 /* adjust the stack for parameters if
2518 if (ic->parmBytes) {
2520 if (ic->parmBytes > 3) {
2521 pic14_emitcode("mov","a,%s",spname);
2522 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2523 pic14_emitcode("mov","%s,a",spname);
2525 for ( i = 0 ; i < ic->parmBytes ;i++)
2526 pic14_emitcode("dec","%s",spname);
2530 /* if register bank was saved then pop them */
2532 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2534 /* if we hade saved some registers then unsave them */
2535 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2536 unsaveRegisters (ic);
2541 /*-----------------------------------------------------------------*/
2542 /* genPcall - generates a call by pointer statement */
2543 /*-----------------------------------------------------------------*/
2544 static void genPcall (iCode *ic)
2547 symbol *albl = newiTempLabel(NULL);
2548 symbol *blbl = newiTempLabel(NULL);
2555 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2556 /* if caller saves & we have not saved then */
2560 /* if we are calling a function that is not using
2561 the same register bank then we need to save the
2562 destination registers on the stack */
2563 dtype = operandType(IC_LEFT(ic));
2564 if (currFunc && dtype &&
2565 IFFUNC_ISISR(currFunc->type) &&
2566 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2567 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2570 aopOp(left,ic,FALSE);
2571 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2573 pushSide(IC_LEFT(ic), FPTRSIZE);
2575 /* if send set is not empty, assign parameters */
2578 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2579 /* no way to pass args - W always gets used to make the call */
2581 /* first idea - factor out a common helper function and call it.
2582 But don't know how to get it generated only once in its own block
2584 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2587 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2588 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2589 buffer = Safe_calloc(1,strlen(rname)+16);
2590 sprintf(buffer, "%s_goto_helper", rname);
2591 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2595 emitpcode(POC_CALL,popGetLabel(albl->key));
2596 pcop = popGetLabel(blbl->key);
2597 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2598 emitpcode(POC_GOTO,pcop);
2599 emitpLabel(albl->key);
2601 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2603 emitpcode(poc,popGet(AOP(left),1));
2604 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2605 emitpcode(poc,popGet(AOP(left),0));
2606 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2608 emitpLabel(blbl->key);
2610 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2612 /* if we need to assign a result value */
2613 if ((IS_ITEMP(IC_RESULT(ic)) &&
2614 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2615 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2616 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2619 aopOp(IC_RESULT(ic),ic,FALSE);
2622 assignResultValue(IC_RESULT(ic));
2624 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2627 /* if register bank was saved then unsave them */
2628 if (currFunc && dtype &&
2629 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2630 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2632 /* if we hade saved some registers then
2635 unsaveRegisters (ic);
2639 /*-----------------------------------------------------------------*/
2640 /* resultRemat - result is rematerializable */
2641 /*-----------------------------------------------------------------*/
2642 static int resultRemat (iCode *ic)
2644 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (SKIP_IC(ic) || ic->op == IFX)
2650 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2651 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2652 if (sym->remat && !POINTER_SET(ic))
2659 #if defined(__BORLANDC__) || defined(_MSC_VER)
2660 #define STRCASECMP stricmp
2662 #define STRCASECMP strcasecmp
2666 /*-----------------------------------------------------------------*/
2667 /* inExcludeList - return 1 if the string is in exclude Reg list */
2668 /*-----------------------------------------------------------------*/
2669 static bool inExcludeList(char *s)
2671 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2675 if (options.excludeRegs[i] &&
2676 STRCASECMP(options.excludeRegs[i],"none") == 0)
2679 for ( i = 0 ; options.excludeRegs[i]; i++) {
2680 if (options.excludeRegs[i] &&
2681 STRCASECMP(s,options.excludeRegs[i]) == 0)
2688 /*-----------------------------------------------------------------*/
2689 /* genFunction - generated code for function entry */
2690 /*-----------------------------------------------------------------*/
2691 static void genFunction (iCode *ic)
2698 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2700 labelOffset += (max_key+4);
2704 /* create the function header */
2705 pic14_emitcode(";","-----------------------------------------");
2706 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2707 pic14_emitcode(";","-----------------------------------------");
2709 pic14_emitcode("","%s:",sym->rname);
2710 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2712 ftype = operandType(IC_LEFT(ic));
2714 /* if critical function then turn interrupts off */
2715 if (IFFUNC_ISCRITICAL(ftype))
2716 pic14_emitcode("clr","ea");
2718 /* here we need to generate the equates for the
2719 register bank if required */
2721 if (FUNC_REGBANK(ftype) != rbank) {
2724 rbank = FUNC_REGBANK(ftype);
2725 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2726 if (strcmp(regspic14[i].base,"0") == 0)
2727 pic14_emitcode("","%s = 0x%02x",
2729 8*rbank+regspic14[i].offset);
2731 pic14_emitcode ("","%s = %s + 0x%02x",
2734 8*rbank+regspic14[i].offset);
2739 /* if this is an interrupt service routine */
2740 if (IFFUNC_ISISR(sym->type)) {
2741 /* already done in pic14createInterruptVect() - delete me
2742 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2743 emitpcodeNULLop(POC_NOP);
2744 emitpcodeNULLop(POC_NOP);
2745 emitpcodeNULLop(POC_NOP);
2747 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2748 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2749 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2750 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2751 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2752 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2753 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2755 pBlockConvert2ISR(pb);
2757 if (!inExcludeList("acc"))
2758 pic14_emitcode ("push","acc");
2759 if (!inExcludeList("b"))
2760 pic14_emitcode ("push","b");
2761 if (!inExcludeList("dpl"))
2762 pic14_emitcode ("push","dpl");
2763 if (!inExcludeList("dph"))
2764 pic14_emitcode ("push","dph");
2765 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2767 pic14_emitcode ("push", "dpx");
2768 /* Make sure we're using standard DPTR */
2769 pic14_emitcode ("push", "dps");
2770 pic14_emitcode ("mov", "dps, #0x00");
2771 if (options.stack10bit)
2773 /* This ISR could conceivably use DPTR2. Better save it. */
2774 pic14_emitcode ("push", "dpl1");
2775 pic14_emitcode ("push", "dph1");
2776 pic14_emitcode ("push", "dpx1");
2779 /* if this isr has no bank i.e. is going to
2780 run with bank 0 , then we need to save more
2782 if (!FUNC_REGBANK(sym->type)) {
2784 /* if this function does not call any other
2785 function then we can be economical and
2786 save only those registers that are used */
2787 if (! IFFUNC_HASFCALL(sym->type)) {
2790 /* if any registers used */
2791 if (sym->regsUsed) {
2792 /* save the registers used */
2793 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2794 if (bitVectBitValue(sym->regsUsed,i) ||
2795 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2796 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2801 /* this function has a function call cannot
2802 determines register usage so we will have the
2804 saverbank(0,ic,FALSE);
2809 /* if callee-save to be used for this function
2810 then save the registers being used in this function */
2811 if (IFFUNC_CALLEESAVES(sym->type)) {
2814 /* if any registers used */
2815 if (sym->regsUsed) {
2816 /* save the registers used */
2817 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2818 if (bitVectBitValue(sym->regsUsed,i) ||
2819 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2820 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2828 /* set the register bank to the desired value */
2829 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2830 pic14_emitcode("push","psw");
2831 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2834 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2836 if (options.useXstack) {
2837 pic14_emitcode("mov","r0,%s",spname);
2838 pic14_emitcode("mov","a,_bp");
2839 pic14_emitcode("movx","@r0,a");
2840 pic14_emitcode("inc","%s",spname);
2844 /* set up the stack */
2845 pic14_emitcode ("push","_bp"); /* save the callers stack */
2847 pic14_emitcode ("mov","_bp,%s",spname);
2850 /* adjust the stack for the function */
2855 werror(W_STACK_OVERFLOW,sym->name);
2857 if (i > 3 && sym->recvSize < 4) {
2859 pic14_emitcode ("mov","a,sp");
2860 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2861 pic14_emitcode ("mov","sp,a");
2866 pic14_emitcode("inc","sp");
2871 pic14_emitcode ("mov","a,_spx");
2872 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2873 pic14_emitcode ("mov","_spx,a");
2878 /*-----------------------------------------------------------------*/
2879 /* genEndFunction - generates epilogue for functions */
2880 /*-----------------------------------------------------------------*/
2881 static void genEndFunction (iCode *ic)
2883 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2889 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2891 pic14_emitcode ("mov","%s,_bp",spname);
2894 /* if use external stack but some variables were
2895 added to the local stack then decrement the
2897 if (options.useXstack && sym->stack) {
2898 pic14_emitcode("mov","a,sp");
2899 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2900 pic14_emitcode("mov","sp,a");
2904 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2905 if (options.useXstack) {
2906 pic14_emitcode("mov","r0,%s",spname);
2907 pic14_emitcode("movx","a,@r0");
2908 pic14_emitcode("mov","_bp,a");
2909 pic14_emitcode("dec","%s",spname);
2913 pic14_emitcode ("pop","_bp");
2917 /* restore the register bank */
2918 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2919 pic14_emitcode ("pop","psw");
2921 if (IFFUNC_ISISR(sym->type)) {
2923 /* now we need to restore the registers */
2924 /* if this isr has no bank i.e. is going to
2925 run with bank 0 , then we need to save more
2927 if (!FUNC_REGBANK(sym->type)) {
2929 /* if this function does not call any other
2930 function then we can be economical and
2931 save only those registers that are used */
2932 if (! IFFUNC_HASFCALL(sym->type)) {
2935 /* if any registers used */
2936 if (sym->regsUsed) {
2937 /* save the registers used */
2938 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2939 if (bitVectBitValue(sym->regsUsed,i) ||
2940 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2941 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2946 /* this function has a function call cannot
2947 determines register usage so we will have the
2949 unsaverbank(0,ic,FALSE);
2953 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2955 if (options.stack10bit)
2957 pic14_emitcode ("pop", "dpx1");
2958 pic14_emitcode ("pop", "dph1");
2959 pic14_emitcode ("pop", "dpl1");
2961 pic14_emitcode ("pop", "dps");
2962 pic14_emitcode ("pop", "dpx");
2964 if (!inExcludeList("dph"))
2965 pic14_emitcode ("pop","dph");
2966 if (!inExcludeList("dpl"))
2967 pic14_emitcode ("pop","dpl");
2968 if (!inExcludeList("b"))
2969 pic14_emitcode ("pop","b");
2970 if (!inExcludeList("acc"))
2971 pic14_emitcode ("pop","acc");
2973 if (IFFUNC_ISCRITICAL(sym->type))
2974 pic14_emitcode("setb","ea");
2977 /* if debug then send end of function */
2978 /* if (options.debug && currFunc) { */
2980 debugFile->writeEndFunction (currFunc, ic, 1);
2983 pic14_emitcode ("reti","");
2984 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2985 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2986 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2987 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2988 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2989 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2990 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2991 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2992 emitpcodeNULLop(POC_RETFIE);
2995 if (IFFUNC_ISCRITICAL(sym->type))
2996 pic14_emitcode("setb","ea");
2998 if (IFFUNC_CALLEESAVES(sym->type)) {
3001 /* if any registers used */
3002 if (sym->regsUsed) {
3003 /* save the registers used */
3004 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3005 if (bitVectBitValue(sym->regsUsed,i) ||
3006 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3007 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
3013 /* if debug then send end of function */
3015 debugFile->writeEndFunction (currFunc, ic, 1);
3018 pic14_emitcode ("return","");
3019 emitpcodeNULLop(POC_RETURN);
3021 /* Mark the end of a function */
3022 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
3027 /*-----------------------------------------------------------------*/
3028 /* genRet - generate code for return statement */
3029 /*-----------------------------------------------------------------*/
3030 static void genRet (iCode *ic)
3032 int size,offset = 0 , pushed = 0;
3036 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3037 /* if we have no return value then
3038 just generate the "ret" */
3042 /* we have something to return then
3043 move the return value into place */
3044 aopOp(IC_LEFT(ic),ic,FALSE);
3045 size = AOP_SIZE(IC_LEFT(ic));
3049 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3051 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3053 pic14_emitcode("push","%s",l);
3056 l = aopGet(AOP(IC_LEFT(ic)),offset,
3058 if (strcmp(fReturn[offset],l)) {
3059 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
3060 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3061 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3062 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3063 emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset));
3065 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3068 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
3078 if (strcmp(fReturn[pushed],"a"))
3079 pic14_emitcode("pop",fReturn[pushed]);
3081 pic14_emitcode("pop","acc");
3084 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3087 /* generate a jump to the return label
3088 if the next is not the return statement */
3089 if (!(ic->next && ic->next->op == LABEL &&
3090 IC_LABEL(ic->next) == returnLabel)) {
3092 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3093 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3098 /*-----------------------------------------------------------------*/
3099 /* genLabel - generates a label */
3100 /*-----------------------------------------------------------------*/
3101 static void genLabel (iCode *ic)
3105 /* special case never generate */
3106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3107 if (IC_LABEL(ic) == entryLabel)
3110 emitpLabel(IC_LABEL(ic)->key);
3111 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3114 /*-----------------------------------------------------------------*/
3115 /* genGoto - generates a goto */
3116 /*-----------------------------------------------------------------*/
3118 static void genGoto (iCode *ic)
3122 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3123 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3127 /*-----------------------------------------------------------------*/
3128 /* genMultbits :- multiplication of bits */
3129 /*-----------------------------------------------------------------*/
3130 static void genMultbits (operand *left,
3135 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3137 if(!pic14_sameRegs(AOP(result),AOP(right)))
3138 emitpcode(POC_BSF, popGet(AOP(result),0));
3140 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3141 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3142 emitpcode(POC_BCF, popGet(AOP(result),0));
3147 /*-----------------------------------------------------------------*/
3148 /* genMultOneByte : 8 bit multiplication & division */
3149 /*-----------------------------------------------------------------*/
3150 static void genMultOneByte (operand *left,
3154 sym_link *opetype = operandType(result);
3161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3162 DEBUGpic14_AopType(__LINE__,left,right,result);
3163 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3165 /* (if two literals, the value is computed before) */
3166 /* if one literal, literal on the right */
3167 if (AOP_TYPE(left) == AOP_LIT){
3173 size = AOP_SIZE(result);
3176 if (AOP_TYPE(right) == AOP_LIT){
3177 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3178 aopGet(AOP(right),0,FALSE,FALSE),
3179 aopGet(AOP(left),0,FALSE,FALSE),
3180 aopGet(AOP(result),0,FALSE,FALSE));
3181 pic14_emitcode("call","genMultLit");
3183 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3184 aopGet(AOP(right),0,FALSE,FALSE),
3185 aopGet(AOP(left),0,FALSE,FALSE),
3186 aopGet(AOP(result),0,FALSE,FALSE));
3187 pic14_emitcode("call","genMult8X8_8");
3190 genMult8X8_8 (left, right,result);
3193 /* signed or unsigned */
3194 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3195 //l = aopGet(AOP(left),0,FALSE,FALSE);
3197 //pic14_emitcode("mul","ab");
3198 /* if result size = 1, mul signed = mul unsigned */
3199 //aopPut(AOP(result),"a",0);
3201 } else { // (size > 1)
3203 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3204 aopGet(AOP(right),0,FALSE,FALSE),
3205 aopGet(AOP(left),0,FALSE,FALSE),
3206 aopGet(AOP(result),0,FALSE,FALSE));
3208 if (SPEC_USIGN(opetype)){
3209 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3210 genUMult8X8_16 (left, right, result, NULL);
3213 /* for filling the MSBs */
3214 emitpcode(POC_CLRF, popGet(AOP(result),2));
3215 emitpcode(POC_CLRF, popGet(AOP(result),3));
3219 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3221 pic14_emitcode("mov","a,b");
3223 /* adjust the MSB if left or right neg */
3225 /* if one literal */
3226 if (AOP_TYPE(right) == AOP_LIT){
3227 pic14_emitcode("multiply ","right is a lit");
3228 /* AND literal negative */
3229 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3230 /* adjust MSB (c==0 after mul) */
3231 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3235 genSMult8X8_16 (left, right, result, NULL);
3239 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3241 pic14_emitcode("rlc","a");
3242 pic14_emitcode("subb","a,acc");
3250 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3251 //aopPut(AOP(result),"a",offset++);
3255 /*-----------------------------------------------------------------*/
3256 /* genMult - generates code for multiplication */
3257 /*-----------------------------------------------------------------*/
3258 static void genMult (iCode *ic)
3260 operand *left = IC_LEFT(ic);
3261 operand *right = IC_RIGHT(ic);
3262 operand *result= IC_RESULT(ic);
3266 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3267 /* assign the amsops */
3268 aopOp (left,ic,FALSE);
3269 aopOp (right,ic,FALSE);
3270 aopOp (result,ic,TRUE);
3272 DEBUGpic14_AopType(__LINE__,left,right,result);
3274 /* special cases first */
3276 if (AOP_TYPE(left) == AOP_CRY &&
3277 AOP_TYPE(right)== AOP_CRY) {
3278 genMultbits(left,right,result);
3282 /* if both are of size == 1 */
3283 if (AOP_SIZE(left) == 1 &&
3284 AOP_SIZE(right) == 1 ) {
3285 genMultOneByte(left,right,result);
3289 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3291 /* should have been converted to function call */
3295 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3296 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3297 freeAsmop(result,NULL,ic,TRUE);
3300 /*-----------------------------------------------------------------*/
3301 /* genDivbits :- division of bits */
3302 /*-----------------------------------------------------------------*/
3303 static void genDivbits (operand *left,
3312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3313 /* the result must be bit */
3314 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3315 l = aopGet(AOP(left),0,FALSE,FALSE);
3319 pic14_emitcode("div","ab");
3320 pic14_emitcode("rrc","a");
3321 aopPut(AOP(result),"c",0);
3324 /*-----------------------------------------------------------------*/
3325 /* genDivOneByte : 8 bit division */
3326 /*-----------------------------------------------------------------*/
3327 static void genDivOneByte (operand *left,
3331 sym_link *opetype = operandType(result);
3337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3338 size = AOP_SIZE(result) - 1;
3340 /* signed or unsigned */
3341 if (SPEC_USIGN(opetype)) {
3342 /* unsigned is easy */
3343 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3344 l = aopGet(AOP(left),0,FALSE,FALSE);
3346 pic14_emitcode("div","ab");
3347 aopPut(AOP(result),"a",0);
3349 aopPut(AOP(result),zero,offset++);
3353 /* signed is a little bit more difficult */
3355 /* save the signs of the operands */
3356 l = aopGet(AOP(left),0,FALSE,FALSE);
3358 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3359 pic14_emitcode("push","acc"); /* save it on the stack */
3361 /* now sign adjust for both left & right */
3362 l = aopGet(AOP(right),0,FALSE,FALSE);
3364 lbl = newiTempLabel(NULL);
3365 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3366 pic14_emitcode("cpl","a");
3367 pic14_emitcode("inc","a");
3368 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3369 pic14_emitcode("mov","b,a");
3371 /* sign adjust left side */
3372 l = aopGet(AOP(left),0,FALSE,FALSE);
3375 lbl = newiTempLabel(NULL);
3376 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3377 pic14_emitcode("cpl","a");
3378 pic14_emitcode("inc","a");
3379 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3381 /* now the division */
3382 pic14_emitcode("div","ab");
3383 /* we are interested in the lower order
3385 pic14_emitcode("mov","b,a");
3386 lbl = newiTempLabel(NULL);
3387 pic14_emitcode("pop","acc");
3388 /* if there was an over flow we don't
3389 adjust the sign of the result */
3390 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3391 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3393 pic14_emitcode("clr","a");
3394 pic14_emitcode("subb","a,b");
3395 pic14_emitcode("mov","b,a");
3396 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3398 /* now we are done */
3399 aopPut(AOP(result),"b",0);
3401 pic14_emitcode("mov","c,b.7");
3402 pic14_emitcode("subb","a,acc");
3405 aopPut(AOP(result),"a",offset++);
3409 /*-----------------------------------------------------------------*/
3410 /* genDiv - generates code for division */
3411 /*-----------------------------------------------------------------*/
3412 static void genDiv (iCode *ic)
3414 operand *left = IC_LEFT(ic);
3415 operand *right = IC_RIGHT(ic);
3416 operand *result= IC_RESULT(ic);
3419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3420 /* assign the amsops */
3421 aopOp (left,ic,FALSE);
3422 aopOp (right,ic,FALSE);
3423 aopOp (result,ic,TRUE);
3425 /* special cases first */
3427 if (AOP_TYPE(left) == AOP_CRY &&
3428 AOP_TYPE(right)== AOP_CRY) {
3429 genDivbits(left,right,result);
3433 /* if both are of size == 1 */
3434 if (AOP_SIZE(left) == 1 &&
3435 AOP_SIZE(right) == 1 ) {
3436 genDivOneByte(left,right,result);
3440 /* should have been converted to function call */
3443 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3444 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3445 freeAsmop(result,NULL,ic,TRUE);
3448 /*-----------------------------------------------------------------*/
3449 /* genModbits :- modulus of bits */
3450 /*-----------------------------------------------------------------*/
3451 static void genModbits (operand *left,
3459 /* the result must be bit */
3460 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3461 l = aopGet(AOP(left),0,FALSE,FALSE);
3465 pic14_emitcode("div","ab");
3466 pic14_emitcode("mov","a,b");
3467 pic14_emitcode("rrc","a");
3468 aopPut(AOP(result),"c",0);
3471 /*-----------------------------------------------------------------*/
3472 /* genModOneByte : 8 bit modulus */
3473 /*-----------------------------------------------------------------*/
3474 static void genModOneByte (operand *left,
3478 sym_link *opetype = operandType(result);
3483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3484 /* signed or unsigned */
3485 if (SPEC_USIGN(opetype)) {
3486 /* unsigned is easy */
3487 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3488 l = aopGet(AOP(left),0,FALSE,FALSE);
3490 pic14_emitcode("div","ab");
3491 aopPut(AOP(result),"b",0);
3495 /* signed is a little bit more difficult */
3497 /* save the signs of the operands */
3498 l = aopGet(AOP(left),0,FALSE,FALSE);
3501 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3502 pic14_emitcode("push","acc"); /* save it on the stack */
3504 /* now sign adjust for both left & right */
3505 l = aopGet(AOP(right),0,FALSE,FALSE);
3508 lbl = newiTempLabel(NULL);
3509 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3510 pic14_emitcode("cpl","a");
3511 pic14_emitcode("inc","a");
3512 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3513 pic14_emitcode("mov","b,a");
3515 /* sign adjust left side */
3516 l = aopGet(AOP(left),0,FALSE,FALSE);
3519 lbl = newiTempLabel(NULL);
3520 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3521 pic14_emitcode("cpl","a");
3522 pic14_emitcode("inc","a");
3523 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3525 /* now the multiplication */
3526 pic14_emitcode("div","ab");
3527 /* we are interested in the lower order
3529 lbl = newiTempLabel(NULL);
3530 pic14_emitcode("pop","acc");
3531 /* if there was an over flow we don't
3532 adjust the sign of the result */
3533 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3534 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3536 pic14_emitcode("clr","a");
3537 pic14_emitcode("subb","a,b");
3538 pic14_emitcode("mov","b,a");
3539 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3541 /* now we are done */
3542 aopPut(AOP(result),"b",0);
3546 /*-----------------------------------------------------------------*/
3547 /* genMod - generates code for division */
3548 /*-----------------------------------------------------------------*/
3549 static void genMod (iCode *ic)
3551 operand *left = IC_LEFT(ic);
3552 operand *right = IC_RIGHT(ic);
3553 operand *result= IC_RESULT(ic);
3556 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3557 /* assign the amsops */
3558 aopOp (left,ic,FALSE);
3559 aopOp (right,ic,FALSE);
3560 aopOp (result,ic,TRUE);
3562 /* special cases first */
3564 if (AOP_TYPE(left) == AOP_CRY &&
3565 AOP_TYPE(right)== AOP_CRY) {
3566 genModbits(left,right,result);
3570 /* if both are of size == 1 */
3571 if (AOP_SIZE(left) == 1 &&
3572 AOP_SIZE(right) == 1 ) {
3573 genModOneByte(left,right,result);
3577 /* should have been converted to function call */
3581 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3582 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3583 freeAsmop(result,NULL,ic,TRUE);
3586 /*-----------------------------------------------------------------*/
3587 /* genIfxJump :- will create a jump depending on the ifx */
3588 /*-----------------------------------------------------------------*/
3590 note: May need to add parameter to indicate when a variable is in bit space.
3592 static void genIfxJump (iCode *ic, char *jval)
3596 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3597 /* if true label then we jump if condition
3599 if ( IC_TRUE(ic) ) {
3601 if(strcmp(jval,"a") == 0)
3603 else if (strcmp(jval,"c") == 0)
3606 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3607 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3610 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3611 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3615 /* false label is present */
3616 if(strcmp(jval,"a") == 0)
3618 else if (strcmp(jval,"c") == 0)
3621 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3622 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3625 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3626 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3631 /* mark the icode as generated */
3635 /*-----------------------------------------------------------------*/
3637 /*-----------------------------------------------------------------*/
3638 static void genSkip(iCode *ifx,int status_bit)
3644 if ( IC_TRUE(ifx) ) {
3645 switch(status_bit) {
3660 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3661 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3665 switch(status_bit) {
3679 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3680 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3686 /*-----------------------------------------------------------------*/
3688 /*-----------------------------------------------------------------*/
3689 static void genSkipc(resolvedIfx *rifx)
3700 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3701 rifx->generated = 1;
3704 /*-----------------------------------------------------------------*/
3706 /*-----------------------------------------------------------------*/
3707 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3713 if( (rifx->condition ^ invert_condition) & 1)
3718 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3719 rifx->generated = 1;
3722 /*-----------------------------------------------------------------*/
3724 /*-----------------------------------------------------------------*/
3725 static void genSkipz(iCode *ifx, int condition)
3737 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3739 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3742 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3744 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3747 /*-----------------------------------------------------------------*/
3749 /*-----------------------------------------------------------------*/
3750 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3757 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3759 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3762 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3763 rifx->generated = 1;
3767 /*-----------------------------------------------------------------*/
3768 /* genChkZeroes :- greater or less than comparison */
3769 /* For each byte in a literal that is zero, inclusive or the */
3770 /* the corresponding byte in the operand with W */
3771 /* returns true if any of the bytes are zero */
3772 /*-----------------------------------------------------------------*/
3773 static int genChkZeroes(operand *op, int lit, int size)
3780 i = (lit >> (size*8)) & 0xff;
3784 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3786 emitpcode(POC_IORFW, popGet(AOP(op),size));
3795 /*-----------------------------------------------------------------*/
3796 /* genCmp :- greater or less than comparison */
3797 /*-----------------------------------------------------------------*/
3798 static void genCmp (operand *left,operand *right,
3799 operand *result, iCode *ifx, int sign)
3801 int size; //, offset = 0 ;
3802 unsigned long lit = 0L,i = 0;
3803 resolvedIfx rFalseIfx;
3804 // resolvedIfx rTrueIfx;
3808 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3811 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3812 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3816 resolveIfx(&rFalseIfx,ifx);
3817 truelbl = newiTempLabel(NULL);
3818 size = max(AOP_SIZE(left),AOP_SIZE(right));
3820 DEBUGpic14_AopType(__LINE__,left,right,result);
3824 /* if literal is on the right then swap with left */
3825 if ((AOP_TYPE(right) == AOP_LIT)) {
3826 operand *tmp = right ;
3827 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3828 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3831 lit = (lit - 1) & mask;
3834 rFalseIfx.condition ^= 1;
3837 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3838 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3842 //if(IC_TRUE(ifx) == NULL)
3843 /* if left & right are bit variables */
3844 if (AOP_TYPE(left) == AOP_CRY &&
3845 AOP_TYPE(right) == AOP_CRY ) {
3846 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3847 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3849 /* subtract right from left if at the
3850 end the carry flag is set then we know that
3851 left is greater than right */
3853 symbol *lbl = newiTempLabel(NULL);
3856 if(AOP_TYPE(right) == AOP_LIT) {
3858 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3860 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3867 genSkipCond(&rFalseIfx,left,size-1,7);
3869 /* no need to compare to 0...*/
3870 /* NOTE: this is a de-generate compare that most certainly
3871 * creates some dead code. */
3872 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3874 if(ifx) ifx->generated = 1;
3881 //i = (lit >> (size*8)) & 0xff;
3882 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3884 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3886 i = ((0-lit) & 0xff);
3889 /* lit is 0x7f, all signed chars are less than
3890 * this except for 0x7f itself */
3891 emitpcode(POC_XORLW, popGetLit(0x7f));
3892 genSkipz2(&rFalseIfx,0);
3894 emitpcode(POC_ADDLW, popGetLit(0x80));
3895 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3896 genSkipc(&rFalseIfx);
3901 genSkipz2(&rFalseIfx,1);
3903 emitpcode(POC_ADDLW, popGetLit(i));
3904 genSkipc(&rFalseIfx);
3908 if(ifx) ifx->generated = 1;
3912 /* chars are out of the way. now do ints and longs */
3915 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3922 genSkipCond(&rFalseIfx,left,size,7);
3923 if(ifx) ifx->generated = 1;
3928 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3930 //rFalseIfx.condition ^= 1;
3931 //genSkipCond(&rFalseIfx,left,size,7);
3932 //rFalseIfx.condition ^= 1;
3934 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3935 if(rFalseIfx.condition)
3936 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3938 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3940 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3941 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3942 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3945 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3947 if(rFalseIfx.condition) {
3949 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3955 genSkipc(&rFalseIfx);
3956 emitpLabel(truelbl->key);
3957 if(ifx) ifx->generated = 1;
3964 if( (lit & 0xff) == 0) {
3965 /* lower byte is zero */
3966 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3967 i = ((lit >> 8) & 0xff) ^0x80;
3968 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3969 emitpcode(POC_ADDLW, popGetLit( 0x80));
3970 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3971 genSkipc(&rFalseIfx);
3974 if(ifx) ifx->generated = 1;
3979 /* Special cases for signed longs */
3980 if( (lit & 0xffffff) == 0) {
3981 /* lower byte is zero */
3982 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3983 i = ((lit >> 8*3) & 0xff) ^0x80;
3984 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3985 emitpcode(POC_ADDLW, popGetLit( 0x80));
3986 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3987 genSkipc(&rFalseIfx);
3990 if(ifx) ifx->generated = 1;
3998 if(lit & (0x80 << (size*8))) {
3999 /* lit is negative */
4000 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4002 //genSkipCond(&rFalseIfx,left,size,7);
4004 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
4006 if(rFalseIfx.condition)
4007 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4009 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4013 /* lit is positive */
4014 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4015 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
4016 if(rFalseIfx.condition)
4017 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4019 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4023 /* There are no more special cases, so perform a general compare */
4025 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4026 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4030 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4032 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4034 //rFalseIfx.condition ^= 1;
4035 genSkipc(&rFalseIfx);
4037 emitpLabel(truelbl->key);
4039 if(ifx) ifx->generated = 1;
4046 /* sign is out of the way. So now do an unsigned compare */
4047 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4050 /* General case - compare to an unsigned literal on the right.*/
4052 i = (lit >> (size*8)) & 0xff;
4053 emitpcode(POC_MOVLW, popGetLit(i));
4054 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4056 i = (lit >> (size*8)) & 0xff;
4059 emitpcode(POC_MOVLW, popGetLit(i));
4061 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4063 /* this byte of the lit is zero,
4064 *if it's not the last then OR in the variable */
4066 emitpcode(POC_IORFW, popGet(AOP(left),size));
4071 emitpLabel(lbl->key);
4072 //if(emitFinalCheck)
4073 genSkipc(&rFalseIfx);
4075 emitpLabel(truelbl->key);
4077 if(ifx) ifx->generated = 1;
4084 if(AOP_TYPE(left) == AOP_LIT) {
4085 //symbol *lbl = newiTempLabel(NULL);
4087 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4090 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4093 if((lit == 0) && (sign == 0)){
4096 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4098 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4100 genSkipz2(&rFalseIfx,0);
4101 if(ifx) ifx->generated = 1;
4108 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4109 /* degenerate compare can never be true */
4110 if(rFalseIfx.condition == 0)
4111 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4113 if(ifx) ifx->generated = 1;
4118 /* signed comparisons to a literal byte */
4120 int lp1 = (lit+1) & 0xff;
4122 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4125 rFalseIfx.condition ^= 1;
4126 genSkipCond(&rFalseIfx,right,0,7);
4129 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4130 emitpcode(POC_XORLW, popGetLit(0x7f));
4131 genSkipz2(&rFalseIfx,1);
4134 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4135 emitpcode(POC_ADDLW, popGetLit(0x80));
4136 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4137 rFalseIfx.condition ^= 1;
4138 genSkipc(&rFalseIfx);
4141 if(ifx) ifx->generated = 1;
4143 /* unsigned comparisons to a literal byte */
4145 switch(lit & 0xff ) {
4147 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4148 genSkipz2(&rFalseIfx,0);
4149 if(ifx) ifx->generated = 1;
4152 genSkipCond(&rFalseIfx,right,0,7);
4153 if(ifx) ifx->generated = 1;
4157 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4158 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4160 rFalseIfx.condition ^= 1;
4161 if (AOP_TYPE(result) == AOP_CRY) {
4162 genSkipc(&rFalseIfx);
4163 if(ifx) ifx->generated = 1;
4165 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4166 emitpcode(POC_CLRF, popGet(AOP(result),0));
4167 emitpcode(POC_RLF, popGet(AOP(result),0));
4168 emitpcode(POC_MOVLW, popGetLit(0x01));
4169 emitpcode(POC_XORWF, popGet(AOP(result),0));
4180 /* Size is greater than 1 */
4188 /* this means lit = 0xffffffff, or -1 */
4191 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4192 rFalseIfx.condition ^= 1;
4193 genSkipCond(&rFalseIfx,right,size,7);
4194 if(ifx) ifx->generated = 1;
4201 if(rFalseIfx.condition) {
4202 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4203 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4206 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4208 emitpcode(POC_IORFW, popGet(AOP(right),size));
4212 if(rFalseIfx.condition) {
4213 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4214 emitpLabel(truelbl->key);
4216 rFalseIfx.condition ^= 1;
4217 genSkipCond(&rFalseIfx,right,s,7);
4220 if(ifx) ifx->generated = 1;
4224 if((size == 1) && (0 == (lp1&0xff))) {
4225 /* lower byte of signed word is zero */
4226 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4227 i = ((lp1 >> 8) & 0xff) ^0x80;
4228 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4229 emitpcode(POC_ADDLW, popGetLit( 0x80));
4230 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4231 rFalseIfx.condition ^= 1;
4232 genSkipc(&rFalseIfx);
4235 if(ifx) ifx->generated = 1;
4239 if(lit & (0x80 << (size*8))) {
4240 /* Lit is less than zero */
4241 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4242 //rFalseIfx.condition ^= 1;
4243 //genSkipCond(&rFalseIfx,left,size,7);
4244 //rFalseIfx.condition ^= 1;
4245 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4246 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4248 if(rFalseIfx.condition)
4249 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4251 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4255 /* Lit is greater than or equal to zero */
4256 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4257 //rFalseIfx.condition ^= 1;
4258 //genSkipCond(&rFalseIfx,right,size,7);
4259 //rFalseIfx.condition ^= 1;
4261 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4262 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4264 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4265 if(rFalseIfx.condition)
4266 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4268 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4273 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4274 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4278 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4280 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4282 rFalseIfx.condition ^= 1;
4283 //rFalseIfx.condition = 1;
4284 genSkipc(&rFalseIfx);
4286 emitpLabel(truelbl->key);
4288 if(ifx) ifx->generated = 1;
4293 /* compare word or long to an unsigned literal on the right.*/
4298 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4301 break; /* handled above */
4304 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4306 emitpcode(POC_IORFW, popGet(AOP(right),size));
4307 genSkipz2(&rFalseIfx,0);
4311 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4313 emitpcode(POC_IORFW, popGet(AOP(right),size));
4316 if(rFalseIfx.condition)
4317 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4319 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4322 emitpcode(POC_MOVLW, popGetLit(lit+1));
4323 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4325 rFalseIfx.condition ^= 1;
4326 genSkipc(&rFalseIfx);
4329 emitpLabel(truelbl->key);
4331 if(ifx) ifx->generated = 1;
4337 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4338 i = (lit >> (size*8)) & 0xff;
4340 emitpcode(POC_MOVLW, popGetLit(i));
4341 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4344 i = (lit >> (size*8)) & 0xff;
4347 emitpcode(POC_MOVLW, popGetLit(i));
4349 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4351 /* this byte of the lit is zero,
4352 *if it's not the last then OR in the variable */
4354 emitpcode(POC_IORFW, popGet(AOP(right),size));
4359 emitpLabel(lbl->key);
4361 rFalseIfx.condition ^= 1;
4362 genSkipc(&rFalseIfx);
4366 emitpLabel(truelbl->key);
4367 if(ifx) ifx->generated = 1;
4371 /* Compare two variables */
4373 DEBUGpic14_emitcode(";sign","%d",sign);
4377 /* Sigh. thus sucks... */
4379 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4380 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4381 emitpcode(POC_MOVLW, popGetLit(0x80));
4382 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4383 emitpcode(POC_XORFW, popGet(AOP(right),size));
4384 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4386 /* Signed char comparison */
4387 /* Special thanks to Nikolai Golovchenko for this snippet */
4388 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4389 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4390 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4391 emitpcode(POC_XORFW, popGet(AOP(left),0));
4392 emitpcode(POC_XORFW, popGet(AOP(right),0));
4393 emitpcode(POC_ADDLW, popGetLit(0x80));
4395 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4396 genSkipc(&rFalseIfx);
4398 if(ifx) ifx->generated = 1;
4404 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4405 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4409 /* The rest of the bytes of a multi-byte compare */
4413 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4416 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4417 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4422 emitpLabel(lbl->key);
4424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4425 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4426 (AOP_TYPE(result) == AOP_REG)) {
4427 emitpcode(POC_CLRF, popGet(AOP(result),0));
4428 emitpcode(POC_RLF, popGet(AOP(result),0));
4430 genSkipc(&rFalseIfx);
4432 //genSkipc(&rFalseIfx);
4433 if(ifx) ifx->generated = 1;
4440 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4441 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4442 pic14_outBitC(result);
4444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4445 /* if the result is used in the next
4446 ifx conditional branch then generate
4447 code a little differently */
4449 genIfxJump (ifx,"c");
4451 pic14_outBitC(result);
4452 /* leave the result in acc */
4457 /*-----------------------------------------------------------------*/
4458 /* genCmpGt :- greater than comparison */
4459 /*-----------------------------------------------------------------*/
4460 static void genCmpGt (iCode *ic, iCode *ifx)
4462 operand *left, *right, *result;
4463 sym_link *letype , *retype;
4467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4469 right= IC_RIGHT(ic);
4470 result = IC_RESULT(ic);
4472 letype = getSpec(operandType(left));
4473 retype =getSpec(operandType(right));
4474 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4475 /* assign the amsops */
4476 aopOp (left,ic,FALSE);
4477 aopOp (right,ic,FALSE);
4478 aopOp (result,ic,TRUE);
4480 genCmp(right, left, result, ifx, sign);
4482 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4483 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4484 freeAsmop(result,NULL,ic,TRUE);
4487 /*-----------------------------------------------------------------*/
4488 /* genCmpLt - less than comparisons */
4489 /*-----------------------------------------------------------------*/
4490 static void genCmpLt (iCode *ic, iCode *ifx)
4492 operand *left, *right, *result;
4493 sym_link *letype , *retype;
4497 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4499 right= IC_RIGHT(ic);
4500 result = IC_RESULT(ic);
4502 letype = getSpec(operandType(left));
4503 retype =getSpec(operandType(right));
4504 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4506 /* assign the amsops */
4507 aopOp (left,ic,FALSE);
4508 aopOp (right,ic,FALSE);
4509 aopOp (result,ic,TRUE);
4511 genCmp(left, right, result, ifx, sign);
4513 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4514 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4515 freeAsmop(result,NULL,ic,TRUE);
4518 /*-----------------------------------------------------------------*/
4519 /* genc16bit2lit - compare a 16 bit value to a literal */
4520 /*-----------------------------------------------------------------*/
4521 static void genc16bit2lit(operand *op, int lit, int offset)
4526 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4527 if( (lit&0xff) == 0)
4532 emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
4533 switch( BYTEofLONG(lit,i)) {
4535 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4538 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4541 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4544 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4545 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4550 emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
4551 switch( BYTEofLONG(lit,i)) {
4553 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4557 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4561 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4564 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4566 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4572 /*-----------------------------------------------------------------*/
4573 /* gencjneshort - compare and jump if not equal */
4574 /*-----------------------------------------------------------------*/
4575 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4577 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4579 int res_offset = 0; /* the result may be a different size then left or right */
4580 int res_size = AOP_SIZE(result);
4584 unsigned long lit = 0L;
4586 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4587 DEBUGpic14_AopType(__LINE__,left,right,result);
4589 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4590 resolveIfx(&rIfx,ifx);
4591 lbl = newiTempLabel(NULL);
4594 /* if the left side is a literal or
4595 if the right is in a pointer register and left
4597 if ((AOP_TYPE(left) == AOP_LIT) ||
4598 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4603 if(AOP_TYPE(right) == AOP_LIT)
4604 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4606 /* if the right side is a literal then anything goes */
4607 if (AOP_TYPE(right) == AOP_LIT &&
4608 AOP_TYPE(left) != AOP_DIR ) {
4611 genc16bit2lit(left, lit, 0);
4613 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4618 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4621 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4625 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4627 if(res_offset < res_size-1)
4635 /* if the right side is in a register or in direct space or
4636 if the left is a pointer register & right is not */
4637 else if (AOP_TYPE(right) == AOP_REG ||
4638 AOP_TYPE(right) == AOP_DIR ||
4639 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4640 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4641 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4642 int lbl_key = lbl->key;
4645 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4646 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4648 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4649 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4650 __FUNCTION__,__LINE__);
4654 /* switch(size) { */
4656 /* genc16bit2lit(left, lit, 0); */
4658 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4663 if((AOP_TYPE(left) == AOP_DIR) &&
4664 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4666 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4667 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4669 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4671 switch (lit & 0xff) {
4673 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4676 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4677 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4678 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4682 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4683 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4684 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4685 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4689 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4690 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4695 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4698 if(AOP_TYPE(result) == AOP_CRY) {
4699 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4704 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4706 /* fix me. probably need to check result size too */
4707 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4712 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4713 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4720 if(res_offset < res_size-1)
4725 } else if(AOP_TYPE(right) == AOP_REG &&
4726 AOP_TYPE(left) != AOP_DIR){
4729 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4730 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4731 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4736 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4738 if(res_offset < res_size-1)
4743 /* right is a pointer reg need both a & b */
4745 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4747 pic14_emitcode("mov","b,%s",l);
4748 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4749 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4754 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4756 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4758 emitpLabel(lbl->key);
4760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4767 /*-----------------------------------------------------------------*/
4768 /* gencjne - compare and jump if not equal */
4769 /*-----------------------------------------------------------------*/
4770 static void gencjne(operand *left, operand *right, iCode *ifx)
4772 symbol *tlbl = newiTempLabel(NULL);
4774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4775 gencjneshort(left, right, lbl);
4777 pic14_emitcode("mov","a,%s",one);
4778 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4779 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4780 pic14_emitcode("clr","a");
4781 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4783 emitpLabel(lbl->key);
4784 emitpLabel(tlbl->key);
4789 /*-----------------------------------------------------------------*/
4790 /* genCmpEq - generates code for equal to */
4791 /*-----------------------------------------------------------------*/
4792 static void genCmpEq (iCode *ic, iCode *ifx)
4794 operand *left, *right, *result;
4795 unsigned long lit = 0L;
4799 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4802 DEBUGpic14_emitcode ("; ifx is non-null","");
4804 DEBUGpic14_emitcode ("; ifx is null","");
4806 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4807 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4808 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4810 size = max(AOP_SIZE(left),AOP_SIZE(right));
4812 DEBUGpic14_AopType(__LINE__,left,right,result);
4814 /* if literal, literal on the right or
4815 if the right is in a pointer register and left
4817 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4818 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4819 operand *tmp = right ;
4825 if(ifx && !AOP_SIZE(result)){
4827 /* if they are both bit variables */
4828 if (AOP_TYPE(left) == AOP_CRY &&
4829 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4830 if(AOP_TYPE(right) == AOP_LIT){
4831 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4833 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4834 pic14_emitcode("cpl","c");
4835 } else if(lit == 1L) {
4836 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4838 pic14_emitcode("clr","c");
4840 /* AOP_TYPE(right) == AOP_CRY */
4842 symbol *lbl = newiTempLabel(NULL);
4843 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4844 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4845 pic14_emitcode("cpl","c");
4846 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4848 /* if true label then we jump if condition
4850 tlbl = newiTempLabel(NULL);
4851 if ( IC_TRUE(ifx) ) {
4852 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4853 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4855 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4856 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4858 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4861 /* left and right are both bit variables, result is carry */
4864 resolveIfx(&rIfx,ifx);
4866 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4867 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4868 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4869 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4874 /* They're not both bit variables. Is the right a literal? */
4875 if(AOP_TYPE(right) == AOP_LIT) {
4876 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4881 switch(lit & 0xff) {
4883 if ( IC_TRUE(ifx) ) {
4884 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4886 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4888 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4889 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4893 if ( IC_TRUE(ifx) ) {
4894 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4896 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4898 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4899 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4903 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4905 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4910 /* end of size == 1 */
4914 genc16bit2lit(left,lit,offset);
4917 /* end of size == 2 */
4922 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4923 emitpcode(POC_IORFW,popGet(AOP(left),1));
4924 emitpcode(POC_IORFW,popGet(AOP(left),2));
4925 emitpcode(POC_IORFW,popGet(AOP(left),3));
4929 /* search for patterns that can be optimized */
4931 genc16bit2lit(left,lit,0);
4934 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4936 genc16bit2lit(left,lit,2);
4938 emitpcode(POC_IORFW,popGet(AOP(left),2));
4939 emitpcode(POC_IORFW,popGet(AOP(left),3));
4952 } else if(AOP_TYPE(right) == AOP_CRY ) {
4953 /* we know the left is not a bit, but that the right is */
4954 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4955 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4956 popGet(AOP(right),offset));
4957 emitpcode(POC_XORLW,popGetLit(1));
4959 /* if the two are equal, then W will be 0 and the Z bit is set
4960 * we could test Z now, or go ahead and check the high order bytes if
4961 * the variable we're comparing is larger than a byte. */
4964 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4966 if ( IC_TRUE(ifx) ) {
4968 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4969 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4972 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4973 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4977 /* They're both variables that are larger than bits */
4980 tlbl = newiTempLabel(NULL);
4983 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4984 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4986 if ( IC_TRUE(ifx) ) {
4989 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4990 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4993 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4994 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4998 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4999 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5003 if(s>1 && IC_TRUE(ifx)) {
5004 emitpLabel(tlbl->key);
5005 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5009 /* mark the icode as generated */
5014 /* if they are both bit variables */
5015 if (AOP_TYPE(left) == AOP_CRY &&
5016 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5017 if(AOP_TYPE(right) == AOP_LIT){
5018 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5020 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5021 pic14_emitcode("cpl","c");
5022 } else if(lit == 1L) {
5023 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5025 pic14_emitcode("clr","c");
5027 /* AOP_TYPE(right) == AOP_CRY */
5029 symbol *lbl = newiTempLabel(NULL);
5030 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5031 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5032 pic14_emitcode("cpl","c");
5033 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
5036 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5037 pic14_outBitC(result);
5041 genIfxJump (ifx,"c");
5044 /* if the result is used in an arithmetic operation
5045 then put the result in place */
5046 pic14_outBitC(result);
5049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5050 gencjne(left,right,result,ifx);
5053 gencjne(left,right,newiTempLabel(NULL));
5055 if(IC_TRUE(ifx)->key)
5056 gencjne(left,right,IC_TRUE(ifx)->key);
5058 gencjne(left,right,IC_FALSE(ifx)->key);
5062 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5063 aopPut(AOP(result),"a",0);
5068 genIfxJump (ifx,"a");
5072 /* if the result is used in an arithmetic operation
5073 then put the result in place */
5075 if (AOP_TYPE(result) != AOP_CRY)
5076 pic14_outAcc(result);
5078 /* leave the result in acc */
5082 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5083 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084 freeAsmop(result,NULL,ic,TRUE);
5087 /*-----------------------------------------------------------------*/
5088 /* ifxForOp - returns the icode containing the ifx for operand */
5089 /*-----------------------------------------------------------------*/
5090 static iCode *ifxForOp ( operand *op, iCode *ic )
5093 /* if true symbol then needs to be assigned */
5094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5095 if (IS_TRUE_SYMOP(op))
5098 /* if this has register type condition and
5099 the next instruction is ifx with the same operand
5100 and live to of the operand is upto the ifx only then */
5102 ic->next->op == IFX &&
5103 IC_COND(ic->next)->key == op->key &&
5104 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5108 ic->next->op == IFX &&
5109 IC_COND(ic->next)->key == op->key) {
5110 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5114 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5116 ic->next->op == IFX)
5117 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5120 ic->next->op == IFX &&
5121 IC_COND(ic->next)->key == op->key) {
5122 DEBUGpic14_emitcode ("; "," key is okay");
5123 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5124 OP_SYMBOL(op)->liveTo,
5131 /*-----------------------------------------------------------------*/
5132 /* genAndOp - for && operation */
5133 /*-----------------------------------------------------------------*/
5134 static void genAndOp (iCode *ic)
5136 operand *left,*right, *result;
5140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5141 /* note here that && operations that are in an
5142 if statement are taken away by backPatchLabels
5143 only those used in arthmetic operations remain */
5144 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5145 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5146 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5148 DEBUGpic14_AopType(__LINE__,left,right,result);
5150 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5151 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5152 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5154 /* if both are bit variables */
5155 /* if (AOP_TYPE(left) == AOP_CRY && */
5156 /* AOP_TYPE(right) == AOP_CRY ) { */
5157 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5158 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5159 /* pic14_outBitC(result); */
5161 /* tlbl = newiTempLabel(NULL); */
5162 /* pic14_toBoolean(left); */
5163 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5164 /* pic14_toBoolean(right); */
5165 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5166 /* pic14_outBitAcc(result); */
5169 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5170 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5171 freeAsmop(result,NULL,ic,TRUE);
5175 /*-----------------------------------------------------------------*/
5176 /* genOrOp - for || operation */
5177 /*-----------------------------------------------------------------*/
5180 modified this code, but it doesn't appear to ever get called
5183 static void genOrOp (iCode *ic)
5185 operand *left,*right, *result;
5188 /* note here that || operations that are in an
5189 if statement are taken away by backPatchLabels
5190 only those used in arthmetic operations remain */
5192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5193 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5194 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5195 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5197 DEBUGpic14_AopType(__LINE__,left,right,result);
5199 /* if both are bit variables */
5200 if (AOP_TYPE(left) == AOP_CRY &&
5201 AOP_TYPE(right) == AOP_CRY ) {
5202 pic14_emitcode("clrc","");
5203 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5204 AOP(left)->aopu.aop_dir,
5205 AOP(left)->aopu.aop_dir);
5206 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5207 AOP(right)->aopu.aop_dir,
5208 AOP(right)->aopu.aop_dir);
5209 pic14_emitcode("setc","");
5212 tlbl = newiTempLabel(NULL);
5213 pic14_toBoolean(left);
5215 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5216 pic14_toBoolean(right);
5217 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5219 pic14_outBitAcc(result);
5222 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5223 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5224 freeAsmop(result,NULL,ic,TRUE);
5227 /*-----------------------------------------------------------------*/
5228 /* isLiteralBit - test if lit == 2^n */
5229 /*-----------------------------------------------------------------*/
5230 static int isLiteralBit(unsigned long lit)
5232 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5233 0x100L,0x200L,0x400L,0x800L,
5234 0x1000L,0x2000L,0x4000L,0x8000L,
5235 0x10000L,0x20000L,0x40000L,0x80000L,
5236 0x100000L,0x200000L,0x400000L,0x800000L,
5237 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5238 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5243 for(idx = 0; idx < 32; idx++)
5249 /*-----------------------------------------------------------------*/
5250 /* continueIfTrue - */
5251 /*-----------------------------------------------------------------*/
5252 static void continueIfTrue (iCode *ic)
5255 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5257 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5261 /*-----------------------------------------------------------------*/
5263 /*-----------------------------------------------------------------*/
5264 static void jumpIfTrue (iCode *ic)
5267 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5269 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5273 /*-----------------------------------------------------------------*/
5274 /* jmpTrueOrFalse - */
5275 /*-----------------------------------------------------------------*/
5276 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5279 // ugly but optimized by peephole
5280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5282 symbol *nlbl = newiTempLabel(NULL);
5283 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5284 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5285 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5286 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5289 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5290 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5295 /*-----------------------------------------------------------------*/
5296 /* genAnd - code for and */
5297 /*-----------------------------------------------------------------*/
5298 static void genAnd (iCode *ic, iCode *ifx)
5300 operand *left, *right, *result;
5302 unsigned long lit = 0L;
5307 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5308 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5309 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5310 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5312 resolveIfx(&rIfx,ifx);
5314 /* if left is a literal & right is not then exchange them */
5315 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5316 AOP_NEEDSACC(left)) {
5317 operand *tmp = right ;
5322 /* if result = right then exchange them */
5323 if(pic14_sameRegs(AOP(result),AOP(right))){
5324 operand *tmp = right ;
5329 /* if right is bit then exchange them */
5330 if (AOP_TYPE(right) == AOP_CRY &&
5331 AOP_TYPE(left) != AOP_CRY){
5332 operand *tmp = right ;
5336 if(AOP_TYPE(right) == AOP_LIT)
5337 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5339 size = AOP_SIZE(result);
5341 DEBUGpic14_AopType(__LINE__,left,right,result);
5344 // result = bit & yy;
5345 if (AOP_TYPE(left) == AOP_CRY){
5346 // c = bit & literal;
5347 if(AOP_TYPE(right) == AOP_LIT){
5349 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5352 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5355 if(size && (AOP_TYPE(result) == AOP_CRY)){
5356 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5359 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5363 pic14_emitcode("clr","c");
5366 if (AOP_TYPE(right) == AOP_CRY){
5368 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5369 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5372 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5374 pic14_emitcode("rrc","a");
5375 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5381 pic14_outBitC(result);
5383 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5384 genIfxJump(ifx, "c");
5388 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5389 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5390 if((AOP_TYPE(right) == AOP_LIT) &&
5391 (AOP_TYPE(result) == AOP_CRY) &&
5392 (AOP_TYPE(left) != AOP_CRY)){
5393 int posbit = isLiteralBit(lit);
5397 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5400 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5405 while (posbit > 7) {
5409 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5410 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5411 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5418 symbol *tlbl = newiTempLabel(NULL);
5419 int sizel = AOP_SIZE(left);
5421 pic14_emitcode("setb","c");
5423 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5424 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5426 if((posbit = isLiteralBit(bytelit)) != 0)
5427 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5429 if(bytelit != 0x0FFL)
5430 pic14_emitcode("anl","a,%s",
5431 aopGet(AOP(right),offset,FALSE,TRUE));
5432 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5437 // bit = left & literal
5439 pic14_emitcode("clr","c");
5440 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5442 // if(left & literal)
5445 jmpTrueOrFalse(ifx, tlbl);
5449 pic14_outBitC(result);
5453 /* if left is same as result */
5454 if(pic14_sameRegs(AOP(result),AOP(left))){
5456 for(;size--; offset++,lit>>=8) {
5457 if(AOP_TYPE(right) == AOP_LIT){
5458 switch(lit & 0xff) {
5460 /* and'ing with 0 has clears the result */
5461 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5464 /* and'ing with 0xff is a nop when the result and left are the same */
5469 int p = my_powof2( (~lit) & 0xff );
5471 /* only one bit is set in the literal, so use a bcf instruction */
5472 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5475 if(know_W != (int)(lit&0xff))
5476 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5478 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5483 if (AOP_TYPE(left) == AOP_ACC) {
5484 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5486 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5487 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5494 // left & result in different registers
5495 if(AOP_TYPE(result) == AOP_CRY){
5497 // if(size), result in bit
5498 // if(!size && ifx), conditional oper: if(left & right)
5499 symbol *tlbl = newiTempLabel(NULL);
5500 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5502 pic14_emitcode("setb","c");
5504 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5505 pic14_emitcode("anl","a,%s",
5506 aopGet(AOP(left),offset,FALSE,FALSE));
5507 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5512 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5513 pic14_outBitC(result);
5515 jmpTrueOrFalse(ifx, tlbl);
5517 for(;(size--);offset++) {
5519 // result = left & right
5520 if(AOP_TYPE(right) == AOP_LIT){
5521 int t = (lit >> (offset*8)) & 0x0FFL;
5524 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5527 if(AOP_TYPE(left) != AOP_ACC) {
5528 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5530 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5533 if(AOP_TYPE(left) == AOP_ACC) {
5534 emitpcode(POC_ANDLW, popGetLit(t));
5536 emitpcode(POC_MOVLW, popGetLit(t));
5537 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5539 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5544 if (AOP_TYPE(left) == AOP_ACC) {
5545 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5547 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5548 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5550 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5556 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5557 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5558 freeAsmop(result,NULL,ic,TRUE);
5561 /*-----------------------------------------------------------------*/
5562 /* genOr - code for or */
5563 /*-----------------------------------------------------------------*/
5564 static void genOr (iCode *ic, iCode *ifx)
5566 operand *left, *right, *result;
5568 unsigned long lit = 0L;
5571 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5573 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5574 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5575 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5577 DEBUGpic14_AopType(__LINE__,left,right,result);
5579 /* if left is a literal & right is not then exchange them */
5580 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5581 AOP_NEEDSACC(left)) {
5582 operand *tmp = right ;
5587 /* if result = right then exchange them */
5588 if(pic14_sameRegs(AOP(result),AOP(right))){
5589 operand *tmp = right ;
5594 /* if right is bit then exchange them */
5595 if (AOP_TYPE(right) == AOP_CRY &&
5596 AOP_TYPE(left) != AOP_CRY){
5597 operand *tmp = right ;
5602 DEBUGpic14_AopType(__LINE__,left,right,result);
5604 if(AOP_TYPE(right) == AOP_LIT)
5605 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5607 size = AOP_SIZE(result);
5611 if (AOP_TYPE(left) == AOP_CRY){
5612 if(AOP_TYPE(right) == AOP_LIT){
5613 // c = bit & literal;
5615 // lit != 0 => result = 1
5616 if(AOP_TYPE(result) == AOP_CRY){
5618 emitpcode(POC_BSF, popGet(AOP(result),0));
5619 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5620 // AOP(result)->aopu.aop_dir,
5621 // AOP(result)->aopu.aop_dir);
5623 continueIfTrue(ifx);
5627 // lit == 0 => result = left
5628 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5630 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5633 if (AOP_TYPE(right) == AOP_CRY){
5634 if(pic14_sameRegs(AOP(result),AOP(left))){
5636 emitpcode(POC_BCF, popGet(AOP(result),0));
5637 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5638 emitpcode(POC_BSF, popGet(AOP(result),0));
5640 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5641 AOP(result)->aopu.aop_dir,
5642 AOP(result)->aopu.aop_dir);
5643 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5644 AOP(right)->aopu.aop_dir,
5645 AOP(right)->aopu.aop_dir);
5646 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5647 AOP(result)->aopu.aop_dir,
5648 AOP(result)->aopu.aop_dir);
5650 if( AOP_TYPE(result) == AOP_ACC) {
5651 emitpcode(POC_MOVLW, popGetLit(0));
5652 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5653 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5654 emitpcode(POC_MOVLW, popGetLit(1));
5658 emitpcode(POC_BCF, popGet(AOP(result),0));
5659 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5660 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5661 emitpcode(POC_BSF, popGet(AOP(result),0));
5663 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5664 AOP(result)->aopu.aop_dir,
5665 AOP(result)->aopu.aop_dir);
5666 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5667 AOP(right)->aopu.aop_dir,
5668 AOP(right)->aopu.aop_dir);
5669 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5670 AOP(left)->aopu.aop_dir,
5671 AOP(left)->aopu.aop_dir);
5672 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5673 AOP(result)->aopu.aop_dir,
5674 AOP(result)->aopu.aop_dir);
5679 symbol *tlbl = newiTempLabel(NULL);
5680 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5683 emitpcode(POC_BCF, popGet(AOP(result),0));
5684 if( AOP_TYPE(right) == AOP_ACC) {
5685 emitpcode(POC_IORLW, popGetLit(0));
5687 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5688 emitpcode(POC_BSF, popGet(AOP(result),0));
5693 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5694 pic14_emitcode(";XXX setb","c");
5695 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5696 AOP(left)->aopu.aop_dir,tlbl->key+100);
5697 pic14_toBoolean(right);
5698 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5699 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5700 jmpTrueOrFalse(ifx, tlbl);
5704 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5711 pic14_outBitC(result);
5713 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5714 genIfxJump(ifx, "c");
5718 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5719 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5720 if((AOP_TYPE(right) == AOP_LIT) &&
5721 (AOP_TYPE(result) == AOP_CRY) &&
5722 (AOP_TYPE(left) != AOP_CRY)){
5724 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5727 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5729 continueIfTrue(ifx);
5732 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5733 // lit = 0, result = boolean(left)
5735 pic14_emitcode(";XXX setb","c");
5736 pic14_toBoolean(right);
5738 symbol *tlbl = newiTempLabel(NULL);
5739 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5741 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5743 genIfxJump (ifx,"a");
5747 pic14_outBitC(result);
5751 /* if left is same as result */
5752 if(pic14_sameRegs(AOP(result),AOP(left))){
5754 for(;size--; offset++,lit>>=8) {
5755 if(AOP_TYPE(right) == AOP_LIT){
5756 if((lit & 0xff) == 0)
5757 /* or'ing with 0 has no effect */
5760 int p = my_powof2(lit & 0xff);
5762 /* only one bit is set in the literal, so use a bsf instruction */
5764 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5766 if(know_W != (int)(lit & 0xff))
5767 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5768 know_W = lit & 0xff;
5769 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5774 if (AOP_TYPE(left) == AOP_ACC) {
5775 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5776 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5778 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5779 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5781 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5782 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5788 // left & result in different registers
5789 if(AOP_TYPE(result) == AOP_CRY){
5791 // if(size), result in bit
5792 // if(!size && ifx), conditional oper: if(left | right)
5793 symbol *tlbl = newiTempLabel(NULL);
5794 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5795 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5799 pic14_emitcode(";XXX setb","c");
5801 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5802 pic14_emitcode(";XXX orl","a,%s",
5803 aopGet(AOP(left),offset,FALSE,FALSE));
5804 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5809 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5810 pic14_outBitC(result);
5812 jmpTrueOrFalse(ifx, tlbl);
5813 } else for(;(size--);offset++){
5815 // result = left | right
5816 if(AOP_TYPE(right) == AOP_LIT){
5817 int t = (lit >> (offset*8)) & 0x0FFL;
5820 if (AOP_TYPE(left) != AOP_ACC) {
5821 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5823 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5827 if (AOP_TYPE(left) == AOP_ACC) {
5828 emitpcode(POC_IORLW, popGetLit(t));
5830 emitpcode(POC_MOVLW, popGetLit(t));
5831 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5833 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5838 // faster than result <- left, anl result,right
5839 // and better if result is SFR
5840 if (AOP_TYPE(left) == AOP_ACC) {
5841 emitpcode(POC_IORFW,popGet(AOP(right),offset));
5843 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5844 emitpcode(POC_IORFW,popGet(AOP(left),offset));
5846 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5851 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5852 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5853 freeAsmop(result,NULL,ic,TRUE);
5856 /*-----------------------------------------------------------------*/
5857 /* genXor - code for xclusive or */
5858 /*-----------------------------------------------------------------*/
5859 static void genXor (iCode *ic, iCode *ifx)
5861 operand *left, *right, *result;
5863 unsigned long lit = 0L;
5866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5868 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5869 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5870 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5872 /* if left is a literal & right is not ||
5873 if left needs acc & right does not */
5874 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5875 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5876 operand *tmp = right ;
5881 /* if result = right then exchange them */
5882 if(pic14_sameRegs(AOP(result),AOP(right))){
5883 operand *tmp = right ;
5888 /* if right is bit then exchange them */
5889 if (AOP_TYPE(right) == AOP_CRY &&
5890 AOP_TYPE(left) != AOP_CRY){
5891 operand *tmp = right ;
5895 if(AOP_TYPE(right) == AOP_LIT)
5896 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5898 size = AOP_SIZE(result);
5902 if (AOP_TYPE(left) == AOP_CRY){
5903 if(AOP_TYPE(right) == AOP_LIT){
5904 // c = bit & literal;
5906 // lit>>1 != 0 => result = 1
5907 if(AOP_TYPE(result) == AOP_CRY){
5909 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5910 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5912 continueIfTrue(ifx);
5915 pic14_emitcode("setb","c");
5919 // lit == 0, result = left
5920 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5922 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5924 // lit == 1, result = not(left)
5925 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5926 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5927 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5928 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5931 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5932 pic14_emitcode("cpl","c");
5939 symbol *tlbl = newiTempLabel(NULL);
5940 if (AOP_TYPE(right) == AOP_CRY){
5942 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5945 int sizer = AOP_SIZE(right);
5947 // if val>>1 != 0, result = 1
5948 pic14_emitcode("setb","c");
5950 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5952 // test the msb of the lsb
5953 pic14_emitcode("anl","a,#0xfe");
5954 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5958 pic14_emitcode("rrc","a");
5960 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5961 pic14_emitcode("cpl","c");
5962 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5967 pic14_outBitC(result);
5969 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5970 genIfxJump(ifx, "c");
5974 if(pic14_sameRegs(AOP(result),AOP(left))){
5975 /* if left is same as result */
5976 for(;size--; offset++) {
5977 if(AOP_TYPE(right) == AOP_LIT){
5978 int t = (lit >> (offset*8)) & 0x0FFL;
5982 if (IS_AOP_PREG(left)) {
5983 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5984 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5985 aopPut(AOP(result),"a",offset);
5987 emitpcode(POC_MOVLW, popGetLit(t));
5988 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5989 pic14_emitcode("xrl","%s,%s",
5990 aopGet(AOP(left),offset,FALSE,TRUE),
5991 aopGet(AOP(right),offset,FALSE,FALSE));
5994 if (AOP_TYPE(left) == AOP_ACC)
5995 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5997 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5998 emitpcode(POC_XORWF,popGet(AOP(left),offset));
6000 if (IS_AOP_PREG(left)) {
6001 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
6002 aopPut(AOP(result),"a",offset);
6004 pic14_emitcode("xrl","%s,a",
6005 aopGet(AOP(left),offset,FALSE,TRUE));
6011 // left & result in different registers
6012 if(AOP_TYPE(result) == AOP_CRY){
6014 // if(size), result in bit
6015 // if(!size && ifx), conditional oper: if(left ^ right)
6016 symbol *tlbl = newiTempLabel(NULL);
6017 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6019 pic14_emitcode("setb","c");
6021 if((AOP_TYPE(right) == AOP_LIT) &&
6022 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6023 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
6025 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6026 pic14_emitcode("xrl","a,%s",
6027 aopGet(AOP(left),offset,FALSE,FALSE));
6029 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6034 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6035 pic14_outBitC(result);
6037 jmpTrueOrFalse(ifx, tlbl);
6038 } else for(;(size--);offset++){
6040 // result = left & right
6041 if(AOP_TYPE(right) == AOP_LIT){
6042 int t = (lit >> (offset*8)) & 0x0FFL;
6045 if (AOP_TYPE(left) != AOP_ACC) {
6046 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6048 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6049 pic14_emitcode("movf","%s,w",
6050 aopGet(AOP(left),offset,FALSE,FALSE));
6051 pic14_emitcode("movwf","%s",
6052 aopGet(AOP(result),offset,FALSE,FALSE));
6055 if (AOP_TYPE(left) == AOP_ACC) {
6056 emitpcode(POC_XORLW, popGetLit(t));
6058 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6060 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6063 if (AOP_TYPE(left) == AOP_ACC) {
6064 emitpcode(POC_XORLW, popGetLit(t));
6066 emitpcode(POC_MOVLW, popGetLit(t));
6067 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6069 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6070 pic14_emitcode("movlw","0x%x",t);
6071 pic14_emitcode("xorwf","%s,w",
6072 aopGet(AOP(left),offset,FALSE,FALSE));
6073 pic14_emitcode("movwf","%s",
6074 aopGet(AOP(result),offset,FALSE,FALSE));
6080 // faster than result <- left, anl result,right
6081 // and better if result is SFR
6082 if (AOP_TYPE(left) == AOP_ACC) {
6083 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6085 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6086 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6088 if ( AOP_TYPE(result) != AOP_ACC){
6089 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6095 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6096 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6097 freeAsmop(result,NULL,ic,TRUE);
6100 /*-----------------------------------------------------------------*/
6101 /* genInline - write the inline code out */
6102 /*-----------------------------------------------------------------*/
6103 static void genInline (iCode *ic)
6105 char *buffer, *bp, *bp1;
6108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6110 _G.inLine += (!options.asmpeep);
6112 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6113 strcpy(buffer,IC_INLINE(ic));
6115 /* emit each line as a code */
6121 addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6129 /* print label, use this special format with NULL directive
6130 * to denote that the argument should not be indented with tab */
6131 addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process
6138 if ((bp1 != bp) && *bp1)
6139 addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6143 _G.inLine -= (!options.asmpeep);
6146 /*-----------------------------------------------------------------*/
6147 /* genRRC - rotate right with carry */
6148 /*-----------------------------------------------------------------*/
6149 static void genRRC (iCode *ic)
6151 operand *left , *result ;
6152 int size, offset = 0, same;
6155 /* rotate right with carry */
6157 result=IC_RESULT(ic);
6158 aopOp (left,ic,FALSE);
6159 aopOp (result,ic,FALSE);
6161 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6163 same = pic14_sameRegs(AOP(result),AOP(left));
6165 size = AOP_SIZE(result);
6167 /* get the lsb and put it into the carry */
6168 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6175 emitpcode(POC_RRF, popGet(AOP(left),offset));
6177 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6178 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6184 freeAsmop(left,NULL,ic,TRUE);
6185 freeAsmop(result,NULL,ic,TRUE);
6188 /*-----------------------------------------------------------------*/
6189 /* genRLC - generate code for rotate left with carry */
6190 /*-----------------------------------------------------------------*/
6191 static void genRLC (iCode *ic)
6193 operand *left , *result ;
6194 int size, offset = 0;
6198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6199 /* rotate right with carry */
6201 result=IC_RESULT(ic);
6202 aopOp (left,ic,FALSE);
6203 aopOp (result,ic,FALSE);
6205 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6207 same = pic14_sameRegs(AOP(result),AOP(left));
6209 /* move it to the result */
6210 size = AOP_SIZE(result);
6212 /* get the msb and put it into the carry */
6213 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6220 emitpcode(POC_RLF, popGet(AOP(left),offset));
6222 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6223 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6230 freeAsmop(left,NULL,ic,TRUE);
6231 freeAsmop(result,NULL,ic,TRUE);
6234 /*-----------------------------------------------------------------*/
6235 /* genGetHbit - generates code get highest order bit */
6236 /*-----------------------------------------------------------------*/
6237 static void genGetHbit (iCode *ic)
6239 operand *left, *result;
6241 result=IC_RESULT(ic);
6242 aopOp (left,ic,FALSE);
6243 aopOp (result,ic,FALSE);
6246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6247 /* get the highest order byte into a */
6248 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6249 if(AOP_TYPE(result) == AOP_CRY){
6250 pic14_emitcode("rlc","a");
6251 pic14_outBitC(result);
6254 pic14_emitcode("rl","a");
6255 pic14_emitcode("anl","a,#0x01");
6256 pic14_outAcc(result);
6260 freeAsmop(left,NULL,ic,TRUE);
6261 freeAsmop(result,NULL,ic,TRUE);
6264 /*-----------------------------------------------------------------*/
6265 /* AccRol - rotate left accumulator by known count */
6266 /*-----------------------------------------------------------------*/
6267 static void AccRol (operand *op,int offset,int shCount)
6270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6271 shCount &= 0x0007; // shCount : 0..7
6276 pic14_emitcode("rl","a");
6277 emitpcode(POC_RLF,popGet(AOP(op),offset));
6280 pic14_emitcode("rl","a");
6281 pic14_emitcode("rl","a");
6282 emitpcode(POC_RLF,popGet(AOP(op),offset));
6283 emitpcode(POC_RLF,popGet(AOP(op),offset));
6286 pic14_emitcode("swap","a");
6287 pic14_emitcode("rr","a");
6288 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6289 emitpcode(POC_RRF,popGet(AOP(op),offset));
6292 pic14_emitcode("swap","a");
6293 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6296 pic14_emitcode("swap","a");
6297 pic14_emitcode("rl","a");
6298 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6299 emitpcode(POC_RLF,popGet(AOP(op),offset));
6302 pic14_emitcode("rr","a");
6303 pic14_emitcode("rr","a");
6304 emitpcode(POC_RRF,popGet(AOP(op),offset));
6305 emitpcode(POC_RRF,popGet(AOP(op),offset));
6308 pic14_emitcode("rr","a");
6309 emitpcode(POC_RRF,popGet(AOP(op),offset));
6314 /*-----------------------------------------------------------------*/
6315 /* AccLsh - left shift accumulator by known count */
6316 /*-----------------------------------------------------------------*/
6317 static void AccLsh (operand *op,int offset,int shCount)
6320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6324 pic14_emitcode("add","a,acc");
6326 emitpcode(POC_RLF,popGet(AOP(op),offset));
6329 pic14_emitcode("add","a,acc");
6331 emitpcode(POC_RLF,popGet(AOP(op),offset));
6332 pic14_emitcode("add","a,acc");
6334 emitpcode(POC_RLF,popGet(AOP(op),offset));
6339 /* rotate left accumulator */
6340 AccRol(op,offset,shCount);
6341 /* and kill the lower order bits */
6342 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6343 emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
6349 /*-----------------------------------------------------------------*/
6350 /* AccRsh - right shift accumulator by known count */
6351 /*-----------------------------------------------------------------*/
6352 static void AccRsh (operand *op,int offset,int shCount)
6355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6359 pic14_emitcode("rrc","a");
6361 /* rotate right accumulator */
6362 AccRol(op,offset,8 - shCount);
6363 /* and kill the higher order bits */
6364 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6370 /*-----------------------------------------------------------------*/
6371 /* AccSRsh - signed right shift accumulator by known count */
6372 /*-----------------------------------------------------------------*/
6373 static void AccSRsh (int shCount)
6376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6379 pic14_emitcode("mov","c,acc.7");
6380 pic14_emitcode("rrc","a");
6381 } else if(shCount == 2){
6382 pic14_emitcode("mov","c,acc.7");
6383 pic14_emitcode("rrc","a");
6384 pic14_emitcode("mov","c,acc.7");
6385 pic14_emitcode("rrc","a");
6387 tlbl = newiTempLabel(NULL);
6388 /* rotate right accumulator */
6389 AccRol(8 - shCount);
6390 /* and kill the higher order bits */
6391 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6392 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6393 pic14_emitcode("orl","a,#0x%02x",
6394 (unsigned char)~SRMask[shCount]);
6395 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6400 /*-----------------------------------------------------------------*/
6401 /* shiftR1Left2Result - shift right one byte from left to result */
6402 /*-----------------------------------------------------------------*/
6403 static void shiftR1Left2ResultSigned (operand *left, int offl,
6404 operand *result, int offr,
6410 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6412 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6416 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6418 emitpcode(POC_RRF, popGet(AOP(result),offr));
6420 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6421 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6429 emitpcode(POC_RRF, popGet(AOP(result),offr));
6431 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6432 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6434 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6435 emitpcode(POC_RRF, popGet(AOP(result),offr));
6441 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6443 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6444 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6447 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6448 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6449 emitpcode(POC_ANDLW, popGetLit(0x1f));
6451 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6452 emitpcode(POC_IORLW, popGetLit(0xe0));
6454 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6458 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6459 emitpcode(POC_ANDLW, popGetLit(0x0f));
6460 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6461 emitpcode(POC_IORLW, popGetLit(0xf0));
6462 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6466 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6468 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6469 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6471 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6472 emitpcode(POC_ANDLW, popGetLit(0x07));
6473 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6474 emitpcode(POC_IORLW, popGetLit(0xf8));
6475 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6480 emitpcode(POC_MOVLW, popGetLit(0x00));
6481 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6482 emitpcode(POC_MOVLW, popGetLit(0xfe));
6483 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6484 emitpcode(POC_IORLW, popGetLit(0x01));
6485 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6487 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6488 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6489 emitpcode(POC_DECF, popGet(AOP(result),offr));
6490 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6491 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6497 emitpcode(POC_MOVLW, popGetLit(0x00));
6498 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6499 emitpcode(POC_MOVLW, popGetLit(0xff));
6500 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6502 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6503 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6504 emitpcode(POC_DECF, popGet(AOP(result),offr));
6512 /*-----------------------------------------------------------------*/
6513 /* shiftR1Left2Result - shift right one byte from left to result */
6514 /*-----------------------------------------------------------------*/
6515 static void shiftR1Left2Result (operand *left, int offl,
6516 operand *result, int offr,
6517 int shCount, int sign)
6522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6524 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6526 /* Copy the msb into the carry if signed. */
6528 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6538 emitpcode(POC_RRF, popGet(AOP(result),offr));
6540 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6541 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6547 emitpcode(POC_RRF, popGet(AOP(result),offr));
6549 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6550 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6553 emitpcode(POC_RRF, popGet(AOP(result),offr));
6558 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6560 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6561 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6564 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6565 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6566 emitpcode(POC_ANDLW, popGetLit(0x1f));
6567 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6571 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6572 emitpcode(POC_ANDLW, popGetLit(0x0f));
6573 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6577 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6578 emitpcode(POC_ANDLW, popGetLit(0x0f));
6579 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6581 emitpcode(POC_RRF, popGet(AOP(result),offr));
6586 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6587 emitpcode(POC_ANDLW, popGetLit(0x80));
6588 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6589 emitpcode(POC_RLF, popGet(AOP(result),offr));
6590 emitpcode(POC_RLF, popGet(AOP(result),offr));
6595 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6596 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6597 emitpcode(POC_RLF, popGet(AOP(result),offr));
6606 /*-----------------------------------------------------------------*/
6607 /* shiftL1Left2Result - shift left one byte from left to result */
6608 /*-----------------------------------------------------------------*/
6609 static void shiftL1Left2Result (operand *left, int offl,
6610 operand *result, int offr, int shCount)
6616 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6618 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6619 DEBUGpic14_emitcode ("; ***","same = %d",same);
6620 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6622 /* shift left accumulator */
6623 //AccLsh(shCount); // don't comment out just yet...
6624 // aopPut(AOP(result),"a",offr);
6628 /* Shift left 1 bit position */
6629 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6631 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6633 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6634 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6638 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6639 emitpcode(POC_ANDLW,popGetLit(0x7e));
6640 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6641 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6644 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6645 emitpcode(POC_ANDLW,popGetLit(0x3e));
6646 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6647 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6648 emitpcode(POC_RLF, popGet(AOP(result),offr));
6651 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6652 emitpcode(POC_ANDLW, popGetLit(0xf0));
6653 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6656 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6657 emitpcode(POC_ANDLW, popGetLit(0xf0));
6658 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6659 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6662 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6663 emitpcode(POC_ANDLW, popGetLit(0x30));
6664 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6665 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6666 emitpcode(POC_RLF, popGet(AOP(result),offr));
6669 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6670 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6671 emitpcode(POC_RRF, popGet(AOP(result),offr));
6675 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6680 /*-----------------------------------------------------------------*/
6681 /* movLeft2Result - move byte from left to result */
6682 /*-----------------------------------------------------------------*/
6683 static void movLeft2Result (operand *left, int offl,
6684 operand *result, int offr)
6688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6689 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6690 l = aopGet(AOP(left),offl,FALSE,FALSE);
6692 if (*l == '@' && (IS_AOP_PREG(result))) {
6693 pic14_emitcode("mov","a,%s",l);
6694 aopPut(AOP(result),"a",offr);
6696 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6697 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6702 /*-----------------------------------------------------------------*/
6703 /* shiftL2Left2Result - shift left two bytes from left to result */
6704 /*-----------------------------------------------------------------*/
6705 static void shiftL2Left2Result (operand *left, int offl,
6706 operand *result, int offr, int shCount)
6710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6712 if(pic14_sameRegs(AOP(result), AOP(left))) {
6720 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6721 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6722 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6726 emitpcode(POC_RLF, popGet(AOP(result),offr));
6727 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6733 emitpcode(POC_MOVLW, popGetLit(0x0f));
6734 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6737 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6738 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6739 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RLF, popGet(AOP(result),offr));
6742 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6747 emitpcode(POC_RRF, popGet(AOP(result),offr));
6748 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6749 emitpcode(POC_RRF, popGet(AOP(result),offr));
6750 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_ANDLW,popGetLit(0xc0));
6752 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6753 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6754 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6755 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6759 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6760 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6761 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6762 emitpcode(POC_RRF, popGet(AOP(result),offr));
6772 /* note, use a mov/add for the shift since the mov has a
6773 chance of getting optimized out */
6774 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6775 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6776 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6777 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6778 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6782 emitpcode(POC_RLF, popGet(AOP(result),offr));
6783 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6789 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6790 emitpcode(POC_ANDLW, popGetLit(0xF0));
6791 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6792 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6793 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6794 emitpcode(POC_ANDLW, popGetLit(0xF0));
6795 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6796 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_RLF, popGet(AOP(result),offr));
6801 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6805 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6806 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6807 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6808 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6810 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6811 emitpcode(POC_RRF, popGet(AOP(result),offr));
6812 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6813 emitpcode(POC_ANDLW,popGetLit(0xc0));
6814 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6815 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6816 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6817 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6820 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6821 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6822 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6823 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6824 emitpcode(POC_RRF, popGet(AOP(result),offr));
6829 /*-----------------------------------------------------------------*/
6830 /* shiftR2Left2Result - shift right two bytes from left to result */
6831 /*-----------------------------------------------------------------*/
6832 static void shiftR2Left2Result (operand *left, int offl,
6833 operand *result, int offr,
6834 int shCount, int sign)
6839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6840 same = pic14_sameRegs(AOP(result), AOP(left));
6842 if(same && ((offl + MSB16) == offr)){
6844 /* don't crash result[offr] */
6845 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6846 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6849 movLeft2Result(left,offl, result, offr);
6850 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6853 /* a:x >> shCount (x = lsb(result))*/
6856 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6858 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6867 emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6872 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6873 emitpcode(POC_RRF,popGet(AOP(result),offr));
6875 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6876 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6878 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6883 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6886 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6887 emitpcode(POC_RRF,popGet(AOP(result),offr));
6894 emitpcode(POC_MOVLW, popGetLit(0xf0));
6895 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6896 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6898 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6899 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6900 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6901 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6903 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6904 emitpcode(POC_ANDLW, popGetLit(0x0f));
6905 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6907 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6908 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6909 emitpcode(POC_ANDLW, popGetLit(0xf0));
6910 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6911 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6915 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6916 emitpcode(POC_RRF, popGet(AOP(result),offr));
6920 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6921 emitpcode(POC_BTFSC,
6922 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6923 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6931 emitpcode(POC_RLF, popGet(AOP(result),offr));
6932 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6934 emitpcode(POC_RLF, popGet(AOP(result),offr));
6935 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6936 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6937 emitpcode(POC_ANDLW,popGetLit(0x03));
6939 emitpcode(POC_BTFSC,
6940 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6941 emitpcode(POC_IORLW,popGetLit(0xfc));
6943 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6944 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6945 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6946 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6948 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6949 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6950 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6951 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6952 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6953 emitpcode(POC_RLF, popGet(AOP(result),offr));
6954 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6955 emitpcode(POC_ANDLW,popGetLit(0x03));
6957 emitpcode(POC_BTFSC,
6958 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6959 emitpcode(POC_IORLW,popGetLit(0xfc));
6961 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6962 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6969 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6970 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6971 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6972 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6975 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6977 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6982 /*-----------------------------------------------------------------*/
6983 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6984 /*-----------------------------------------------------------------*/
6985 static void shiftLLeftOrResult (operand *left, int offl,
6986 operand *result, int offr, int shCount)
6989 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6990 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6991 /* shift left accumulator */
6992 AccLsh(left,offl,shCount);
6993 /* or with result */
6994 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6995 /* back to result */
6996 aopPut(AOP(result),"a",offr);
6999 /*-----------------------------------------------------------------*/
7000 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7001 /*-----------------------------------------------------------------*/
7002 static void shiftRLeftOrResult (operand *left, int offl,
7003 operand *result, int offr, int shCount)
7006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7007 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
7008 /* shift right accumulator */
7009 AccRsh(left,offl,shCount);
7010 /* or with result */
7011 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
7012 /* back to result */
7013 aopPut(AOP(result),"a",offr);
7016 /*-----------------------------------------------------------------*/
7017 /* genlshOne - left shift a one byte quantity by known count */
7018 /*-----------------------------------------------------------------*/
7019 static void genlshOne (operand *result, operand *left, int shCount)
7022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7023 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7026 /*-----------------------------------------------------------------*/
7027 /* genlshTwo - left shift two bytes by known amount != 0 */
7028 /*-----------------------------------------------------------------*/
7029 static void genlshTwo (operand *result,operand *left, int shCount)
7034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7035 size = pic14_getDataSize(result);
7037 /* if shCount >= 8 */
7043 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7045 movLeft2Result(left, LSB, result, MSB16);
7047 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
7050 /* 1 <= shCount <= 7 */
7053 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7055 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7059 /*-----------------------------------------------------------------*/
7060 /* shiftLLong - shift left one long from left to result */
7061 /* offl = LSB or MSB16 */
7062 /*-----------------------------------------------------------------*/
7063 static void shiftLLong (operand *left, operand *result, int offr )
7066 int size = AOP_SIZE(result);
7069 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7070 if(size >= LSB+offr){
7071 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7073 pic14_emitcode("add","a,acc");
7074 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7075 size >= MSB16+offr && offr != LSB )
7076 pic14_emitcode("xch","a,%s",
7077 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7079 aopPut(AOP(result),"a",LSB+offr);
7082 if(size >= MSB16+offr){
7083 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7084 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7087 pic14_emitcode("rlc","a");
7088 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7089 size >= MSB24+offr && offr != LSB)
7090 pic14_emitcode("xch","a,%s",
7091 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7093 aopPut(AOP(result),"a",MSB16+offr);
7096 if(size >= MSB24+offr){
7097 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7098 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7101 pic14_emitcode("rlc","a");
7102 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7103 size >= MSB32+offr && offr != LSB )
7104 pic14_emitcode("xch","a,%s",
7105 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7107 aopPut(AOP(result),"a",MSB24+offr);
7110 if(size > MSB32+offr){
7111 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7112 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7115 pic14_emitcode("rlc","a");
7116 aopPut(AOP(result),"a",MSB32+offr);
7119 aopPut(AOP(result),zero,LSB);
7122 /*-----------------------------------------------------------------*/
7123 /* genlshFour - shift four byte by a known amount != 0 */
7124 /*-----------------------------------------------------------------*/
7125 static void genlshFour (operand *result, operand *left, int shCount)
7130 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7131 size = AOP_SIZE(result);
7133 /* if shifting more that 3 bytes */
7134 if (shCount >= 24 ) {
7137 /* lowest order of left goes to the highest
7138 order of the destination */
7139 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7141 movLeft2Result(left, LSB, result, MSB32);
7142 aopPut(AOP(result),zero,LSB);
7143 aopPut(AOP(result),zero,MSB16);
7144 aopPut(AOP(result),zero,MSB32);
7148 /* more than two bytes */
7149 else if ( shCount >= 16 ) {
7150 /* lower order two bytes goes to higher order two bytes */
7152 /* if some more remaining */
7154 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7156 movLeft2Result(left, MSB16, result, MSB32);
7157 movLeft2Result(left, LSB, result, MSB24);
7159 aopPut(AOP(result),zero,MSB16);
7160 aopPut(AOP(result),zero,LSB);
7164 /* if more than 1 byte */
7165 else if ( shCount >= 8 ) {
7166 /* lower order three bytes goes to higher order three bytes */
7170 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7172 movLeft2Result(left, LSB, result, MSB16);
7174 else{ /* size = 4 */
7176 movLeft2Result(left, MSB24, result, MSB32);
7177 movLeft2Result(left, MSB16, result, MSB24);
7178 movLeft2Result(left, LSB, result, MSB16);
7179 aopPut(AOP(result),zero,LSB);
7181 else if(shCount == 1)
7182 shiftLLong(left, result, MSB16);
7184 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7185 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7186 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7187 aopPut(AOP(result),zero,LSB);
7192 /* 1 <= shCount <= 7 */
7193 else if(shCount <= 2){
7194 shiftLLong(left, result, LSB);
7196 shiftLLong(result, result, LSB);
7198 /* 3 <= shCount <= 7, optimize */
7200 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7201 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7202 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7206 /*-----------------------------------------------------------------*/
7207 /* genLeftShiftLiteral - left shifting by known count */
7208 /*-----------------------------------------------------------------*/
7209 static void genLeftShiftLiteral (operand *left,
7214 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7218 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7219 freeAsmop(right,NULL,ic,TRUE);
7221 aopOp(left,ic,FALSE);
7222 aopOp(result,ic,FALSE);
7224 size = getSize(operandType(result));
7227 pic14_emitcode("; shift left ","result %d, left %d",size,
7231 /* I suppose that the left size >= result size */
7234 movLeft2Result(left, size, result, size);
7238 else if(shCount >= (size * 8))
7240 aopPut(AOP(result),zero,size);
7244 genlshOne (result,left,shCount);
7249 genlshTwo (result,left,shCount);
7253 genlshFour (result,left,shCount);
7257 freeAsmop(left,NULL,ic,TRUE);
7258 freeAsmop(result,NULL,ic,TRUE);
7261 /*-----------------------------------------------------------------*
7262 * genMultiAsm - repeat assembly instruction for size of register.
7263 * if endian == 1, then the high byte (i.e base address + size of
7264 * register) is used first else the low byte is used first;
7265 *-----------------------------------------------------------------*/
7266 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7285 emitpcode(poc, popGet(AOP(reg),offset));
7290 /*-----------------------------------------------------------------*/
7291 /* genLeftShift - generates code for left shifting */
7292 /*-----------------------------------------------------------------*/
7293 static void genLeftShift (iCode *ic)
7295 operand *left,*right, *result;
7297 unsigned long lit = 0L;
7299 symbol *tlbl , *tlbl1;
7303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7305 right = IC_RIGHT(ic);
7307 result = IC_RESULT(ic);
7309 aopOp(right,ic,FALSE);
7311 /* if the shift count is known then do it
7312 as efficiently as possible */
7313 if (AOP_TYPE(right) == AOP_LIT) {
7314 genLeftShiftLiteral (left,right,result,ic);
7318 /* shift count is unknown then we have to form
7319 a loop get the loop count in B : Note: we take
7320 only the lower order byte since shifting
7321 more that 32 bits make no sense anyway, ( the
7322 largest size of an object can be only 32 bits ) */
7325 aopOp(left,ic,FALSE);
7326 aopOp(result,ic,FALSE);
7328 /* now move the left to the result if they are not the
7330 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7331 AOP_SIZE(result) > 1) {
7333 size = AOP_SIZE(result);
7336 l = aopGet(AOP(left),offset,FALSE,TRUE);
7337 if (*l == '@' && (IS_AOP_PREG(result))) {
7339 pic14_emitcode("mov","a,%s",l);
7340 aopPut(AOP(result),"a",offset);
7342 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7343 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7344 //aopPut(AOP(result),l,offset);
7350 if(AOP_TYPE(left) == AOP_LIT)
7351 lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
7353 size = AOP_SIZE(result);
7355 /* if it is only one byte then */
7357 if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
7358 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7359 emitpcode(POC_ANDLW, popGetLit(0xf0));
7360 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7361 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7362 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7363 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7364 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7365 emitpcode(POC_RLFW, popGet(AOP(result),0));
7366 emitpcode(POC_ANDLW, popGetLit(0xfe));
7367 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7368 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7369 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7372 tlbl = newiTempLabel(NULL);
7373 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7374 if (AOP_TYPE(left) == AOP_LIT)
7375 emitpcode(POC_MOVLW, popGetLit(lit));
7377 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7378 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7381 emitpcode(POC_COMFW, popGet(AOP(right),0));
7382 emitpcode(POC_RRF, popGet(AOP(result),0));
7383 emitpLabel(tlbl->key);
7384 emitpcode(POC_RLF, popGet(AOP(result),0));
7385 emitpcode(POC_ADDLW, popGetLit(1));
7387 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7392 if (pic14_sameRegs(AOP(left),AOP(result))) {
7394 tlbl = newiTempLabel(NULL);
7395 emitpcode(POC_COMFW, popGet(AOP(right),0));
7396 genMultiAsm(POC_RRF, result, size,1);
7397 emitpLabel(tlbl->key);
7398 genMultiAsm(POC_RLF, result, size,0);
7399 emitpcode(POC_ADDLW, popGetLit(1));
7401 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7405 //tlbl = newiTempLabel(NULL);
7407 //tlbl1 = newiTempLabel(NULL);
7409 //reAdjustPreg(AOP(result));
7411 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7412 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7413 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7415 //pic14_emitcode("add","a,acc");
7416 //aopPut(AOP(result),"a",offset++);
7418 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7420 // pic14_emitcode("rlc","a");
7421 // aopPut(AOP(result),"a",offset++);
7423 //reAdjustPreg(AOP(result));
7425 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7426 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7429 tlbl = newiTempLabel(NULL);
7430 tlbl1= newiTempLabel(NULL);
7432 size = AOP_SIZE(result);
7435 pctemp = popGetTempReg(); /* grab a temporary working register. */
7437 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7439 /* offset should be 0, 1 or 3 */
7440 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7442 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7444 emitpcode(POC_MOVWF, pctemp);
7447 emitpLabel(tlbl->key);
7450 emitpcode(POC_RLF, popGet(AOP(result),0));
7452 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7454 emitpcode(POC_DECFSZ, pctemp);
7455 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7456 emitpLabel(tlbl1->key);
7458 popReleaseTempReg(pctemp);
7462 freeAsmop (right,NULL,ic,TRUE);
7463 freeAsmop(left,NULL,ic,TRUE);
7464 freeAsmop(result,NULL,ic,TRUE);
7467 /*-----------------------------------------------------------------*/
7468 /* genrshOne - right shift a one byte quantity by known count */
7469 /*-----------------------------------------------------------------*/
7470 static void genrshOne (operand *result, operand *left,
7471 int shCount, int sign)
7474 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7475 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7478 /*-----------------------------------------------------------------*/
7479 /* genrshTwo - right shift two bytes by known amount != 0 */
7480 /*-----------------------------------------------------------------*/
7481 static void genrshTwo (operand *result,operand *left,
7482 int shCount, int sign)
7485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7486 /* if shCount >= 8 */
7490 shiftR1Left2Result(left, MSB16, result, LSB,
7493 movLeft2Result(left, MSB16, result, LSB);
7495 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7498 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7499 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7503 /* 1 <= shCount <= 7 */
7505 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7508 /*-----------------------------------------------------------------*/
7509 /* shiftRLong - shift right one long from left to result */
7510 /* offl = LSB or MSB16 */
7511 /*-----------------------------------------------------------------*/
7512 static void shiftRLong (operand *left, int offl,
7513 operand *result, int sign)
7516 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7518 pic14_emitcode("clr","c");
7519 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7521 pic14_emitcode("mov","c,acc.7");
7522 pic14_emitcode("rrc","a");
7523 aopPut(AOP(result),"a",MSB32-offl);
7525 /* add sign of "a" */
7526 addSign(result, MSB32, sign);
7528 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7529 pic14_emitcode("rrc","a");
7530 aopPut(AOP(result),"a",MSB24-offl);
7532 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7533 pic14_emitcode("rrc","a");
7534 aopPut(AOP(result),"a",MSB16-offl);
7537 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7538 pic14_emitcode("rrc","a");
7539 aopPut(AOP(result),"a",LSB);
7543 /*-----------------------------------------------------------------*/
7544 /* genrshFour - shift four byte by a known amount != 0 */
7545 /*-----------------------------------------------------------------*/
7546 static void genrshFour (operand *result, operand *left,
7547 int shCount, int sign)
7550 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7551 /* if shifting more that 3 bytes */
7552 if(shCount >= 24 ) {
7555 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7557 movLeft2Result(left, MSB32, result, LSB);
7559 addSign(result, MSB16, sign);
7561 else if(shCount >= 16){
7564 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7566 movLeft2Result(left, MSB24, result, LSB);
7567 movLeft2Result(left, MSB32, result, MSB16);
7569 addSign(result, MSB24, sign);
7571 else if(shCount >= 8){
7574 shiftRLong(left, MSB16, result, sign);
7575 else if(shCount == 0){
7576 movLeft2Result(left, MSB16, result, LSB);
7577 movLeft2Result(left, MSB24, result, MSB16);
7578 movLeft2Result(left, MSB32, result, MSB24);
7579 addSign(result, MSB32, sign);
7582 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7583 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7584 /* the last shift is signed */
7585 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7586 addSign(result, MSB32, sign);
7589 else{ /* 1 <= shCount <= 7 */
7591 shiftRLong(left, LSB, result, sign);
7593 shiftRLong(result, LSB, result, sign);
7596 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7597 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7598 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7603 /*-----------------------------------------------------------------*/
7604 /* genRightShiftLiteral - right shifting by known count */
7605 /*-----------------------------------------------------------------*/
7606 static void genRightShiftLiteral (operand *left,
7612 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7616 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7617 freeAsmop(right,NULL,ic,TRUE);
7619 aopOp(left,ic,FALSE);
7620 aopOp(result,ic,FALSE);
7623 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7627 lsize = pic14_getDataSize(left);
7628 res_size = pic14_getDataSize(result);
7629 /* test the LEFT size !!! */
7631 /* I suppose that the left size >= result size */
7634 movLeft2Result(left, lsize, result, res_size);
7637 else if(shCount >= (lsize * 8)){
7640 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7642 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7643 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7648 emitpcode(POC_MOVLW, popGetLit(0));
7649 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7650 emitpcode(POC_MOVLW, popGetLit(0xff));
7652 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7657 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7664 genrshOne (result,left,shCount,sign);
7668 genrshTwo (result,left,shCount,sign);
7672 genrshFour (result,left,shCount,sign);
7680 freeAsmop(left,NULL,ic,TRUE);
7681 freeAsmop(result,NULL,ic,TRUE);
7684 /*-----------------------------------------------------------------*/
7685 /* genSignedRightShift - right shift of signed number */
7686 /*-----------------------------------------------------------------*/
7687 static void genSignedRightShift (iCode *ic)
7689 operand *right, *left, *result;
7692 symbol *tlbl, *tlbl1 ;
7695 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7697 /* we do it the hard way put the shift count in b
7698 and loop thru preserving the sign */
7700 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7702 right = IC_RIGHT(ic);
7704 result = IC_RESULT(ic);
7706 aopOp(right,ic,FALSE);
7707 aopOp(left,ic,FALSE);
7708 aopOp(result,ic,FALSE);
7711 if ( AOP_TYPE(right) == AOP_LIT) {
7712 genRightShiftLiteral (left,right,result,ic,1);
7715 /* shift count is unknown then we have to form
7716 a loop get the loop count in B : Note: we take
7717 only the lower order byte since shifting
7718 more that 32 bits make no sense anyway, ( the
7719 largest size of an object can be only 32 bits ) */
7721 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7722 //pic14_emitcode("inc","b");
7723 //freeAsmop (right,NULL,ic,TRUE);
7724 //aopOp(left,ic,FALSE);
7725 //aopOp(result,ic,FALSE);
7727 /* now move the left to the result if they are not the
7729 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7730 AOP_SIZE(result) > 1) {
7732 size = AOP_SIZE(result);
7736 l = aopGet(AOP(left),offset,FALSE,TRUE);
7737 if (*l == '@' && IS_AOP_PREG(result)) {
7738 pic14_emitcode("mov","a,%s",l);
7739 aopPut(AOP(result),"a",offset);
7741 aopPut(AOP(result),l,offset);
7743 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7744 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7750 /* mov the highest order bit to OVR */
7751 tlbl = newiTempLabel(NULL);
7752 tlbl1= newiTempLabel(NULL);
7754 size = AOP_SIZE(result);
7757 pctemp = popGetTempReg(); /* grab a temporary working register. */
7759 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7761 /* offset should be 0, 1 or 3 */
7762 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7764 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7766 emitpcode(POC_MOVWF, pctemp);
7769 emitpLabel(tlbl->key);
7771 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7772 emitpcode(POC_RRF, popGet(AOP(result),offset));
7775 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7778 emitpcode(POC_DECFSZ, pctemp);
7779 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7780 emitpLabel(tlbl1->key);
7782 popReleaseTempReg(pctemp);
7784 size = AOP_SIZE(result);
7786 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7787 pic14_emitcode("rlc","a");
7788 pic14_emitcode("mov","ov,c");
7789 /* if it is only one byte then */
7791 l = aopGet(AOP(left),0,FALSE,FALSE);
7793 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7794 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7795 pic14_emitcode("mov","c,ov");
7796 pic14_emitcode("rrc","a");
7797 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7798 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7799 aopPut(AOP(result),"a",0);
7803 reAdjustPreg(AOP(result));
7804 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7805 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7806 pic14_emitcode("mov","c,ov");
7808 l = aopGet(AOP(result),offset,FALSE,FALSE);
7810 pic14_emitcode("rrc","a");
7811 aopPut(AOP(result),"a",offset--);
7813 reAdjustPreg(AOP(result));
7814 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7815 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7820 freeAsmop(left,NULL,ic,TRUE);
7821 freeAsmop(result,NULL,ic,TRUE);
7822 freeAsmop(right,NULL,ic,TRUE);
7825 /*-----------------------------------------------------------------*/
7826 /* genRightShift - generate code for right shifting */
7827 /*-----------------------------------------------------------------*/
7828 static void genRightShift (iCode *ic)
7830 operand *right, *left, *result;
7834 symbol *tlbl, *tlbl1 ;
7837 /* if signed then we do it the hard way preserve the
7838 sign bit moving it inwards */
7839 retype = getSpec(operandType(IC_RESULT(ic)));
7840 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7842 if (!SPEC_USIGN(retype)) {
7843 genSignedRightShift (ic);
7847 /* signed & unsigned types are treated the same : i.e. the
7848 signed is NOT propagated inwards : quoting from the
7849 ANSI - standard : "for E1 >> E2, is equivalent to division
7850 by 2**E2 if unsigned or if it has a non-negative value,
7851 otherwise the result is implementation defined ", MY definition
7852 is that the sign does not get propagated */
7854 right = IC_RIGHT(ic);
7856 result = IC_RESULT(ic);
7858 aopOp(right,ic,FALSE);
7860 /* if the shift count is known then do it
7861 as efficiently as possible */
7862 if (AOP_TYPE(right) == AOP_LIT) {
7863 genRightShiftLiteral (left,right,result,ic, 0);
7867 /* shift count is unknown then we have to form
7868 a loop get the loop count in B : Note: we take
7869 only the lower order byte since shifting
7870 more that 32 bits make no sense anyway, ( the
7871 largest size of an object can be only 32 bits ) */
7873 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7874 pic14_emitcode("inc","b");
7875 aopOp(left,ic,FALSE);
7876 aopOp(result,ic,FALSE);
7878 /* now move the left to the result if they are not the
7880 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7881 AOP_SIZE(result) > 1) {
7883 size = AOP_SIZE(result);
7886 l = aopGet(AOP(left),offset,FALSE,TRUE);
7887 if (*l == '@' && IS_AOP_PREG(result)) {
7889 pic14_emitcode("mov","a,%s",l);
7890 aopPut(AOP(result),"a",offset);
7892 aopPut(AOP(result),l,offset);
7897 tlbl = newiTempLabel(NULL);
7898 tlbl1= newiTempLabel(NULL);
7899 size = AOP_SIZE(result);
7902 /* if it is only one byte then */
7905 tlbl = newiTempLabel(NULL);
7906 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7907 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7908 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7911 emitpcode(POC_COMFW, popGet(AOP(right),0));
7912 emitpcode(POC_RLF, popGet(AOP(result),0));
7913 emitpLabel(tlbl->key);
7914 emitpcode(POC_RRF, popGet(AOP(result),0));
7915 emitpcode(POC_ADDLW, popGetLit(1));
7917 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7922 reAdjustPreg(AOP(result));
7923 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7924 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7927 l = aopGet(AOP(result),offset,FALSE,FALSE);
7929 pic14_emitcode("rrc","a");
7930 aopPut(AOP(result),"a",offset--);
7932 reAdjustPreg(AOP(result));
7934 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7935 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7938 freeAsmop(left,NULL,ic,TRUE);
7939 freeAsmop (right,NULL,ic,TRUE);
7940 freeAsmop(result,NULL,ic,TRUE);
7943 /*-----------------------------------------------------------------*/
7944 /* genUnpackBits - generates code for unpacking bits */
7945 /*-----------------------------------------------------------------*/
7946 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
7949 int offset = 0; /* result byte offset */
7950 int rsize; /* result size */
7951 int rlen = 0; /* remaining bitfield length */
7952 sym_link *etype; /* bitfield type information */
7953 int blen; /* bitfield length */
7954 int bstr; /* bitfield starting bit within byte */
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7958 etype = getSpec(operandType(result));
7959 rsize = getSize (operandType (result));
7960 blen = SPEC_BLEN (etype);
7961 bstr = SPEC_BSTR (etype);
7963 /* single bit field case */
7965 if (ifx) { /* that is for an if statement */
7968 resolveIfx(&rIfx,ifx);
7969 if (ptype == -1) /* direct */
7970 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7972 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7973 emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
7974 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
7978 if (ptype == -1) /* direct */
7979 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7981 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7982 emitpcode(POC_BTFSC,pcop);
7983 emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7985 if (ptype == -1) /* direct */
7986 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7988 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7989 emitpcode(POC_BTFSS,pcop);
7990 emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7995 /* read the first byte */
8000 // pic14_emitcode("mov","a,@%s",rname);
8001 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8005 pic14_emitcode("movx","a,@%s",rname);
8009 pic14_emitcode("movx","a,@dptr");
8013 pic14_emitcode("clr","a");
8014 pic14_emitcode("movc","a","@a+dptr");
8018 pic14_emitcode("lcall","__gptrget");
8022 /* if we have bitdisplacement then it fits */
8023 /* into this byte completely or if length is */
8024 /* less than a byte */
8025 if ((shCnt = SPEC_BSTR(etype)) || blen <= 8) {
8027 /* shift right acc */
8028 AccRsh(left,0,shCnt);
8030 pic14_emitcode("anl","a,#0x%02x",
8031 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8032 aopPut(AOP(result),"a",offset);
8036 /* bit field did not fit in a byte */
8037 rlen = SPEC_BLEN(etype) - 8;
8038 aopPut(AOP(result),"a",offset++);
8045 pic14_emitcode("inc","%s",rname);
8046 pic14_emitcode("mov","a,@%s",rname);
8050 pic14_emitcode("inc","%s",rname);
8051 pic14_emitcode("movx","a,@%s",rname);
8055 pic14_emitcode("inc","dptr");
8056 pic14_emitcode("movx","a,@dptr");
8060 pic14_emitcode("clr","a");
8061 pic14_emitcode("inc","dptr");
8062 pic14_emitcode("movc","a","@a+dptr");
8066 pic14_emitcode("inc","dptr");
8067 pic14_emitcode("lcall","__gptrget");
8072 /* if we are done */
8076 aopPut(AOP(result),"a",offset++);
8081 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8082 aopPut(AOP(result),"a",offset);
8089 /*-----------------------------------------------------------------*/
8090 /* genDataPointerGet - generates code when ptr offset is known */
8091 /*-----------------------------------------------------------------*/
8092 static void genDataPointerGet (operand *left,
8096 int size , offset = 0;
8099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8102 /* optimization - most of the time, left and result are the same
8103 * address, but different types. for the pic code, we could omit
8106 aopOp(result,ic,TRUE);
8108 if (pic14_sameRegs (AOP(left), AOP(result)))
8111 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8113 //emitpcode(POC_MOVFW, popGet(AOP(left),0));
8115 size = AOP_SIZE(result);
8116 if (size > AOP_SIZE(left)) size = AOP_SIZE(left);
8119 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
8120 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8124 freeAsmop(left,NULL,ic,TRUE);
8125 freeAsmop(result,NULL,ic,TRUE);
8128 /*-----------------------------------------------------------------*/
8129 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
8130 /*-----------------------------------------------------------------*/
8131 static void genNearPointerGet (operand *left,
8136 sym_link *ltype = operandType(left);
8137 sym_link *rtype = operandType(result);
8138 sym_link *retype= getSpec(rtype); /* bitfield type information */
8142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8145 aopOp(left,ic,FALSE);
8147 /* if left is rematerialisable and
8148 result is not bit variable type and
8149 the left is pointer to data space i.e
8150 lower 128 bytes of space */
8151 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8152 !IS_BITVAR(retype) &&
8153 DCL_TYPE(ltype) == POINTER) {
8154 genDataPointerGet (left,result,ic);
8158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8159 aopOp (result,ic,FALSE);
8161 /* Check if can access directly instead of via a pointer */
8162 if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
8166 /* If the pointer value is not in a the FSR then need to put it in */
8167 if (!AOP_INPREG(AOP(left)) && !direct) {
8168 /* otherwise get a free pointer register */
8169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8170 if (PCOP(AOP(result))->type == PO_LITERAL)
8171 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8173 emitpcode(POC_MOVFW, popGet(AOP(left),0));
8174 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8179 /* if bitfield then unpack the bits */
8180 if (IS_BITFIELD(retype))
8181 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8183 /* we have can just get the values */
8184 int size = AOP_SIZE(result);
8187 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8191 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8193 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8194 if (AOP_TYPE(result) == AOP_LIT) {
8195 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8197 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8199 if (size && !direct)
8200 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8205 /* now some housekeeping stuff */
8207 /* we had to allocate for this iCode */
8208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8209 freeAsmop(NULL,aop,ic,TRUE);
8211 /* we did not allocate which means left
8212 already in a pointer register, then
8213 if size > 0 && this could be used again
8214 we have to point it back to where it
8216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8217 if (AOP_SIZE(result) > 1 &&
8218 !OP_SYMBOL(left)->remat &&
8219 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8221 int size = AOP_SIZE(result) - 1;
8223 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8228 freeAsmop(left,NULL,ic,TRUE);
8229 freeAsmop(result,NULL,ic,TRUE);
8233 /*-----------------------------------------------------------------*/
8234 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8235 /*-----------------------------------------------------------------*/
8236 static void genPagedPointerGet (operand *left,
8243 sym_link *rtype, *retype;
8246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8248 rtype = operandType(result);
8249 retype= getSpec(rtype);
8251 aopOp(left,ic,FALSE);
8253 /* if the value is already in a pointer register
8254 then don't need anything more */
8255 if (!AOP_INPREG(AOP(left))) {
8256 /* otherwise get a free pointer register */
8258 preg = getFreePtr(ic,&aop,FALSE);
8259 pic14_emitcode("mov","%s,%s",
8261 aopGet(AOP(left),0,FALSE,TRUE));
8262 rname = preg->name ;
8264 rname = aopGet(AOP(left),0,FALSE,FALSE);
8266 freeAsmop(left,NULL,ic,TRUE);
8267 aopOp (result,ic,FALSE);
8269 /* if bitfield then unpack the bits */
8270 if (IS_BITFIELD(retype))
8271 genUnpackBits (result,left,rname,PPOINTER,0);
8273 /* we have can just get the values */
8274 int size = AOP_SIZE(result);
8279 pic14_emitcode("movx","a,@%s",rname);
8280 aopPut(AOP(result),"a",offset);
8285 pic14_emitcode("inc","%s",rname);
8289 /* now some housekeeping stuff */
8291 /* we had to allocate for this iCode */
8292 freeAsmop(NULL,aop,ic,TRUE);
8294 /* we did not allocate which means left
8295 already in a pointer register, then
8296 if size > 0 && this could be used again
8297 we have to point it back to where it
8299 if (AOP_SIZE(result) > 1 &&
8300 !OP_SYMBOL(left)->remat &&
8301 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8303 int size = AOP_SIZE(result) - 1;
8305 pic14_emitcode("dec","%s",rname);
8310 freeAsmop(result,NULL,ic,TRUE);
8315 /*-----------------------------------------------------------------*/
8316 /* genFarPointerGet - gget value from far space */
8317 /*-----------------------------------------------------------------*/
8318 static void genFarPointerGet (operand *left,
8319 operand *result, iCode *ic)
8322 sym_link *retype = getSpec(operandType(result));
8325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8327 aopOp(left,ic,FALSE);
8329 /* if the operand is already in dptr
8330 then we do nothing else we move the value to dptr */
8331 if (AOP_TYPE(left) != AOP_STR) {
8332 /* if this is remateriazable */
8333 if (AOP_TYPE(left) == AOP_IMMD)
8334 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8335 else { /* we need to get it byte by byte */
8336 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8337 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8338 if (options.model == MODEL_FLAT24)
8340 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8344 /* so dptr know contains the address */
8345 freeAsmop(left,NULL,ic,TRUE);
8346 aopOp(result,ic,FALSE);
8348 /* if bit then unpack */
8349 if (IS_BITFIELD(retype))
8350 genUnpackBits(result,left,"dptr",FPOINTER,0);
8352 size = AOP_SIZE(result);
8356 pic14_emitcode("movx","a,@dptr");
8357 aopPut(AOP(result),"a",offset++);
8359 pic14_emitcode("inc","dptr");
8363 freeAsmop(result,NULL,ic,TRUE);
8366 /*-----------------------------------------------------------------*/
8367 /* genCodePointerGet - get value from code space */
8368 /*-----------------------------------------------------------------*/
8369 static void genCodePointerGet (operand *left,
8370 operand *result, iCode *ic)
8373 sym_link *retype = getSpec(operandType(result));
8375 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8377 aopOp(left,ic,FALSE);
8379 /* if the operand is already in dptr
8380 then we do nothing else we move the value to dptr */
8381 if (AOP_TYPE(left) != AOP_STR) {
8382 /* if this is remateriazable */
8383 if (AOP_TYPE(left) == AOP_IMMD)
8384 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8385 else { /* we need to get it byte by byte */
8386 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8387 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8388 if (options.model == MODEL_FLAT24)
8390 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8394 /* so dptr know contains the address */
8395 freeAsmop(left,NULL,ic,TRUE);
8396 aopOp(result,ic,FALSE);
8398 /* if bit then unpack */
8399 if (IS_BITFIELD(retype))
8400 genUnpackBits(result,left,"dptr",CPOINTER,0);
8402 size = AOP_SIZE(result);
8406 pic14_emitcode("clr","a");
8407 pic14_emitcode("movc","a,@a+dptr");
8408 aopPut(AOP(result),"a",offset++);
8410 pic14_emitcode("inc","dptr");
8414 freeAsmop(result,NULL,ic,TRUE);
8417 /*-----------------------------------------------------------------*/
8418 /* genGenPointerGet - gget value from generic pointer space */
8419 /*-----------------------------------------------------------------*/
8420 static void genGenPointerGet (operand *left,
8421 operand *result, iCode *ic)
8424 sym_link *retype = getSpec(operandType(result));
8427 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8428 aopOp(left,ic,FALSE);
8429 aopOp(result,ic,FALSE);
8432 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8434 /* if the operand is already in dptr
8435 then we do nothing else we move the value to dptr */
8436 // if (AOP_TYPE(left) != AOP_STR) {
8437 /* if this is remateriazable */
8438 if (AOP_TYPE(left) == AOP_IMMD) {
8439 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8440 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8442 else { /* we need to get it byte by byte */
8444 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8445 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8447 size = AOP_SIZE(result);
8451 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8452 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8454 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8459 /* so dptr know contains the address */
8461 /* if bit then unpack */
8462 //if (IS_BITFIELD(retype))
8463 // genUnpackBits(result,"dptr",GPOINTER);
8466 freeAsmop(left,NULL,ic,TRUE);
8467 freeAsmop(result,NULL,ic,TRUE);
8471 /*-----------------------------------------------------------------*/
8472 /* genConstPointerGet - get value from const generic pointer space */
8473 /*-----------------------------------------------------------------*/
8474 static void genConstPointerGet (operand *left,
8475 operand *result, iCode *ic)
8477 //sym_link *retype = getSpec(operandType(result));
8478 symbol *albl = newiTempLabel(NULL);
8479 symbol *blbl = newiTempLabel(NULL);
8484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8485 aopOp(left,ic,FALSE);
8486 aopOp(result,ic,FALSE);
8489 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8491 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8493 emitpcode(POC_CALL,popGetLabel(albl->key));
8494 pcop = popGetLabel(blbl->key);
8495 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8496 emitpcode(POC_GOTO,pcop);
8497 emitpLabel(albl->key);
8499 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8501 emitpcode(poc,popGet(AOP(left),1));
8502 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8503 emitpcode(poc,popGet(AOP(left),0));
8504 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8506 emitpLabel(blbl->key);
8508 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8511 freeAsmop(left,NULL,ic,TRUE);
8512 freeAsmop(result,NULL,ic,TRUE);
8515 /*-----------------------------------------------------------------*/
8516 /* genPointerGet - generate code for pointer get */
8517 /*-----------------------------------------------------------------*/
8518 static void genPointerGet (iCode *ic)
8520 operand *left, *result ;
8521 sym_link *type, *etype;
8525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8528 result = IC_RESULT(ic) ;
8530 /* depending on the type of pointer we need to
8531 move it to the correct pointer register */
8532 type = operandType(left);
8533 etype = getSpec(type);
8535 if (IS_PTR_CONST(type))
8536 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8538 /* if left is of type of pointer then it is simple */
8539 if (IS_PTR(type) && !IS_FUNC(type->next))
8540 p_type = DCL_TYPE(type);
8542 /* we have to go by the storage class */
8543 p_type = PTR_TYPE(SPEC_OCLS(etype));
8545 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8547 if (SPEC_OCLS(etype)->codesp ) {
8548 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8549 //p_type = CPOINTER ;
8552 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8553 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8554 /*p_type = FPOINTER ;*/
8556 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8557 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8558 /* p_type = PPOINTER; */
8560 if (SPEC_OCLS(etype) == idata )
8561 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8562 /* p_type = IPOINTER; */
8564 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8565 /* p_type = POINTER ; */
8568 /* now that we have the pointer type we assign
8569 the pointer values */
8574 genNearPointerGet (left,result,ic);
8578 genPagedPointerGet(left,result,ic);
8582 genFarPointerGet (left,result,ic);
8586 genConstPointerGet (left,result,ic);
8587 //pic14_emitcodePointerGet (left,result,ic);
8591 if (IS_PTR_CONST(type))
8592 genConstPointerGet (left,result,ic);
8594 genGenPointerGet (left,result,ic);
8600 /*-----------------------------------------------------------------*/
8601 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into */
8602 /* A through a pointer register (R0, R1, or DPTR). The original */
8603 /* value of A can be preserved in B. */
8604 /* PIC has to use INDF register. */
8605 /*-----------------------------------------------------------------*/
8607 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8615 pic14_emitcode ("mov", "b,a");
8616 // pic14_emitcode ("mov", "a,@%s", rname);
8617 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8622 pic14_emitcode ("mov", "b,a");
8623 pic14_emitcode ("movx", "a,@%s", rname);
8628 pic14_emitcode ("mov", "b,a");
8629 pic14_emitcode ("movx", "a,@dptr");
8634 pic14_emitcode ("mov", "b,a");
8635 pic14_emitcode ("clr", "a");
8636 pic14_emitcode ("movc", "a,@a+dptr");
8642 pic14_emitcode ("push", "b");
8643 pic14_emitcode ("push", "acc");
8645 pic14_emitcode ("lcall", "__gptrget");
8647 pic14_emitcode ("pop", "b");
8652 /*-----------------------------------------------------------------*/
8653 /* emitPtrByteSet - emits code to set a byte from src through a */
8654 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR). */
8655 /*-----------------------------------------------------------------*/
8657 emitPtrByteSet (char *rname, int p_type, char *src)
8667 pic14_emitcode ("mov", "@%s,a", rname);
8670 // pic14_emitcode ("mov", "@%s,%s", rname, src);
8671 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8676 pic14_emitcode ("movx", "@%s,a", rname);
8681 pic14_emitcode ("movx", "@dptr,a");
8686 pic14_emitcode ("lcall", "__gptrput");
8691 /*-----------------------------------------------------------------*/
8692 /* genPackBits - generates code for packed bit storage */
8693 /*-----------------------------------------------------------------*/
8694 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8696 int offset = 0; /* source byte offset */
8697 int rlen = 0; /* remaining bitfield length */
8698 int blen; /* bitfield length */
8699 int bstr; /* bitfield starting bit within byte */
8700 int litval; /* source literal value (if AOP_LIT) */
8701 unsigned char mask; /* bitmask within current byte */
8704 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8706 blen = SPEC_BLEN (etype);
8707 bstr = SPEC_BSTR (etype);
8709 /* If the bitfield length is less than a byte */
8712 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8713 (unsigned char) (0xFF >> (8 - bstr)));
8715 if (AOP_TYPE (right) == AOP_LIT)
8717 /* Case with a bitfield length <8 and literal source
8719 int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8723 if (AOP(result)->type == AOP_PCODE)
8724 pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
8726 pcop = popGet(AOP(result),0);
8727 emitpcode(lit?POC_BSF:POC_BCF,pcop);
8729 emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8733 litval = lit << bstr;
8734 litval &= (~mask) & 0xff;
8736 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8738 emitPtrByteGet (rname, p_type, FALSE);
8739 if ((mask|litval)!=0xff)
8740 emitpcode(POC_ANDLW,popGetLit(mask));
8742 emitpcode(POC_IORLW,popGetLit(litval));
8749 /* 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 */
8750 emitpcode(POC_RLF,popGet(AOP(right),0));
8752 emitpcode(POC_BCF,popGet(AOP(result),0));
8754 emitpcode(POC_BSF,popGet(AOP(result),0));
8755 } else if (p_type!=GPOINTER) {
8756 /* Case with a bitfield length == 1 and no generic pointer
8758 if (AOP_TYPE (right) == AOP_CRY)
8759 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
8762 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8763 pic14_emitcode ("rrc","a");
8765 emitPtrByteGet (rname, p_type, FALSE);
8766 pic14_emitcode ("mov","acc.%d,c",bstr);
8772 /* Case with a bitfield length < 8 and arbitrary source
8774 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8775 /* shift and mask source value */
8776 AccLsh (right,0,bstr);
8777 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8778 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
8780 //pushedB = pushB ();
8782 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8784 emitPtrByteGet (rname, p_type, TRUE);
8786 pic14_emitcode ("anl", "a,#0x%02x", mask);
8787 pic14_emitcode ("orl", "a,b");
8788 emitpcode(POC_ANDLW,popGetLit(mask));
8789 emitpcode(POC_IORFW,popGet(AOP(right),0));
8790 if (p_type == GPOINTER)
8791 pic14_emitcode ("pop", "b");
8798 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8800 emitPtrByteSet (rname, p_type, "a");
8804 /* Bit length is greater than 7 bits. In this case, copy */
8805 /* all except the partial byte at the end */
8806 for (rlen=blen;rlen>=8;rlen-=8)
8808 emitPtrByteSet (rname, p_type,
8809 aopGet (AOP (right), offset++, FALSE, TRUE) );
8811 pic14_emitcode ("inc", "%s", rname);
8814 /* If there was a partial byte at the end */
8817 mask = (((unsigned char) -1 << rlen) & 0xff);
8819 if (AOP_TYPE (right) == AOP_LIT)
8821 /* Case with partial byte and literal source
8823 litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8824 litval >>= (blen-rlen);
8825 litval &= (~mask) & 0xff;
8826 emitPtrByteGet (rname, p_type, FALSE);
8827 if ((mask|litval)!=0xff)
8828 pic14_emitcode ("anl","a,#0x%02x", mask);
8830 pic14_emitcode ("orl","a,#0x%02x", litval);
8835 /* Case with partial byte and arbitrary source
8837 MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
8838 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8840 //pushedB = pushB ();
8841 /* transfer A to B and get next byte */
8842 emitPtrByteGet (rname, p_type, TRUE);
8844 pic14_emitcode ("anl", "a,#0x%02x", mask);
8845 pic14_emitcode ("orl", "a,b");
8846 if (p_type == GPOINTER)
8847 pic14_emitcode ("pop", "b");
8851 emitPtrByteSet (rname, p_type, "a");
8856 /*-----------------------------------------------------------------*/
8857 /* SetIrp - Set IRP bit */
8858 /*-----------------------------------------------------------------*/
8859 void SetIrp(operand *result) {
8861 if (AOP_TYPE(result) == AOP_LIT) {
8862 unsigned lit = (unsigned)operandLitValue(result);
8863 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8865 if (PCOP(AOP(result))->type == PO_LITERAL) {
8866 int addrs = PCOL(AOP(result))->lit;
8867 emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8869 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
8870 if(AOP_SIZE(result) > 1) {
8871 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8872 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8878 /*-----------------------------------------------------------------*/
8879 /* genDataPointerSet - remat pointer to data space */
8880 /*-----------------------------------------------------------------*/
8881 static void genDataPointerSet(operand *right,
8885 int size, offset = 0 ;
8886 char *l, buffer[256];
8889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8890 aopOp(right,ic,FALSE);
8892 l = aopGet(AOP(result),0,FALSE,TRUE);
8893 size = AOP_SIZE(right);
8895 if ( AOP_TYPE(result) == AOP_PCODE) {
8896 fprintf(stderr,"genDataPointerSet %s, %d\n",
8897 AOP(result)->aopu.pcop->name,
8898 PCOI(AOP(result)->aopu.pcop)->offset);
8902 // tsd, was l+1 - the underline `_' prefix was being stripped
8904 emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset);
8906 sprintf(buffer,"(%s + %d)",l,offset);
8907 fprintf(stderr,"%s:%i: oops %s (%i, AOP_LIT=%i)\n",__FILE__,__LINE__,buffer, AOP_TYPE(right), AOP_LIT);
8909 sprintf(buffer,"%s",l);
8911 if (AOP_TYPE(right) == AOP_LIT) {
8912 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8913 lit = lit >> (8*offset);
8915 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8916 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8918 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8921 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8922 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8928 freeAsmop(right,NULL,ic,TRUE);
8929 freeAsmop(result,NULL,ic,TRUE);
8932 /*-----------------------------------------------------------------*/
8933 /* genNearPointerSet - pic14_emitcode for near pointer put */
8934 /*-----------------------------------------------------------------*/
8935 static void genNearPointerSet (operand *right,
8940 sym_link *ptype = operandType(result);
8941 sym_link *retype = getSpec(operandType(right));
8942 sym_link *letype = getSpec(ptype);
8947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8948 aopOp(result,ic,FALSE);
8951 /* if the result is rematerializable &
8952 in data space & not a bit variable */
8953 //if (AOP_TYPE(result) == AOP_IMMD &&
8954 if (AOP_TYPE(result) == AOP_PCODE &&
8955 DCL_TYPE(ptype) == POINTER &&
8956 !IS_BITVAR (retype) &&
8957 !IS_BITVAR (letype)) {
8958 genDataPointerSet (right,result,ic);
8959 freeAsmop(result,NULL,ic,TRUE);
8963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8964 aopOp(right,ic,FALSE);
8965 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8967 /* Check if can access directly instead of via a pointer */
8968 if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
8972 /* If the pointer value is not in a the FSR then need to put it in */
8973 if (!AOP_INPREG(AOP(result)) && !direct) {
8974 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8975 if (PCOP(AOP(result))->type == PO_LITERAL)
8976 emitpcode(POC_MOVLW, popGet(AOP(result),0));
8978 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8979 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8982 /* Must set/reset IRP bit for use with FSR. */
8983 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
8987 /* if bitfield then unpack the bits */
8988 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
8989 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
8991 /* we have can just get the values */
8992 int size = AOP_SIZE(right);
8995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8997 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
8999 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9001 if (AOP_TYPE(right) == AOP_LIT) {
9002 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9004 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9007 emitpcode(POC_MOVWF,popGet(AOP(result),0));
9009 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9011 if (size && !direct)
9012 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9018 /* now some housekeeping stuff */
9020 /* we had to allocate for this iCode */
9021 freeAsmop(NULL,aop,ic,TRUE);
9023 /* we did not allocate which means left
9024 already in a pointer register, then
9025 if size > 0 && this could be used again
9026 we have to point it back to where it
9028 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9029 if (AOP_SIZE(right) > 1 &&
9030 !OP_SYMBOL(result)->remat &&
9031 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9033 int size = AOP_SIZE(right) - 1;
9035 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
9039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9042 freeAsmop(right,NULL,ic,TRUE);
9043 freeAsmop(result,NULL,ic,TRUE);
9046 /*-----------------------------------------------------------------*/
9047 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
9048 /*-----------------------------------------------------------------*/
9049 static void genPagedPointerSet (operand *right,
9059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9061 retype= getSpec(operandType(right));
9063 aopOp(result,ic,FALSE);
9065 /* if the value is already in a pointer register
9066 then don't need anything more */
9067 if (!AOP_INPREG(AOP(result))) {
9068 /* otherwise get a free pointer register */
9070 preg = getFreePtr(ic,&aop,FALSE);
9071 pic14_emitcode("mov","%s,%s",
9073 aopGet(AOP(result),0,FALSE,TRUE));
9074 rname = preg->name ;
9076 rname = aopGet(AOP(result),0,FALSE,FALSE);
9078 freeAsmop(result,NULL,ic,TRUE);
9079 aopOp (right,ic,FALSE);
9081 /* if bitfield then unpack the bits */
9082 if (IS_BITFIELD(retype))
9083 genPackBits (retype,result,right,rname,PPOINTER);
9085 /* we have can just get the values */
9086 int size = AOP_SIZE(right);
9090 l = aopGet(AOP(right),offset,FALSE,TRUE);
9093 pic14_emitcode("movx","@%s,a",rname);
9096 pic14_emitcode("inc","%s",rname);
9102 /* now some housekeeping stuff */
9104 /* we had to allocate for this iCode */
9105 freeAsmop(NULL,aop,ic,TRUE);
9107 /* we did not allocate which means left
9108 already in a pointer register, then
9109 if size > 0 && this could be used again
9110 we have to point it back to where it
9112 if (AOP_SIZE(right) > 1 &&
9113 !OP_SYMBOL(result)->remat &&
9114 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9116 int size = AOP_SIZE(right) - 1;
9118 pic14_emitcode("dec","%s",rname);
9123 freeAsmop(right,NULL,ic,TRUE);
9128 /*-----------------------------------------------------------------*/
9129 /* genFarPointerSet - set value from far space */
9130 /*-----------------------------------------------------------------*/
9131 static void genFarPointerSet (operand *right,
9132 operand *result, iCode *ic)
9135 sym_link *retype = getSpec(operandType(right));
9138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9139 aopOp(result,ic,FALSE);
9141 /* if the operand is already in dptr
9142 then we do nothing else we move the value to dptr */
9143 if (AOP_TYPE(result) != AOP_STR) {
9144 /* if this is remateriazable */
9145 if (AOP_TYPE(result) == AOP_IMMD)
9146 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9147 else { /* we need to get it byte by byte */
9148 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
9149 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
9150 if (options.model == MODEL_FLAT24)
9152 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
9156 /* so dptr know contains the address */
9157 freeAsmop(result,NULL,ic,TRUE);
9158 aopOp(right,ic,FALSE);
9160 /* if bit then unpack */
9161 if (IS_BITFIELD(retype))
9162 genPackBits(retype,result,right,"dptr",FPOINTER);
9164 size = AOP_SIZE(right);
9168 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
9170 pic14_emitcode("movx","@dptr,a");
9172 pic14_emitcode("inc","dptr");
9176 freeAsmop(right,NULL,ic,TRUE);
9179 /*-----------------------------------------------------------------*/
9180 /* genGenPointerSet - set value from generic pointer space */
9181 /*-----------------------------------------------------------------*/
9182 static void genGenPointerSet (operand *right,
9183 operand *result, iCode *ic)
9185 sym_link *ptype = operandType(result);
9186 sym_link *retype = getSpec(operandType(right));
9187 sym_link *letype = getSpec (ptype);
9190 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9192 aopOp(result,ic,FALSE);
9193 aopOp(right,ic,FALSE);
9195 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9197 /* if the operand is already in dptr
9198 then we do nothing else we move the value to dptr */
9199 if (AOP_TYPE(result) != AOP_STR) {
9200 /* if this is remateriazable */
9201 if (AOP_TYPE(result) == AOP_IMMD) {
9202 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9203 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9206 emitpcode(POC_MOVFW,popGet(AOP(result),0));
9207 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9209 /* Must set/reset IRP bit for use with FSR. */
9210 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9215 /* if bitfield then unpack the bits */
9216 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9217 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9219 /* we have can just get the values */
9220 int size = AOP_SIZE(right);
9223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9225 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9227 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9229 if (AOP_TYPE(right) == AOP_LIT) {
9230 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9232 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9234 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9237 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9242 freeAsmop(right,NULL,ic,TRUE);
9243 freeAsmop(result,NULL,ic,TRUE);
9246 /*-----------------------------------------------------------------*/
9247 /* genPointerSet - stores the value into a pointer location */
9248 /*-----------------------------------------------------------------*/
9249 static void genPointerSet (iCode *ic)
9251 operand *right, *result ;
9252 sym_link *type, *etype;
9256 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9258 right = IC_RIGHT(ic);
9259 result = IC_RESULT(ic) ;
9261 /* depending on the type of pointer we need to
9262 move it to the correct pointer register */
9263 type = operandType(result);
9264 etype = getSpec(type);
9265 /* if left is of type of pointer then it is simple */
9266 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9267 p_type = DCL_TYPE(type);
9270 /* we have to go by the storage class */
9271 p_type = PTR_TYPE(SPEC_OCLS(etype));
9273 /* if (SPEC_OCLS(etype)->codesp ) { */
9274 /* p_type = CPOINTER ; */
9277 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9278 /* p_type = FPOINTER ; */
9280 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9281 /* p_type = PPOINTER ; */
9283 /* if (SPEC_OCLS(etype) == idata ) */
9284 /* p_type = IPOINTER ; */
9286 /* p_type = POINTER ; */
9289 /* now that we have the pointer type we assign
9290 the pointer values */
9295 genNearPointerSet (right,result,ic);
9299 genPagedPointerSet (right,result,ic);
9303 genFarPointerSet (right,result,ic);
9307 genGenPointerSet (right,result,ic);
9311 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9312 "genPointerSet: illegal pointer type");
9316 /*-----------------------------------------------------------------*/
9317 /* genIfx - generate code for Ifx statement */
9318 /*-----------------------------------------------------------------*/
9319 static void genIfx (iCode *ic, iCode *popIc)
9321 operand *cond = IC_COND(ic);
9325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9327 aopOp(cond,ic,FALSE);
9329 /* get the value into acc */
9330 if (AOP_TYPE(cond) != AOP_CRY)
9331 pic14_toBoolean(cond);
9334 /* the result is now in the accumulator */
9335 freeAsmop(cond,NULL,ic,TRUE);
9337 /* if there was something to be popped then do it */
9341 /* if the condition is a bit variable */
9342 if (isbit && IS_ITEMP(cond) &&
9344 genIfxJump(ic,SPIL_LOC(cond)->rname);
9345 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9348 if (isbit && !IS_ITEMP(cond))
9349 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9357 /*-----------------------------------------------------------------*/
9358 /* genAddrOf - generates code for address of */
9359 /*-----------------------------------------------------------------*/
9360 static void genAddrOf (iCode *ic)
9362 operand *right, *result, *left;
9366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9369 //aopOp(IC_RESULT(ic),ic,FALSE);
9371 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9372 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9373 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9375 DEBUGpic14_AopType(__LINE__,left,right,result);
9377 size = AOP_SIZE(IC_RESULT(ic));
9381 /* fixing bug #863624, reported from (errolv) */
9382 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9383 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9386 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9387 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9392 freeAsmop(left,NULL,ic,FALSE);
9393 freeAsmop(result,NULL,ic,TRUE);
9398 /*-----------------------------------------------------------------*/
9399 /* genFarFarAssign - assignment when both are in far space */
9400 /*-----------------------------------------------------------------*/
9401 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9403 int size = AOP_SIZE(right);
9406 /* first push the right side on to the stack */
9408 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9410 pic14_emitcode ("push","acc");
9413 freeAsmop(right,NULL,ic,FALSE);
9414 /* now assign DPTR to result */
9415 aopOp(result,ic,FALSE);
9416 size = AOP_SIZE(result);
9418 pic14_emitcode ("pop","acc");
9419 aopPut(AOP(result),"a",--offset);
9421 freeAsmop(result,NULL,ic,FALSE);
9426 /*-----------------------------------------------------------------*/
9427 /* genAssign - generate code for assignment */
9428 /*-----------------------------------------------------------------*/
9429 static void genAssign (iCode *ic)
9431 operand *result, *right;
9432 int size, offset,know_W;
9433 unsigned long lit = 0L;
9435 result = IC_RESULT(ic);
9436 right = IC_RIGHT(ic) ;
9439 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9441 /* if they are the same */
9442 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9445 aopOp(right,ic,FALSE);
9446 aopOp(result,ic,TRUE);
9448 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9450 /* if they are the same registers */
9451 if (pic14_sameRegs(AOP(right),AOP(result)))
9454 /* if the result is a bit */
9455 if (AOP_TYPE(result) == AOP_CRY) {
9457 /* if the right size is a literal then
9458 we know what the value is */
9459 if (AOP_TYPE(right) == AOP_LIT) {
9461 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9462 popGet(AOP(result),0));
9464 if (((int) operandLitValue(right)))
9465 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9466 AOP(result)->aopu.aop_dir,
9467 AOP(result)->aopu.aop_dir);
9469 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9470 AOP(result)->aopu.aop_dir,
9471 AOP(result)->aopu.aop_dir);
9475 /* the right is also a bit variable */
9476 if (AOP_TYPE(right) == AOP_CRY) {
9477 emitpcode(POC_BCF, popGet(AOP(result),0));
9478 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9479 emitpcode(POC_BSF, popGet(AOP(result),0));
9481 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9482 AOP(result)->aopu.aop_dir,
9483 AOP(result)->aopu.aop_dir);
9484 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9485 AOP(right)->aopu.aop_dir,
9486 AOP(right)->aopu.aop_dir);
9487 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9488 AOP(result)->aopu.aop_dir,
9489 AOP(result)->aopu.aop_dir);
9494 emitpcode(POC_BCF, popGet(AOP(result),0));
9495 pic14_toBoolean(right);
9497 emitpcode(POC_BSF, popGet(AOP(result),0));
9498 //aopPut(AOP(result),"a",0);
9502 /* bit variables done */
9504 size = AOP_SIZE(result);
9506 if(AOP_TYPE(right) == AOP_LIT)
9507 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9509 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9511 if(aopIdx(AOP(result),0) == 4) {
9512 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9513 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9514 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9517 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9523 if(AOP_TYPE(right) == AOP_LIT) {
9525 if(know_W != (int)(lit&0xff))
9526 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9528 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9530 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9534 } else if (AOP_TYPE(right) == AOP_CRY) {
9535 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9537 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9538 emitpcode(POC_INCF, popGet(AOP(result),0));
9541 mov2w (AOP(right), offset);
9542 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9550 freeAsmop (right,NULL,ic,FALSE);
9551 freeAsmop (result,NULL,ic,TRUE);
9554 /*-----------------------------------------------------------------*/
9555 /* genJumpTab - genrates code for jump table */
9556 /*-----------------------------------------------------------------*/
9557 static void genJumpTab (iCode *ic)
9563 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9565 aopOp(IC_JTCOND(ic),ic,FALSE);
9566 /* get the condition into accumulator */
9567 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9569 /* multiply by three */
9570 pic14_emitcode("add","a,acc");
9571 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9573 jtab = newiTempLabel(NULL);
9574 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9575 pic14_emitcode("jmp","@a+dptr");
9576 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9578 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9579 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9580 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9581 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9583 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9584 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9585 emitpLabel(jtab->key);
9587 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9589 /* now generate the jump labels */
9590 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9591 jtab = setNextItem(IC_JTLABELS(ic))) {
9592 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9593 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9599 /*-----------------------------------------------------------------*/
9600 /* genMixedOperation - gen code for operators between mixed types */
9601 /*-----------------------------------------------------------------*/
9603 TSD - Written for the PIC port - but this unfortunately is buggy.
9604 This routine is good in that it is able to efficiently promote
9605 types to different (larger) sizes. Unfortunately, the temporary
9606 variables that are optimized out by this routine are sometimes
9607 used in other places. So until I know how to really parse the
9608 iCode tree, I'm going to not be using this routine :(.
9610 static int genMixedOperation (iCode *ic)
9614 operand *result = IC_RESULT(ic);
9615 sym_link *ctype = operandType(IC_LEFT(ic));
9616 operand *right = IC_RIGHT(ic);
9622 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9624 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9630 nextright = IC_RIGHT(nextic);
9631 nextleft = IC_LEFT(nextic);
9632 nextresult = IC_RESULT(nextic);
9634 aopOp(right,ic,FALSE);
9635 aopOp(result,ic,FALSE);
9636 aopOp(nextright, nextic, FALSE);
9637 aopOp(nextleft, nextic, FALSE);
9638 aopOp(nextresult, nextic, FALSE);
9640 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9646 pic14_emitcode(";remove right +","");
9648 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9654 pic14_emitcode(";remove left +","");
9658 big = AOP_SIZE(nextleft);
9659 small = AOP_SIZE(nextright);
9661 switch(nextic->op) {
9664 pic14_emitcode(";optimize a +","");
9665 /* if unsigned or not an integral type */
9666 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9667 pic14_emitcode(";add a bit to something","");
9670 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9672 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9673 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9674 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9676 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9684 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9685 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9686 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9689 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9691 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9692 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9693 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9694 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9695 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9698 pic14_emitcode("rlf","known_zero,w");
9705 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9706 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9707 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9709 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9719 freeAsmop(right,NULL,ic,TRUE);
9720 freeAsmop(result,NULL,ic,TRUE);
9721 freeAsmop(nextright,NULL,ic,TRUE);
9722 freeAsmop(nextleft,NULL,ic,TRUE);
9724 nextic->generated = 1;
9731 /*-----------------------------------------------------------------*/
9732 /* genCast - gen code for casting */
9733 /*-----------------------------------------------------------------*/
9734 static void genCast (iCode *ic)
9736 operand *result = IC_RESULT(ic);
9737 sym_link *ctype = operandType(IC_LEFT(ic));
9738 sym_link *rtype = operandType(IC_RIGHT(ic));
9739 operand *right = IC_RIGHT(ic);
9743 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9744 /* if they are equivalent then do nothing */
9745 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9748 aopOp(right,ic,FALSE) ;
9749 aopOp(result,ic,FALSE);
9751 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9753 /* if the result is a bit */
9754 if (AOP_TYPE(result) == AOP_CRY) {
9755 /* if the right size is a literal then
9756 we know what the value is */
9757 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9758 if (AOP_TYPE(right) == AOP_LIT) {
9760 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9761 popGet(AOP(result),0));
9763 if (((int) operandLitValue(right)))
9764 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9765 AOP(result)->aopu.aop_dir,
9766 AOP(result)->aopu.aop_dir);
9768 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9769 AOP(result)->aopu.aop_dir,
9770 AOP(result)->aopu.aop_dir);
9775 /* the right is also a bit variable */
9776 if (AOP_TYPE(right) == AOP_CRY) {
9779 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9781 pic14_emitcode("clrc","");
9782 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9783 AOP(right)->aopu.aop_dir,
9784 AOP(right)->aopu.aop_dir);
9785 aopPut(AOP(result),"c",0);
9790 if (AOP_TYPE(right) == AOP_REG) {
9791 emitpcode(POC_BCF, popGet(AOP(result),0));
9792 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9793 emitpcode(POC_BSF, popGet(AOP(result),0));
9795 pic14_toBoolean(right);
9796 aopPut(AOP(result),"a",0);
9800 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9802 size = AOP_SIZE(result);
9804 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9806 emitpcode(POC_CLRF, popGet(AOP(result),0));
9807 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9808 emitpcode(POC_INCF, popGet(AOP(result),0));
9811 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9816 /* if they are the same size : or less */
9817 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9819 /* if they are in the same place */
9820 if (pic14_sameRegs(AOP(right),AOP(result)))
9823 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9824 if (IS_PTR_CONST(rtype))
9825 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9826 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9827 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9829 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9830 emitpcode(POC_MOVLW, popGetAddr(AOP(right),0));
9831 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9832 emitpcode(POC_MOVLW, popGetAddr(AOP(right),1));
9833 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9834 if(AOP_SIZE(result) <2)
9835 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9839 /* if they in different places then copy */
9840 size = AOP_SIZE(result);
9843 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9844 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9846 //aopPut(AOP(result),
9847 // aopGet(AOP(right),offset,FALSE,FALSE),
9857 /* if the result is of type pointer */
9858 if (IS_PTR(ctype)) {
9861 sym_link *type = operandType(right);
9862 sym_link *etype = getSpec(type);
9863 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9865 /* pointer to generic pointer */
9866 if (IS_GENPTR(ctype)) {
9870 p_type = DCL_TYPE(type);
9872 /* we have to go by the storage class */
9873 p_type = PTR_TYPE(SPEC_OCLS(etype));
9875 /* if (SPEC_OCLS(etype)->codesp ) */
9876 /* p_type = CPOINTER ; */
9878 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9879 /* p_type = FPOINTER ; */
9881 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9882 /* p_type = PPOINTER; */
9884 /* if (SPEC_OCLS(etype) == idata ) */
9885 /* p_type = IPOINTER ; */
9887 /* p_type = POINTER ; */
9890 /* the first two bytes are known */
9891 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9892 size = GPTRSIZE - 1;
9895 if(offset < AOP_SIZE(right)) {
9896 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9897 if ((AOP_TYPE(right) == AOP_PCODE) &&
9898 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9899 emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset));
9900 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9903 aopGet(AOP(right),offset,FALSE,FALSE),
9907 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9910 /* the last byte depending on type */
9914 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9917 pic14_emitcode(";BUG!? ","%d",__LINE__);
9921 pic14_emitcode(";BUG!? ","%d",__LINE__);
9925 pic14_emitcode(";BUG!? ","%d",__LINE__);
9930 /* this should never happen */
9931 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9932 "got unknown pointer type");
9935 //aopPut(AOP(result),l, GPTRSIZE - 1);
9939 /* just copy the pointers */
9940 size = AOP_SIZE(result);
9944 aopGet(AOP(right),offset,FALSE,FALSE),
9953 /* so we now know that the size of destination is greater
9954 than the size of the source.
9955 Now, if the next iCode is an operator then we might be
9956 able to optimize the operation without performing a cast.
9958 if(genMixedOperation(ic))
9961 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9963 /* we move to result for the size of source */
9964 size = AOP_SIZE(right);
9967 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9968 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9972 /* now depending on the sign of the destination */
9973 size = AOP_SIZE(result) - AOP_SIZE(right);
9974 /* if unsigned or not an integral type */
9975 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9977 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9979 /* we need to extend the sign :{ */
9982 /* Save one instruction of casting char to int */
9983 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9984 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9985 emitpcode(POC_DECF, popGet(AOP(result),offset));
9987 emitpcodeNULLop(POC_CLRW);
9990 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9992 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9994 emitpcode(POC_MOVLW, popGetLit(0xff));
9997 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
10002 freeAsmop(right,NULL,ic,TRUE);
10003 freeAsmop(result,NULL,ic,TRUE);
10007 /*-----------------------------------------------------------------*/
10008 /* genDjnz - generate decrement & jump if not zero instrucion */
10009 /*-----------------------------------------------------------------*/
10010 static int genDjnz (iCode *ic, iCode *ifx)
10012 symbol *lbl, *lbl1;
10014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10019 /* if the if condition has a false label
10020 then we cannot save */
10024 /* if the minus is not of the form
10026 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10027 !IS_OP_LITERAL(IC_RIGHT(ic)))
10030 if (operandLitValue(IC_RIGHT(ic)) != 1)
10033 /* if the size of this greater than one then no
10035 if (getSize(operandType(IC_RESULT(ic))) > 1)
10038 /* otherwise we can save BIG */
10039 lbl = newiTempLabel(NULL);
10040 lbl1= newiTempLabel(NULL);
10042 aopOp(IC_RESULT(ic),ic,FALSE);
10044 if (IS_AOP_PREG(IC_RESULT(ic))) {
10045 pic14_emitcode("dec","%s",
10046 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10047 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10048 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
10052 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
10053 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
10055 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10056 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10059 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10060 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
10061 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10062 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
10065 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10066 ifx->generated = 1;
10070 /*-----------------------------------------------------------------*/
10071 /* genReceive - generate code for a receive iCode */
10072 /*-----------------------------------------------------------------*/
10073 static void genReceive (iCode *ic)
10076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10078 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10079 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10080 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10082 int size = getSize(operandType(IC_RESULT(ic)));
10083 int offset = fReturnSizePic - size;
10085 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
10086 fReturn[fReturnSizePic - offset - 1] : "acc"));
10089 aopOp(IC_RESULT(ic),ic,FALSE);
10090 size = AOP_SIZE(IC_RESULT(ic));
10093 pic14_emitcode ("pop","acc");
10094 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10099 aopOp(IC_RESULT(ic),ic,FALSE);
10101 assignResultValue(IC_RESULT(ic));
10104 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10107 /*-----------------------------------------------------------------*/
10108 /* genDummyRead - generate code for dummy read of volatiles */
10109 /*-----------------------------------------------------------------*/
10111 genDummyRead (iCode * ic)
10114 pic14_emitcode ("; genDummyRead","");
10115 pic14_emitcode ("; not implemented","");
10120 /*-----------------------------------------------------------------*/
10121 /* genpic14Code - generate code for pic14 based controllers */
10122 /*-----------------------------------------------------------------*/
10124 * At this point, ralloc.c has gone through the iCode and attempted
10125 * to optimize in a way suitable for a PIC. Now we've got to generate
10126 * PIC instructions that correspond to the iCode.
10128 * Once the instructions are generated, we'll pass through both the
10129 * peep hole optimizer and the pCode optimizer.
10130 *-----------------------------------------------------------------*/
10132 void genpic14Code (iCode *lic)
10138 lineHead = lineCurr = NULL;
10140 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
10143 /* if debug information required */
10144 if (options.debug && currFunc) {
10146 debugFile->writeFunction (currFunc, lic);
10151 for (ic = lic ; ic ; ic = ic->next ) {
10153 //DEBUGpic14_emitcode(";ic","");
10154 //fprintf (stderr, "in ic loop\n");
10155 //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
10156 //ic->lineno, printCLine(ic->filename, ic->lineno));
10158 if (!options.noCcodeInAsm && (cln != ic->lineno)) {
10160 //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
10161 emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, printCLine (ic->filename, cln));
10164 if (options.iCodeInAsm) {
10165 emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
10167 /* if the result is marked as
10168 spilt and rematerializable or code for
10169 this has already been generated then
10171 if (resultRemat(ic) || ic->generated )
10174 /* depending on the operation */
10193 /* IPOP happens only when trying to restore a
10194 spilt live range, if there is an ifx statement
10195 following this pop then the if statement might
10196 be using some of the registers being popped which
10197 would destory the contents of the register so
10198 we need to check for this condition and handle it */
10200 ic->next->op == IFX &&
10201 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10202 genIfx (ic->next,ic);
10220 genEndFunction (ic);
10240 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10257 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10261 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10268 /* note these two are xlated by algebraic equivalence
10269 during parsing SDCC.y */
10270 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10271 "got '>=' or '<=' shouldn't have come here");
10275 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10287 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10291 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10295 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10319 genRightShift (ic);
10322 case GET_VALUE_AT_ADDRESS:
10327 if (POINTER_SET(ic))
10354 addSet(&_G.sendSet,ic);
10357 case DUMMY_READ_VOLATILE:
10367 /* now we are ready to call the
10368 peep hole optimizer */
10369 if (!options.nopeep) {
10370 peepHole (&lineHead);
10372 /* now do the actual printing */
10373 printLine (lineHead,codeOutFile);
10376 DFPRINTF((stderr,"printing pBlock\n\n"));
10377 printpBlock(stdout,pb);