1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
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"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 static int labelOffset=0;
64 static int debug_verbose=1;
65 static int optimized_for_speed = 0;
67 /* max_key keeps track of the largest label number used in
68 a function. This is then used to adjust the label offset
69 for the next function.
72 static int GpsuedoStkPtr=0;
74 unsigned int pic14aopLiteral (value *val, int offset);
75 const char *AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic14[] = {"FSR","dph","b","a" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic14;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic14_ptrRegReq ;
119 extern int pic14_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 char lb[INITIAL_INLINEASM];
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));
208 static void emitpLabel(int key)
210 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
213 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 addpCode2pBlock(pb,newpCode(poc,pcop));
219 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
222 void emitpcodeNULLop(PIC_OPCODE poc)
225 addpCode2pBlock(pb,newpCode(poc,NULL));
229 /*-----------------------------------------------------------------*/
230 /* pic14_emitcode - writes the code into a file : for now it is simple */
231 /*-----------------------------------------------------------------*/
232 void pic14_emitcode (char *inst,char *fmt, ...)
235 char lb[INITIAL_INLINEASM];
242 sprintf(lb,"%s\t",inst);
244 sprintf(lb,"%s",inst);
245 vsprintf(lb+(strlen(lb)),fmt,ap);
249 while (isspace(*lbp)) lbp++;
252 lineCurr = (lineCurr ?
253 connectLine(lineCurr,newLineNode(lb)) :
254 (lineHead = newLineNode(lb)));
255 lineCurr->isInline = _G.inLine;
256 lineCurr->isDebug = _G.debugLine;
259 addpCode2pBlock(pb,newpCodeCharP(lb));
265 /*-----------------------------------------------------------------*/
266 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
267 /*-----------------------------------------------------------------*/
268 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
270 bool r0iu = FALSE , r1iu = FALSE;
271 bool r0ou = FALSE , r1ou = FALSE;
273 /* the logic: if r0 & r1 used in the instruction
274 then we are in trouble otherwise */
276 /* first check if r0 & r1 are used by this
277 instruction, in which case we are in trouble */
278 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
279 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
284 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
285 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
287 /* if no usage of r0 then return it */
288 if (!r0iu && !r0ou) {
289 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
290 (*aopp)->type = AOP_R0;
292 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
295 /* if no usage of r1 then return it */
296 if (!r1iu && !r1ou) {
297 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
298 (*aopp)->type = AOP_R1;
300 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
303 /* now we know they both have usage */
304 /* if r0 not used in this instruction */
306 /* push it if not already pushed */
308 pic14_emitcode ("push","%s",
309 pic14_regWithIdx(R0_IDX)->dname);
313 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
314 (*aopp)->type = AOP_R0;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
319 /* if r1 not used then */
322 /* push it if not already pushed */
324 pic14_emitcode ("push","%s",
325 pic14_regWithIdx(R1_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
330 (*aopp)->type = AOP_R1;
331 return pic14_regWithIdx(R1_IDX);
335 /* I said end of world but not quite end of world yet */
336 /* if this is a result then we can push it on the stack*/
338 (*aopp)->type = AOP_STK;
342 /* other wise this is true end of the world */
343 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
344 "getFreePtr should never reach here");
348 /*-----------------------------------------------------------------*/
349 /* newAsmop - creates a new asmOp */
350 /*-----------------------------------------------------------------*/
351 asmop *newAsmop (short type)
355 aop = Safe_calloc(1,sizeof(asmop));
360 static void genSetDPTR(int n)
364 pic14_emitcode(";", "Select standard DPTR");
365 pic14_emitcode("mov", "dps, #0x00");
369 pic14_emitcode(";", "Select alternate DPTR");
370 pic14_emitcode("mov", "dps, #0x01");
374 /*-----------------------------------------------------------------*/
375 /* resolveIfx - converts an iCode ifx into a form more useful for */
376 /* generating code */
377 /*-----------------------------------------------------------------*/
378 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
385 resIfx->condition = 1; /* assume that the ifx is true */
386 resIfx->generated = 0; /* indicate that the ifx has not been used */
389 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
390 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
391 __FUNCTION__,__LINE__,resIfx->lbl->key);
394 resIfx->lbl = IC_TRUE(ifx);
396 resIfx->lbl = IC_FALSE(ifx);
397 resIfx->condition = 0;
400 DEBUGpic14_emitcode("; ***","ifx true is non-null");
402 DEBUGpic14_emitcode("; ***","ifx false is non-null");
405 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
408 /*-----------------------------------------------------------------*/
409 /* pointerCode - returns the code for a pointer type */
410 /*-----------------------------------------------------------------*/
411 static int pointerCode (sym_link *etype)
414 return PTR_TYPE(SPEC_OCLS(etype));
418 /*-----------------------------------------------------------------*/
419 /* aopForSym - for a true symbol */
420 /*-----------------------------------------------------------------*/
421 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
424 memmap *space= SPEC_OCLS(sym->etype);
426 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
427 /* if already has one */
431 /* assign depending on the storage class */
432 /* if it is on the stack or indirectly addressable */
433 /* space we need to assign either r0 or r1 to it */
434 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
435 sym->aop = aop = newAsmop(0);
436 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
437 aop->size = getSize(sym->type);
439 /* now assign the address of the variable to
440 the pointer register */
441 if (aop->type != AOP_STK) {
445 pic14_emitcode("push","acc");
447 pic14_emitcode("mov","a,_bp");
448 pic14_emitcode("add","a,#0x%02x",
450 ((char)(sym->stack - _G.nRegsSaved )) :
451 ((char)sym->stack)) & 0xff);
452 pic14_emitcode("mov","%s,a",
453 aop->aopu.aop_ptr->name);
456 pic14_emitcode("pop","acc");
458 pic14_emitcode("mov","%s,#%s",
459 aop->aopu.aop_ptr->name,
461 aop->paged = space->paged;
463 aop->aopu.aop_stk = sym->stack;
467 if (sym->onStack && options.stack10bit)
469 /* It's on the 10 bit stack, which is located in
473 //DEBUGpic14_emitcode(";","%d",__LINE__);
476 pic14_emitcode("push","acc");
478 pic14_emitcode("mov","a,_bp");
479 pic14_emitcode("add","a,#0x%02x",
481 ((char)(sym->stack - _G.nRegsSaved )) :
482 ((char)sym->stack)) & 0xff);
485 pic14_emitcode ("mov","dpx1,#0x40");
486 pic14_emitcode ("mov","dph1,#0x00");
487 pic14_emitcode ("mov","dpl1, a");
491 pic14_emitcode("pop","acc");
493 sym->aop = aop = newAsmop(AOP_DPTR2);
494 aop->size = getSize(sym->type);
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
499 /* if in bit space */
500 if (IN_BITSPACE(space)) {
501 sym->aop = aop = newAsmop (AOP_CRY);
502 aop->aopu.aop_dir = sym->rname ;
503 aop->size = getSize(sym->type);
504 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
507 /* if it is in direct space */
508 if (IN_DIRSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_DIR);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
516 /* special case for a function */
517 if (IS_FUNC(sym->type)) {
518 sym->aop = aop = newAsmop(AOP_IMMD);
519 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
520 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
521 strcpy(aop->aopu.aop_immd,sym->rname);
522 aop->size = FPTRSIZE;
527 /* only remaining is far space */
528 /* in which case DPTR gets the address */
529 sym->aop = aop = newAsmop(AOP_DPTR);
530 pic14_emitcode ("mov","dptr,#%s", sym->rname);
531 aop->size = getSize(sym->type);
533 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
534 /* if it is in code space */
535 if (IN_CODESPACE(space))
541 /*-----------------------------------------------------------------*/
542 /* aopForRemat - rematerialzes an object */
543 /*-----------------------------------------------------------------*/
544 static asmop *aopForRemat (symbol *sym)
546 iCode *ic = sym->rematiCode;
547 asmop *aop = newAsmop(AOP_IMMD);
549 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
552 val += (int) operandLitValue(IC_RIGHT(ic));
553 else if (ic->op == '-')
554 val -= (int) operandLitValue(IC_RIGHT(ic));
558 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
562 sprintf(buffer,"(%s %c 0x%04x)",
563 OP_SYMBOL(IC_LEFT(ic))->rname,
564 val >= 0 ? '+' : '-',
567 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
569 //DEBUGpic14_emitcode(";","%s",buffer);
570 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
571 strcpy(aop->aopu.aop_immd,buffer);
575 int aopIdx (asmop *aop, int offset)
580 if(aop->type != AOP_REG)
583 return aop->aopu.aop_reg[offset]->rIdx;
586 /*-----------------------------------------------------------------*/
587 /* regsInCommon - two operands have some registers in common */
588 /*-----------------------------------------------------------------*/
589 static bool regsInCommon (operand *op1, operand *op2)
594 /* if they have registers in common */
595 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
598 sym1 = OP_SYMBOL(op1);
599 sym2 = OP_SYMBOL(op2);
601 if (sym1->nRegs == 0 || sym2->nRegs == 0)
604 for (i = 0 ; i < sym1->nRegs ; i++) {
609 for (j = 0 ; j < sym2->nRegs ;j++ ) {
613 if (sym2->regs[j] == sym1->regs[i])
621 /*-----------------------------------------------------------------*/
622 /* operandsEqu - equivalent */
623 /*-----------------------------------------------------------------*/
624 static bool operandsEqu ( operand *op1, operand *op2)
628 /* if they not symbols */
629 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
632 sym1 = OP_SYMBOL(op1);
633 sym2 = OP_SYMBOL(op2);
635 /* if both are itemps & one is spilt
636 and the other is not then false */
637 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
638 sym1->isspilt != sym2->isspilt )
641 /* if they are the same */
645 if (strcmp(sym1->rname,sym2->rname) == 0)
649 /* if left is a tmp & right is not */
653 (sym1->usl.spillLoc == sym2))
660 (sym2->usl.spillLoc == sym1))
666 /*-----------------------------------------------------------------*/
667 /* pic14_sameRegs - two asmops have the same registers */
668 /*-----------------------------------------------------------------*/
669 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
676 if (aop1->type != AOP_REG ||
677 aop2->type != AOP_REG )
680 if (aop1->size != aop2->size )
683 for (i = 0 ; i < aop1->size ; i++ )
684 if (aop1->aopu.aop_reg[i] !=
685 aop2->aopu.aop_reg[i] )
691 /*-----------------------------------------------------------------*/
692 /* aopOp - allocates an asmop for an operand : */
693 /*-----------------------------------------------------------------*/
694 void aopOp (operand *op, iCode *ic, bool result)
703 // DEBUGpic14_emitcode(";","%d",__LINE__);
704 /* if this a literal */
705 if (IS_OP_LITERAL(op)) {
706 op->aop = aop = newAsmop(AOP_LIT);
707 aop->aopu.aop_lit = op->operand.valOperand;
708 aop->size = getSize(operandType(op));
712 /* if already has a asmop then continue */
716 /* if the underlying symbol has a aop */
717 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
718 DEBUGpic14_emitcode(";","%d",__LINE__);
719 op->aop = OP_SYMBOL(op)->aop;
723 /* if this is a true symbol */
724 if (IS_TRUE_SYMOP(op)) {
725 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
726 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
730 /* this is a temporary : this has
736 e) can be a return use only */
741 /* if the type is a conditional */
742 if (sym->regType == REG_CND) {
743 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
748 /* if it is spilt then two situations
750 b) has a spill location */
751 if (sym->isspilt || sym->nRegs == 0) {
753 DEBUGpic14_emitcode(";","%d",__LINE__);
754 /* rematerialize it NOW */
756 sym->aop = op->aop = aop =
758 aop->size = getSize(sym->type);
764 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
765 aop->size = getSize(sym->type);
766 for ( i = 0 ; i < 2 ; i++ )
767 aop->aopu.aop_str[i] = accUse[i];
768 DEBUGpic14_emitcode(";","%d",__LINE__);
774 aop = op->aop = sym->aop = newAsmop(AOP_STR);
775 aop->size = getSize(sym->type);
776 for ( i = 0 ; i < fReturnSizePic ; i++ )
777 aop->aopu.aop_str[i] = fReturn[i];
778 DEBUGpic14_emitcode(";","%d",__LINE__);
782 /* else spill location */
783 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
784 sym->aop = op->aop = aop =
785 aopForSym(ic,sym->usl.spillLoc,result);
786 aop->size = getSize(sym->type);
790 /* must be in a register */
791 sym->aop = op->aop = aop = newAsmop(AOP_REG);
792 aop->size = sym->nRegs;
793 for ( i = 0 ; i < sym->nRegs ;i++)
794 aop->aopu.aop_reg[i] = sym->regs[i];
797 /*-----------------------------------------------------------------*/
798 /* freeAsmop - free up the asmop given to an operand */
799 /*----------------------------------------------------------------*/
800 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
817 /* depending on the asmop type only three cases need work AOP_RO
818 , AOP_R1 && AOP_STK */
824 pic14_emitcode ("pop","ar0");
828 bitVectUnSetBit(ic->rUsed,R0_IDX);
834 pic14_emitcode ("pop","ar1");
838 bitVectUnSetBit(ic->rUsed,R1_IDX);
844 int stk = aop->aopu.aop_stk + aop->size;
845 bitVectUnSetBit(ic->rUsed,R0_IDX);
846 bitVectUnSetBit(ic->rUsed,R1_IDX);
848 getFreePtr(ic,&aop,FALSE);
850 if (options.stack10bit)
852 /* I'm not sure what to do here yet... */
855 "*** Warning: probably generating bad code for "
856 "10 bit stack mode.\n");
860 pic14_emitcode ("mov","a,_bp");
861 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
862 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
864 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
868 pic14_emitcode("pop","acc");
869 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
871 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
874 freeAsmop(op,NULL,ic,TRUE);
876 pic14_emitcode("pop","ar0");
881 pic14_emitcode("pop","ar1");
889 /* all other cases just dealloc */
893 OP_SYMBOL(op)->aop = NULL;
894 /* if the symbol has a spill */
896 SPIL_LOC(op)->aop = NULL;
901 /*-----------------------------------------------------------------*/
902 /* aopGet - for fetching value of the aop */
903 /*-----------------------------------------------------------------*/
904 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
909 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
910 /* offset is greater than
912 if (offset > (aop->size - 1) &&
913 aop->type != AOP_LIT)
916 /* depending on type */
921 DEBUGpic14_emitcode(";","%d",__LINE__);
922 /* if we need to increment it */
923 while (offset > aop->coff) {
924 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
928 while (offset < aop->coff) {
929 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
935 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
936 return (dname ? "acc" : "a");
938 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
939 rs = Safe_calloc(1,strlen(s)+1);
945 DEBUGpic14_emitcode(";","%d",__LINE__);
946 if (aop->type == AOP_DPTR2)
951 while (offset > aop->coff) {
952 pic14_emitcode ("inc","dptr");
956 while (offset < aop->coff) {
957 pic14_emitcode("lcall","__decdptr");
963 pic14_emitcode("clr","a");
964 pic14_emitcode("movc","a,@a+dptr");
967 pic14_emitcode("movx","a,@dptr");
970 if (aop->type == AOP_DPTR2)
975 return (dname ? "acc" : "a");
979 DEBUGpic14_emitcode(";","%d",__LINE__);
981 sprintf (s,"%s",aop->aopu.aop_immd);
984 sprintf(s,"(%s >> %d)",
990 rs = Safe_calloc(1,strlen(s)+1);
996 sprintf(s,"(%s + %d)",
1000 sprintf(s,"%s",aop->aopu.aop_dir);
1001 rs = Safe_calloc(1,strlen(s)+1);
1007 return aop->aopu.aop_reg[offset]->dname;
1009 return aop->aopu.aop_reg[offset]->name;
1012 //pic14_emitcode(";","%d",__LINE__);
1013 return aop->aopu.aop_dir;
1016 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1017 return "AOP_accumulator_bug";
1020 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1021 rs = Safe_calloc(1,strlen(s)+1);
1026 DEBUGpic14_emitcode(";","%d",__LINE__);
1027 aop->coff = offset ;
1028 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1032 return aop->aopu.aop_str[offset];
1036 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1037 "aopget got unsupported aop->type");
1041 /*-----------------------------------------------------------------*/
1042 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1043 /*-----------------------------------------------------------------*/
1044 pCodeOp *popGetLabel(unsigned int key)
1047 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1052 return newpCodeOpLabel(key+100+labelOffset);
1055 /*-----------------------------------------------------------------*/
1056 /* popCopyReg - copy a pcode operator */
1057 /*-----------------------------------------------------------------*/
1058 pCodeOp *popCopyReg(pCodeOpReg *pc)
1062 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1063 pcor->pcop.type = pc->pcop.type;
1064 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1065 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1067 pcor->rIdx = pc->rIdx;
1073 /*-----------------------------------------------------------------*/
1074 /* popCopy - copy a pcode operator */
1075 /*-----------------------------------------------------------------*/
1076 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1080 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1081 pcop->type = PO_BIT;
1082 if(!(pcop->name = Safe_strdup(pc->name)))
1083 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1084 ((pCodeOpBit *)pcop)->bit = bitval;
1086 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1091 /*-----------------------------------------------------------------*/
1092 /* popGet - asm operator to pcode operator conversion */
1093 /*-----------------------------------------------------------------*/
1094 pCodeOp *popGetLit(unsigned int lit)
1097 return newpCodeOpLit(lit);
1101 /*-----------------------------------------------------------------*/
1102 /* popGet - asm operator to pcode operator conversion */
1103 /*-----------------------------------------------------------------*/
1104 pCodeOp *popGetWithString(char *str)
1110 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1114 pcop = newpCodeOp(str,PO_STR);
1119 pCodeOp *popRegFromString(char *str)
1122 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1123 pcop->type = PO_GPR_REGISTER;
1125 PCOR(pcop)->rIdx = -1;
1126 PCOR(pcop)->r = NULL;
1128 DEBUGpic14_emitcode(";","%d",__LINE__);
1129 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1134 pCodeOp *popRegFromIdx(int rIdx)
1138 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1139 __FUNCTION__,__LINE__,rIdx);
1141 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1143 PCOR(pcop)->rIdx = rIdx;
1144 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1145 PCOR(pcop)->r->isFree = 0;
1146 PCOR(pcop)->r->wasUsed = 1;
1148 pcop->type = PCOR(pcop)->r->pc_type;
1153 /*-----------------------------------------------------------------*/
1154 /* popGet - asm operator to pcode operator conversion */
1155 /*-----------------------------------------------------------------*/
1156 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1163 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1164 /* offset is greater than
1167 if (offset > (aop->size - 1) &&
1168 aop->type != AOP_LIT)
1169 return NULL; //zero;
1171 /* depending on type */
1172 switch (aop->type) {
1179 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1180 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1181 //pcop->type = PO_SFR_REGISTER;
1183 //PCOR(pcop)->rIdx = -1;
1184 //PCOR(pcop)->r = NULL;
1185 // Really nasty hack to check for temporary registers
1187 //pcop->name = Safe_strdup("BAD_REGISTER");
1192 DEBUGpic14_emitcode(";","%d",__LINE__);
1193 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1194 pcop->type = PO_IMMEDIATE;
1196 // sprintf (s,"%s",aop->aopu.aop_immd);
1199 sprintf(s,"(%s >> %d)",
1204 aop->aopu.aop_immd);
1205 pcop->name = Safe_calloc(1,strlen(s)+1);
1206 strcpy(pcop->name,s);
1210 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1211 pcop->type = PO_DIR;
1213 sprintf(s,"(%s + %d)",
1217 sprintf(s,"%s",aop->aopu.aop_dir);
1218 pcop->name = Safe_calloc(1,strlen(s)+1);
1219 strcpy(pcop->name,s);
1224 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1226 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1227 PCOR(pcop)->rIdx = rIdx;
1228 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1229 pcop->type = PCOR(pcop)->r->pc_type;
1230 rs = aop->aopu.aop_reg[offset]->name;
1235 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1239 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1242 DEBUGpic14_emitcode(";","%d",__LINE__);
1244 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1245 pcop->type = PO_STR;
1247 //aop->coff = offset ;
1248 //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1249 // sprintf(s,"%s","acc");
1251 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1252 pcop->name = Safe_calloc(1,strlen(s)+1);
1253 strcpy(pcop->name,s);
1258 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1259 "popGet got unsupported aop->type");
1262 /*-----------------------------------------------------------------*/
1263 /* aopPut - puts a string for a aop */
1264 /*-----------------------------------------------------------------*/
1265 void aopPut (asmop *aop, char *s, int offset)
1270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1272 if (aop->size && offset > ( aop->size - 1)) {
1273 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1274 "aopPut got offset > aop->size");
1278 /* will assign value to value */
1279 /* depending on where it is ofcourse */
1280 switch (aop->type) {
1283 sprintf(d,"(%s + %d)",
1284 aop->aopu.aop_dir,offset);
1286 sprintf(d,"%s",aop->aopu.aop_dir);
1289 DEBUGpic14_emitcode(";","%d",__LINE__);
1291 pic14_emitcode("movf","%s,w",s);
1292 pic14_emitcode("movwf","%s",d);
1295 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1296 emitpcode(POC_MOVWF,popGet(aop,offset));
1303 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1304 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1307 strcmp(s,"r0") == 0 ||
1308 strcmp(s,"r1") == 0 ||
1309 strcmp(s,"r2") == 0 ||
1310 strcmp(s,"r3") == 0 ||
1311 strcmp(s,"r4") == 0 ||
1312 strcmp(s,"r5") == 0 ||
1313 strcmp(s,"r6") == 0 ||
1314 strcmp(s,"r7") == 0 )
1315 pic14_emitcode("mov","%s,%s ; %d",
1316 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1321 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1323 pic14_emitcode("movwf","%s",
1324 aop->aopu.aop_reg[offset]->name);
1327 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1328 pcop->type = PO_GPR_REGISTER;
1330 PCOR(pcop)->rIdx = -1;
1331 PCOR(pcop)->r = NULL;
1333 DEBUGpic14_emitcode(";","%d",__LINE__);
1334 pcop->name = Safe_strdup(s);
1335 emitpcode(POC_MOVFW,pcop);
1337 emitpcode(POC_MOVWF,popGet(aop,offset));
1345 if (aop->type == AOP_DPTR2)
1351 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1352 "aopPut writting to code space");
1356 while (offset > aop->coff) {
1358 pic14_emitcode ("inc","dptr");
1361 while (offset < aop->coff) {
1363 pic14_emitcode("lcall","__decdptr");
1368 /* if not in accumulater */
1371 pic14_emitcode ("movx","@dptr,a");
1373 if (aop->type == AOP_DPTR2)
1381 while (offset > aop->coff) {
1383 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1385 while (offset < aop->coff) {
1387 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1393 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1398 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1400 if (strcmp(s,"r0") == 0 ||
1401 strcmp(s,"r1") == 0 ||
1402 strcmp(s,"r2") == 0 ||
1403 strcmp(s,"r3") == 0 ||
1404 strcmp(s,"r4") == 0 ||
1405 strcmp(s,"r5") == 0 ||
1406 strcmp(s,"r6") == 0 ||
1407 strcmp(s,"r7") == 0 ) {
1409 sprintf(buffer,"a%s",s);
1410 pic14_emitcode("mov","@%s,%s",
1411 aop->aopu.aop_ptr->name,buffer);
1413 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1418 if (strcmp(s,"a") == 0)
1419 pic14_emitcode("push","acc");
1421 pic14_emitcode("push","%s",s);
1426 /* if bit variable */
1427 if (!aop->aopu.aop_dir) {
1428 pic14_emitcode("clr","a");
1429 pic14_emitcode("rlc","a");
1432 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1435 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1438 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1440 lbl = newiTempLabel(NULL);
1442 if (strcmp(s,"a")) {
1445 pic14_emitcode("clr","c");
1446 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1447 pic14_emitcode("cpl","c");
1448 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1449 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1456 if (strcmp(aop->aopu.aop_str[offset],s))
1457 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1462 if (!offset && (strcmp(s,"acc") == 0))
1465 if (strcmp(aop->aopu.aop_str[offset],s))
1466 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1470 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1471 "aopPut got unsupported aop->type");
1477 /*-----------------------------------------------------------------*/
1478 /* reAdjustPreg - points a register back to where it should */
1479 /*-----------------------------------------------------------------*/
1480 static void reAdjustPreg (asmop *aop)
1484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1486 if ((size = aop->size) <= 1)
1489 switch (aop->type) {
1493 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1497 if (aop->type == AOP_DPTR2)
1503 pic14_emitcode("lcall","__decdptr");
1506 if (aop->type == AOP_DPTR2)
1516 /*-----------------------------------------------------------------*/
1517 /* genNotFloat - generates not for float operations */
1518 /*-----------------------------------------------------------------*/
1519 static void genNotFloat (operand *op, operand *res)
1525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1526 /* we will put 127 in the first byte of
1528 aopPut(AOP(res),"#127",0);
1529 size = AOP_SIZE(op) - 1;
1532 l = aopGet(op->aop,offset++,FALSE,FALSE);
1536 pic14_emitcode("orl","a,%s",
1538 offset++,FALSE,FALSE));
1540 tlbl = newiTempLabel(NULL);
1542 tlbl = newiTempLabel(NULL);
1543 aopPut(res->aop,one,1);
1544 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1545 aopPut(res->aop,zero,1);
1546 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1548 size = res->aop->size - 2;
1550 /* put zeros in the rest */
1552 aopPut(res->aop,zero,offset++);
1556 /*-----------------------------------------------------------------*/
1557 /* opIsGptr: returns non-zero if the passed operand is */
1558 /* a generic pointer type. */
1559 /*-----------------------------------------------------------------*/
1560 static int opIsGptr(operand *op)
1562 sym_link *type = operandType(op);
1564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1565 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1573 /*-----------------------------------------------------------------*/
1574 /* pic14_getDataSize - get the operand data size */
1575 /*-----------------------------------------------------------------*/
1576 int pic14_getDataSize(operand *op)
1578 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1581 return AOP_SIZE(op);
1583 // tsd- in the pic port, the genptr size is 1, so this code here
1584 // fails. ( in the 8051 port, the size was 4).
1587 size = AOP_SIZE(op);
1588 if (size == GPTRSIZE)
1590 sym_link *type = operandType(op);
1591 if (IS_GENPTR(type))
1593 /* generic pointer; arithmetic operations
1594 * should ignore the high byte (pointer type).
1597 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1604 /*-----------------------------------------------------------------*/
1605 /* pic14_outAcc - output Acc */
1606 /*-----------------------------------------------------------------*/
1607 void pic14_outAcc(operand *result)
1610 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1611 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1614 size = pic14_getDataSize(result);
1616 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1619 /* unsigned or positive */
1621 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1626 /*-----------------------------------------------------------------*/
1627 /* pic14_outBitC - output a bit C */
1628 /*-----------------------------------------------------------------*/
1629 void pic14_outBitC(operand *result)
1632 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1633 /* if the result is bit */
1634 if (AOP_TYPE(result) == AOP_CRY)
1635 aopPut(AOP(result),"c",0);
1637 pic14_emitcode("clr","a ; %d", __LINE__);
1638 pic14_emitcode("rlc","a");
1639 pic14_outAcc(result);
1643 /*-----------------------------------------------------------------*/
1644 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1645 /*-----------------------------------------------------------------*/
1646 void pic14_toBoolean(operand *oper)
1648 int size = AOP_SIZE(oper) - 1;
1651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1653 if ( AOP_TYPE(oper) != AOP_ACC) {
1654 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1655 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1658 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1663 /*-----------------------------------------------------------------*/
1664 /* genNot - generate code for ! operation */
1665 /*-----------------------------------------------------------------*/
1666 static void genNot (iCode *ic)
1669 sym_link *optype = operandType(IC_LEFT(ic));
1672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1673 /* assign asmOps to operand & result */
1674 aopOp (IC_LEFT(ic),ic,FALSE);
1675 aopOp (IC_RESULT(ic),ic,TRUE);
1677 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1678 /* if in bit space then a special case */
1679 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1680 pic14_emitcode("movlw","1<<%s");
1681 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1682 //pic14_emitcode("cpl","c");
1683 //pic14_outBitC(IC_RESULT(ic));
1687 /* if type float then do float */
1688 if (IS_FLOAT(optype)) {
1689 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1693 size = AOP_SIZE(IC_RESULT(ic));
1695 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1696 emitpcode(POC_ANDLW,popGetLit(1));
1697 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1700 pic14_toBoolean(IC_LEFT(ic));
1702 tlbl = newiTempLabel(NULL);
1703 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1704 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1705 pic14_outBitC(IC_RESULT(ic));
1708 /* release the aops */
1709 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1710 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1714 /*-----------------------------------------------------------------*/
1715 /* genCpl - generate code for complement */
1716 /*-----------------------------------------------------------------*/
1717 static void genCpl (iCode *ic)
1723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1724 /* assign asmOps to operand & result */
1725 aopOp (IC_LEFT(ic),ic,FALSE);
1726 aopOp (IC_RESULT(ic),ic,TRUE);
1728 /* if both are in bit space then
1730 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1731 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1733 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1734 pic14_emitcode("cpl","c");
1735 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1739 size = AOP_SIZE(IC_RESULT(ic));
1741 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1743 pic14_emitcode("cpl","a");
1744 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1749 /* release the aops */
1750 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1751 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1754 /*-----------------------------------------------------------------*/
1755 /* genUminusFloat - unary minus for floating points */
1756 /*-----------------------------------------------------------------*/
1757 static void genUminusFloat(operand *op,operand *result)
1759 int size ,offset =0 ;
1762 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1763 /* for this we just need to flip the
1764 first it then copy the rest in place */
1765 size = AOP_SIZE(op) - 1;
1766 l = aopGet(AOP(op),3,FALSE,FALSE);
1770 pic14_emitcode("cpl","acc.7");
1771 aopPut(AOP(result),"a",3);
1775 aopGet(AOP(op),offset,FALSE,FALSE),
1781 /*-----------------------------------------------------------------*/
1782 /* genUminus - unary minus code generation */
1783 /*-----------------------------------------------------------------*/
1784 static void genUminus (iCode *ic)
1787 sym_link *optype, *rtype;
1790 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1792 aopOp(IC_LEFT(ic),ic,FALSE);
1793 aopOp(IC_RESULT(ic),ic,TRUE);
1795 /* if both in bit space then special
1797 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1798 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1800 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1801 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1802 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1807 optype = operandType(IC_LEFT(ic));
1808 rtype = operandType(IC_RESULT(ic));
1810 /* if float then do float stuff */
1811 if (IS_FLOAT(optype)) {
1812 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1816 /* otherwise subtract from zero by taking the 2's complement */
1817 size = AOP_SIZE(IC_LEFT(ic));
1819 for(i=0; i<size; i++) {
1820 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1821 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1823 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1824 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1828 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1829 for(i=1; i<size; i++) {
1831 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1835 /* release the aops */
1836 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1837 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1840 /*-----------------------------------------------------------------*/
1841 /* saveRegisters - will look for a call and save the registers */
1842 /*-----------------------------------------------------------------*/
1843 static void saveRegisters(iCode *lic)
1850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1852 for (ic = lic ; ic ; ic = ic->next)
1853 if (ic->op == CALL || ic->op == PCALL)
1857 fprintf(stderr,"found parameter push with no function call\n");
1861 /* if the registers have been saved already then
1863 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1866 /* find the registers in use at this time
1867 and push them away to safety */
1868 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1872 if (options.useXstack) {
1873 if (bitVectBitValue(rsave,R0_IDX))
1874 pic14_emitcode("mov","b,r0");
1875 pic14_emitcode("mov","r0,%s",spname);
1876 for (i = 0 ; i < pic14_nRegs ; i++) {
1877 if (bitVectBitValue(rsave,i)) {
1879 pic14_emitcode("mov","a,b");
1881 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1882 pic14_emitcode("movx","@r0,a");
1883 pic14_emitcode("inc","r0");
1886 pic14_emitcode("mov","%s,r0",spname);
1887 if (bitVectBitValue(rsave,R0_IDX))
1888 pic14_emitcode("mov","r0,b");
1890 for (i = 0 ; i < pic14_nRegs ; i++) {
1891 if (bitVectBitValue(rsave,i))
1892 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1895 dtype = operandType(IC_LEFT(ic));
1897 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1898 IFFUNC_ISISR(currFunc->type) &&
1901 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1904 /*-----------------------------------------------------------------*/
1905 /* unsaveRegisters - pop the pushed registers */
1906 /*-----------------------------------------------------------------*/
1907 static void unsaveRegisters (iCode *ic)
1912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1913 /* find the registers in use at this time
1914 and push them away to safety */
1915 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1918 if (options.useXstack) {
1919 pic14_emitcode("mov","r0,%s",spname);
1920 for (i = pic14_nRegs ; i >= 0 ; i--) {
1921 if (bitVectBitValue(rsave,i)) {
1922 pic14_emitcode("dec","r0");
1923 pic14_emitcode("movx","a,@r0");
1925 pic14_emitcode("mov","b,a");
1927 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1931 pic14_emitcode("mov","%s,r0",spname);
1932 if (bitVectBitValue(rsave,R0_IDX))
1933 pic14_emitcode("mov","r0,b");
1935 for (i = pic14_nRegs ; i >= 0 ; i--) {
1936 if (bitVectBitValue(rsave,i))
1937 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1943 /*-----------------------------------------------------------------*/
1945 /*-----------------------------------------------------------------*/
1946 static void pushSide(operand * oper, int size)
1950 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1952 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1953 if (AOP_TYPE(oper) != AOP_REG &&
1954 AOP_TYPE(oper) != AOP_DIR &&
1956 pic14_emitcode("mov","a,%s",l);
1957 pic14_emitcode("push","acc");
1959 pic14_emitcode("push","%s",l);
1964 /*-----------------------------------------------------------------*/
1965 /* assignResultValue - */
1966 /*-----------------------------------------------------------------*/
1967 static void assignResultValue(operand * oper)
1969 int size = AOP_SIZE(oper);
1971 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1973 if(!GpsuedoStkPtr) {
1974 /* The last byte in the assignment is in W */
1976 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1981 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1983 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1988 /*-----------------------------------------------------------------*/
1989 /* genIpush - genrate code for pushing this gets a little complex */
1990 /*-----------------------------------------------------------------*/
1991 static void genIpush (iCode *ic)
1994 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
1996 int size, offset = 0 ;
2000 /* if this is not a parm push : ie. it is spill push
2001 and spill push is always done on the local stack */
2002 if (!ic->parmPush) {
2004 /* and the item is spilt then do nothing */
2005 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2008 aopOp(IC_LEFT(ic),ic,FALSE);
2009 size = AOP_SIZE(IC_LEFT(ic));
2010 /* push it on the stack */
2012 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2017 pic14_emitcode("push","%s",l);
2022 /* this is a paramter push: in this case we call
2023 the routine to find the call and save those
2024 registers that need to be saved */
2027 /* then do the push */
2028 aopOp(IC_LEFT(ic),ic,FALSE);
2031 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2032 size = AOP_SIZE(IC_LEFT(ic));
2035 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2036 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2037 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2039 pic14_emitcode("mov","a,%s",l);
2040 pic14_emitcode("push","acc");
2042 pic14_emitcode("push","%s",l);
2045 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2049 /*-----------------------------------------------------------------*/
2050 /* genIpop - recover the registers: can happen only for spilling */
2051 /*-----------------------------------------------------------------*/
2052 static void genIpop (iCode *ic)
2054 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2059 /* if the temp was not pushed then */
2060 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2063 aopOp(IC_LEFT(ic),ic,FALSE);
2064 size = AOP_SIZE(IC_LEFT(ic));
2067 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2070 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2074 /*-----------------------------------------------------------------*/
2075 /* unsaverbank - restores the resgister bank from stack */
2076 /*-----------------------------------------------------------------*/
2077 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2079 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2087 if (options.useXstack) {
2089 r = getFreePtr(ic,&aop,FALSE);
2092 pic14_emitcode("mov","%s,_spx",r->name);
2093 pic14_emitcode("movx","a,@%s",r->name);
2094 pic14_emitcode("mov","psw,a");
2095 pic14_emitcode("dec","%s",r->name);
2098 pic14_emitcode ("pop","psw");
2101 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2102 if (options.useXstack) {
2103 pic14_emitcode("movx","a,@%s",r->name);
2104 //pic14_emitcode("mov","(%s+%d),a",
2105 // regspic14[i].base,8*bank+regspic14[i].offset);
2106 pic14_emitcode("dec","%s",r->name);
2109 pic14_emitcode("pop",""); //"(%s+%d)",
2110 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2113 if (options.useXstack) {
2115 pic14_emitcode("mov","_spx,%s",r->name);
2116 freeAsmop(NULL,aop,ic,TRUE);
2122 /*-----------------------------------------------------------------*/
2123 /* saverbank - saves an entire register bank on the stack */
2124 /*-----------------------------------------------------------------*/
2125 static void saverbank (int bank, iCode *ic, bool pushPsw)
2127 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2134 if (options.useXstack) {
2137 r = getFreePtr(ic,&aop,FALSE);
2138 pic14_emitcode("mov","%s,_spx",r->name);
2142 for (i = 0 ; i < pic14_nRegs ;i++) {
2143 if (options.useXstack) {
2144 pic14_emitcode("inc","%s",r->name);
2145 //pic14_emitcode("mov","a,(%s+%d)",
2146 // regspic14[i].base,8*bank+regspic14[i].offset);
2147 pic14_emitcode("movx","@%s,a",r->name);
2149 pic14_emitcode("push","");// "(%s+%d)",
2150 //regspic14[i].base,8*bank+regspic14[i].offset);
2154 if (options.useXstack) {
2155 pic14_emitcode("mov","a,psw");
2156 pic14_emitcode("movx","@%s,a",r->name);
2157 pic14_emitcode("inc","%s",r->name);
2158 pic14_emitcode("mov","_spx,%s",r->name);
2159 freeAsmop (NULL,aop,ic,TRUE);
2162 pic14_emitcode("push","psw");
2164 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2170 /*-----------------------------------------------------------------*/
2171 /* genCall - generates a call statement */
2172 /*-----------------------------------------------------------------*/
2173 static void genCall (iCode *ic)
2177 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2179 /* if caller saves & we have not saved then */
2183 /* if we are calling a function that is not using
2184 the same register bank then we need to save the
2185 destination registers on the stack */
2186 dtype = operandType(IC_LEFT(ic));
2188 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2189 IFFUNC_ISISR(currFunc->type) &&
2192 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2194 /* if send set is not empty the assign */
2197 /* For the Pic port, there is no data stack.
2198 * So parameters passed to functions are stored
2199 * in registers. (The pCode optimizer will get
2200 * rid of most of these :).
2202 int psuedoStkPtr=-1;
2203 int firstTimeThruLoop = 1;
2205 _G.sendSet = reverseSet(_G.sendSet);
2207 /* First figure how many parameters are getting passed */
2208 for (sic = setFirstItem(_G.sendSet) ; sic ;
2209 sic = setNextItem(_G.sendSet)) {
2211 aopOp(IC_LEFT(sic),sic,FALSE);
2212 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2213 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2216 for (sic = setFirstItem(_G.sendSet) ; sic ;
2217 sic = setNextItem(_G.sendSet)) {
2218 int size, offset = 0;
2220 aopOp(IC_LEFT(sic),sic,FALSE);
2221 size = AOP_SIZE(IC_LEFT(sic));
2225 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2226 AopType(AOP_TYPE(IC_LEFT(sic))));
2228 if(!firstTimeThruLoop) {
2229 /* If this is not the first time we've been through the loop
2230 * then we need to save the parameter in a temporary
2231 * register. The last byte of the last parameter is
2233 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2236 firstTimeThruLoop=0;
2238 //if (strcmp(l,fReturn[offset])) {
2240 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2241 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2242 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2244 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2249 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2254 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2255 OP_SYMBOL(IC_LEFT(ic))->rname :
2256 OP_SYMBOL(IC_LEFT(ic))->name));
2259 /* if we need assign a result value */
2260 if ((IS_ITEMP(IC_RESULT(ic)) &&
2261 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2262 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2263 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2266 aopOp(IC_RESULT(ic),ic,FALSE);
2269 assignResultValue(IC_RESULT(ic));
2271 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2272 AopType(AOP_TYPE(IC_RESULT(ic))));
2274 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2277 /* adjust the stack for parameters if
2279 if (ic->parmBytes) {
2281 if (ic->parmBytes > 3) {
2282 pic14_emitcode("mov","a,%s",spname);
2283 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2284 pic14_emitcode("mov","%s,a",spname);
2286 for ( i = 0 ; i < ic->parmBytes ;i++)
2287 pic14_emitcode("dec","%s",spname);
2291 /* if register bank was saved then pop them */
2293 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2295 /* if we hade saved some registers then unsave them */
2296 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2297 unsaveRegisters (ic);
2302 /*-----------------------------------------------------------------*/
2303 /* genPcall - generates a call by pointer statement */
2304 /*-----------------------------------------------------------------*/
2305 static void genPcall (iCode *ic)
2308 symbol *rlbl = newiTempLabel(NULL);
2311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2312 /* if caller saves & we have not saved then */
2316 /* if we are calling a function that is not using
2317 the same register bank then we need to save the
2318 destination registers on the stack */
2319 dtype = operandType(IC_LEFT(ic));
2321 IFFUNC_ISISR(currFunc->type) &&
2322 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2323 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2326 /* push the return address on to the stack */
2327 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2328 pic14_emitcode("push","acc");
2329 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2330 pic14_emitcode("push","acc");
2332 if (options.model == MODEL_FLAT24)
2334 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2335 pic14_emitcode("push","acc");
2338 /* now push the calling address */
2339 aopOp(IC_LEFT(ic),ic,FALSE);
2341 pushSide(IC_LEFT(ic), FPTRSIZE);
2343 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2345 /* if send set is not empty the assign */
2349 for (sic = setFirstItem(_G.sendSet) ; sic ;
2350 sic = setNextItem(_G.sendSet)) {
2351 int size, offset = 0;
2352 aopOp(IC_LEFT(sic),sic,FALSE);
2353 size = AOP_SIZE(IC_LEFT(sic));
2355 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2357 if (strcmp(l,fReturn[offset]))
2358 pic14_emitcode("mov","%s,%s",
2363 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2368 pic14_emitcode("ret","");
2369 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2372 /* if we need assign a result value */
2373 if ((IS_ITEMP(IC_RESULT(ic)) &&
2374 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2375 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2376 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2379 aopOp(IC_RESULT(ic),ic,FALSE);
2382 assignResultValue(IC_RESULT(ic));
2384 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2387 /* adjust the stack for parameters if
2389 if (ic->parmBytes) {
2391 if (ic->parmBytes > 3) {
2392 pic14_emitcode("mov","a,%s",spname);
2393 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2394 pic14_emitcode("mov","%s,a",spname);
2396 for ( i = 0 ; i < ic->parmBytes ;i++)
2397 pic14_emitcode("dec","%s",spname);
2401 /* if register bank was saved then unsave them */
2403 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2404 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2406 /* if we hade saved some registers then
2409 unsaveRegisters (ic);
2413 /*-----------------------------------------------------------------*/
2414 /* resultRemat - result is rematerializable */
2415 /*-----------------------------------------------------------------*/
2416 static int resultRemat (iCode *ic)
2418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2419 if (SKIP_IC(ic) || ic->op == IFX)
2422 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2423 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2424 if (sym->remat && !POINTER_SET(ic))
2431 #if defined(__BORLANDC__) || defined(_MSC_VER)
2432 #define STRCASECMP stricmp
2434 #define STRCASECMP strcasecmp
2437 /*-----------------------------------------------------------------*/
2438 /* inExcludeList - return 1 if the string is in exclude Reg list */
2439 /*-----------------------------------------------------------------*/
2440 static bool inExcludeList(char *s)
2442 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2447 if (options.excludeRegs[i] &&
2448 STRCASECMP(options.excludeRegs[i],"none") == 0)
2451 for ( i = 0 ; options.excludeRegs[i]; i++) {
2452 if (options.excludeRegs[i] &&
2453 STRCASECMP(s,options.excludeRegs[i]) == 0)
2460 /*-----------------------------------------------------------------*/
2461 /* genFunction - generated code for function entry */
2462 /*-----------------------------------------------------------------*/
2463 static void genFunction (iCode *ic)
2468 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2470 labelOffset += (max_key+4);
2474 /* create the function header */
2475 pic14_emitcode(";","-----------------------------------------");
2476 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2477 pic14_emitcode(";","-----------------------------------------");
2479 pic14_emitcode("","%s:",sym->rname);
2480 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2482 ftype = operandType(IC_LEFT(ic));
2484 /* if critical function then turn interrupts off */
2485 if (IFFUNC_ISCRITICAL(ftype))
2486 pic14_emitcode("clr","ea");
2488 /* here we need to generate the equates for the
2489 register bank if required */
2491 if (FUNC_REGBANK(ftype) != rbank) {
2494 rbank = FUNC_REGBANK(ftype);
2495 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2496 if (strcmp(regspic14[i].base,"0") == 0)
2497 pic14_emitcode("","%s = 0x%02x",
2499 8*rbank+regspic14[i].offset);
2501 pic14_emitcode ("","%s = %s + 0x%02x",
2504 8*rbank+regspic14[i].offset);
2509 /* if this is an interrupt service routine then
2510 save acc, b, dpl, dph */
2511 if (IFFUNC_ISISR(sym->type)) {
2513 if (!inExcludeList("acc"))
2514 pic14_emitcode ("push","acc");
2515 if (!inExcludeList("b"))
2516 pic14_emitcode ("push","b");
2517 if (!inExcludeList("dpl"))
2518 pic14_emitcode ("push","dpl");
2519 if (!inExcludeList("dph"))
2520 pic14_emitcode ("push","dph");
2521 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2523 pic14_emitcode ("push", "dpx");
2524 /* Make sure we're using standard DPTR */
2525 pic14_emitcode ("push", "dps");
2526 pic14_emitcode ("mov", "dps, #0x00");
2527 if (options.stack10bit)
2529 /* This ISR could conceivably use DPTR2. Better save it. */
2530 pic14_emitcode ("push", "dpl1");
2531 pic14_emitcode ("push", "dph1");
2532 pic14_emitcode ("push", "dpx1");
2535 /* if this isr has no bank i.e. is going to
2536 run with bank 0 , then we need to save more
2538 if (!FUNC_REGBANK(sym->type)) {
2540 /* if this function does not call any other
2541 function then we can be economical and
2542 save only those registers that are used */
2543 if (! IFFUNC_HASFCALL(sym->type)) {
2546 /* if any registers used */
2547 if (sym->regsUsed) {
2548 /* save the registers used */
2549 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2550 if (bitVectBitValue(sym->regsUsed,i) ||
2551 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2552 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2557 /* this function has a function call cannot
2558 determines register usage so we will have the
2560 saverbank(0,ic,FALSE);
2564 /* if callee-save to be used for this function
2565 then save the registers being used in this function */
2566 if (IFFUNC_CALLEESAVES(sym->type)) {
2569 /* if any registers used */
2570 if (sym->regsUsed) {
2571 /* save the registers used */
2572 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2573 if (bitVectBitValue(sym->regsUsed,i) ||
2574 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2575 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2583 /* set the register bank to the desired value */
2584 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2585 pic14_emitcode("push","psw");
2586 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2589 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2591 if (options.useXstack) {
2592 pic14_emitcode("mov","r0,%s",spname);
2593 pic14_emitcode("mov","a,_bp");
2594 pic14_emitcode("movx","@r0,a");
2595 pic14_emitcode("inc","%s",spname);
2599 /* set up the stack */
2600 pic14_emitcode ("push","_bp"); /* save the callers stack */
2602 pic14_emitcode ("mov","_bp,%s",spname);
2605 /* adjust the stack for the function */
2610 werror(W_STACK_OVERFLOW,sym->name);
2612 if (i > 3 && sym->recvSize < 4) {
2614 pic14_emitcode ("mov","a,sp");
2615 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2616 pic14_emitcode ("mov","sp,a");
2621 pic14_emitcode("inc","sp");
2626 pic14_emitcode ("mov","a,_spx");
2627 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2628 pic14_emitcode ("mov","_spx,a");
2633 /*-----------------------------------------------------------------*/
2634 /* genEndFunction - generates epilogue for functions */
2635 /*-----------------------------------------------------------------*/
2636 static void genEndFunction (iCode *ic)
2638 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2640 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2642 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2644 pic14_emitcode ("mov","%s,_bp",spname);
2647 /* if use external stack but some variables were
2648 added to the local stack then decrement the
2650 if (options.useXstack && sym->stack) {
2651 pic14_emitcode("mov","a,sp");
2652 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2653 pic14_emitcode("mov","sp,a");
2657 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2658 if (options.useXstack) {
2659 pic14_emitcode("mov","r0,%s",spname);
2660 pic14_emitcode("movx","a,@r0");
2661 pic14_emitcode("mov","_bp,a");
2662 pic14_emitcode("dec","%s",spname);
2666 pic14_emitcode ("pop","_bp");
2670 /* restore the register bank */
2671 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2672 pic14_emitcode ("pop","psw");
2674 if (IFFUNC_ISISR(sym->type)) {
2676 /* now we need to restore the registers */
2677 /* if this isr has no bank i.e. is going to
2678 run with bank 0 , then we need to save more
2680 if (!FUNC_REGBANK(sym->type)) {
2682 /* if this function does not call any other
2683 function then we can be economical and
2684 save only those registers that are used */
2685 if (! IFFUNC_HASFCALL(sym->type)) {
2688 /* if any registers used */
2689 if (sym->regsUsed) {
2690 /* save the registers used */
2691 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2692 if (bitVectBitValue(sym->regsUsed,i) ||
2693 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2694 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2699 /* this function has a function call cannot
2700 determines register usage so we will have the
2702 unsaverbank(0,ic,FALSE);
2706 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2708 if (options.stack10bit)
2710 pic14_emitcode ("pop", "dpx1");
2711 pic14_emitcode ("pop", "dph1");
2712 pic14_emitcode ("pop", "dpl1");
2714 pic14_emitcode ("pop", "dps");
2715 pic14_emitcode ("pop", "dpx");
2717 if (!inExcludeList("dph"))
2718 pic14_emitcode ("pop","dph");
2719 if (!inExcludeList("dpl"))
2720 pic14_emitcode ("pop","dpl");
2721 if (!inExcludeList("b"))
2722 pic14_emitcode ("pop","b");
2723 if (!inExcludeList("acc"))
2724 pic14_emitcode ("pop","acc");
2726 if (IFFUNC_ISCRITICAL(sym->type))
2727 pic14_emitcode("setb","ea");
2729 /* if debug then send end of function */
2730 /* if (options.debug && currFunc) { */
2733 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2734 FileBaseName(ic->filename),currFunc->lastLine,
2735 ic->level,ic->block);
2736 if (IS_STATIC(currFunc->etype))
2737 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2739 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2743 pic14_emitcode ("reti","");
2746 if (IFFUNC_ISCRITICAL(sym->type))
2747 pic14_emitcode("setb","ea");
2749 if (IFFUNC_CALLEESAVES(sym->type)) {
2752 /* if any registers used */
2753 if (sym->regsUsed) {
2754 /* save the registers used */
2755 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2756 if (bitVectBitValue(sym->regsUsed,i) ||
2757 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2758 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2764 /* if debug then send end of function */
2767 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2768 FileBaseName(ic->filename),currFunc->lastLine,
2769 ic->level,ic->block);
2770 if (IS_STATIC(currFunc->etype))
2771 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2773 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2777 pic14_emitcode ("return","");
2778 emitpcodeNULLop(POC_RETURN);
2780 /* Mark the end of a function */
2781 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2786 /*-----------------------------------------------------------------*/
2787 /* genRet - generate code for return statement */
2788 /*-----------------------------------------------------------------*/
2789 static void genRet (iCode *ic)
2791 int size,offset = 0 , pushed = 0;
2793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2794 /* if we have no return value then
2795 just generate the "ret" */
2799 /* we have something to return then
2800 move the return value into place */
2801 aopOp(IC_LEFT(ic),ic,FALSE);
2802 size = AOP_SIZE(IC_LEFT(ic));
2806 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2808 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2810 pic14_emitcode("push","%s",l);
2813 l = aopGet(AOP(IC_LEFT(ic)),offset,
2815 if (strcmp(fReturn[offset],l)) {
2816 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2817 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2818 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2820 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2823 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2824 pic14_emitcode("movwf","%s",fReturn[offset]);
2834 if (strcmp(fReturn[pushed],"a"))
2835 pic14_emitcode("pop",fReturn[pushed]);
2837 pic14_emitcode("pop","acc");
2840 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2843 /* generate a jump to the return label
2844 if the next is not the return statement */
2845 if (!(ic->next && ic->next->op == LABEL &&
2846 IC_LABEL(ic->next) == returnLabel)) {
2848 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2849 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2854 /*-----------------------------------------------------------------*/
2855 /* genLabel - generates a label */
2856 /*-----------------------------------------------------------------*/
2857 static void genLabel (iCode *ic)
2859 /* special case never generate */
2860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2861 if (IC_LABEL(ic) == entryLabel)
2864 emitpLabel(IC_LABEL(ic)->key);
2865 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2868 /*-----------------------------------------------------------------*/
2869 /* genGoto - generates a goto */
2870 /*-----------------------------------------------------------------*/
2872 static void genGoto (iCode *ic)
2874 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2875 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2879 /*-----------------------------------------------------------------*/
2880 /* genMultbits :- multiplication of bits */
2881 /*-----------------------------------------------------------------*/
2882 static void genMultbits (operand *left,
2886 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2888 if(!pic14_sameRegs(AOP(result),AOP(right)))
2889 emitpcode(POC_BSF, popGet(AOP(result),0));
2891 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2892 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2893 emitpcode(POC_BCF, popGet(AOP(result),0));
2898 /*-----------------------------------------------------------------*/
2899 /* genMultOneByte : 8 bit multiplication & division */
2900 /*-----------------------------------------------------------------*/
2901 static void genMultOneByte (operand *left,
2905 sym_link *opetype = operandType(result);
2910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2911 DEBUGpic14_AopType(__LINE__,left,right,result);
2913 /* (if two literals, the value is computed before) */
2914 /* if one literal, literal on the right */
2915 if (AOP_TYPE(left) == AOP_LIT){
2921 size = AOP_SIZE(result);
2922 /* signed or unsigned */
2923 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2924 l = aopGet(AOP(left),0,FALSE,FALSE);
2926 pic14_emitcode("mul","ab");
2927 /* if result size = 1, mul signed = mul unsigned */
2928 aopPut(AOP(result),"a",0);
2930 if (SPEC_USIGN(opetype)){
2931 aopPut(AOP(result),"b",1);
2933 /* for filling the MSBs */
2934 pic14_emitcode("clr","a");
2937 pic14_emitcode("mov","a,b");
2939 /* adjust the MSB if left or right neg */
2941 /* if one literal */
2942 if (AOP_TYPE(right) == AOP_LIT){
2943 /* AND literal negative */
2944 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2945 /* adjust MSB (c==0 after mul) */
2946 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2950 lbl = newiTempLabel(NULL);
2951 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2952 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2953 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2954 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2955 lbl = newiTempLabel(NULL);
2956 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2957 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2958 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2961 lbl = newiTempLabel(NULL);
2962 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2963 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2964 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2965 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2966 lbl = newiTempLabel(NULL);
2967 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2968 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2969 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2971 aopPut(AOP(result),"a",1);
2974 pic14_emitcode("rlc","a");
2975 pic14_emitcode("subb","a,acc");
2982 aopPut(AOP(result),"a",offset++);
2986 /*-----------------------------------------------------------------*/
2987 /* genMult - generates code for multiplication */
2988 /*-----------------------------------------------------------------*/
2989 static void genMult (iCode *ic)
2991 operand *left = IC_LEFT(ic);
2992 operand *right = IC_RIGHT(ic);
2993 operand *result= IC_RESULT(ic);
2995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2996 /* assign the amsops */
2997 aopOp (left,ic,FALSE);
2998 aopOp (right,ic,FALSE);
2999 aopOp (result,ic,TRUE);
3001 DEBUGpic14_AopType(__LINE__,left,right,result);
3003 /* special cases first */
3005 if (AOP_TYPE(left) == AOP_CRY &&
3006 AOP_TYPE(right)== AOP_CRY) {
3007 genMultbits(left,right,result);
3011 /* if both are of size == 1 */
3012 if (AOP_SIZE(left) == 1 &&
3013 AOP_SIZE(right) == 1 ) {
3014 genMultOneByte(left,right,result);
3018 /* should have been converted to function call */
3022 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3023 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3024 freeAsmop(result,NULL,ic,TRUE);
3027 /*-----------------------------------------------------------------*/
3028 /* genDivbits :- division of bits */
3029 /*-----------------------------------------------------------------*/
3030 static void genDivbits (operand *left,
3037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3038 /* the result must be bit */
3039 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3040 l = aopGet(AOP(left),0,FALSE,FALSE);
3044 pic14_emitcode("div","ab");
3045 pic14_emitcode("rrc","a");
3046 aopPut(AOP(result),"c",0);
3049 /*-----------------------------------------------------------------*/
3050 /* genDivOneByte : 8 bit division */
3051 /*-----------------------------------------------------------------*/
3052 static void genDivOneByte (operand *left,
3056 sym_link *opetype = operandType(result);
3061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3062 size = AOP_SIZE(result) - 1;
3064 /* signed or unsigned */
3065 if (SPEC_USIGN(opetype)) {
3066 /* unsigned is easy */
3067 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3068 l = aopGet(AOP(left),0,FALSE,FALSE);
3070 pic14_emitcode("div","ab");
3071 aopPut(AOP(result),"a",0);
3073 aopPut(AOP(result),zero,offset++);
3077 /* signed is a little bit more difficult */
3079 /* save the signs of the operands */
3080 l = aopGet(AOP(left),0,FALSE,FALSE);
3082 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3083 pic14_emitcode("push","acc"); /* save it on the stack */
3085 /* now sign adjust for both left & right */
3086 l = aopGet(AOP(right),0,FALSE,FALSE);
3088 lbl = newiTempLabel(NULL);
3089 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3090 pic14_emitcode("cpl","a");
3091 pic14_emitcode("inc","a");
3092 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3093 pic14_emitcode("mov","b,a");
3095 /* sign adjust left side */
3096 l = aopGet(AOP(left),0,FALSE,FALSE);
3099 lbl = newiTempLabel(NULL);
3100 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3101 pic14_emitcode("cpl","a");
3102 pic14_emitcode("inc","a");
3103 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3105 /* now the division */
3106 pic14_emitcode("div","ab");
3107 /* we are interested in the lower order
3109 pic14_emitcode("mov","b,a");
3110 lbl = newiTempLabel(NULL);
3111 pic14_emitcode("pop","acc");
3112 /* if there was an over flow we don't
3113 adjust the sign of the result */
3114 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3115 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3117 pic14_emitcode("clr","a");
3118 pic14_emitcode("subb","a,b");
3119 pic14_emitcode("mov","b,a");
3120 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3122 /* now we are done */
3123 aopPut(AOP(result),"b",0);
3125 pic14_emitcode("mov","c,b.7");
3126 pic14_emitcode("subb","a,acc");
3129 aopPut(AOP(result),"a",offset++);
3133 /*-----------------------------------------------------------------*/
3134 /* genDiv - generates code for division */
3135 /*-----------------------------------------------------------------*/
3136 static void genDiv (iCode *ic)
3138 operand *left = IC_LEFT(ic);
3139 operand *right = IC_RIGHT(ic);
3140 operand *result= IC_RESULT(ic);
3142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3143 /* assign the amsops */
3144 aopOp (left,ic,FALSE);
3145 aopOp (right,ic,FALSE);
3146 aopOp (result,ic,TRUE);
3148 /* special cases first */
3150 if (AOP_TYPE(left) == AOP_CRY &&
3151 AOP_TYPE(right)== AOP_CRY) {
3152 genDivbits(left,right,result);
3156 /* if both are of size == 1 */
3157 if (AOP_SIZE(left) == 1 &&
3158 AOP_SIZE(right) == 1 ) {
3159 genDivOneByte(left,right,result);
3163 /* should have been converted to function call */
3166 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3167 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3168 freeAsmop(result,NULL,ic,TRUE);
3171 /*-----------------------------------------------------------------*/
3172 /* genModbits :- modulus of bits */
3173 /*-----------------------------------------------------------------*/
3174 static void genModbits (operand *left,
3181 /* the result must be bit */
3182 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3183 l = aopGet(AOP(left),0,FALSE,FALSE);
3187 pic14_emitcode("div","ab");
3188 pic14_emitcode("mov","a,b");
3189 pic14_emitcode("rrc","a");
3190 aopPut(AOP(result),"c",0);
3193 /*-----------------------------------------------------------------*/
3194 /* genModOneByte : 8 bit modulus */
3195 /*-----------------------------------------------------------------*/
3196 static void genModOneByte (operand *left,
3200 sym_link *opetype = operandType(result);
3204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3205 /* signed or unsigned */
3206 if (SPEC_USIGN(opetype)) {
3207 /* unsigned is easy */
3208 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3209 l = aopGet(AOP(left),0,FALSE,FALSE);
3211 pic14_emitcode("div","ab");
3212 aopPut(AOP(result),"b",0);
3216 /* signed is a little bit more difficult */
3218 /* save the signs of the operands */
3219 l = aopGet(AOP(left),0,FALSE,FALSE);
3222 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3223 pic14_emitcode("push","acc"); /* save it on the stack */
3225 /* now sign adjust for both left & right */
3226 l = aopGet(AOP(right),0,FALSE,FALSE);
3229 lbl = newiTempLabel(NULL);
3230 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3231 pic14_emitcode("cpl","a");
3232 pic14_emitcode("inc","a");
3233 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3234 pic14_emitcode("mov","b,a");
3236 /* sign adjust left side */
3237 l = aopGet(AOP(left),0,FALSE,FALSE);
3240 lbl = newiTempLabel(NULL);
3241 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3242 pic14_emitcode("cpl","a");
3243 pic14_emitcode("inc","a");
3244 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3246 /* now the multiplication */
3247 pic14_emitcode("div","ab");
3248 /* we are interested in the lower order
3250 lbl = newiTempLabel(NULL);
3251 pic14_emitcode("pop","acc");
3252 /* if there was an over flow we don't
3253 adjust the sign of the result */
3254 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3255 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3257 pic14_emitcode("clr","a");
3258 pic14_emitcode("subb","a,b");
3259 pic14_emitcode("mov","b,a");
3260 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3262 /* now we are done */
3263 aopPut(AOP(result),"b",0);
3267 /*-----------------------------------------------------------------*/
3268 /* genMod - generates code for division */
3269 /*-----------------------------------------------------------------*/
3270 static void genMod (iCode *ic)
3272 operand *left = IC_LEFT(ic);
3273 operand *right = IC_RIGHT(ic);
3274 operand *result= IC_RESULT(ic);
3276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3277 /* assign the amsops */
3278 aopOp (left,ic,FALSE);
3279 aopOp (right,ic,FALSE);
3280 aopOp (result,ic,TRUE);
3282 /* special cases first */
3284 if (AOP_TYPE(left) == AOP_CRY &&
3285 AOP_TYPE(right)== AOP_CRY) {
3286 genModbits(left,right,result);
3290 /* if both are of size == 1 */
3291 if (AOP_SIZE(left) == 1 &&
3292 AOP_SIZE(right) == 1 ) {
3293 genModOneByte(left,right,result);
3297 /* should have been converted to function call */
3301 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3302 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3303 freeAsmop(result,NULL,ic,TRUE);
3306 /*-----------------------------------------------------------------*/
3307 /* genIfxJump :- will create a jump depending on the ifx */
3308 /*-----------------------------------------------------------------*/
3310 note: May need to add parameter to indicate when a variable is in bit space.
3312 static void genIfxJump (iCode *ic, char *jval)
3315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3316 /* if true label then we jump if condition
3318 if ( IC_TRUE(ic) ) {
3320 if(strcmp(jval,"a") == 0)
3322 else if (strcmp(jval,"c") == 0)
3325 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3326 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3329 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3330 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3334 /* false label is present */
3335 if(strcmp(jval,"a") == 0)
3337 else if (strcmp(jval,"c") == 0)
3340 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3341 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3344 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3345 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3350 /* mark the icode as generated */
3354 /*-----------------------------------------------------------------*/
3356 /*-----------------------------------------------------------------*/
3357 static void genSkip(iCode *ifx,int status_bit)
3362 if ( IC_TRUE(ifx) ) {
3363 switch(status_bit) {
3378 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3379 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3383 switch(status_bit) {
3397 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3398 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3404 /*-----------------------------------------------------------------*/
3406 /*-----------------------------------------------------------------*/
3407 static void genSkipc(resolvedIfx *rifx)
3417 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3418 rifx->generated = 1;
3421 /*-----------------------------------------------------------------*/
3423 /*-----------------------------------------------------------------*/
3424 static void genSkipz2(resolvedIfx *rifx)
3434 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3435 rifx->generated = 1;
3438 /*-----------------------------------------------------------------*/
3440 /*-----------------------------------------------------------------*/
3441 static void genSkipz(iCode *ifx, int condition)
3452 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3454 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3457 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3459 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3462 /*-----------------------------------------------------------------*/
3464 /*-----------------------------------------------------------------*/
3465 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3471 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3473 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3476 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3477 rifx->generated = 1;
3479 /*-----------------------------------------------------------------*/
3480 /* genCmp :- greater or less than comparison */
3481 /*-----------------------------------------------------------------*/
3482 static void genCmp (operand *left,operand *right,
3483 operand *result, iCode *ifx, int sign)
3485 int size, offset = 0 ;
3486 unsigned long lit = 0L,i = 0;
3489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3491 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3492 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3495 resolveIfx(&rIfx,ifx);
3497 /* if left & right are bit variables */
3498 if (AOP_TYPE(left) == AOP_CRY &&
3499 AOP_TYPE(right) == AOP_CRY ) {
3500 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3501 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3503 /* subtract right from left if at the
3504 end the carry flag is set then we know that
3505 left is greater than right */
3506 size = max(AOP_SIZE(left),AOP_SIZE(right));
3508 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3509 if((size == 1) && !sign &&
3510 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3511 symbol *lbl = newiTempLabel(NULL);
3512 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3513 aopGet(AOP(left),offset,FALSE,FALSE),
3514 aopGet(AOP(right),offset,FALSE,FALSE),
3516 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3519 symbol *lbl = newiTempLabel(NULL);
3521 symbol *truelbl = newiTempLabel(NULL);
3524 if(AOP_TYPE(right) == AOP_LIT) {
3526 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3528 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3532 if(lit == 0 && sign == 0) {
3533 /* no need to compare to 0...*/
3534 if(ifx) ifx->generated = 1;
3541 i = (lit >> (size*8)) & 0xff;
3542 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3547 genSkipCond(&rIfx,left,0,7);
3550 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3554 emitpcode(POC_ADDLW, popGetLit(0x80));
3555 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3557 emitpcode(POC_ADDLW, popGetLit(i));
3562 if(ifx) ifx->generated = 1;
3569 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3574 i = (lit >> (size*8)) & 0xff;
3576 /* handle the first byte differently in signed compares */
3578 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3579 emitpcode(POC_ADDLW, popGetLit(0x80));
3580 emitpcode(POC_ADDLW, popGetLit(((-i)&0xff) ^ 0x80));
3583 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3588 emitpcode(POC_MOVLW, popGetLit(i));
3589 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3592 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3596 emitpLabel(lbl->key);
3599 emitpLabel(truelbl->key);
3601 if(ifx) ifx->generated = 1;
3607 if(AOP_TYPE(left) == AOP_LIT) {
3608 //symbol *lbl = newiTempLabel(NULL);
3610 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3612 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3615 if((lit == 0)&& (sign==0)) {
3618 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3620 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3622 if(ifx) ifx->generated = 1;
3629 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3630 emitpcode(POC_ADDLW, popGetLit(0x80));
3631 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3632 rIfx.condition ^= 1;
3635 genSkipCond(&rIfx,right,0,7);
3640 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3641 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3643 rIfx.condition ^= 1;
3646 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3654 i = (lit >> (size*8)) & 0xff;
3657 /* Handle first byte of compare differently */
3659 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3662 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3663 emitpcode(POC_ADDLW, popGetLit(0x80));
3664 emitpcode(POC_SUBLW, popGetLit( (i & 0xff) ^ 0x80));
3665 //rIfx.condition ^= 1;
3668 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3670 rIfx.condition ^= 1;
3671 genSkipCond(&rIfx,right,size,7);
3672 rIfx.condition ^= 1;
3679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3680 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3681 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3683 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3686 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
3687 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3695 emitpLabel(lbl->key);
3697 rIfx.condition ^= 1;
3702 emitpLabel(truelbl->key);
3703 if(ifx) ifx->generated = 1;
3707 /* Compare two variables */
3709 DEBUGpic14_emitcode(";sign","%d",sign);
3713 /* Sigh. thus sucks... */
3715 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3716 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
3717 emitpcode(POC_MOVLW, popGetLit(0x80));
3718 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
3719 emitpcode(POC_XORFW, popGet(AOP(right),size));
3720 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
3722 /* Signed char comparison */
3723 /* Special thanks to Nikolai Golovchenko for this snippet */
3724 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3725 emitpcode(POC_SUBFW, popGet(AOP(left),0));
3726 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
3727 emitpcode(POC_XORFW, popGet(AOP(left),0));
3728 emitpcode(POC_XORFW, popGet(AOP(right),0));
3729 emitpcode(POC_ADDLW, popGetLit(0x80));
3731 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3734 if(ifx) ifx->generated = 1;
3740 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3741 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3745 /* The rest of the bytes of a multi-byte compare */
3749 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3752 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3753 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3758 emitpLabel(lbl->key);
3760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3762 if(ifx) ifx->generated = 1;
3769 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3770 pic14_outBitC(result);
3772 /* if the result is used in the next
3773 ifx conditional branch then generate
3774 code a little differently */
3776 genIfxJump (ifx,"c");
3778 pic14_outBitC(result);
3779 /* leave the result in acc */
3784 /*-----------------------------------------------------------------*/
3785 /* genCmpGt :- greater than comparison */
3786 /*-----------------------------------------------------------------*/
3787 static void genCmpGt (iCode *ic, iCode *ifx)
3789 operand *left, *right, *result;
3790 sym_link *letype , *retype;
3793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3795 right= IC_RIGHT(ic);
3796 result = IC_RESULT(ic);
3798 letype = getSpec(operandType(left));
3799 retype =getSpec(operandType(right));
3800 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3801 /* assign the amsops */
3802 aopOp (left,ic,FALSE);
3803 aopOp (right,ic,FALSE);
3804 aopOp (result,ic,TRUE);
3806 genCmp(right, left, result, ifx, sign);
3808 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3809 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3810 freeAsmop(result,NULL,ic,TRUE);
3813 /*-----------------------------------------------------------------*/
3814 /* genCmpLt - less than comparisons */
3815 /*-----------------------------------------------------------------*/
3816 static void genCmpLt (iCode *ic, iCode *ifx)
3818 operand *left, *right, *result;
3819 sym_link *letype , *retype;
3822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3824 right= IC_RIGHT(ic);
3825 result = IC_RESULT(ic);
3827 letype = getSpec(operandType(left));
3828 retype =getSpec(operandType(right));
3829 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3831 /* assign the amsops */
3832 aopOp (left,ic,FALSE);
3833 aopOp (right,ic,FALSE);
3834 aopOp (result,ic,TRUE);
3836 genCmp(left, right, result, ifx, sign);
3838 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3839 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3840 freeAsmop(result,NULL,ic,TRUE);
3843 /*-----------------------------------------------------------------*/
3844 /* genc16bit2lit - compare a 16 bit value to a literal */
3845 /*-----------------------------------------------------------------*/
3846 static void genc16bit2lit(operand *op, int lit, int offset)
3850 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3851 if( (lit&0xff) == 0)
3856 switch( BYTEofLONG(lit,i)) {
3858 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
3861 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
3864 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
3867 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
3868 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3873 switch( BYTEofLONG(lit,i)) {
3875 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
3879 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
3883 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
3886 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3888 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
3894 /*-----------------------------------------------------------------*/
3895 /* gencjneshort - compare and jump if not equal */
3896 /*-----------------------------------------------------------------*/
3897 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
3899 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3904 unsigned long lit = 0L;
3905 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3906 DEBUGpic14_AopType(__LINE__,left,right,NULL);
3908 resolveIfx(&rIfx,ifx);
3909 lbl = newiTempLabel(NULL);
3912 /* if the left side is a literal or
3913 if the right is in a pointer register and left
3915 if ((AOP_TYPE(left) == AOP_LIT) ||
3916 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3921 if(AOP_TYPE(right) == AOP_LIT)
3922 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3924 /* if the right side is a literal then anything goes */
3925 if (AOP_TYPE(right) == AOP_LIT &&
3926 AOP_TYPE(left) != AOP_DIR ) {
3929 genc16bit2lit(left, lit, 0);
3931 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3936 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3937 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3939 emitpcode(POC_MOVF,popGet(AOP(left),offset));
3943 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3951 /* if the right side is in a register or in direct space or
3952 if the left is a pointer register & right is not */
3953 else if (AOP_TYPE(right) == AOP_REG ||
3954 AOP_TYPE(right) == AOP_DIR ||
3955 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3956 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3959 genc16bit2lit(left, lit, 0);
3961 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3966 if((AOP_TYPE(left) == AOP_DIR) &&
3967 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3969 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3970 emitpcode(POC_XORFW,popGet(AOP(right),offset));
3972 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3974 switch (lit & 0xff) {
3976 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3979 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
3980 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3984 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
3985 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3989 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3990 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3995 emitpcode(POC_MOVF,popGet(AOP(left),offset));
3998 if(AOP_TYPE(result) == AOP_CRY) {
3999 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4004 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4006 /* fix me. probably need to check result size too */
4007 emitpcode(POC_CLRF,popGet(AOP(result),0));
4012 emitpcode(POC_INCF,popGet(AOP(result),0));
4022 } else if(AOP_TYPE(right) == AOP_REG &&
4023 AOP_TYPE(left) != AOP_DIR){
4026 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4027 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4028 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4033 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4038 /* right is a pointer reg need both a & b */
4040 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4042 pic14_emitcode("mov","b,%s",l);
4043 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4044 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4048 emitpLabel(lbl->key);
4055 /*-----------------------------------------------------------------*/
4056 /* gencjne - compare and jump if not equal */
4057 /*-----------------------------------------------------------------*/
4058 static void gencjne(operand *left, operand *right, iCode *ifx)
4060 symbol *tlbl = newiTempLabel(NULL);
4062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4063 gencjneshort(left, right, lbl);
4065 pic14_emitcode("mov","a,%s",one);
4066 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4067 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4068 pic14_emitcode("clr","a");
4069 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4071 emitpLabel(lbl->key);
4072 emitpLabel(tlbl->key);
4077 /*-----------------------------------------------------------------*/
4078 /* genCmpEq - generates code for equal to */
4079 /*-----------------------------------------------------------------*/
4080 static void genCmpEq (iCode *ic, iCode *ifx)
4082 operand *left, *right, *result;
4083 unsigned long lit = 0L;
4086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4089 DEBUGpic14_emitcode ("; ifx is non-null","");
4091 DEBUGpic14_emitcode ("; ifx is null","");
4093 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4094 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4095 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4097 size = max(AOP_SIZE(left),AOP_SIZE(right));
4099 DEBUGpic14_AopType(__LINE__,left,right,result);
4101 /* if literal, literal on the right or
4102 if the right is in a pointer register and left
4104 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4105 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4106 operand *t = IC_RIGHT(ic);
4107 IC_RIGHT(ic) = IC_LEFT(ic);
4111 if(ifx && !AOP_SIZE(result)){
4113 /* if they are both bit variables */
4114 if (AOP_TYPE(left) == AOP_CRY &&
4115 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4116 if(AOP_TYPE(right) == AOP_LIT){
4117 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4119 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4120 pic14_emitcode("cpl","c");
4121 } else if(lit == 1L) {
4122 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4124 pic14_emitcode("clr","c");
4126 /* AOP_TYPE(right) == AOP_CRY */
4128 symbol *lbl = newiTempLabel(NULL);
4129 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4130 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4131 pic14_emitcode("cpl","c");
4132 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4134 /* if true label then we jump if condition
4136 tlbl = newiTempLabel(NULL);
4137 if ( IC_TRUE(ifx) ) {
4138 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4139 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4141 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4142 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4144 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4147 /* They're not both bit variables. Is the right a literal? */
4148 if(AOP_TYPE(right) == AOP_LIT) {
4149 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4155 switch(lit & 0xff) {
4157 if ( IC_TRUE(ifx) ) {
4158 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4160 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4162 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4163 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4167 if ( IC_TRUE(ifx) ) {
4168 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4170 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4172 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4173 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4177 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4179 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4184 /* end of size == 1 */
4188 genc16bit2lit(left,lit,offset);
4191 /* end of size == 2 */
4196 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4197 emitpcode(POC_IORFW,popGet(AOP(left),1));
4198 emitpcode(POC_IORFW,popGet(AOP(left),2));
4199 emitpcode(POC_IORFW,popGet(AOP(left),3));
4203 /* search for patterns that can be optimized */
4205 genc16bit2lit(left,lit,0);
4208 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4210 genc16bit2lit(left,lit,2);
4212 emitpcode(POC_IORFW,popGet(AOP(left),2));
4213 emitpcode(POC_IORFW,popGet(AOP(left),3));
4226 } else if(AOP_TYPE(right) == AOP_CRY ) {
4227 /* we know the left is not a bit, but that the right is */
4228 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4229 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4230 popGet(AOP(right),offset));
4231 emitpcode(POC_XORLW,popGetLit(1));
4233 /* if the two are equal, then W will be 0 and the Z bit is set
4234 * we could test Z now, or go ahead and check the high order bytes if
4235 * the variable we're comparing is larger than a byte. */
4238 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4240 if ( IC_TRUE(ifx) ) {
4242 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4243 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4246 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4247 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4251 /* They're both variables that are larger than bits */
4254 tlbl = newiTempLabel(NULL);
4257 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4258 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4260 if ( IC_TRUE(ifx) ) {
4263 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4264 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4267 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4268 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4272 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4273 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4277 if(s>1 && IC_TRUE(ifx)) {
4278 emitpLabel(tlbl->key);
4279 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4283 /* mark the icode as generated */
4288 /* if they are both bit variables */
4289 if (AOP_TYPE(left) == AOP_CRY &&
4290 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4291 if(AOP_TYPE(right) == AOP_LIT){
4292 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4294 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4295 pic14_emitcode("cpl","c");
4296 } else if(lit == 1L) {
4297 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4299 pic14_emitcode("clr","c");
4301 /* AOP_TYPE(right) == AOP_CRY */
4303 symbol *lbl = newiTempLabel(NULL);
4304 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4305 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4306 pic14_emitcode("cpl","c");
4307 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4310 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4311 pic14_outBitC(result);
4315 genIfxJump (ifx,"c");
4318 /* if the result is used in an arithmetic operation
4319 then put the result in place */
4320 pic14_outBitC(result);
4323 gencjne(left,right,result,ifx);
4326 gencjne(left,right,newiTempLabel(NULL));
4328 if(IC_TRUE(ifx)->key)
4329 gencjne(left,right,IC_TRUE(ifx)->key);
4331 gencjne(left,right,IC_FALSE(ifx)->key);
4335 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4336 aopPut(AOP(result),"a",0);
4341 genIfxJump (ifx,"a");
4345 /* if the result is used in an arithmetic operation
4346 then put the result in place */
4348 if (AOP_TYPE(result) != AOP_CRY)
4349 pic14_outAcc(result);
4351 /* leave the result in acc */
4355 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4356 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4357 freeAsmop(result,NULL,ic,TRUE);
4360 /*-----------------------------------------------------------------*/
4361 /* ifxForOp - returns the icode containing the ifx for operand */
4362 /*-----------------------------------------------------------------*/
4363 static iCode *ifxForOp ( operand *op, iCode *ic )
4365 /* if true symbol then needs to be assigned */
4366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4367 if (IS_TRUE_SYMOP(op))
4370 /* if this has register type condition and
4371 the next instruction is ifx with the same operand
4372 and live to of the operand is upto the ifx only then */
4374 ic->next->op == IFX &&
4375 IC_COND(ic->next)->key == op->key &&
4376 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4380 ic->next->op == IFX &&
4381 IC_COND(ic->next)->key == op->key) {
4382 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4386 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4388 ic->next->op == IFX)
4389 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4392 ic->next->op == IFX &&
4393 IC_COND(ic->next)->key == op->key) {
4394 DEBUGpic14_emitcode ("; "," key is okay");
4395 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4396 OP_SYMBOL(op)->liveTo,
4403 /*-----------------------------------------------------------------*/
4404 /* genAndOp - for && operation */
4405 /*-----------------------------------------------------------------*/
4406 static void genAndOp (iCode *ic)
4408 operand *left,*right, *result;
4411 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4412 /* note here that && operations that are in an
4413 if statement are taken away by backPatchLabels
4414 only those used in arthmetic operations remain */
4415 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4416 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4417 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4419 /* if both are bit variables */
4420 if (AOP_TYPE(left) == AOP_CRY &&
4421 AOP_TYPE(right) == AOP_CRY ) {
4422 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4423 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4424 pic14_outBitC(result);
4426 tlbl = newiTempLabel(NULL);
4427 pic14_toBoolean(left);
4428 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4429 pic14_toBoolean(right);
4430 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4431 pic14_outBitAcc(result);
4434 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4435 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4436 freeAsmop(result,NULL,ic,TRUE);
4440 /*-----------------------------------------------------------------*/
4441 /* genOrOp - for || operation */
4442 /*-----------------------------------------------------------------*/
4445 modified this code, but it doesn't appear to ever get called
4448 static void genOrOp (iCode *ic)
4450 operand *left,*right, *result;
4453 /* note here that || operations that are in an
4454 if statement are taken away by backPatchLabels
4455 only those used in arthmetic operations remain */
4456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4457 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4458 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4459 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4461 DEBUGpic14_AopType(__LINE__,left,right,result);
4463 /* if both are bit variables */
4464 if (AOP_TYPE(left) == AOP_CRY &&
4465 AOP_TYPE(right) == AOP_CRY ) {
4466 pic14_emitcode("clrc","");
4467 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4468 AOP(left)->aopu.aop_dir,
4469 AOP(left)->aopu.aop_dir);
4470 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4471 AOP(right)->aopu.aop_dir,
4472 AOP(right)->aopu.aop_dir);
4473 pic14_emitcode("setc","");
4476 tlbl = newiTempLabel(NULL);
4477 pic14_toBoolean(left);
4479 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4480 pic14_toBoolean(right);
4481 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4483 pic14_outBitAcc(result);
4486 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4487 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4488 freeAsmop(result,NULL,ic,TRUE);
4491 /*-----------------------------------------------------------------*/
4492 /* isLiteralBit - test if lit == 2^n */
4493 /*-----------------------------------------------------------------*/
4494 static int isLiteralBit(unsigned long lit)
4496 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4497 0x100L,0x200L,0x400L,0x800L,
4498 0x1000L,0x2000L,0x4000L,0x8000L,
4499 0x10000L,0x20000L,0x40000L,0x80000L,
4500 0x100000L,0x200000L,0x400000L,0x800000L,
4501 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4502 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4505 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4506 for(idx = 0; idx < 32; idx++)
4512 /*-----------------------------------------------------------------*/
4513 /* continueIfTrue - */
4514 /*-----------------------------------------------------------------*/
4515 static void continueIfTrue (iCode *ic)
4517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4519 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4523 /*-----------------------------------------------------------------*/
4525 /*-----------------------------------------------------------------*/
4526 static void jumpIfTrue (iCode *ic)
4528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4530 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4534 /*-----------------------------------------------------------------*/
4535 /* jmpTrueOrFalse - */
4536 /*-----------------------------------------------------------------*/
4537 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4539 // ugly but optimized by peephole
4540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4542 symbol *nlbl = newiTempLabel(NULL);
4543 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4544 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4545 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4546 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4549 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4550 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4555 /*-----------------------------------------------------------------*/
4556 /* genAnd - code for and */
4557 /*-----------------------------------------------------------------*/
4558 static void genAnd (iCode *ic, iCode *ifx)
4560 operand *left, *right, *result;
4562 unsigned long lit = 0L;
4567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4568 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4569 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4570 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4572 resolveIfx(&rIfx,ifx);
4574 /* if left is a literal & right is not then exchange them */
4575 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4576 AOP_NEEDSACC(left)) {
4577 operand *tmp = right ;
4582 /* if result = right then exchange them */
4583 if(pic14_sameRegs(AOP(result),AOP(right))){
4584 operand *tmp = right ;
4589 /* if right is bit then exchange them */
4590 if (AOP_TYPE(right) == AOP_CRY &&
4591 AOP_TYPE(left) != AOP_CRY){
4592 operand *tmp = right ;
4596 if(AOP_TYPE(right) == AOP_LIT)
4597 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4599 size = AOP_SIZE(result);
4601 DEBUGpic14_AopType(__LINE__,left,right,result);
4604 // result = bit & yy;
4605 if (AOP_TYPE(left) == AOP_CRY){
4606 // c = bit & literal;
4607 if(AOP_TYPE(right) == AOP_LIT){
4609 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4612 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4615 if(size && (AOP_TYPE(result) == AOP_CRY)){
4616 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4619 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4623 pic14_emitcode("clr","c");
4626 if (AOP_TYPE(right) == AOP_CRY){
4628 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4629 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4632 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4634 pic14_emitcode("rrc","a");
4635 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4641 pic14_outBitC(result);
4643 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4644 genIfxJump(ifx, "c");
4648 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4649 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4650 if((AOP_TYPE(right) == AOP_LIT) &&
4651 (AOP_TYPE(result) == AOP_CRY) &&
4652 (AOP_TYPE(left) != AOP_CRY)){
4653 int posbit = isLiteralBit(lit);
4657 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4660 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4666 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4667 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4669 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4670 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4673 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4674 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4675 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4682 symbol *tlbl = newiTempLabel(NULL);
4683 int sizel = AOP_SIZE(left);
4685 pic14_emitcode("setb","c");
4687 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4688 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4690 if((posbit = isLiteralBit(bytelit)) != 0)
4691 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4693 if(bytelit != 0x0FFL)
4694 pic14_emitcode("anl","a,%s",
4695 aopGet(AOP(right),offset,FALSE,TRUE));
4696 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4701 // bit = left & literal
4703 pic14_emitcode("clr","c");
4704 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4706 // if(left & literal)
4709 jmpTrueOrFalse(ifx, tlbl);
4713 pic14_outBitC(result);
4717 /* if left is same as result */
4718 if(pic14_sameRegs(AOP(result),AOP(left))){
4720 for(;size--; offset++,lit>>=8) {
4721 if(AOP_TYPE(right) == AOP_LIT){
4722 switch(lit & 0xff) {
4724 /* and'ing with 0 has clears the result */
4725 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4726 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4729 /* and'ing with 0xff is a nop when the result and left are the same */
4734 int p = my_powof2( (~lit) & 0xff );
4736 /* only one bit is set in the literal, so use a bcf instruction */
4737 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4738 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4741 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4742 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4743 if(know_W != (lit&0xff))
4744 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4746 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
4751 if (AOP_TYPE(left) == AOP_ACC) {
4752 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
4754 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
4755 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
4762 // left & result in different registers
4763 if(AOP_TYPE(result) == AOP_CRY){
4765 // if(size), result in bit
4766 // if(!size && ifx), conditional oper: if(left & right)
4767 symbol *tlbl = newiTempLabel(NULL);
4768 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4770 pic14_emitcode("setb","c");
4772 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4773 pic14_emitcode("anl","a,%s",
4774 aopGet(AOP(left),offset,FALSE,FALSE));
4775 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4780 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4781 pic14_outBitC(result);
4783 jmpTrueOrFalse(ifx, tlbl);
4785 for(;(size--);offset++) {
4787 // result = left & right
4788 if(AOP_TYPE(right) == AOP_LIT){
4789 int t = (lit >> (offset*8)) & 0x0FFL;
4792 pic14_emitcode("clrf","%s",
4793 aopGet(AOP(result),offset,FALSE,FALSE));
4794 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4797 pic14_emitcode("movf","%s,w",
4798 aopGet(AOP(left),offset,FALSE,FALSE));
4799 pic14_emitcode("movwf","%s",
4800 aopGet(AOP(result),offset,FALSE,FALSE));
4801 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4802 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4805 pic14_emitcode("movlw","0x%x",t);
4806 pic14_emitcode("andwf","%s,w",
4807 aopGet(AOP(left),offset,FALSE,FALSE));
4808 pic14_emitcode("movwf","%s",
4809 aopGet(AOP(result),offset,FALSE,FALSE));
4811 emitpcode(POC_MOVLW, popGetLit(t));
4812 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
4813 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4818 if (AOP_TYPE(left) == AOP_ACC) {
4819 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4820 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
4822 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4823 pic14_emitcode("andwf","%s,w",
4824 aopGet(AOP(left),offset,FALSE,FALSE));
4825 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
4826 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
4828 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4829 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4835 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4836 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4837 freeAsmop(result,NULL,ic,TRUE);
4840 /*-----------------------------------------------------------------*/
4841 /* genOr - code for or */
4842 /*-----------------------------------------------------------------*/
4843 static void genOr (iCode *ic, iCode *ifx)
4845 operand *left, *right, *result;
4847 unsigned long lit = 0L;
4849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4851 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4852 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4853 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4855 DEBUGpic14_AopType(__LINE__,left,right,result);
4857 /* if left is a literal & right is not then exchange them */
4858 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4859 AOP_NEEDSACC(left)) {
4860 operand *tmp = right ;
4865 /* if result = right then exchange them */
4866 if(pic14_sameRegs(AOP(result),AOP(right))){
4867 operand *tmp = right ;
4872 /* if right is bit then exchange them */
4873 if (AOP_TYPE(right) == AOP_CRY &&
4874 AOP_TYPE(left) != AOP_CRY){
4875 operand *tmp = right ;
4880 DEBUGpic14_AopType(__LINE__,left,right,result);
4882 if(AOP_TYPE(right) == AOP_LIT)
4883 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4885 size = AOP_SIZE(result);
4889 if (AOP_TYPE(left) == AOP_CRY){
4890 if(AOP_TYPE(right) == AOP_LIT){
4891 // c = bit & literal;
4893 // lit != 0 => result = 1
4894 if(AOP_TYPE(result) == AOP_CRY){
4896 emitpcode(POC_BSF, popGet(AOP(result),0));
4897 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4898 // AOP(result)->aopu.aop_dir,
4899 // AOP(result)->aopu.aop_dir);
4901 continueIfTrue(ifx);
4905 // lit == 0 => result = left
4906 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4908 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4911 if (AOP_TYPE(right) == AOP_CRY){
4912 if(pic14_sameRegs(AOP(result),AOP(left))){
4914 emitpcode(POC_BCF, popGet(AOP(result),0));
4915 emitpcode(POC_BTFSC, popGet(AOP(right),0));
4916 emitpcode(POC_BSF, popGet(AOP(result),0));
4918 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4919 AOP(result)->aopu.aop_dir,
4920 AOP(result)->aopu.aop_dir);
4921 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4922 AOP(right)->aopu.aop_dir,
4923 AOP(right)->aopu.aop_dir);
4924 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4925 AOP(result)->aopu.aop_dir,
4926 AOP(result)->aopu.aop_dir);
4928 if( AOP_TYPE(result) == AOP_ACC) {
4929 emitpcode(POC_MOVLW, popGetLit(0));
4930 emitpcode(POC_BTFSS, popGet(AOP(right),0));
4931 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4932 emitpcode(POC_MOVLW, popGetLit(1));
4936 emitpcode(POC_BCF, popGet(AOP(result),0));
4937 emitpcode(POC_BTFSS, popGet(AOP(right),0));
4938 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4939 emitpcode(POC_BSF, popGet(AOP(result),0));
4941 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4942 AOP(result)->aopu.aop_dir,
4943 AOP(result)->aopu.aop_dir);
4944 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4945 AOP(right)->aopu.aop_dir,
4946 AOP(right)->aopu.aop_dir);
4947 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4948 AOP(left)->aopu.aop_dir,
4949 AOP(left)->aopu.aop_dir);
4950 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4951 AOP(result)->aopu.aop_dir,
4952 AOP(result)->aopu.aop_dir);
4957 symbol *tlbl = newiTempLabel(NULL);
4958 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4961 emitpcode(POC_BCF, popGet(AOP(result),0));
4962 if( AOP_TYPE(right) == AOP_ACC) {
4963 emitpcode(POC_IORLW, popGetLit(0));
4965 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4966 emitpcode(POC_BSF, popGet(AOP(result),0));
4971 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4972 pic14_emitcode(";XXX setb","c");
4973 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4974 AOP(left)->aopu.aop_dir,tlbl->key+100);
4975 pic14_toBoolean(right);
4976 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4977 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4978 jmpTrueOrFalse(ifx, tlbl);
4982 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4989 pic14_outBitC(result);
4991 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4992 genIfxJump(ifx, "c");
4996 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4997 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4998 if((AOP_TYPE(right) == AOP_LIT) &&
4999 (AOP_TYPE(result) == AOP_CRY) &&
5000 (AOP_TYPE(left) != AOP_CRY)){
5002 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5005 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5007 continueIfTrue(ifx);
5010 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5011 // lit = 0, result = boolean(left)
5013 pic14_emitcode(";XXX setb","c");
5014 pic14_toBoolean(right);
5016 symbol *tlbl = newiTempLabel(NULL);
5017 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5019 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5021 genIfxJump (ifx,"a");
5025 pic14_outBitC(result);
5029 /* if left is same as result */
5030 if(pic14_sameRegs(AOP(result),AOP(left))){
5032 for(;size--; offset++,lit>>=8) {
5033 if(AOP_TYPE(right) == AOP_LIT){
5034 if((lit & 0xff) == 0)
5035 /* or'ing with 0 has no effect */
5038 int p = my_powof2(lit & 0xff);
5040 /* only one bit is set in the literal, so use a bsf instruction */
5042 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5044 if(know_W != (lit & 0xff))
5045 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5046 know_W = lit & 0xff;
5047 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5052 if (AOP_TYPE(left) == AOP_ACC) {
5053 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5054 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5056 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5057 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5059 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5060 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5066 // left & result in different registers
5067 if(AOP_TYPE(result) == AOP_CRY){
5069 // if(size), result in bit
5070 // if(!size && ifx), conditional oper: if(left | right)
5071 symbol *tlbl = newiTempLabel(NULL);
5072 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5073 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5077 pic14_emitcode(";XXX setb","c");
5079 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5080 pic14_emitcode(";XXX orl","a,%s",
5081 aopGet(AOP(left),offset,FALSE,FALSE));
5082 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5087 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5088 pic14_outBitC(result);
5090 jmpTrueOrFalse(ifx, tlbl);
5091 } else for(;(size--);offset++){
5093 // result = left & right
5094 if(AOP_TYPE(right) == AOP_LIT){
5095 int t = (lit >> (offset*8)) & 0x0FFL;
5098 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5099 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5101 pic14_emitcode("movf","%s,w",
5102 aopGet(AOP(left),offset,FALSE,FALSE));
5103 pic14_emitcode("movwf","%s",
5104 aopGet(AOP(result),offset,FALSE,FALSE));
5107 emitpcode(POC_MOVLW, popGetLit(t));
5108 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5109 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5111 pic14_emitcode("movlw","0x%x",t);
5112 pic14_emitcode("iorwf","%s,w",
5113 aopGet(AOP(left),offset,FALSE,FALSE));
5114 pic14_emitcode("movwf","%s",
5115 aopGet(AOP(result),offset,FALSE,FALSE));
5121 // faster than result <- left, anl result,right
5122 // and better if result is SFR
5123 if (AOP_TYPE(left) == AOP_ACC) {
5124 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5125 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5127 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5128 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5130 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5131 pic14_emitcode("iorwf","%s,w",
5132 aopGet(AOP(left),offset,FALSE,FALSE));
5134 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5135 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5140 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5141 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5142 freeAsmop(result,NULL,ic,TRUE);
5145 /*-----------------------------------------------------------------*/
5146 /* genXor - code for xclusive or */
5147 /*-----------------------------------------------------------------*/
5148 static void genXor (iCode *ic, iCode *ifx)
5150 operand *left, *right, *result;
5152 unsigned long lit = 0L;
5154 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5156 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5157 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5158 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5160 /* if left is a literal & right is not ||
5161 if left needs acc & right does not */
5162 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5163 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5164 operand *tmp = right ;
5169 /* if result = right then exchange them */
5170 if(pic14_sameRegs(AOP(result),AOP(right))){
5171 operand *tmp = right ;
5176 /* if right is bit then exchange them */
5177 if (AOP_TYPE(right) == AOP_CRY &&
5178 AOP_TYPE(left) != AOP_CRY){
5179 operand *tmp = right ;
5183 if(AOP_TYPE(right) == AOP_LIT)
5184 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5186 size = AOP_SIZE(result);
5190 if (AOP_TYPE(left) == AOP_CRY){
5191 if(AOP_TYPE(right) == AOP_LIT){
5192 // c = bit & literal;
5194 // lit>>1 != 0 => result = 1
5195 if(AOP_TYPE(result) == AOP_CRY){
5197 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5199 continueIfTrue(ifx);
5202 pic14_emitcode("setb","c");
5206 // lit == 0, result = left
5207 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5209 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5211 // lit == 1, result = not(left)
5212 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5213 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5216 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5217 pic14_emitcode("cpl","c");
5224 symbol *tlbl = newiTempLabel(NULL);
5225 if (AOP_TYPE(right) == AOP_CRY){
5227 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5230 int sizer = AOP_SIZE(right);
5232 // if val>>1 != 0, result = 1
5233 pic14_emitcode("setb","c");
5235 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5237 // test the msb of the lsb
5238 pic14_emitcode("anl","a,#0xfe");
5239 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5243 pic14_emitcode("rrc","a");
5245 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5246 pic14_emitcode("cpl","c");
5247 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5252 pic14_outBitC(result);
5254 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5255 genIfxJump(ifx, "c");
5259 if(pic14_sameRegs(AOP(result),AOP(left))){
5260 /* if left is same as result */
5261 for(;size--; offset++) {
5262 if(AOP_TYPE(right) == AOP_LIT){
5263 int t = (lit >> (offset*8)) & 0x0FFL;
5267 if (IS_AOP_PREG(left)) {
5268 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5269 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5270 aopPut(AOP(result),"a",offset);
5272 emitpcode(POC_MOVLW, popGetLit(t));
5273 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5274 pic14_emitcode("xrl","%s,%s",
5275 aopGet(AOP(left),offset,FALSE,TRUE),
5276 aopGet(AOP(right),offset,FALSE,FALSE));
5279 if (AOP_TYPE(left) == AOP_ACC)
5280 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5282 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5283 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5285 if (IS_AOP_PREG(left)) {
5286 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5287 aopPut(AOP(result),"a",offset);
5289 pic14_emitcode("xrl","%s,a",
5290 aopGet(AOP(left),offset,FALSE,TRUE));
5296 // left & result in different registers
5297 if(AOP_TYPE(result) == AOP_CRY){
5299 // if(size), result in bit
5300 // if(!size && ifx), conditional oper: if(left ^ right)
5301 symbol *tlbl = newiTempLabel(NULL);
5302 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5304 pic14_emitcode("setb","c");
5306 if((AOP_TYPE(right) == AOP_LIT) &&
5307 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5308 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5310 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5311 pic14_emitcode("xrl","a,%s",
5312 aopGet(AOP(left),offset,FALSE,FALSE));
5314 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5319 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5320 pic14_outBitC(result);
5322 jmpTrueOrFalse(ifx, tlbl);
5323 } else for(;(size--);offset++){
5325 // result = left & right
5326 if(AOP_TYPE(right) == AOP_LIT){
5327 int t = (lit >> (offset*8)) & 0x0FFL;
5330 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5331 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5332 pic14_emitcode("movf","%s,w",
5333 aopGet(AOP(left),offset,FALSE,FALSE));
5334 pic14_emitcode("movwf","%s",
5335 aopGet(AOP(result),offset,FALSE,FALSE));
5338 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5339 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5340 pic14_emitcode("comf","%s,w",
5341 aopGet(AOP(left),offset,FALSE,FALSE));
5342 pic14_emitcode("movwf","%s",
5343 aopGet(AOP(result),offset,FALSE,FALSE));
5346 emitpcode(POC_MOVLW, popGetLit(t));
5347 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5348 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5349 pic14_emitcode("movlw","0x%x",t);
5350 pic14_emitcode("xorwf","%s,w",
5351 aopGet(AOP(left),offset,FALSE,FALSE));
5352 pic14_emitcode("movwf","%s",
5353 aopGet(AOP(result),offset,FALSE,FALSE));
5359 // faster than result <- left, anl result,right
5360 // and better if result is SFR
5361 if (AOP_TYPE(left) == AOP_ACC) {
5362 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5363 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5365 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5366 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5367 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5368 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5370 if ( AOP_TYPE(result) != AOP_ACC){
5371 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5372 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5378 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5379 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5380 freeAsmop(result,NULL,ic,TRUE);
5383 /*-----------------------------------------------------------------*/
5384 /* genInline - write the inline code out */
5385 /*-----------------------------------------------------------------*/
5386 static void genInline (iCode *ic)
5388 char *buffer, *bp, *bp1;
5390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5392 _G.inLine += (!options.asmpeep);
5394 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5395 strcpy(buffer,IC_INLINE(ic));
5397 /* emit each line as a code */
5401 pic14_emitcode(bp1,"");
5408 pic14_emitcode(bp1,"");
5415 pic14_emitcode(bp1,"");
5416 /* pic14_emitcode("",buffer); */
5417 _G.inLine -= (!options.asmpeep);
5420 /*-----------------------------------------------------------------*/
5421 /* genRRC - rotate right with carry */
5422 /*-----------------------------------------------------------------*/
5423 static void genRRC (iCode *ic)
5425 operand *left , *result ;
5426 int size, offset = 0, same;
5428 /* rotate right with carry */
5430 result=IC_RESULT(ic);
5431 aopOp (left,ic,FALSE);
5432 aopOp (result,ic,FALSE);
5434 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5436 same = pic14_sameRegs(AOP(result),AOP(left));
5438 size = AOP_SIZE(result);
5440 /* get the lsb and put it into the carry */
5441 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5448 emitpcode(POC_RRF, popGet(AOP(left),offset));
5450 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5451 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5457 freeAsmop(left,NULL,ic,TRUE);
5458 freeAsmop(result,NULL,ic,TRUE);
5461 /*-----------------------------------------------------------------*/
5462 /* genRLC - generate code for rotate left with carry */
5463 /*-----------------------------------------------------------------*/
5464 static void genRLC (iCode *ic)
5466 operand *left , *result ;
5467 int size, offset = 0;
5470 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5471 /* rotate right with carry */
5473 result=IC_RESULT(ic);
5474 aopOp (left,ic,FALSE);
5475 aopOp (result,ic,FALSE);
5477 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5479 same = pic14_sameRegs(AOP(result),AOP(left));
5481 /* move it to the result */
5482 size = AOP_SIZE(result);
5484 /* get the msb and put it into the carry */
5485 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5492 emitpcode(POC_RLF, popGet(AOP(left),offset));
5494 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5495 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5502 freeAsmop(left,NULL,ic,TRUE);
5503 freeAsmop(result,NULL,ic,TRUE);
5506 /*-----------------------------------------------------------------*/
5507 /* genGetHbit - generates code get highest order bit */
5508 /*-----------------------------------------------------------------*/
5509 static void genGetHbit (iCode *ic)
5511 operand *left, *result;
5513 result=IC_RESULT(ic);
5514 aopOp (left,ic,FALSE);
5515 aopOp (result,ic,FALSE);
5517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5518 /* get the highest order byte into a */
5519 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5520 if(AOP_TYPE(result) == AOP_CRY){
5521 pic14_emitcode("rlc","a");
5522 pic14_outBitC(result);
5525 pic14_emitcode("rl","a");
5526 pic14_emitcode("anl","a,#0x01");
5527 pic14_outAcc(result);
5531 freeAsmop(left,NULL,ic,TRUE);
5532 freeAsmop(result,NULL,ic,TRUE);
5535 /*-----------------------------------------------------------------*/
5536 /* AccRol - rotate left accumulator by known count */
5537 /*-----------------------------------------------------------------*/
5538 static void AccRol (int shCount)
5540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5541 shCount &= 0x0007; // shCount : 0..7
5546 pic14_emitcode("rl","a");
5549 pic14_emitcode("rl","a");
5550 pic14_emitcode("rl","a");
5553 pic14_emitcode("swap","a");
5554 pic14_emitcode("rr","a");
5557 pic14_emitcode("swap","a");
5560 pic14_emitcode("swap","a");
5561 pic14_emitcode("rl","a");
5564 pic14_emitcode("rr","a");
5565 pic14_emitcode("rr","a");
5568 pic14_emitcode("rr","a");
5573 /*-----------------------------------------------------------------*/
5574 /* AccLsh - left shift accumulator by known count */
5575 /*-----------------------------------------------------------------*/
5576 static void AccLsh (int shCount)
5578 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5581 pic14_emitcode("add","a,acc");
5584 pic14_emitcode("add","a,acc");
5585 pic14_emitcode("add","a,acc");
5587 /* rotate left accumulator */
5589 /* and kill the lower order bits */
5590 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5595 /*-----------------------------------------------------------------*/
5596 /* AccRsh - right shift accumulator by known count */
5597 /*-----------------------------------------------------------------*/
5598 static void AccRsh (int shCount)
5600 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5604 pic14_emitcode("rrc","a");
5606 /* rotate right accumulator */
5607 AccRol(8 - shCount);
5608 /* and kill the higher order bits */
5609 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5615 /*-----------------------------------------------------------------*/
5616 /* AccSRsh - signed right shift accumulator by known count */
5617 /*-----------------------------------------------------------------*/
5618 static void AccSRsh (int shCount)
5621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5624 pic14_emitcode("mov","c,acc.7");
5625 pic14_emitcode("rrc","a");
5626 } else if(shCount == 2){
5627 pic14_emitcode("mov","c,acc.7");
5628 pic14_emitcode("rrc","a");
5629 pic14_emitcode("mov","c,acc.7");
5630 pic14_emitcode("rrc","a");
5632 tlbl = newiTempLabel(NULL);
5633 /* rotate right accumulator */
5634 AccRol(8 - shCount);
5635 /* and kill the higher order bits */
5636 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5637 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5638 pic14_emitcode("orl","a,#0x%02x",
5639 (unsigned char)~SRMask[shCount]);
5640 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5645 /*-----------------------------------------------------------------*/
5646 /* shiftR1Left2Result - shift right one byte from left to result */
5647 /*-----------------------------------------------------------------*/
5648 static void shiftR1Left2ResultSigned (operand *left, int offl,
5649 operand *result, int offr,
5654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5656 same = (left == result) || (AOP(left) == AOP(result));
5660 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5662 emitpcode(POC_RRF, popGet(AOP(result),offr));
5664 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5665 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5675 /*-----------------------------------------------------------------*/
5676 /* shiftR1Left2Result - shift right one byte from left to result */
5677 /*-----------------------------------------------------------------*/
5678 static void shiftR1Left2Result (operand *left, int offl,
5679 operand *result, int offr,
5680 int shCount, int sign)
5684 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5686 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5688 /* Copy the msb into the carry if signed. */
5690 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5700 emitpcode(POC_RRF, popGet(AOP(result),offr));
5702 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5703 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5709 emitpcode(POC_RRF, popGet(AOP(result),offr));
5711 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5712 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5715 emitpcode(POC_RRF, popGet(AOP(result),offr));
5720 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5722 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5723 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5726 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5727 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5728 emitpcode(POC_ANDLW, popGetLit(0x1f));
5729 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5733 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5734 emitpcode(POC_ANDLW, popGetLit(0x0f));
5735 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5739 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5740 emitpcode(POC_ANDLW, popGetLit(0x0f));
5741 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5743 emitpcode(POC_RRF, popGet(AOP(result),offr));
5748 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5749 emitpcode(POC_ANDLW, popGetLit(0x80));
5750 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5751 emitpcode(POC_RLF, popGet(AOP(result),offr));
5752 emitpcode(POC_RLF, popGet(AOP(result),offr));
5757 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5758 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5759 emitpcode(POC_RLF, popGet(AOP(result),offr));
5770 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5772 /* shift right accumulator */
5777 aopPut(AOP(result),"a",offr);
5781 /*-----------------------------------------------------------------*/
5782 /* shiftL1Left2Result - shift left one byte from left to result */
5783 /*-----------------------------------------------------------------*/
5784 static void shiftL1Left2Result (operand *left, int offl,
5785 operand *result, int offr, int shCount)
5790 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5792 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5793 DEBUGpic14_emitcode ("; ***","same = %d",same);
5794 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5796 /* shift left accumulator */
5797 //AccLsh(shCount); // don't comment out just yet...
5798 // aopPut(AOP(result),"a",offr);
5802 /* Shift left 1 bit position */
5803 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5805 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
5807 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
5808 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5812 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5813 emitpcode(POC_ANDLW,popGetLit(0x7e));
5814 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5815 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5818 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5819 emitpcode(POC_ANDLW,popGetLit(0x3e));
5820 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5821 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5822 emitpcode(POC_RLF, popGet(AOP(result),offr));
5825 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5826 emitpcode(POC_ANDLW, popGetLit(0xf0));
5827 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5830 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5831 emitpcode(POC_ANDLW, popGetLit(0xf0));
5832 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5833 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5836 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5837 emitpcode(POC_ANDLW, popGetLit(0x30));
5838 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5839 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5840 emitpcode(POC_RLF, popGet(AOP(result),offr));
5843 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5844 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5845 emitpcode(POC_RRF, popGet(AOP(result),offr));
5849 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5854 /*-----------------------------------------------------------------*/
5855 /* movLeft2Result - move byte from left to result */
5856 /*-----------------------------------------------------------------*/
5857 static void movLeft2Result (operand *left, int offl,
5858 operand *result, int offr, int sign)
5861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5862 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5863 l = aopGet(AOP(left),offl,FALSE,FALSE);
5865 if (*l == '@' && (IS_AOP_PREG(result))) {
5866 pic14_emitcode("mov","a,%s",l);
5867 aopPut(AOP(result),"a",offr);
5870 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5871 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5873 //aopPut(AOP(result),l,offr);
5875 /* MSB sign in acc.7 ! */
5876 if(pic14_getDataSize(left) == offl+1){
5877 pic14_emitcode("mov","a,%s",l);
5878 aopPut(AOP(result),"a",offr);
5885 /*-----------------------------------------------------------------*/
5886 /* shiftL2Left2Result - shift left two bytes from left to result */
5887 /*-----------------------------------------------------------------*/
5888 static void shiftL2Left2Result (operand *left, int offl,
5889 operand *result, int offr, int shCount)
5893 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5895 if(pic14_sameRegs(AOP(result), AOP(left))) {
5903 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
5904 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5905 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5909 emitpcode(POC_RLF, popGet(AOP(result),offr));
5910 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5916 emitpcode(POC_MOVLW, popGetLit(0x0f));
5917 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
5918 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
5919 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5920 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
5921 emitpcode(POC_XORWF, popGet(AOP(result),offr));
5922 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
5924 emitpcode(POC_RLF, popGet(AOP(result),offr));
5925 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5929 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5930 emitpcode(POC_RRF, popGet(AOP(result),offr));
5931 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5932 emitpcode(POC_RRF, popGet(AOP(result),offr));
5933 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5934 emitpcode(POC_ANDLW,popGetLit(0xc0));
5935 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5936 emitpcode(POC_XORWF,popGet(AOP(result),offr));
5937 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5938 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5941 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5942 emitpcode(POC_RRFW, popGet(AOP(result),offr));
5943 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5944 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5945 emitpcode(POC_RRF, popGet(AOP(result),offr));
5955 /* note, use a mov/add for the shift since the mov has a
5956 chance of getting optimized out */
5957 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5958 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5959 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
5960 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
5961 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
5965 emitpcode(POC_RLF, popGet(AOP(result),offr));
5966 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5972 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
5973 emitpcode(POC_ANDLW, popGetLit(0xF0));
5974 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
5975 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5976 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5977 emitpcode(POC_ANDLW, popGetLit(0xF0));
5978 emitpcode(POC_XORWF, popGet(AOP(result),offr));
5979 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
5983 emitpcode(POC_RLF, popGet(AOP(result),offr));
5984 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5988 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
5989 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5990 emitpcode(POC_RRFW, popGet(AOP(result),offl));
5991 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5993 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5994 emitpcode(POC_RRF, popGet(AOP(result),offr));
5995 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5996 emitpcode(POC_ANDLW,popGetLit(0xc0));
5997 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5998 emitpcode(POC_XORWF,popGet(AOP(result),offr));
5999 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6000 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6003 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6004 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6005 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6006 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6007 emitpcode(POC_RRF, popGet(AOP(result),offr));
6012 /*-----------------------------------------------------------------*/
6013 /* shiftR2Left2Result - shift right two bytes from left to result */
6014 /*-----------------------------------------------------------------*/
6015 static void shiftR2Left2Result (operand *left, int offl,
6016 operand *result, int offr,
6017 int shCount, int sign)
6021 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6022 same = pic14_sameRegs(AOP(result), AOP(left));
6024 if(same && ((offl + MSB16) == offr)){
6026 /* don't crash result[offr] */
6027 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6028 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6030 movLeft2Result(left,offl, result, offr, 0);
6031 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6033 /* a:x >> shCount (x = lsb(result))*/
6036 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6038 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6048 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6049 emitpcode(POC_RRF,popGet(AOP(result),offr));
6052 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6053 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6054 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6055 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6060 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6061 emitpcode(POC_RRF,popGet(AOP(result),offr));
6068 emitpcode(POC_MOVLW, popGetLit(0xf0));
6069 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6070 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6072 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6073 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6074 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6075 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6077 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6078 emitpcode(POC_ANDLW, popGetLit(0x0f));
6079 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6081 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6082 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6083 emitpcode(POC_ANDLW, popGetLit(0xf0));
6084 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6085 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6089 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6090 emitpcode(POC_RRF, popGet(AOP(result),offr));
6098 emitpcode(POC_RLF, popGet(AOP(result),offr));
6099 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6101 emitpcode(POC_RLF, popGet(AOP(result),offr));
6102 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6103 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6104 emitpcode(POC_ANDLW,popGetLit(0x03));
6105 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6106 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6107 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6108 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6110 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6111 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6112 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6113 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6114 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6115 emitpcode(POC_RLF, popGet(AOP(result),offr));
6116 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6117 emitpcode(POC_ANDLW,popGetLit(0x03));
6118 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6123 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6124 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6125 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6126 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6127 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6132 /*-----------------------------------------------------------------*/
6133 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6134 /*-----------------------------------------------------------------*/
6135 static void shiftLLeftOrResult (operand *left, int offl,
6136 operand *result, int offr, int shCount)
6138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6139 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6140 /* shift left accumulator */
6142 /* or with result */
6143 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6144 /* back to result */
6145 aopPut(AOP(result),"a",offr);
6148 /*-----------------------------------------------------------------*/
6149 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6150 /*-----------------------------------------------------------------*/
6151 static void shiftRLeftOrResult (operand *left, int offl,
6152 operand *result, int offr, int shCount)
6154 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6155 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6156 /* shift right accumulator */
6158 /* or with result */
6159 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6160 /* back to result */
6161 aopPut(AOP(result),"a",offr);
6164 /*-----------------------------------------------------------------*/
6165 /* genlshOne - left shift a one byte quantity by known count */
6166 /*-----------------------------------------------------------------*/
6167 static void genlshOne (operand *result, operand *left, int shCount)
6169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6170 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6173 /*-----------------------------------------------------------------*/
6174 /* genlshTwo - left shift two bytes by known amount != 0 */
6175 /*-----------------------------------------------------------------*/
6176 static void genlshTwo (operand *result,operand *left, int shCount)
6180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6181 size = pic14_getDataSize(result);
6183 /* if shCount >= 8 */
6189 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6191 movLeft2Result(left, LSB, result, MSB16, 0);
6193 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6196 /* 1 <= shCount <= 7 */
6199 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6201 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6205 /*-----------------------------------------------------------------*/
6206 /* shiftLLong - shift left one long from left to result */
6207 /* offl = LSB or MSB16 */
6208 /*-----------------------------------------------------------------*/
6209 static void shiftLLong (operand *left, operand *result, int offr )
6212 int size = AOP_SIZE(result);
6214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6215 if(size >= LSB+offr){
6216 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6218 pic14_emitcode("add","a,acc");
6219 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6220 size >= MSB16+offr && offr != LSB )
6221 pic14_emitcode("xch","a,%s",
6222 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6224 aopPut(AOP(result),"a",LSB+offr);
6227 if(size >= MSB16+offr){
6228 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6229 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6232 pic14_emitcode("rlc","a");
6233 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6234 size >= MSB24+offr && offr != LSB)
6235 pic14_emitcode("xch","a,%s",
6236 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6238 aopPut(AOP(result),"a",MSB16+offr);
6241 if(size >= MSB24+offr){
6242 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6243 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6246 pic14_emitcode("rlc","a");
6247 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6248 size >= MSB32+offr && offr != LSB )
6249 pic14_emitcode("xch","a,%s",
6250 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6252 aopPut(AOP(result),"a",MSB24+offr);
6255 if(size > MSB32+offr){
6256 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6257 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6260 pic14_emitcode("rlc","a");
6261 aopPut(AOP(result),"a",MSB32+offr);
6264 aopPut(AOP(result),zero,LSB);
6267 /*-----------------------------------------------------------------*/
6268 /* genlshFour - shift four byte by a known amount != 0 */
6269 /*-----------------------------------------------------------------*/
6270 static void genlshFour (operand *result, operand *left, int shCount)
6274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6275 size = AOP_SIZE(result);
6277 /* if shifting more that 3 bytes */
6278 if (shCount >= 24 ) {
6281 /* lowest order of left goes to the highest
6282 order of the destination */
6283 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6285 movLeft2Result(left, LSB, result, MSB32, 0);
6286 aopPut(AOP(result),zero,LSB);
6287 aopPut(AOP(result),zero,MSB16);
6288 aopPut(AOP(result),zero,MSB32);
6292 /* more than two bytes */
6293 else if ( shCount >= 16 ) {
6294 /* lower order two bytes goes to higher order two bytes */
6296 /* if some more remaining */
6298 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6300 movLeft2Result(left, MSB16, result, MSB32, 0);
6301 movLeft2Result(left, LSB, result, MSB24, 0);
6303 aopPut(AOP(result),zero,MSB16);
6304 aopPut(AOP(result),zero,LSB);
6308 /* if more than 1 byte */
6309 else if ( shCount >= 8 ) {
6310 /* lower order three bytes goes to higher order three bytes */
6314 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6316 movLeft2Result(left, LSB, result, MSB16, 0);
6318 else{ /* size = 4 */
6320 movLeft2Result(left, MSB24, result, MSB32, 0);
6321 movLeft2Result(left, MSB16, result, MSB24, 0);
6322 movLeft2Result(left, LSB, result, MSB16, 0);
6323 aopPut(AOP(result),zero,LSB);
6325 else if(shCount == 1)
6326 shiftLLong(left, result, MSB16);
6328 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6329 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6330 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6331 aopPut(AOP(result),zero,LSB);
6336 /* 1 <= shCount <= 7 */
6337 else if(shCount <= 2){
6338 shiftLLong(left, result, LSB);
6340 shiftLLong(result, result, LSB);
6342 /* 3 <= shCount <= 7, optimize */
6344 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6345 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6346 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6350 /*-----------------------------------------------------------------*/
6351 /* genLeftShiftLiteral - left shifting by known count */
6352 /*-----------------------------------------------------------------*/
6353 static void genLeftShiftLiteral (operand *left,
6358 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6362 freeAsmop(right,NULL,ic,TRUE);
6364 aopOp(left,ic,FALSE);
6365 aopOp(result,ic,FALSE);
6367 size = getSize(operandType(result));
6370 pic14_emitcode("; shift left ","result %d, left %d",size,
6374 /* I suppose that the left size >= result size */
6377 movLeft2Result(left, size, result, size, 0);
6381 else if(shCount >= (size * 8))
6383 aopPut(AOP(result),zero,size);
6387 genlshOne (result,left,shCount);
6392 genlshTwo (result,left,shCount);
6396 genlshFour (result,left,shCount);
6400 freeAsmop(left,NULL,ic,TRUE);
6401 freeAsmop(result,NULL,ic,TRUE);
6404 /*-----------------------------------------------------------------*/
6405 /* genLeftShift - generates code for left shifting */
6406 /*-----------------------------------------------------------------*/
6407 static void genLeftShift (iCode *ic)
6409 operand *left,*right, *result;
6412 symbol *tlbl , *tlbl1;
6414 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6416 right = IC_RIGHT(ic);
6418 result = IC_RESULT(ic);
6420 aopOp(right,ic,FALSE);
6422 /* if the shift count is known then do it
6423 as efficiently as possible */
6424 if (AOP_TYPE(right) == AOP_LIT) {
6425 genLeftShiftLiteral (left,right,result,ic);
6429 /* shift count is unknown then we have to form
6430 a loop get the loop count in B : Note: we take
6431 only the lower order byte since shifting
6432 more that 32 bits make no sense anyway, ( the
6433 largest size of an object can be only 32 bits ) */
6436 aopOp(left,ic,FALSE);
6437 aopOp(result,ic,FALSE);
6439 /* now move the left to the result if they are not the
6441 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6442 AOP_SIZE(result) > 1) {
6444 size = AOP_SIZE(result);
6447 l = aopGet(AOP(left),offset,FALSE,TRUE);
6448 if (*l == '@' && (IS_AOP_PREG(result))) {
6450 pic14_emitcode("mov","a,%s",l);
6451 aopPut(AOP(result),"a",offset);
6453 aopPut(AOP(result),l,offset);
6458 size = AOP_SIZE(result);
6460 /* if it is only one byte then */
6462 if(optimized_for_speed) {
6463 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6464 emitpcode(POC_ANDLW, popGetLit(0xf0));
6465 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6466 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6467 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6468 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6469 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6470 emitpcode(POC_RLFW, popGet(AOP(result),0));
6471 emitpcode(POC_ANDLW, popGetLit(0xfe));
6472 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6473 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6474 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6477 tlbl = newiTempLabel(NULL);
6478 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6479 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6480 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6483 emitpcode(POC_COMFW, popGet(AOP(right),0));
6484 emitpcode(POC_RRF, popGet(AOP(result),0));
6485 emitpLabel(tlbl->key);
6486 emitpcode(POC_RLF, popGet(AOP(result),0));
6487 emitpcode(POC_ADDLW, popGetLit(1));
6489 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6495 tlbl = newiTempLabel(NULL);
6497 tlbl1 = newiTempLabel(NULL);
6499 reAdjustPreg(AOP(result));
6501 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6502 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6503 l = aopGet(AOP(result),offset,FALSE,FALSE);
6505 pic14_emitcode("add","a,acc");
6506 aopPut(AOP(result),"a",offset++);
6508 l = aopGet(AOP(result),offset,FALSE,FALSE);
6510 pic14_emitcode("rlc","a");
6511 aopPut(AOP(result),"a",offset++);
6513 reAdjustPreg(AOP(result));
6515 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6516 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6518 freeAsmop (right,NULL,ic,TRUE);
6519 freeAsmop(left,NULL,ic,TRUE);
6520 freeAsmop(result,NULL,ic,TRUE);
6523 /*-----------------------------------------------------------------*/
6524 /* genrshOne - right shift a one byte quantity by known count */
6525 /*-----------------------------------------------------------------*/
6526 static void genrshOne (operand *result, operand *left,
6527 int shCount, int sign)
6529 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6530 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6533 /*-----------------------------------------------------------------*/
6534 /* genrshTwo - right shift two bytes by known amount != 0 */
6535 /*-----------------------------------------------------------------*/
6536 static void genrshTwo (operand *result,operand *left,
6537 int shCount, int sign)
6539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6540 /* if shCount >= 8 */
6544 shiftR1Left2Result(left, MSB16, result, LSB,
6547 movLeft2Result(left, MSB16, result, LSB, sign);
6549 addSign(result, MSB16, sign);
6551 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6555 /* 1 <= shCount <= 7 */
6557 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6560 /*-----------------------------------------------------------------*/
6561 /* shiftRLong - shift right one long from left to result */
6562 /* offl = LSB or MSB16 */
6563 /*-----------------------------------------------------------------*/
6564 static void shiftRLong (operand *left, int offl,
6565 operand *result, int sign)
6567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6569 pic14_emitcode("clr","c");
6570 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6572 pic14_emitcode("mov","c,acc.7");
6573 pic14_emitcode("rrc","a");
6574 aopPut(AOP(result),"a",MSB32-offl);
6576 /* add sign of "a" */
6577 addSign(result, MSB32, sign);
6579 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6580 pic14_emitcode("rrc","a");
6581 aopPut(AOP(result),"a",MSB24-offl);
6583 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6584 pic14_emitcode("rrc","a");
6585 aopPut(AOP(result),"a",MSB16-offl);
6588 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6589 pic14_emitcode("rrc","a");
6590 aopPut(AOP(result),"a",LSB);
6594 /*-----------------------------------------------------------------*/
6595 /* genrshFour - shift four byte by a known amount != 0 */
6596 /*-----------------------------------------------------------------*/
6597 static void genrshFour (operand *result, operand *left,
6598 int shCount, int sign)
6600 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6601 /* if shifting more that 3 bytes */
6602 if(shCount >= 24 ) {
6605 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6607 movLeft2Result(left, MSB32, result, LSB, sign);
6608 addSign(result, MSB16, sign);
6610 else if(shCount >= 16){
6613 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6615 movLeft2Result(left, MSB24, result, LSB, 0);
6616 movLeft2Result(left, MSB32, result, MSB16, sign);
6618 addSign(result, MSB24, sign);
6620 else if(shCount >= 8){
6623 shiftRLong(left, MSB16, result, sign);
6624 else if(shCount == 0){
6625 movLeft2Result(left, MSB16, result, LSB, 0);
6626 movLeft2Result(left, MSB24, result, MSB16, 0);
6627 movLeft2Result(left, MSB32, result, MSB24, sign);
6628 addSign(result, MSB32, sign);
6631 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6632 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6633 /* the last shift is signed */
6634 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6635 addSign(result, MSB32, sign);
6638 else{ /* 1 <= shCount <= 7 */
6640 shiftRLong(left, LSB, result, sign);
6642 shiftRLong(result, LSB, result, sign);
6645 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6646 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6647 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6652 /*-----------------------------------------------------------------*/
6653 /* genRightShiftLiteral - right shifting by known count */
6654 /*-----------------------------------------------------------------*/
6655 static void genRightShiftLiteral (operand *left,
6661 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6665 freeAsmop(right,NULL,ic,TRUE);
6667 aopOp(left,ic,FALSE);
6668 aopOp(result,ic,FALSE);
6671 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6675 size = pic14_getDataSize(left);
6676 /* test the LEFT size !!! */
6678 /* I suppose that the left size >= result size */
6680 size = pic14_getDataSize(result);
6682 movLeft2Result(left, size, result, size, 0);
6685 else if(shCount >= (size * 8)){
6687 /* get sign in acc.7 */
6688 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6689 addSign(result, LSB, sign);
6693 genrshOne (result,left,shCount,sign);
6697 genrshTwo (result,left,shCount,sign);
6701 genrshFour (result,left,shCount,sign);
6707 freeAsmop(left,NULL,ic,TRUE);
6708 freeAsmop(result,NULL,ic,TRUE);
6712 /*-----------------------------------------------------------------*/
6713 /* genSignedRightShift - right shift of signed number */
6714 /*-----------------------------------------------------------------*/
6715 static void genSignedRightShift (iCode *ic)
6717 operand *right, *left, *result;
6720 symbol *tlbl, *tlbl1 ;
6722 /* we do it the hard way put the shift count in b
6723 and loop thru preserving the sign */
6724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6726 right = IC_RIGHT(ic);
6728 result = IC_RESULT(ic);
6730 aopOp(right,ic,FALSE);
6733 if ( AOP_TYPE(right) == AOP_LIT) {
6734 genRightShiftLiteral (left,right,result,ic,1);
6737 /* shift count is unknown then we have to form
6738 a loop get the loop count in B : Note: we take
6739 only the lower order byte since shifting
6740 more that 32 bits make no sense anyway, ( the
6741 largest size of an object can be only 32 bits ) */
6743 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6744 pic14_emitcode("inc","b");
6745 freeAsmop (right,NULL,ic,TRUE);
6746 aopOp(left,ic,FALSE);
6747 aopOp(result,ic,FALSE);
6749 /* now move the left to the result if they are not the
6751 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6752 AOP_SIZE(result) > 1) {
6754 size = AOP_SIZE(result);
6757 l = aopGet(AOP(left),offset,FALSE,TRUE);
6758 if (*l == '@' && IS_AOP_PREG(result)) {
6760 pic14_emitcode("mov","a,%s",l);
6761 aopPut(AOP(result),"a",offset);
6763 aopPut(AOP(result),l,offset);
6768 /* mov the highest order bit to OVR */
6769 tlbl = newiTempLabel(NULL);
6770 tlbl1= newiTempLabel(NULL);
6772 size = AOP_SIZE(result);
6774 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6775 pic14_emitcode("rlc","a");
6776 pic14_emitcode("mov","ov,c");
6777 /* if it is only one byte then */
6779 l = aopGet(AOP(left),0,FALSE,FALSE);
6781 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6782 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6783 pic14_emitcode("mov","c,ov");
6784 pic14_emitcode("rrc","a");
6785 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6786 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6787 aopPut(AOP(result),"a",0);
6791 reAdjustPreg(AOP(result));
6792 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6793 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6794 pic14_emitcode("mov","c,ov");
6796 l = aopGet(AOP(result),offset,FALSE,FALSE);
6798 pic14_emitcode("rrc","a");
6799 aopPut(AOP(result),"a",offset--);
6801 reAdjustPreg(AOP(result));
6802 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6803 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6806 freeAsmop(left,NULL,ic,TRUE);
6807 freeAsmop(result,NULL,ic,TRUE);
6810 /*-----------------------------------------------------------------*/
6811 /* genRightShift - generate code for right shifting */
6812 /*-----------------------------------------------------------------*/
6813 static void genRightShift (iCode *ic)
6815 operand *right, *left, *result;
6819 symbol *tlbl, *tlbl1 ;
6821 /* if signed then we do it the hard way preserve the
6822 sign bit moving it inwards */
6823 retype = getSpec(operandType(IC_RESULT(ic)));
6824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6826 if (!SPEC_USIGN(retype)) {
6827 genSignedRightShift (ic);
6831 /* signed & unsigned types are treated the same : i.e. the
6832 signed is NOT propagated inwards : quoting from the
6833 ANSI - standard : "for E1 >> E2, is equivalent to division
6834 by 2**E2 if unsigned or if it has a non-negative value,
6835 otherwise the result is implementation defined ", MY definition
6836 is that the sign does not get propagated */
6838 right = IC_RIGHT(ic);
6840 result = IC_RESULT(ic);
6842 aopOp(right,ic,FALSE);
6844 /* if the shift count is known then do it
6845 as efficiently as possible */
6846 if (AOP_TYPE(right) == AOP_LIT) {
6847 genRightShiftLiteral (left,right,result,ic, 0);
6851 /* shift count is unknown then we have to form
6852 a loop get the loop count in B : Note: we take
6853 only the lower order byte since shifting
6854 more that 32 bits make no sense anyway, ( the
6855 largest size of an object can be only 32 bits ) */
6857 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6858 pic14_emitcode("inc","b");
6859 aopOp(left,ic,FALSE);
6860 aopOp(result,ic,FALSE);
6862 /* now move the left to the result if they are not the
6864 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6865 AOP_SIZE(result) > 1) {
6867 size = AOP_SIZE(result);
6870 l = aopGet(AOP(left),offset,FALSE,TRUE);
6871 if (*l == '@' && IS_AOP_PREG(result)) {
6873 pic14_emitcode("mov","a,%s",l);
6874 aopPut(AOP(result),"a",offset);
6876 aopPut(AOP(result),l,offset);
6881 tlbl = newiTempLabel(NULL);
6882 tlbl1= newiTempLabel(NULL);
6883 size = AOP_SIZE(result);
6886 /* if it is only one byte then */
6889 l = aopGet(AOP(left),0,FALSE,FALSE);
6891 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6892 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6894 pic14_emitcode("rrc","a");
6895 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6896 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6897 aopPut(AOP(result),"a",0);
6899 tlbl = newiTempLabel(NULL);
6900 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6901 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6902 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6905 emitpcode(POC_COMFW, popGet(AOP(right),0));
6906 emitpcode(POC_RLF, popGet(AOP(result),0));
6907 emitpLabel(tlbl->key);
6908 emitpcode(POC_RRF, popGet(AOP(result),0));
6909 emitpcode(POC_ADDLW, popGetLit(1));
6911 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6916 reAdjustPreg(AOP(result));
6917 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6918 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6921 l = aopGet(AOP(result),offset,FALSE,FALSE);
6923 pic14_emitcode("rrc","a");
6924 aopPut(AOP(result),"a",offset--);
6926 reAdjustPreg(AOP(result));
6928 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6929 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6932 freeAsmop(left,NULL,ic,TRUE);
6933 freeAsmop (right,NULL,ic,TRUE);
6934 freeAsmop(result,NULL,ic,TRUE);
6937 /*-----------------------------------------------------------------*/
6938 /* genUnpackBits - generates code for unpacking bits */
6939 /*-----------------------------------------------------------------*/
6940 static void genUnpackBits (operand *result, char *rname, int ptype)
6947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6948 etype = getSpec(operandType(result));
6950 /* read the first byte */
6955 pic14_emitcode("mov","a,@%s",rname);
6959 pic14_emitcode("movx","a,@%s",rname);
6963 pic14_emitcode("movx","a,@dptr");
6967 pic14_emitcode("clr","a");
6968 pic14_emitcode("movc","a","@a+dptr");
6972 pic14_emitcode("lcall","__gptrget");
6976 /* if we have bitdisplacement then it fits */
6977 /* into this byte completely or if length is */
6978 /* less than a byte */
6979 if ((shCnt = SPEC_BSTR(etype)) ||
6980 (SPEC_BLEN(etype) <= 8)) {
6982 /* shift right acc */
6985 pic14_emitcode("anl","a,#0x%02x",
6986 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6987 aopPut(AOP(result),"a",offset);
6991 /* bit field did not fit in a byte */
6992 rlen = SPEC_BLEN(etype) - 8;
6993 aopPut(AOP(result),"a",offset++);
7000 pic14_emitcode("inc","%s",rname);
7001 pic14_emitcode("mov","a,@%s",rname);
7005 pic14_emitcode("inc","%s",rname);
7006 pic14_emitcode("movx","a,@%s",rname);
7010 pic14_emitcode("inc","dptr");
7011 pic14_emitcode("movx","a,@dptr");
7015 pic14_emitcode("clr","a");
7016 pic14_emitcode("inc","dptr");
7017 pic14_emitcode("movc","a","@a+dptr");
7021 pic14_emitcode("inc","dptr");
7022 pic14_emitcode("lcall","__gptrget");
7027 /* if we are done */
7031 aopPut(AOP(result),"a",offset++);
7036 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7037 aopPut(AOP(result),"a",offset);
7044 /*-----------------------------------------------------------------*/
7045 /* genDataPointerGet - generates code when ptr offset is known */
7046 /*-----------------------------------------------------------------*/
7047 static void genDataPointerGet (operand *left,
7051 int size , offset = 0;
7054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7057 /* optimization - most of the time, left and result are the same
7058 * address, but different types. for the pic code, we could omit
7062 aopOp(result,ic,TRUE);
7064 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7066 size = AOP_SIZE(result);
7069 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7073 freeAsmop(left,NULL,ic,TRUE);
7074 freeAsmop(result,NULL,ic,TRUE);
7077 /*-----------------------------------------------------------------*/
7078 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7079 /*-----------------------------------------------------------------*/
7080 static void genNearPointerGet (operand *left,
7087 sym_link *rtype, *retype;
7088 sym_link *ltype = operandType(left);
7091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7093 rtype = operandType(result);
7094 retype= getSpec(rtype);
7096 aopOp(left,ic,FALSE);
7098 /* if left is rematerialisable and
7099 result is not bit variable type and
7100 the left is pointer to data space i.e
7101 lower 128 bytes of space */
7102 if (AOP_TYPE(left) == AOP_IMMD &&
7103 !IS_BITVAR(retype) &&
7104 DCL_TYPE(ltype) == POINTER) {
7105 genDataPointerGet (left,result,ic);
7109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7111 /* if the value is already in a pointer register
7112 then don't need anything more */
7113 if (!AOP_INPREG(AOP(left))) {
7114 /* otherwise get a free pointer register */
7115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7117 preg = getFreePtr(ic,&aop,FALSE);
7118 pic14_emitcode("mov","%s,%s",
7120 aopGet(AOP(left),0,FALSE,TRUE));
7121 rname = preg->name ;
7123 rname = aopGet(AOP(left),0,FALSE,FALSE);
7125 freeAsmop(left,NULL,ic,TRUE);
7126 aopOp (result,ic,FALSE);
7128 /* if bitfield then unpack the bits */
7129 if (IS_BITVAR(retype))
7130 genUnpackBits (result,rname,POINTER);
7132 /* we have can just get the values */
7133 int size = AOP_SIZE(result);
7136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7138 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7140 pic14_emitcode("mov","a,@%s",rname);
7141 aopPut(AOP(result),"a",offset);
7143 sprintf(buffer,"@%s",rname);
7144 aopPut(AOP(result),buffer,offset);
7148 pic14_emitcode("inc","%s",rname);
7152 /* now some housekeeping stuff */
7154 /* we had to allocate for this iCode */
7155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7156 freeAsmop(NULL,aop,ic,TRUE);
7158 /* we did not allocate which means left
7159 already in a pointer register, then
7160 if size > 0 && this could be used again
7161 we have to point it back to where it
7163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7164 if (AOP_SIZE(result) > 1 &&
7165 !OP_SYMBOL(left)->remat &&
7166 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7168 int size = AOP_SIZE(result) - 1;
7170 pic14_emitcode("dec","%s",rname);
7175 freeAsmop(result,NULL,ic,TRUE);
7179 /*-----------------------------------------------------------------*/
7180 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7181 /*-----------------------------------------------------------------*/
7182 static void genPagedPointerGet (operand *left,
7189 sym_link *rtype, *retype;
7191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7193 rtype = operandType(result);
7194 retype= getSpec(rtype);
7196 aopOp(left,ic,FALSE);
7198 /* if the value is already in a pointer register
7199 then don't need anything more */
7200 if (!AOP_INPREG(AOP(left))) {
7201 /* otherwise get a free pointer register */
7203 preg = getFreePtr(ic,&aop,FALSE);
7204 pic14_emitcode("mov","%s,%s",
7206 aopGet(AOP(left),0,FALSE,TRUE));
7207 rname = preg->name ;
7209 rname = aopGet(AOP(left),0,FALSE,FALSE);
7211 freeAsmop(left,NULL,ic,TRUE);
7212 aopOp (result,ic,FALSE);
7214 /* if bitfield then unpack the bits */
7215 if (IS_BITVAR(retype))
7216 genUnpackBits (result,rname,PPOINTER);
7218 /* we have can just get the values */
7219 int size = AOP_SIZE(result);
7224 pic14_emitcode("movx","a,@%s",rname);
7225 aopPut(AOP(result),"a",offset);
7230 pic14_emitcode("inc","%s",rname);
7234 /* now some housekeeping stuff */
7236 /* we had to allocate for this iCode */
7237 freeAsmop(NULL,aop,ic,TRUE);
7239 /* we did not allocate which means left
7240 already in a pointer register, then
7241 if size > 0 && this could be used again
7242 we have to point it back to where it
7244 if (AOP_SIZE(result) > 1 &&
7245 !OP_SYMBOL(left)->remat &&
7246 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7248 int size = AOP_SIZE(result) - 1;
7250 pic14_emitcode("dec","%s",rname);
7255 freeAsmop(result,NULL,ic,TRUE);
7260 /*-----------------------------------------------------------------*/
7261 /* genFarPointerGet - gget value from far space */
7262 /*-----------------------------------------------------------------*/
7263 static void genFarPointerGet (operand *left,
7264 operand *result, iCode *ic)
7267 sym_link *retype = getSpec(operandType(result));
7269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7271 aopOp(left,ic,FALSE);
7273 /* if the operand is already in dptr
7274 then we do nothing else we move the value to dptr */
7275 if (AOP_TYPE(left) != AOP_STR) {
7276 /* if this is remateriazable */
7277 if (AOP_TYPE(left) == AOP_IMMD)
7278 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7279 else { /* we need to get it byte by byte */
7280 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7281 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7282 if (options.model == MODEL_FLAT24)
7284 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7288 /* so dptr know contains the address */
7289 freeAsmop(left,NULL,ic,TRUE);
7290 aopOp(result,ic,FALSE);
7292 /* if bit then unpack */
7293 if (IS_BITVAR(retype))
7294 genUnpackBits(result,"dptr",FPOINTER);
7296 size = AOP_SIZE(result);
7300 pic14_emitcode("movx","a,@dptr");
7301 aopPut(AOP(result),"a",offset++);
7303 pic14_emitcode("inc","dptr");
7307 freeAsmop(result,NULL,ic,TRUE);
7310 /*-----------------------------------------------------------------*/
7311 /* pic14_emitcodePointerGet - gget value from code space */
7312 /*-----------------------------------------------------------------*/
7313 static void pic14_emitcodePointerGet (operand *left,
7314 operand *result, iCode *ic)
7317 sym_link *retype = getSpec(operandType(result));
7319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7321 aopOp(left,ic,FALSE);
7323 /* if the operand is already in dptr
7324 then we do nothing else we move the value to dptr */
7325 if (AOP_TYPE(left) != AOP_STR) {
7326 /* if this is remateriazable */
7327 if (AOP_TYPE(left) == AOP_IMMD)
7328 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7329 else { /* we need to get it byte by byte */
7330 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7331 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7332 if (options.model == MODEL_FLAT24)
7334 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7338 /* so dptr know contains the address */
7339 freeAsmop(left,NULL,ic,TRUE);
7340 aopOp(result,ic,FALSE);
7342 /* if bit then unpack */
7343 if (IS_BITVAR(retype))
7344 genUnpackBits(result,"dptr",CPOINTER);
7346 size = AOP_SIZE(result);
7350 pic14_emitcode("clr","a");
7351 pic14_emitcode("movc","a,@a+dptr");
7352 aopPut(AOP(result),"a",offset++);
7354 pic14_emitcode("inc","dptr");
7358 freeAsmop(result,NULL,ic,TRUE);
7361 /*-----------------------------------------------------------------*/
7362 /* genGenPointerGet - gget value from generic pointer space */
7363 /*-----------------------------------------------------------------*/
7364 static void genGenPointerGet (operand *left,
7365 operand *result, iCode *ic)
7368 sym_link *retype = getSpec(operandType(result));
7370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7371 aopOp(left,ic,FALSE);
7372 aopOp(result,ic,FALSE);
7375 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7377 /* if the operand is already in dptr
7378 then we do nothing else we move the value to dptr */
7379 if (AOP_TYPE(left) != AOP_STR) {
7380 /* if this is remateriazable */
7381 if (AOP_TYPE(left) == AOP_IMMD) {
7382 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7383 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7385 else { /* we need to get it byte by byte */
7387 size = AOP_SIZE(result);
7391 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7392 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7394 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7399 /* so dptr know contains the address */
7401 /* if bit then unpack */
7402 if (IS_BITVAR(retype))
7403 genUnpackBits(result,"dptr",GPOINTER);
7406 freeAsmop(left,NULL,ic,TRUE);
7407 freeAsmop(result,NULL,ic,TRUE);
7411 /*-----------------------------------------------------------------*/
7412 /* genPointerGet - generate code for pointer get */
7413 /*-----------------------------------------------------------------*/
7414 static void genPointerGet (iCode *ic)
7416 operand *left, *result ;
7417 sym_link *type, *etype;
7420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7423 result = IC_RESULT(ic) ;
7425 /* depending on the type of pointer we need to
7426 move it to the correct pointer register */
7427 type = operandType(left);
7428 etype = getSpec(type);
7429 /* if left is of type of pointer then it is simple */
7430 if (IS_PTR(type) && !IS_FUNC(type->next))
7431 p_type = DCL_TYPE(type);
7433 /* we have to go by the storage class */
7434 p_type = PTR_TYPE(SPEC_OCLS(etype));
7436 /* if (SPEC_OCLS(etype)->codesp ) { */
7437 /* p_type = CPOINTER ; */
7440 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7441 /* p_type = FPOINTER ; */
7443 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7444 /* p_type = PPOINTER; */
7446 /* if (SPEC_OCLS(etype) == idata ) */
7447 /* p_type = IPOINTER; */
7449 /* p_type = POINTER ; */
7452 /* now that we have the pointer type we assign
7453 the pointer values */
7458 genNearPointerGet (left,result,ic);
7462 genPagedPointerGet(left,result,ic);
7466 genFarPointerGet (left,result,ic);
7470 pic14_emitcodePointerGet (left,result,ic);
7474 genGenPointerGet (left,result,ic);
7480 /*-----------------------------------------------------------------*/
7481 /* genPackBits - generates code for packed bit storage */
7482 /*-----------------------------------------------------------------*/
7483 static void genPackBits (sym_link *etype ,
7485 char *rname, int p_type)
7493 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7494 blen = SPEC_BLEN(etype);
7495 bstr = SPEC_BSTR(etype);
7497 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7500 /* if the bit lenth is less than or */
7501 /* it exactly fits a byte then */
7502 if (SPEC_BLEN(etype) <= 8 ) {
7503 shCount = SPEC_BSTR(etype) ;
7505 /* shift left acc */
7508 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7513 pic14_emitcode ("mov","b,a");
7514 pic14_emitcode("mov","a,@%s",rname);
7518 pic14_emitcode ("mov","b,a");
7519 pic14_emitcode("movx","a,@dptr");
7523 pic14_emitcode ("push","b");
7524 pic14_emitcode ("push","acc");
7525 pic14_emitcode ("lcall","__gptrget");
7526 pic14_emitcode ("pop","b");
7530 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7531 ((unsigned char)(0xFF << (blen+bstr)) |
7532 (unsigned char)(0xFF >> (8-bstr)) ) );
7533 pic14_emitcode ("orl","a,b");
7534 if (p_type == GPOINTER)
7535 pic14_emitcode("pop","b");
7541 pic14_emitcode("mov","@%s,a",rname);
7545 pic14_emitcode("movx","@dptr,a");
7549 DEBUGpic14_emitcode(";lcall","__gptrput");
7554 if ( SPEC_BLEN(etype) <= 8 )
7557 pic14_emitcode("inc","%s",rname);
7558 rLen = SPEC_BLEN(etype) ;
7560 /* now generate for lengths greater than one byte */
7563 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7573 pic14_emitcode("mov","@%s,a",rname);
7575 pic14_emitcode("mov","@%s,%s",rname,l);
7580 pic14_emitcode("movx","@dptr,a");
7585 DEBUGpic14_emitcode(";lcall","__gptrput");
7588 pic14_emitcode ("inc","%s",rname);
7593 /* last last was not complete */
7595 /* save the byte & read byte */
7598 pic14_emitcode ("mov","b,a");
7599 pic14_emitcode("mov","a,@%s",rname);
7603 pic14_emitcode ("mov","b,a");
7604 pic14_emitcode("movx","a,@dptr");
7608 pic14_emitcode ("push","b");
7609 pic14_emitcode ("push","acc");
7610 pic14_emitcode ("lcall","__gptrget");
7611 pic14_emitcode ("pop","b");
7615 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7616 pic14_emitcode ("orl","a,b");
7619 if (p_type == GPOINTER)
7620 pic14_emitcode("pop","b");
7625 pic14_emitcode("mov","@%s,a",rname);
7629 pic14_emitcode("movx","@dptr,a");
7633 DEBUGpic14_emitcode(";lcall","__gptrput");
7637 /*-----------------------------------------------------------------*/
7638 /* genDataPointerSet - remat pointer to data space */
7639 /*-----------------------------------------------------------------*/
7640 static void genDataPointerSet(operand *right,
7644 int size, offset = 0 ;
7645 char *l, buffer[256];
7647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7648 aopOp(right,ic,FALSE);
7650 l = aopGet(AOP(result),0,FALSE,TRUE);
7651 size = AOP_SIZE(right);
7652 // tsd, was l+1 - the underline `_' prefix was being stripped
7655 sprintf(buffer,"(%s + %d)",l,offset);
7657 sprintf(buffer,"%s",l);
7659 if (AOP_TYPE(right) == AOP_LIT) {
7660 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7661 lit = lit >> (8*offset);
7663 pic14_emitcode("movlw","%d",lit);
7664 pic14_emitcode("movwf","%s",buffer);
7666 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7667 emitpcode(POC_MOVWF, popRegFromString(buffer));
7670 pic14_emitcode("clrf","%s",buffer);
7671 emitpcode(POC_CLRF, popRegFromString(buffer));
7674 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7675 pic14_emitcode("movwf","%s",buffer);
7677 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
7678 emitpcode(POC_MOVWF, popRegFromString(buffer));
7685 freeAsmop(right,NULL,ic,TRUE);
7686 freeAsmop(result,NULL,ic,TRUE);
7689 /*-----------------------------------------------------------------*/
7690 /* genNearPointerSet - pic14_emitcode for near pointer put */
7691 /*-----------------------------------------------------------------*/
7692 static void genNearPointerSet (operand *right,
7699 sym_link *ptype = operandType(result);
7702 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7703 retype= getSpec(operandType(right));
7705 aopOp(result,ic,FALSE);
7707 /* if the result is rematerializable &
7708 in data space & not a bit variable */
7709 if (AOP_TYPE(result) == AOP_IMMD &&
7710 DCL_TYPE(ptype) == POINTER &&
7711 !IS_BITVAR(retype)) {
7712 genDataPointerSet (right,result,ic);
7716 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7718 /* if the value is already in a pointer register
7719 then don't need anything more */
7720 if (!AOP_INPREG(AOP(result))) {
7721 /* otherwise get a free pointer register */
7722 //aop = newAsmop(0);
7723 //preg = getFreePtr(ic,&aop,FALSE);
7724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7725 //pic14_emitcode("mov","%s,%s",
7727 // aopGet(AOP(result),0,FALSE,TRUE));
7728 //rname = preg->name ;
7729 pic14_emitcode("movwf","fsr");
7731 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7733 freeAsmop(result,NULL,ic,TRUE);
7734 aopOp (right,ic,FALSE);
7735 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7737 /* if bitfield then unpack the bits */
7738 if (IS_BITVAR(retype)) {
7739 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7740 "The programmer is obviously confused");
7741 //genPackBits (retype,right,rname,POINTER);
7745 /* we have can just get the values */
7746 int size = AOP_SIZE(right);
7749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7751 l = aopGet(AOP(right),offset,FALSE,TRUE);
7754 //pic14_emitcode("mov","@%s,a",rname);
7755 pic14_emitcode("movf","indf,w ;1");
7758 if (AOP_TYPE(right) == AOP_LIT) {
7759 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7761 pic14_emitcode("movlw","%s",l);
7762 pic14_emitcode("movwf","indf ;2");
7764 pic14_emitcode("clrf","indf");
7766 pic14_emitcode("movf","%s,w",l);
7767 pic14_emitcode("movwf","indf ;2");
7769 //pic14_emitcode("mov","@%s,%s",rname,l);
7772 pic14_emitcode("incf","fsr,f ;3");
7773 //pic14_emitcode("inc","%s",rname);
7778 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7779 /* now some housekeeping stuff */
7781 /* we had to allocate for this iCode */
7782 freeAsmop(NULL,aop,ic,TRUE);
7784 /* we did not allocate which means left
7785 already in a pointer register, then
7786 if size > 0 && this could be used again
7787 we have to point it back to where it
7789 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7790 if (AOP_SIZE(right) > 1 &&
7791 !OP_SYMBOL(result)->remat &&
7792 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7794 int size = AOP_SIZE(right) - 1;
7796 pic14_emitcode("decf","fsr,f");
7797 //pic14_emitcode("dec","%s",rname);
7801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7803 freeAsmop(right,NULL,ic,TRUE);
7808 /*-----------------------------------------------------------------*/
7809 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7810 /*-----------------------------------------------------------------*/
7811 static void genPagedPointerSet (operand *right,
7820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7822 retype= getSpec(operandType(right));
7824 aopOp(result,ic,FALSE);
7826 /* if the value is already in a pointer register
7827 then don't need anything more */
7828 if (!AOP_INPREG(AOP(result))) {
7829 /* otherwise get a free pointer register */
7831 preg = getFreePtr(ic,&aop,FALSE);
7832 pic14_emitcode("mov","%s,%s",
7834 aopGet(AOP(result),0,FALSE,TRUE));
7835 rname = preg->name ;
7837 rname = aopGet(AOP(result),0,FALSE,FALSE);
7839 freeAsmop(result,NULL,ic,TRUE);
7840 aopOp (right,ic,FALSE);
7842 /* if bitfield then unpack the bits */
7843 if (IS_BITVAR(retype))
7844 genPackBits (retype,right,rname,PPOINTER);
7846 /* we have can just get the values */
7847 int size = AOP_SIZE(right);
7851 l = aopGet(AOP(right),offset,FALSE,TRUE);
7854 pic14_emitcode("movx","@%s,a",rname);
7857 pic14_emitcode("inc","%s",rname);
7863 /* now some housekeeping stuff */
7865 /* we had to allocate for this iCode */
7866 freeAsmop(NULL,aop,ic,TRUE);
7868 /* we did not allocate which means left
7869 already in a pointer register, then
7870 if size > 0 && this could be used again
7871 we have to point it back to where it
7873 if (AOP_SIZE(right) > 1 &&
7874 !OP_SYMBOL(result)->remat &&
7875 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7877 int size = AOP_SIZE(right) - 1;
7879 pic14_emitcode("dec","%s",rname);
7884 freeAsmop(right,NULL,ic,TRUE);
7889 /*-----------------------------------------------------------------*/
7890 /* genFarPointerSet - set value from far space */
7891 /*-----------------------------------------------------------------*/
7892 static void genFarPointerSet (operand *right,
7893 operand *result, iCode *ic)
7896 sym_link *retype = getSpec(operandType(right));
7898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7899 aopOp(result,ic,FALSE);
7901 /* if the operand is already in dptr
7902 then we do nothing else we move the value to dptr */
7903 if (AOP_TYPE(result) != AOP_STR) {
7904 /* if this is remateriazable */
7905 if (AOP_TYPE(result) == AOP_IMMD)
7906 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7907 else { /* we need to get it byte by byte */
7908 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7909 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7910 if (options.model == MODEL_FLAT24)
7912 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7916 /* so dptr know contains the address */
7917 freeAsmop(result,NULL,ic,TRUE);
7918 aopOp(right,ic,FALSE);
7920 /* if bit then unpack */
7921 if (IS_BITVAR(retype))
7922 genPackBits(retype,right,"dptr",FPOINTER);
7924 size = AOP_SIZE(right);
7928 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7930 pic14_emitcode("movx","@dptr,a");
7932 pic14_emitcode("inc","dptr");
7936 freeAsmop(right,NULL,ic,TRUE);
7939 /*-----------------------------------------------------------------*/
7940 /* genGenPointerSet - set value from generic pointer space */
7941 /*-----------------------------------------------------------------*/
7942 static void genGenPointerSet (operand *right,
7943 operand *result, iCode *ic)
7946 sym_link *retype = getSpec(operandType(right));
7948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7950 aopOp(result,ic,FALSE);
7951 aopOp(right,ic,FALSE);
7952 size = AOP_SIZE(right);
7954 DEBUGpic14_AopType(__LINE__,NULL,right,result);
7956 /* if the operand is already in dptr
7957 then we do nothing else we move the value to dptr */
7958 if (AOP_TYPE(result) != AOP_STR) {
7959 /* if this is remateriazable */
7960 if (AOP_TYPE(result) == AOP_IMMD) {
7961 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7962 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7964 else { /* we need to get it byte by byte */
7965 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
7966 size = AOP_SIZE(right);
7969 /* hack hack! see if this the FSR. If so don't load W */
7970 if(AOP_TYPE(right) != AOP_ACC) {
7973 emitpcode(POC_DECF,popCopyReg(&pc_fsr));
7976 emitpcode(POC_MOVLW,popGetLit(0xfd));
7977 emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
7981 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
7982 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7985 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7992 if(aopIdx(AOP(result),0) != 4) {
7994 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7998 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8003 /* so dptr know contains the address */
8006 /* if bit then unpack */
8007 if (IS_BITVAR(retype))
8008 genPackBits(retype,right,"dptr",GPOINTER);
8010 size = AOP_SIZE(right);
8014 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8016 pic14_emitcode("incf","fsr,f");
8017 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8018 pic14_emitcode("movwf","indf");
8020 //DEBUGpic14_emitcode(";lcall","__gptrput");
8022 // pic14_emitcode("inc","dptr");
8027 freeAsmop(right,NULL,ic,TRUE);
8028 freeAsmop(result,NULL,ic,TRUE);
8031 /*-----------------------------------------------------------------*/
8032 /* genPointerSet - stores the value into a pointer location */
8033 /*-----------------------------------------------------------------*/
8034 static void genPointerSet (iCode *ic)
8036 operand *right, *result ;
8037 sym_link *type, *etype;
8040 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8042 right = IC_RIGHT(ic);
8043 result = IC_RESULT(ic) ;
8045 /* depending on the type of pointer we need to
8046 move it to the correct pointer register */
8047 type = operandType(result);
8048 etype = getSpec(type);
8049 /* if left is of type of pointer then it is simple */
8050 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8051 p_type = DCL_TYPE(type);
8054 /* we have to go by the storage class */
8055 p_type = PTR_TYPE(SPEC_OCLS(etype));
8057 /* if (SPEC_OCLS(etype)->codesp ) { */
8058 /* p_type = CPOINTER ; */
8061 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8062 /* p_type = FPOINTER ; */
8064 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8065 /* p_type = PPOINTER ; */
8067 /* if (SPEC_OCLS(etype) == idata ) */
8068 /* p_type = IPOINTER ; */
8070 /* p_type = POINTER ; */
8073 /* now that we have the pointer type we assign
8074 the pointer values */
8079 genNearPointerSet (right,result,ic);
8083 genPagedPointerSet (right,result,ic);
8087 genFarPointerSet (right,result,ic);
8091 genGenPointerSet (right,result,ic);
8097 /*-----------------------------------------------------------------*/
8098 /* genIfx - generate code for Ifx statement */
8099 /*-----------------------------------------------------------------*/
8100 static void genIfx (iCode *ic, iCode *popIc)
8102 operand *cond = IC_COND(ic);
8105 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8107 aopOp(cond,ic,FALSE);
8109 /* get the value into acc */
8110 if (AOP_TYPE(cond) != AOP_CRY)
8111 pic14_toBoolean(cond);
8114 /* the result is now in the accumulator */
8115 freeAsmop(cond,NULL,ic,TRUE);
8117 /* if there was something to be popped then do it */
8121 /* if the condition is a bit variable */
8122 if (isbit && IS_ITEMP(cond) &&
8124 genIfxJump(ic,SPIL_LOC(cond)->rname);
8125 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8128 if (isbit && !IS_ITEMP(cond))
8129 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8137 /*-----------------------------------------------------------------*/
8138 /* genAddrOf - generates code for address of */
8139 /*-----------------------------------------------------------------*/
8140 static void genAddrOf (iCode *ic)
8142 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8143 operand *right, *result, *left;
8144 //int size, offset ;
8146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8149 //aopOp(IC_RESULT(ic),ic,FALSE);
8151 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8152 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8153 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8155 DEBUGpic14_AopType(__LINE__,left,right,result);
8157 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8158 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8161 /* object not on stack then we need the name */
8162 size = AOP_SIZE(IC_RESULT(ic));
8166 char s[SDCC_NAME_MAX];
8168 sprintf(s,"#(%s >> %d)",
8172 sprintf(s,"#%s",sym->rname);
8173 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8178 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8179 freeAsmop(left,NULL,ic,FALSE);
8180 freeAsmop(result,NULL,ic,TRUE);
8185 /*-----------------------------------------------------------------*/
8186 /* genFarFarAssign - assignment when both are in far space */
8187 /*-----------------------------------------------------------------*/
8188 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8190 int size = AOP_SIZE(right);
8193 /* first push the right side on to the stack */
8195 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8197 pic14_emitcode ("push","acc");
8200 freeAsmop(right,NULL,ic,FALSE);
8201 /* now assign DPTR to result */
8202 aopOp(result,ic,FALSE);
8203 size = AOP_SIZE(result);
8205 pic14_emitcode ("pop","acc");
8206 aopPut(AOP(result),"a",--offset);
8208 freeAsmop(result,NULL,ic,FALSE);
8213 /*-----------------------------------------------------------------*/
8214 /* genAssign - generate code for assignment */
8215 /*-----------------------------------------------------------------*/
8216 static void genAssign (iCode *ic)
8218 operand *result, *right;
8219 int size, offset,know_W;
8220 unsigned long lit = 0L;
8222 result = IC_RESULT(ic);
8223 right = IC_RIGHT(ic) ;
8225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8227 /* if they are the same */
8228 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8231 aopOp(right,ic,FALSE);
8232 aopOp(result,ic,TRUE);
8234 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8236 /* if they are the same registers */
8237 if (pic14_sameRegs(AOP(right),AOP(result)))
8240 /* if the result is a bit */
8241 if (AOP_TYPE(result) == AOP_CRY) {
8243 /* if the right size is a literal then
8244 we know what the value is */
8245 if (AOP_TYPE(right) == AOP_LIT) {
8247 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8248 popGet(AOP(result),0));
8250 if (((int) operandLitValue(right)))
8251 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8252 AOP(result)->aopu.aop_dir,
8253 AOP(result)->aopu.aop_dir);
8255 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8256 AOP(result)->aopu.aop_dir,
8257 AOP(result)->aopu.aop_dir);
8261 /* the right is also a bit variable */
8262 if (AOP_TYPE(right) == AOP_CRY) {
8263 emitpcode(POC_BCF, popGet(AOP(result),0));
8264 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8265 emitpcode(POC_BSF, popGet(AOP(result),0));
8267 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8268 AOP(result)->aopu.aop_dir,
8269 AOP(result)->aopu.aop_dir);
8270 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8271 AOP(right)->aopu.aop_dir,
8272 AOP(right)->aopu.aop_dir);
8273 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8274 AOP(result)->aopu.aop_dir,
8275 AOP(result)->aopu.aop_dir);
8280 emitpcode(POC_BCF, popGet(AOP(result),0));
8281 pic14_toBoolean(right);
8283 emitpcode(POC_BSF, popGet(AOP(result),0));
8284 //aopPut(AOP(result),"a",0);
8288 /* bit variables done */
8290 size = AOP_SIZE(result);
8292 if(AOP_TYPE(right) == AOP_LIT)
8293 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8295 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8296 if(aopIdx(AOP(result),0) == 4) {
8297 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8298 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8301 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8306 if(AOP_TYPE(right) == AOP_LIT) {
8308 if(know_W != (lit&0xff))
8309 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8311 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8313 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8317 } else if (AOP_TYPE(right) == AOP_CRY) {
8318 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8320 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8321 emitpcode(POC_INCF, popGet(AOP(result),0));
8324 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8325 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8333 freeAsmop (right,NULL,ic,FALSE);
8334 freeAsmop (result,NULL,ic,TRUE);
8337 /*-----------------------------------------------------------------*/
8338 /* genJumpTab - genrates code for jump table */
8339 /*-----------------------------------------------------------------*/
8340 static void genJumpTab (iCode *ic)
8345 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8347 aopOp(IC_JTCOND(ic),ic,FALSE);
8348 /* get the condition into accumulator */
8349 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8351 /* multiply by three */
8352 pic14_emitcode("add","a,acc");
8353 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8355 jtab = newiTempLabel(NULL);
8356 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8357 pic14_emitcode("jmp","@a+dptr");
8358 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8360 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8361 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8363 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8364 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8365 emitpLabel(jtab->key);
8367 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8369 /* now generate the jump labels */
8370 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8371 jtab = setNextItem(IC_JTLABELS(ic))) {
8372 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8373 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8379 /*-----------------------------------------------------------------*/
8380 /* genMixedOperation - gen code for operators between mixed types */
8381 /*-----------------------------------------------------------------*/
8383 TSD - Written for the PIC port - but this unfortunately is buggy.
8384 This routine is good in that it is able to efficiently promote
8385 types to different (larger) sizes. Unfortunately, the temporary
8386 variables that are optimized out by this routine are sometimes
8387 used in other places. So until I know how to really parse the
8388 iCode tree, I'm going to not be using this routine :(.
8390 static int genMixedOperation (iCode *ic)
8393 operand *result = IC_RESULT(ic);
8394 sym_link *ctype = operandType(IC_LEFT(ic));
8395 operand *right = IC_RIGHT(ic);
8401 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8403 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8409 nextright = IC_RIGHT(nextic);
8410 nextleft = IC_LEFT(nextic);
8411 nextresult = IC_RESULT(nextic);
8413 aopOp(right,ic,FALSE);
8414 aopOp(result,ic,FALSE);
8415 aopOp(nextright, nextic, FALSE);
8416 aopOp(nextleft, nextic, FALSE);
8417 aopOp(nextresult, nextic, FALSE);
8419 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8425 pic14_emitcode(";remove right +","");
8427 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8433 pic14_emitcode(";remove left +","");
8437 big = AOP_SIZE(nextleft);
8438 small = AOP_SIZE(nextright);
8440 switch(nextic->op) {
8443 pic14_emitcode(";optimize a +","");
8444 /* if unsigned or not an integral type */
8445 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8446 pic14_emitcode(";add a bit to something","");
8449 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8451 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8452 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8453 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8455 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8463 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8464 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8465 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8468 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8470 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8471 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8472 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8473 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8474 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8477 pic14_emitcode("rlf","known_zero,w");
8484 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8485 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8486 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8488 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8498 freeAsmop(right,NULL,ic,TRUE);
8499 freeAsmop(result,NULL,ic,TRUE);
8500 freeAsmop(nextright,NULL,ic,TRUE);
8501 freeAsmop(nextleft,NULL,ic,TRUE);
8503 nextic->generated = 1;
8510 /*-----------------------------------------------------------------*/
8511 /* genCast - gen code for casting */
8512 /*-----------------------------------------------------------------*/
8513 static void genCast (iCode *ic)
8515 operand *result = IC_RESULT(ic);
8516 sym_link *ctype = operandType(IC_LEFT(ic));
8517 operand *right = IC_RIGHT(ic);
8520 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8521 /* if they are equivalent then do nothing */
8522 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8525 aopOp(right,ic,FALSE) ;
8526 aopOp(result,ic,FALSE);
8528 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8530 /* if the result is a bit */
8531 if (AOP_TYPE(result) == AOP_CRY) {
8532 /* if the right size is a literal then
8533 we know what the value is */
8534 if (AOP_TYPE(right) == AOP_LIT) {
8536 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8537 popGet(AOP(result),0));
8539 if (((int) operandLitValue(right)))
8540 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8541 AOP(result)->aopu.aop_dir,
8542 AOP(result)->aopu.aop_dir);
8544 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8545 AOP(result)->aopu.aop_dir,
8546 AOP(result)->aopu.aop_dir);
8551 /* the right is also a bit variable */
8552 if (AOP_TYPE(right) == AOP_CRY) {
8555 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8557 pic14_emitcode("clrc","");
8558 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8559 AOP(right)->aopu.aop_dir,
8560 AOP(right)->aopu.aop_dir);
8561 aopPut(AOP(result),"c",0);
8566 if (AOP_TYPE(right) == AOP_REG) {
8567 emitpcode(POC_BCF, popGet(AOP(result),0));
8568 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8569 emitpcode(POC_BSF, popGet(AOP(result),0));
8571 pic14_toBoolean(right);
8572 aopPut(AOP(result),"a",0);
8576 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
8578 size = AOP_SIZE(result);
8580 emitpcode(POC_CLRF, popGet(AOP(result),0));
8581 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8582 emitpcode(POC_INCF, popGet(AOP(result),0));
8585 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8590 /* if they are the same size : or less */
8591 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8593 /* if they are in the same place */
8594 if (pic14_sameRegs(AOP(right),AOP(result)))
8597 /* if they in different places then copy */
8598 size = AOP_SIZE(result);
8602 aopGet(AOP(right),offset,FALSE,FALSE),
8610 /* if the result is of type pointer */
8611 if (IS_PTR(ctype)) {
8614 sym_link *type = operandType(right);
8615 sym_link *etype = getSpec(type);
8617 /* pointer to generic pointer */
8618 if (IS_GENPTR(ctype)) {
8622 p_type = DCL_TYPE(type);
8624 /* we have to go by the storage class */
8625 p_type = PTR_TYPE(SPEC_OCLS(etype));
8627 /* if (SPEC_OCLS(etype)->codesp ) */
8628 /* p_type = CPOINTER ; */
8630 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8631 /* p_type = FPOINTER ; */
8633 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8634 /* p_type = PPOINTER; */
8636 /* if (SPEC_OCLS(etype) == idata ) */
8637 /* p_type = IPOINTER ; */
8639 /* p_type = POINTER ; */
8642 /* the first two bytes are known */
8643 size = GPTRSIZE - 1;
8647 aopGet(AOP(right),offset,FALSE,FALSE),
8651 /* the last byte depending on type */
8668 /* this should never happen */
8669 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8670 "got unknown pointer type");
8673 aopPut(AOP(result),l, GPTRSIZE - 1);
8677 /* just copy the pointers */
8678 size = AOP_SIZE(result);
8682 aopGet(AOP(right),offset,FALSE,FALSE),
8691 /* so we now know that the size of destination is greater
8692 than the size of the source.
8693 Now, if the next iCode is an operator then we might be
8694 able to optimize the operation without performing a cast.
8696 if(genMixedOperation(ic))
8700 /* we move to result for the size of source */
8701 size = AOP_SIZE(right);
8704 pic14_emitcode(";","%d",__LINE__);
8705 /* aopPut(AOP(result),
8706 aopGet(AOP(right),offset,FALSE,FALSE),
8708 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8709 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8713 /* now depending on the sign of the destination */
8714 size = AOP_SIZE(result) - AOP_SIZE(right);
8715 /* if unsigned or not an integral type */
8716 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8718 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8719 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8723 /* we need to extend the sign :{ */
8725 emitpcodeNULLop(POC_CLRW);
8728 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8730 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8732 emitpcode(POC_MOVLW, popGetLit(0xff));
8734 pic14_emitcode("clrw","");
8735 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8736 AOP(right)->aopu.aop_dir,
8737 AOP(right)->aopu.aop_dir);
8738 pic14_emitcode("movlw","0xff");
8740 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8741 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8743 // aopPut(AOP(result),"a",offset++);
8748 /* we are done hurray !!!! */
8751 freeAsmop(right,NULL,ic,TRUE);
8752 freeAsmop(result,NULL,ic,TRUE);
8756 /*-----------------------------------------------------------------*/
8757 /* genDjnz - generate decrement & jump if not zero instrucion */
8758 /*-----------------------------------------------------------------*/
8759 static int genDjnz (iCode *ic, iCode *ifx)
8762 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 /* if the if condition has a false label
8768 then we cannot save */
8772 /* if the minus is not of the form
8774 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8775 !IS_OP_LITERAL(IC_RIGHT(ic)))
8778 if (operandLitValue(IC_RIGHT(ic)) != 1)
8781 /* if the size of this greater than one then no
8783 if (getSize(operandType(IC_RESULT(ic))) > 1)
8786 /* otherwise we can save BIG */
8787 lbl = newiTempLabel(NULL);
8788 lbl1= newiTempLabel(NULL);
8790 aopOp(IC_RESULT(ic),ic,FALSE);
8792 if (IS_AOP_PREG(IC_RESULT(ic))) {
8793 pic14_emitcode("dec","%s",
8794 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8795 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8796 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8800 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
8801 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8803 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8804 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8807 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8808 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8809 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8810 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8813 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8818 /*-----------------------------------------------------------------*/
8819 /* genReceive - generate code for a receive iCode */
8820 /*-----------------------------------------------------------------*/
8821 static void genReceive (iCode *ic)
8823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8825 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8826 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8827 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8829 int size = getSize(operandType(IC_RESULT(ic)));
8830 int offset = fReturnSizePic - size;
8832 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8833 fReturn[fReturnSizePic - offset - 1] : "acc"));
8836 aopOp(IC_RESULT(ic),ic,FALSE);
8837 size = AOP_SIZE(IC_RESULT(ic));
8840 pic14_emitcode ("pop","acc");
8841 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8846 aopOp(IC_RESULT(ic),ic,FALSE);
8848 assignResultValue(IC_RESULT(ic));
8851 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8854 /*-----------------------------------------------------------------*/
8855 /* genpic14Code - generate code for pic14 based controllers */
8856 /*-----------------------------------------------------------------*/
8858 * At this point, ralloc.c has gone through the iCode and attempted
8859 * to optimize in a way suitable for a PIC. Now we've got to generate
8860 * PIC instructions that correspond to the iCode.
8862 * Once the instructions are generated, we'll pass through both the
8863 * peep hole optimizer and the pCode optimizer.
8864 *-----------------------------------------------------------------*/
8866 void genpic14Code (iCode *lic)
8871 lineHead = lineCurr = NULL;
8873 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8876 /* if debug information required */
8877 /* if (options.debug && currFunc) { */
8879 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8881 if (IS_STATIC(currFunc->etype)) {
8882 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8883 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8885 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8886 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8892 for (ic = lic ; ic ; ic = ic->next ) {
8894 DEBUGpic14_emitcode(";ic","");
8895 if ( cln != ic->lineno ) {
8896 if ( options.debug ) {
8898 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8899 FileBaseName(ic->filename),ic->lineno,
8900 ic->level,ic->block);
8903 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
8906 /* if the result is marked as
8907 spilt and rematerializable or code for
8908 this has already been generated then
8910 if (resultRemat(ic) || ic->generated )
8913 /* depending on the operation */
8932 /* IPOP happens only when trying to restore a
8933 spilt live range, if there is an ifx statement
8934 following this pop then the if statement might
8935 be using some of the registers being popped which
8936 would destory the contents of the register so
8937 we need to check for this condition and handle it */
8939 ic->next->op == IFX &&
8940 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8941 genIfx (ic->next,ic);
8959 genEndFunction (ic);
8979 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8996 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9000 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9007 /* note these two are xlated by algebraic equivalence
9008 during parsing SDCC.y */
9009 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9010 "got '>=' or '<=' shouldn't have come here");
9014 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9026 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9030 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9034 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9061 case GET_VALUE_AT_ADDRESS:
9066 if (POINTER_SET(ic))
9093 addSet(&_G.sendSet,ic);
9102 /* now we are ready to call the
9103 peep hole optimizer */
9104 if (!options.nopeep) {
9105 printf("peep hole optimizing\n");
9106 peepHole (&lineHead);
9108 /* now do the actual printing */
9109 printLine (lineHead,codeOutFile);
9111 printf("printing pBlock\n\n");
9112 printpBlock(stdout,pb);