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"
62 static int labelOffset=0;
63 static int debug_verbose=1;
64 static int optimized_for_speed = 0;
66 /* max_key keeps track of the largest label number used in
67 a function. This is then used to adjust the label offset
68 for the next function.
71 unsigned int pic14aopLiteral (value *val, int offset);
72 const char *AopType(short type);
74 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
76 /* this is the down and dirty file with all kinds of
77 kludgy & hacky stuff. This is what it is all about
78 CODE GENERATION for a specific MCU . some of the
79 routines may be reusable, will have to see */
81 static char *zero = "#0x00";
82 static char *one = "#0x01";
83 static char *spname = "sp";
85 char *fReturnpic14[] = {"FSR","dph","b","a" };
86 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
87 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
88 static char **fReturn = fReturnpic14;
90 static char *accUse[] = {"a","b"};
92 //static short rbank = -1;
104 extern int pic14_ptrRegReq ;
105 extern int pic14_nRegs;
106 extern FILE *codeOutFile;
107 static void saverbank (int, iCode *,bool);
109 static lineNode *lineHead = NULL;
110 static lineNode *lineCurr = NULL;
112 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
113 0xE0, 0xC0, 0x80, 0x00};
114 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
115 0x07, 0x03, 0x01, 0x00};
119 /*-----------------------------------------------------------------*/
120 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
121 /* exponent of 2 is returned, otherwise -1 is */
123 /* note that this is similar to the function `powof2' in SDCCsymt */
127 /*-----------------------------------------------------------------*/
128 static int my_powof2 (unsigned long num)
131 if( (num & (num-1)) == 0) {
144 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
147 char lb[INITIAL_INLINEASM];
157 sprintf(lb,"%s\t",inst);
159 sprintf(lb,"%s",inst);
160 vsprintf(lb+(strlen(lb)),fmt,ap);
164 while (isspace(*lbp)) lbp++;
167 lineCurr = (lineCurr ?
168 connectLine(lineCurr,newLineNode(lb)) :
169 (lineHead = newLineNode(lb)));
170 lineCurr->isInline = _G.inLine;
171 lineCurr->isDebug = _G.debugLine;
173 addpCode2pBlock(pb,newpCodeCharP(lb));
179 static void emitpLabel(int key)
181 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
184 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
188 addpCode2pBlock(pb,newpCode(poc,pcop));
190 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
193 void emitpcodeNULLop(PIC_OPCODE poc)
196 addpCode2pBlock(pb,newpCode(poc,NULL));
200 /*-----------------------------------------------------------------*/
201 /* pic14_emitcode - writes the code into a file : for now it is simple */
202 /*-----------------------------------------------------------------*/
203 void pic14_emitcode (char *inst,char *fmt, ...)
206 char lb[INITIAL_INLINEASM];
213 sprintf(lb,"%s\t",inst);
215 sprintf(lb,"%s",inst);
216 vsprintf(lb+(strlen(lb)),fmt,ap);
220 while (isspace(*lbp)) lbp++;
223 lineCurr = (lineCurr ?
224 connectLine(lineCurr,newLineNode(lb)) :
225 (lineHead = newLineNode(lb)));
226 lineCurr->isInline = _G.inLine;
227 lineCurr->isDebug = _G.debugLine;
230 addpCode2pBlock(pb,newpCodeCharP(lb));
236 /*-----------------------------------------------------------------*/
237 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
238 /*-----------------------------------------------------------------*/
239 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
241 bool r0iu = FALSE , r1iu = FALSE;
242 bool r0ou = FALSE , r1ou = FALSE;
244 /* the logic: if r0 & r1 used in the instruction
245 then we are in trouble otherwise */
247 /* first check if r0 & r1 are used by this
248 instruction, in which case we are in trouble */
249 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
250 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
255 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
256 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
258 /* if no usage of r0 then return it */
259 if (!r0iu && !r0ou) {
260 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
261 (*aopp)->type = AOP_R0;
263 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
266 /* if no usage of r1 then return it */
267 if (!r1iu && !r1ou) {
268 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
269 (*aopp)->type = AOP_R1;
271 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
274 /* now we know they both have usage */
275 /* if r0 not used in this instruction */
277 /* push it if not already pushed */
279 pic14_emitcode ("push","%s",
280 pic14_regWithIdx(R0_IDX)->dname);
284 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
285 (*aopp)->type = AOP_R0;
287 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
290 /* if r1 not used then */
293 /* push it if not already pushed */
295 pic14_emitcode ("push","%s",
296 pic14_regWithIdx(R1_IDX)->dname);
300 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
301 (*aopp)->type = AOP_R1;
302 return pic14_regWithIdx(R1_IDX);
306 /* I said end of world but not quite end of world yet */
307 /* if this is a result then we can push it on the stack*/
309 (*aopp)->type = AOP_STK;
313 /* other wise this is true end of the world */
314 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
315 "getFreePtr should never reach here");
319 /*-----------------------------------------------------------------*/
320 /* newAsmop - creates a new asmOp */
321 /*-----------------------------------------------------------------*/
322 asmop *newAsmop (short type)
326 aop = Safe_calloc(1,sizeof(asmop));
331 static void genSetDPTR(int n)
335 pic14_emitcode(";", "Select standard DPTR");
336 pic14_emitcode("mov", "dps, #0x00");
340 pic14_emitcode(";", "Select alternate DPTR");
341 pic14_emitcode("mov", "dps, #0x01");
345 /*-----------------------------------------------------------------*/
346 /* pointerCode - returns the code for a pointer type */
347 /*-----------------------------------------------------------------*/
348 static int pointerCode (sym_link *etype)
351 return PTR_TYPE(SPEC_OCLS(etype));
355 /*-----------------------------------------------------------------*/
356 /* aopForSym - for a true symbol */
357 /*-----------------------------------------------------------------*/
358 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
361 memmap *space= SPEC_OCLS(sym->etype);
363 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
364 /* if already has one */
368 /* assign depending on the storage class */
369 /* if it is on the stack or indirectly addressable */
370 /* space we need to assign either r0 or r1 to it */
371 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
372 sym->aop = aop = newAsmop(0);
373 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
374 aop->size = getSize(sym->type);
376 /* now assign the address of the variable to
377 the pointer register */
378 if (aop->type != AOP_STK) {
382 pic14_emitcode("push","acc");
384 pic14_emitcode("mov","a,_bp");
385 pic14_emitcode("add","a,#0x%02x",
387 ((char)(sym->stack - _G.nRegsSaved )) :
388 ((char)sym->stack)) & 0xff);
389 pic14_emitcode("mov","%s,a",
390 aop->aopu.aop_ptr->name);
393 pic14_emitcode("pop","acc");
395 pic14_emitcode("mov","%s,#%s",
396 aop->aopu.aop_ptr->name,
398 aop->paged = space->paged;
400 aop->aopu.aop_stk = sym->stack;
404 if (sym->onStack && options.stack10bit)
406 /* It's on the 10 bit stack, which is located in
410 //DEBUGpic14_emitcode(";","%d",__LINE__);
413 pic14_emitcode("push","acc");
415 pic14_emitcode("mov","a,_bp");
416 pic14_emitcode("add","a,#0x%02x",
418 ((char)(sym->stack - _G.nRegsSaved )) :
419 ((char)sym->stack)) & 0xff);
422 pic14_emitcode ("mov","dpx1,#0x40");
423 pic14_emitcode ("mov","dph1,#0x00");
424 pic14_emitcode ("mov","dpl1, a");
428 pic14_emitcode("pop","acc");
430 sym->aop = aop = newAsmop(AOP_DPTR2);
431 aop->size = getSize(sym->type);
435 //DEBUGpic14_emitcode(";","%d",__LINE__);
436 /* if in bit space */
437 if (IN_BITSPACE(space)) {
438 sym->aop = aop = newAsmop (AOP_CRY);
439 aop->aopu.aop_dir = sym->rname ;
440 aop->size = getSize(sym->type);
441 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
444 /* if it is in direct space */
445 if (IN_DIRSPACE(space)) {
446 sym->aop = aop = newAsmop (AOP_DIR);
447 aop->aopu.aop_dir = sym->rname ;
448 aop->size = getSize(sym->type);
449 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
453 /* special case for a function */
454 if (IS_FUNC(sym->type)) {
455 sym->aop = aop = newAsmop(AOP_IMMD);
456 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
457 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
458 strcpy(aop->aopu.aop_immd,sym->rname);
459 aop->size = FPTRSIZE;
464 /* only remaining is far space */
465 /* in which case DPTR gets the address */
466 sym->aop = aop = newAsmop(AOP_DPTR);
467 pic14_emitcode ("mov","dptr,#%s", sym->rname);
468 aop->size = getSize(sym->type);
470 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
471 /* if it is in code space */
472 if (IN_CODESPACE(space))
478 /*-----------------------------------------------------------------*/
479 /* aopForRemat - rematerialzes an object */
480 /*-----------------------------------------------------------------*/
481 static asmop *aopForRemat (symbol *sym)
483 iCode *ic = sym->rematiCode;
484 asmop *aop = newAsmop(AOP_IMMD);
486 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
489 val += (int) operandLitValue(IC_RIGHT(ic));
490 else if (ic->op == '-')
491 val -= (int) operandLitValue(IC_RIGHT(ic));
495 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
499 sprintf(buffer,"(%s %c 0x%04x)",
500 OP_SYMBOL(IC_LEFT(ic))->rname,
501 val >= 0 ? '+' : '-',
504 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
506 //DEBUGpic14_emitcode(";","%s",buffer);
507 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
508 strcpy(aop->aopu.aop_immd,buffer);
512 /*-----------------------------------------------------------------*/
513 /* regsInCommon - two operands have some registers in common */
514 /*-----------------------------------------------------------------*/
515 static bool regsInCommon (operand *op1, operand *op2)
520 /* if they have registers in common */
521 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
524 sym1 = OP_SYMBOL(op1);
525 sym2 = OP_SYMBOL(op2);
527 if (sym1->nRegs == 0 || sym2->nRegs == 0)
530 for (i = 0 ; i < sym1->nRegs ; i++) {
535 for (j = 0 ; j < sym2->nRegs ;j++ ) {
539 if (sym2->regs[j] == sym1->regs[i])
547 /*-----------------------------------------------------------------*/
548 /* operandsEqu - equivalent */
549 /*-----------------------------------------------------------------*/
550 static bool operandsEqu ( operand *op1, operand *op2)
554 /* if they not symbols */
555 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
558 sym1 = OP_SYMBOL(op1);
559 sym2 = OP_SYMBOL(op2);
561 /* if both are itemps & one is spilt
562 and the other is not then false */
563 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
564 sym1->isspilt != sym2->isspilt )
567 /* if they are the same */
571 if (strcmp(sym1->rname,sym2->rname) == 0)
575 /* if left is a tmp & right is not */
579 (sym1->usl.spillLoc == sym2))
586 (sym2->usl.spillLoc == sym1))
592 /*-----------------------------------------------------------------*/
593 /* pic14_sameRegs - two asmops have the same registers */
594 /*-----------------------------------------------------------------*/
595 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
602 if (aop1->type != AOP_REG ||
603 aop2->type != AOP_REG )
606 if (aop1->size != aop2->size )
609 for (i = 0 ; i < aop1->size ; i++ )
610 if (aop1->aopu.aop_reg[i] !=
611 aop2->aopu.aop_reg[i] )
617 /*-----------------------------------------------------------------*/
618 /* aopOp - allocates an asmop for an operand : */
619 /*-----------------------------------------------------------------*/
620 void aopOp (operand *op, iCode *ic, bool result)
629 DEBUGpic14_emitcode(";","%d",__LINE__);
630 /* if this a literal */
631 if (IS_OP_LITERAL(op)) {
632 op->aop = aop = newAsmop(AOP_LIT);
633 aop->aopu.aop_lit = op->operand.valOperand;
634 aop->size = getSize(operandType(op));
635 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
639 /* if already has a asmop then continue */
643 /* if the underlying symbol has a aop */
644 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
645 DEBUGpic14_emitcode(";","%d",__LINE__);
646 op->aop = OP_SYMBOL(op)->aop;
650 /* if this is a true symbol */
651 if (IS_TRUE_SYMOP(op)) {
652 DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
653 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
657 /* this is a temporary : this has
663 e) can be a return use only */
668 /* if the type is a conditional */
669 if (sym->regType == REG_CND) {
670 DEBUGpic14_emitcode(";","%d",__LINE__);
671 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
676 /* if it is spilt then two situations
678 b) has a spill location */
679 if (sym->isspilt || sym->nRegs == 0) {
681 DEBUGpic14_emitcode(";","%d",__LINE__);
682 /* rematerialize it NOW */
684 sym->aop = op->aop = aop =
686 aop->size = getSize(sym->type);
687 DEBUGpic14_emitcode(";","%d",__LINE__);
693 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
694 aop->size = getSize(sym->type);
695 for ( i = 0 ; i < 2 ; i++ )
696 aop->aopu.aop_str[i] = accUse[i];
697 DEBUGpic14_emitcode(";","%d",__LINE__);
703 aop = op->aop = sym->aop = newAsmop(AOP_STR);
704 aop->size = getSize(sym->type);
705 for ( i = 0 ; i < fReturnSizePic ; i++ )
706 aop->aopu.aop_str[i] = fReturn[i];
707 DEBUGpic14_emitcode(";","%d",__LINE__);
711 /* else spill location */
712 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
713 sym->aop = op->aop = aop =
714 aopForSym(ic,sym->usl.spillLoc,result);
715 aop->size = getSize(sym->type);
719 /* must be in a register */
720 sym->aop = op->aop = aop = newAsmop(AOP_REG);
721 aop->size = sym->nRegs;
722 for ( i = 0 ; i < sym->nRegs ;i++)
723 aop->aopu.aop_reg[i] = sym->regs[i];
726 /*-----------------------------------------------------------------*/
727 /* freeAsmop - free up the asmop given to an operand */
728 /*----------------------------------------------------------------*/
729 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
746 /* depending on the asmop type only three cases need work AOP_RO
747 , AOP_R1 && AOP_STK */
752 pic14_emitcode ("pop","ar0");
756 bitVectUnSetBit(ic->rUsed,R0_IDX);
762 pic14_emitcode ("pop","ar1");
766 bitVectUnSetBit(ic->rUsed,R1_IDX);
772 int stk = aop->aopu.aop_stk + aop->size;
773 bitVectUnSetBit(ic->rUsed,R0_IDX);
774 bitVectUnSetBit(ic->rUsed,R1_IDX);
776 getFreePtr(ic,&aop,FALSE);
778 if (options.stack10bit)
780 /* I'm not sure what to do here yet... */
783 "*** Warning: probably generating bad code for "
784 "10 bit stack mode.\n");
788 pic14_emitcode ("mov","a,_bp");
789 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
790 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
792 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
796 pic14_emitcode("pop","acc");
797 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
799 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
802 freeAsmop(op,NULL,ic,TRUE);
804 pic14_emitcode("pop","ar0");
809 pic14_emitcode("pop","ar1");
816 /* all other cases just dealloc */
820 OP_SYMBOL(op)->aop = NULL;
821 /* if the symbol has a spill */
823 SPIL_LOC(op)->aop = NULL;
828 /*-----------------------------------------------------------------*/
829 /* aopGet - for fetching value of the aop */
830 /*-----------------------------------------------------------------*/
831 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
836 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
837 /* offset is greater than
839 if (offset > (aop->size - 1) &&
840 aop->type != AOP_LIT)
843 /* depending on type */
848 DEBUGpic14_emitcode(";","%d",__LINE__);
849 /* if we need to increment it */
850 while (offset > aop->coff) {
851 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
855 while (offset < aop->coff) {
856 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
862 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
863 return (dname ? "acc" : "a");
865 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
866 rs = Safe_calloc(1,strlen(s)+1);
872 DEBUGpic14_emitcode(";","%d",__LINE__);
873 if (aop->type == AOP_DPTR2)
878 while (offset > aop->coff) {
879 pic14_emitcode ("inc","dptr");
883 while (offset < aop->coff) {
884 pic14_emitcode("lcall","__decdptr");
890 pic14_emitcode("clr","a");
891 pic14_emitcode("movc","a,@a+dptr");
894 pic14_emitcode("movx","a,@dptr");
897 if (aop->type == AOP_DPTR2)
902 return (dname ? "acc" : "a");
906 DEBUGpic14_emitcode(";","%d",__LINE__);
908 sprintf (s,"%s",aop->aopu.aop_immd);
911 sprintf(s,"(%s >> %d)",
917 rs = Safe_calloc(1,strlen(s)+1);
923 sprintf(s,"(%s + %d)",
927 sprintf(s,"%s",aop->aopu.aop_dir);
928 rs = Safe_calloc(1,strlen(s)+1);
933 DEBUGpic14_emitcode(";","%d",__LINE__);
935 return aop->aopu.aop_reg[offset]->dname;
937 return aop->aopu.aop_reg[offset]->name;
940 pic14_emitcode(";","%d",__LINE__);
941 //pic14_emitcode("clr","a");
942 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
943 //pic14_emitcode("rlc","a") ;
944 //return (dname ? "acc" : "a");
945 return aop->aopu.aop_dir;
948 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
949 //if (!offset && dname)
951 //return aop->aopu.aop_str[offset];
952 return "AOP_accumulator_bug";
955 DEBUGpic14_emitcode(";","%d",__LINE__);
956 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
957 rs = Safe_calloc(1,strlen(s)+1);
962 DEBUGpic14_emitcode(";","%d",__LINE__);
964 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
968 return aop->aopu.aop_str[offset];
972 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
973 "aopget got unsupported aop->type");
977 /*-----------------------------------------------------------------*/
978 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
979 /*-----------------------------------------------------------------*/
980 pCodeOp *popGetLabel(unsigned int key)
983 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
988 return newpCodeOpLabel(key+100+labelOffset);
991 /*-----------------------------------------------------------------*/
992 /* popCopyReg - copy a pcode operator */
993 /*-----------------------------------------------------------------*/
994 pCodeOp *popCopyReg(pCodeOpReg *pc)
998 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
999 pcor->pcop.type = pc->pcop.type;
1000 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1001 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1003 pcor->rIdx = pc->rIdx;
1009 /*-----------------------------------------------------------------*/
1010 /* popCopy - copy a pcode operator */
1011 /*-----------------------------------------------------------------*/
1012 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1016 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1017 pcop->type = PO_BIT;
1018 if(!(pcop->name = Safe_strdup(pc->name)))
1019 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1020 ((pCodeOpBit *)pcop)->bit = bitval;
1022 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1027 /*-----------------------------------------------------------------*/
1028 /* popGet - asm operator to pcode operator conversion */
1029 /*-----------------------------------------------------------------*/
1030 pCodeOp *popGetLit(unsigned int lit)
1033 return newpCodeOpLit(lit);
1037 /*-----------------------------------------------------------------*/
1038 /* popGet - asm operator to pcode operator conversion */
1039 /*-----------------------------------------------------------------*/
1040 pCodeOp *popGetWithString(char *str)
1046 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1050 pcop = newpCodeOp(str,PO_STR);
1055 pCodeOp *popRegFromString(char *str)
1058 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1059 pcop->type = PO_GPR_REGISTER;
1061 PCOR(pcop)->rIdx = -1;
1062 PCOR(pcop)->r = NULL;
1064 DEBUGpic14_emitcode(";","%d",__LINE__);
1065 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1070 /*-----------------------------------------------------------------*/
1071 /* popGet - asm operator to pcode operator conversion */
1072 /*-----------------------------------------------------------------*/
1073 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1080 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1081 /* offset is greater than
1084 if (offset > (aop->size - 1) &&
1085 aop->type != AOP_LIT)
1086 return NULL; //zero;
1088 /* depending on type */
1089 switch (aop->type) {
1096 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1097 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1098 //pcop->type = PO_SFR_REGISTER;
1100 //PCOR(pcop)->rIdx = -1;
1101 //PCOR(pcop)->r = NULL;
1102 // Really nasty hack to check for temporary registers
1104 //pcop->name = Safe_strdup("BAD_REGISTER");
1109 DEBUGpic14_emitcode(";","%d",__LINE__);
1110 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1111 pcop->type = PO_IMMEDIATE;
1113 sprintf (s,"%s",aop->aopu.aop_immd);
1116 sprintf(s,"(%s >> %d)",
1121 aop->aopu.aop_immd);
1122 pcop->name = Safe_calloc(1,strlen(s)+1);
1123 strcpy(pcop->name,s);
1127 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1128 pcop->type = PO_DIR;
1130 sprintf(s,"(%s + %d)",
1134 sprintf(s,"%s",aop->aopu.aop_dir);
1135 pcop->name = Safe_calloc(1,strlen(s)+1);
1136 strcpy(pcop->name,s);
1141 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1143 DEBUGpic14_emitcode(";","%d",__LINE__);
1145 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1147 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1148 //pcop->type = PO_GPR_REGISTER;
1149 PCOR(pcop)->rIdx = rIdx;
1150 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1151 pcop->type = PCOR(pcop)->r->pc_type;
1154 rs = aop->aopu.aop_reg[offset]->dname;
1156 rs = aop->aopu.aop_reg[offset]->name;
1158 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1164 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1168 DEBUGpic14_emitcode(";","%d",__LINE__);
1169 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1172 DEBUGpic14_emitcode(";","%d",__LINE__);
1174 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1175 pcop->type = PO_STR;
1177 //aop->coff = offset ;
1178 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1179 sprintf(s,"%s","acc");
1181 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1182 pcop->name = Safe_calloc(1,strlen(s)+1);
1183 strcpy(pcop->name,s);
1188 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1189 "popGet got unsupported aop->type");
1192 /*-----------------------------------------------------------------*/
1193 /* aopPut - puts a string for a aop */
1194 /*-----------------------------------------------------------------*/
1195 void aopPut (asmop *aop, char *s, int offset)
1200 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1202 if (aop->size && offset > ( aop->size - 1)) {
1203 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1204 "aopPut got offset > aop->size");
1208 /* will assign value to value */
1209 /* depending on where it is ofcourse */
1210 switch (aop->type) {
1213 sprintf(d,"(%s + %d)",
1214 aop->aopu.aop_dir,offset);
1216 sprintf(d,"%s",aop->aopu.aop_dir);
1219 DEBUGpic14_emitcode(";","%d",__LINE__);
1221 pic14_emitcode("movf","%s,w",s);
1222 pic14_emitcode("movwf","%s",d);
1225 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1226 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1233 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1234 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1237 strcmp(s,"r0") == 0 ||
1238 strcmp(s,"r1") == 0 ||
1239 strcmp(s,"r2") == 0 ||
1240 strcmp(s,"r3") == 0 ||
1241 strcmp(s,"r4") == 0 ||
1242 strcmp(s,"r5") == 0 ||
1243 strcmp(s,"r6") == 0 ||
1244 strcmp(s,"r7") == 0 )
1245 pic14_emitcode("mov","%s,%s ; %d",
1246 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1251 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1253 pic14_emitcode("movwf","%s",
1254 aop->aopu.aop_reg[offset]->name);
1257 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1258 pcop->type = PO_GPR_REGISTER;
1260 PCOR(pcop)->rIdx = -1;
1261 PCOR(pcop)->r = NULL;
1263 DEBUGpic14_emitcode(";","%d",__LINE__);
1264 pcop->name = Safe_strdup(s);
1265 emitpcode(POC_MOVFW,pcop);
1267 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1275 if (aop->type == AOP_DPTR2)
1281 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1282 "aopPut writting to code space");
1286 while (offset > aop->coff) {
1288 pic14_emitcode ("inc","dptr");
1291 while (offset < aop->coff) {
1293 pic14_emitcode("lcall","__decdptr");
1298 /* if not in accumulater */
1301 pic14_emitcode ("movx","@dptr,a");
1303 if (aop->type == AOP_DPTR2)
1311 while (offset > aop->coff) {
1313 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1315 while (offset < aop->coff) {
1317 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1323 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1328 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1330 if (strcmp(s,"r0") == 0 ||
1331 strcmp(s,"r1") == 0 ||
1332 strcmp(s,"r2") == 0 ||
1333 strcmp(s,"r3") == 0 ||
1334 strcmp(s,"r4") == 0 ||
1335 strcmp(s,"r5") == 0 ||
1336 strcmp(s,"r6") == 0 ||
1337 strcmp(s,"r7") == 0 ) {
1339 sprintf(buffer,"a%s",s);
1340 pic14_emitcode("mov","@%s,%s",
1341 aop->aopu.aop_ptr->name,buffer);
1343 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1348 if (strcmp(s,"a") == 0)
1349 pic14_emitcode("push","acc");
1351 pic14_emitcode("push","%s",s);
1356 /* if bit variable */
1357 if (!aop->aopu.aop_dir) {
1358 pic14_emitcode("clr","a");
1359 pic14_emitcode("rlc","a");
1362 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1365 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1368 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1370 lbl = newiTempLabel(NULL);
1372 if (strcmp(s,"a")) {
1375 pic14_emitcode("clr","c");
1376 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1377 pic14_emitcode("cpl","c");
1378 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1379 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1386 if (strcmp(aop->aopu.aop_str[offset],s))
1387 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1392 if (!offset && (strcmp(s,"acc") == 0))
1395 if (strcmp(aop->aopu.aop_str[offset],s))
1396 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1400 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1401 "aopPut got unsupported aop->type");
1407 /*-----------------------------------------------------------------*/
1408 /* reAdjustPreg - points a register back to where it should */
1409 /*-----------------------------------------------------------------*/
1410 static void reAdjustPreg (asmop *aop)
1414 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1416 if ((size = aop->size) <= 1)
1419 switch (aop->type) {
1423 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1427 if (aop->type == AOP_DPTR2)
1433 pic14_emitcode("lcall","__decdptr");
1436 if (aop->type == AOP_DPTR2)
1446 /*-----------------------------------------------------------------*/
1447 /* genNotFloat - generates not for float operations */
1448 /*-----------------------------------------------------------------*/
1449 static void genNotFloat (operand *op, operand *res)
1455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1456 /* we will put 127 in the first byte of
1458 aopPut(AOP(res),"#127",0);
1459 size = AOP_SIZE(op) - 1;
1462 l = aopGet(op->aop,offset++,FALSE,FALSE);
1466 pic14_emitcode("orl","a,%s",
1468 offset++,FALSE,FALSE));
1470 tlbl = newiTempLabel(NULL);
1472 tlbl = newiTempLabel(NULL);
1473 aopPut(res->aop,one,1);
1474 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1475 aopPut(res->aop,zero,1);
1476 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1478 size = res->aop->size - 2;
1480 /* put zeros in the rest */
1482 aopPut(res->aop,zero,offset++);
1486 /*-----------------------------------------------------------------*/
1487 /* opIsGptr: returns non-zero if the passed operand is */
1488 /* a generic pointer type. */
1489 /*-----------------------------------------------------------------*/
1490 static int opIsGptr(operand *op)
1492 sym_link *type = operandType(op);
1494 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1495 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1503 /*-----------------------------------------------------------------*/
1504 /* pic14_getDataSize - get the operand data size */
1505 /*-----------------------------------------------------------------*/
1506 int pic14_getDataSize(operand *op)
1508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1511 return AOP_SIZE(op);
1513 // tsd- in the pic port, the genptr size is 1, so this code here
1514 // fails. ( in the 8051 port, the size was 4).
1517 size = AOP_SIZE(op);
1518 if (size == GPTRSIZE)
1520 sym_link *type = operandType(op);
1521 if (IS_GENPTR(type))
1523 /* generic pointer; arithmetic operations
1524 * should ignore the high byte (pointer type).
1527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1534 /*-----------------------------------------------------------------*/
1535 /* pic14_outAcc - output Acc */
1536 /*-----------------------------------------------------------------*/
1537 void pic14_outAcc(operand *result)
1540 DEBUGpic14_emitcode ("; ***","%s %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1543 size = pic14_getDataSize(result);
1545 aopPut(AOP(result),"a",0);
1548 /* unsigned or positive */
1550 aopPut(AOP(result),zero,offset++);
1556 /*-----------------------------------------------------------------*/
1557 /* pic14_outBitC - output a bit C */
1558 /*-----------------------------------------------------------------*/
1559 void pic14_outBitC(operand *result)
1562 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1563 /* if the result is bit */
1564 if (AOP_TYPE(result) == AOP_CRY)
1565 aopPut(AOP(result),"c",0);
1567 pic14_emitcode("clr","a ; %d", __LINE__);
1568 pic14_emitcode("rlc","a");
1569 pic14_outAcc(result);
1573 /*-----------------------------------------------------------------*/
1574 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1575 /*-----------------------------------------------------------------*/
1576 void pic14_toBoolean(operand *oper)
1578 int size = AOP_SIZE(oper) - 1;
1581 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1583 if ( AOP_TYPE(oper) != AOP_ACC) {
1584 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1585 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1588 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1589 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1594 /*-----------------------------------------------------------------*/
1595 /* genNot - generate code for ! operation */
1596 /*-----------------------------------------------------------------*/
1597 static void genNot (iCode *ic)
1600 sym_link *optype = operandType(IC_LEFT(ic));
1602 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1603 /* assign asmOps to operand & result */
1604 aopOp (IC_LEFT(ic),ic,FALSE);
1605 aopOp (IC_RESULT(ic),ic,TRUE);
1607 /* if in bit space then a special case */
1608 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1609 pic14_emitcode("movlw","1<<%s");
1610 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1611 //pic14_emitcode("cpl","c");
1612 //pic14_outBitC(IC_RESULT(ic));
1616 /* if type float then do float */
1617 if (IS_FLOAT(optype)) {
1618 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1622 pic14_toBoolean(IC_LEFT(ic));
1624 tlbl = newiTempLabel(NULL);
1625 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1626 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1627 pic14_outBitC(IC_RESULT(ic));
1630 /* release the aops */
1631 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1632 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1636 /*-----------------------------------------------------------------*/
1637 /* genCpl - generate code for complement */
1638 /*-----------------------------------------------------------------*/
1639 static void genCpl (iCode *ic)
1645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1646 /* assign asmOps to operand & result */
1647 aopOp (IC_LEFT(ic),ic,FALSE);
1648 aopOp (IC_RESULT(ic),ic,TRUE);
1650 /* if both are in bit space then
1652 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1653 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1655 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1656 pic14_emitcode("cpl","c");
1657 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1661 size = AOP_SIZE(IC_RESULT(ic));
1663 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1665 pic14_emitcode("cpl","a");
1666 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1671 /* release the aops */
1672 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1673 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1676 /*-----------------------------------------------------------------*/
1677 /* genUminusFloat - unary minus for floating points */
1678 /*-----------------------------------------------------------------*/
1679 static void genUminusFloat(operand *op,operand *result)
1681 int size ,offset =0 ;
1684 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1685 /* for this we just need to flip the
1686 first it then copy the rest in place */
1687 size = AOP_SIZE(op) - 1;
1688 l = aopGet(AOP(op),3,FALSE,FALSE);
1692 pic14_emitcode("cpl","acc.7");
1693 aopPut(AOP(result),"a",3);
1697 aopGet(AOP(op),offset,FALSE,FALSE),
1703 /*-----------------------------------------------------------------*/
1704 /* genUminus - unary minus code generation */
1705 /*-----------------------------------------------------------------*/
1706 static void genUminus (iCode *ic)
1709 sym_link *optype, *rtype;
1712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1714 aopOp(IC_LEFT(ic),ic,FALSE);
1715 aopOp(IC_RESULT(ic),ic,TRUE);
1717 /* if both in bit space then special
1719 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1720 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1722 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1723 pic14_emitcode("cpl","c");
1724 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1728 optype = operandType(IC_LEFT(ic));
1729 rtype = operandType(IC_RESULT(ic));
1731 /* if float then do float stuff */
1732 if (IS_FLOAT(optype)) {
1733 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1737 /* otherwise subtract from zero */
1738 size = AOP_SIZE(IC_LEFT(ic));
1742 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1743 if (!strcmp(l,"a")) {
1744 pic14_emitcode("cpl","a");
1745 pic14_emitcode("inc","a");
1747 pic14_emitcode("clr","a");
1748 pic14_emitcode("subb","a,%s",l);
1750 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1753 /* if any remaining bytes in the result */
1754 /* we just need to propagate the sign */
1755 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1756 pic14_emitcode("rlc","a");
1757 pic14_emitcode("subb","a,acc");
1759 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1763 /* release the aops */
1764 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1765 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1768 /*-----------------------------------------------------------------*/
1769 /* saveRegisters - will look for a call and save the registers */
1770 /*-----------------------------------------------------------------*/
1771 static void saveRegisters(iCode *lic)
1778 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1780 for (ic = lic ; ic ; ic = ic->next)
1781 if (ic->op == CALL || ic->op == PCALL)
1785 fprintf(stderr,"found parameter push with no function call\n");
1789 /* if the registers have been saved already then
1791 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1794 /* find the registers in use at this time
1795 and push them away to safety */
1796 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1800 if (options.useXstack) {
1801 if (bitVectBitValue(rsave,R0_IDX))
1802 pic14_emitcode("mov","b,r0");
1803 pic14_emitcode("mov","r0,%s",spname);
1804 for (i = 0 ; i < pic14_nRegs ; i++) {
1805 if (bitVectBitValue(rsave,i)) {
1807 pic14_emitcode("mov","a,b");
1809 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1810 pic14_emitcode("movx","@r0,a");
1811 pic14_emitcode("inc","r0");
1814 pic14_emitcode("mov","%s,r0",spname);
1815 if (bitVectBitValue(rsave,R0_IDX))
1816 pic14_emitcode("mov","r0,b");
1818 for (i = 0 ; i < pic14_nRegs ; i++) {
1819 if (bitVectBitValue(rsave,i))
1820 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1823 detype = getSpec(operandType(IC_LEFT(ic)));
1825 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1826 IS_ISR(currFunc->etype) &&
1829 saverbank(SPEC_BANK(detype),ic,TRUE);
1832 /*-----------------------------------------------------------------*/
1833 /* unsaveRegisters - pop the pushed registers */
1834 /*-----------------------------------------------------------------*/
1835 static void unsaveRegisters (iCode *ic)
1840 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1841 /* find the registers in use at this time
1842 and push them away to safety */
1843 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1846 if (options.useXstack) {
1847 pic14_emitcode("mov","r0,%s",spname);
1848 for (i = pic14_nRegs ; i >= 0 ; i--) {
1849 if (bitVectBitValue(rsave,i)) {
1850 pic14_emitcode("dec","r0");
1851 pic14_emitcode("movx","a,@r0");
1853 pic14_emitcode("mov","b,a");
1855 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1859 pic14_emitcode("mov","%s,r0",spname);
1860 if (bitVectBitValue(rsave,R0_IDX))
1861 pic14_emitcode("mov","r0,b");
1863 for (i = pic14_nRegs ; i >= 0 ; i--) {
1864 if (bitVectBitValue(rsave,i))
1865 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1871 /*-----------------------------------------------------------------*/
1873 /*-----------------------------------------------------------------*/
1874 static void pushSide(operand * oper, int size)
1877 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1879 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1880 if (AOP_TYPE(oper) != AOP_REG &&
1881 AOP_TYPE(oper) != AOP_DIR &&
1883 pic14_emitcode("mov","a,%s",l);
1884 pic14_emitcode("push","acc");
1886 pic14_emitcode("push","%s",l);
1890 /*-----------------------------------------------------------------*/
1891 /* assignResultValue - */
1892 /*-----------------------------------------------------------------*/
1893 static void assignResultValue(operand * oper)
1896 int size = AOP_SIZE(oper);
1898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1900 // The last byte in the assignment is in W
1901 aopPut(AOP(oper),"W",size-1);
1905 aopPut(AOP(oper),fReturn[offset],offset);
1913 /*-----------------------------------------------------------------*/
1914 /* genXpush - pushes onto the external stack */
1915 /*-----------------------------------------------------------------*/
1916 static void genXpush (iCode *ic)
1918 asmop *aop = newAsmop(0);
1920 int size,offset = 0;
1922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1923 aopOp(IC_LEFT(ic),ic,FALSE);
1924 r = getFreePtr(ic,&aop,FALSE);
1927 pic14_emitcode("mov","%s,_spx",r->name);
1929 size = AOP_SIZE(IC_LEFT(ic));
1932 char *l = aopGet(AOP(IC_LEFT(ic)),
1933 offset++,FALSE,FALSE);
1935 pic14_emitcode("movx","@%s,a",r->name);
1936 pic14_emitcode("inc","%s",r->name);
1941 pic14_emitcode("mov","_spx,%s",r->name);
1943 freeAsmop(NULL,aop,ic,TRUE);
1944 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1947 /*-----------------------------------------------------------------*/
1948 /* genIpush - genrate code for pushing this gets a little complex */
1949 /*-----------------------------------------------------------------*/
1950 static void genIpush (iCode *ic)
1952 int size, offset = 0 ;
1956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1957 /* if this is not a parm push : ie. it is spill push
1958 and spill push is always done on the local stack */
1959 if (!ic->parmPush) {
1961 /* and the item is spilt then do nothing */
1962 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1965 aopOp(IC_LEFT(ic),ic,FALSE);
1966 size = AOP_SIZE(IC_LEFT(ic));
1967 /* push it on the stack */
1969 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1974 pic14_emitcode("push","%s",l);
1979 /* this is a paramter push: in this case we call
1980 the routine to find the call and save those
1981 registers that need to be saved */
1984 /* if use external stack then call the external
1985 stack pushing routine */
1986 if (options.useXstack) {
1991 /* then do the push */
1992 aopOp(IC_LEFT(ic),ic,FALSE);
1995 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1996 size = AOP_SIZE(IC_LEFT(ic));
1999 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2000 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2001 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2003 pic14_emitcode("mov","a,%s",l);
2004 pic14_emitcode("push","acc");
2006 pic14_emitcode("push","%s",l);
2009 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2012 /*-----------------------------------------------------------------*/
2013 /* genIpop - recover the registers: can happen only for spilling */
2014 /*-----------------------------------------------------------------*/
2015 static void genIpop (iCode *ic)
2020 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2021 /* if the temp was not pushed then */
2022 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2025 aopOp(IC_LEFT(ic),ic,FALSE);
2026 size = AOP_SIZE(IC_LEFT(ic));
2029 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2032 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2035 /*-----------------------------------------------------------------*/
2036 /* unsaverbank - restores the resgister bank from stack */
2037 /*-----------------------------------------------------------------*/
2038 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2046 if (options.useXstack) {
2048 r = getFreePtr(ic,&aop,FALSE);
2051 pic14_emitcode("mov","%s,_spx",r->name);
2052 pic14_emitcode("movx","a,@%s",r->name);
2053 pic14_emitcode("mov","psw,a");
2054 pic14_emitcode("dec","%s",r->name);
2057 pic14_emitcode ("pop","psw");
2060 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2061 if (options.useXstack) {
2062 pic14_emitcode("movx","a,@%s",r->name);
2063 //pic14_emitcode("mov","(%s+%d),a",
2064 // regspic14[i].base,8*bank+regspic14[i].offset);
2065 pic14_emitcode("dec","%s",r->name);
2068 pic14_emitcode("pop",""); //"(%s+%d)",
2069 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2072 if (options.useXstack) {
2074 pic14_emitcode("mov","_spx,%s",r->name);
2075 freeAsmop(NULL,aop,ic,TRUE);
2080 /*-----------------------------------------------------------------*/
2081 /* saverbank - saves an entire register bank on the stack */
2082 /*-----------------------------------------------------------------*/
2083 static void saverbank (int bank, iCode *ic, bool pushPsw)
2089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2090 if (options.useXstack) {
2093 r = getFreePtr(ic,&aop,FALSE);
2094 pic14_emitcode("mov","%s,_spx",r->name);
2098 for (i = 0 ; i < pic14_nRegs ;i++) {
2099 if (options.useXstack) {
2100 pic14_emitcode("inc","%s",r->name);
2101 //pic14_emitcode("mov","a,(%s+%d)",
2102 // regspic14[i].base,8*bank+regspic14[i].offset);
2103 pic14_emitcode("movx","@%s,a",r->name);
2105 pic14_emitcode("push","");// "(%s+%d)",
2106 //regspic14[i].base,8*bank+regspic14[i].offset);
2110 if (options.useXstack) {
2111 pic14_emitcode("mov","a,psw");
2112 pic14_emitcode("movx","@%s,a",r->name);
2113 pic14_emitcode("inc","%s",r->name);
2114 pic14_emitcode("mov","_spx,%s",r->name);
2115 freeAsmop (NULL,aop,ic,TRUE);
2118 pic14_emitcode("push","psw");
2120 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2126 /*-----------------------------------------------------------------*/
2127 /* genCall - generates a call statement */
2128 /*-----------------------------------------------------------------*/
2129 static void genCall (iCode *ic)
2133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2135 /* if caller saves & we have not saved then */
2139 /* if we are calling a function that is not using
2140 the same register bank then we need to save the
2141 destination registers on the stack */
2142 detype = getSpec(operandType(IC_LEFT(ic)));
2144 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2145 IS_ISR(currFunc->etype) &&
2148 saverbank(SPEC_BANK(detype),ic,TRUE);
2150 /* if send set is not empty the assign */
2154 for (sic = setFirstItem(_G.sendSet) ; sic ;
2155 sic = setNextItem(_G.sendSet)) {
2156 int size, offset = 0;
2158 aopOp(IC_LEFT(sic),sic,FALSE);
2159 size = AOP_SIZE(IC_LEFT(sic));
2161 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2163 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2165 if (strcmp(l,fReturn[offset])) {
2167 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2168 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2169 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2170 //pic14_emitcode("movlw","%s",l);
2172 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2173 //pic14_emitcode("movf","%s,w",l);
2175 // The last one is passed in W
2177 pic14_emitcode("movwf","%s",fReturn[offset]);
2181 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2186 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2187 OP_SYMBOL(IC_LEFT(ic))->rname :
2188 OP_SYMBOL(IC_LEFT(ic))->name));
2190 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2191 OP_SYMBOL(IC_LEFT(ic))->rname :
2192 OP_SYMBOL(IC_LEFT(ic))->name));
2194 /* if we need assign a result value */
2195 if ((IS_ITEMP(IC_RESULT(ic)) &&
2196 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2197 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2198 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2201 aopOp(IC_RESULT(ic),ic,FALSE);
2204 assignResultValue(IC_RESULT(ic));
2206 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2209 /* adjust the stack for parameters if
2211 if (ic->parmBytes) {
2213 if (ic->parmBytes > 3) {
2214 pic14_emitcode("mov","a,%s",spname);
2215 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2216 pic14_emitcode("mov","%s,a",spname);
2218 for ( i = 0 ; i < ic->parmBytes ;i++)
2219 pic14_emitcode("dec","%s",spname);
2223 /* if register bank was saved then pop them */
2225 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2227 /* if we hade saved some registers then unsave them */
2228 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2229 unsaveRegisters (ic);
2234 /*-----------------------------------------------------------------*/
2235 /* genPcall - generates a call by pointer statement */
2236 /*-----------------------------------------------------------------*/
2237 static void genPcall (iCode *ic)
2240 symbol *rlbl = newiTempLabel(NULL);
2243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2244 /* if caller saves & we have not saved then */
2248 /* if we are calling a function that is not using
2249 the same register bank then we need to save the
2250 destination registers on the stack */
2251 detype = getSpec(operandType(IC_LEFT(ic)));
2253 IS_ISR(currFunc->etype) &&
2254 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2255 saverbank(SPEC_BANK(detype),ic,TRUE);
2258 /* push the return address on to the stack */
2259 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2260 pic14_emitcode("push","acc");
2261 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2262 pic14_emitcode("push","acc");
2264 if (options.model == MODEL_FLAT24)
2266 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2267 pic14_emitcode("push","acc");
2270 /* now push the calling address */
2271 aopOp(IC_LEFT(ic),ic,FALSE);
2273 pushSide(IC_LEFT(ic), FPTRSIZE);
2275 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2277 /* if send set is not empty the assign */
2281 for (sic = setFirstItem(_G.sendSet) ; sic ;
2282 sic = setNextItem(_G.sendSet)) {
2283 int size, offset = 0;
2284 aopOp(IC_LEFT(sic),sic,FALSE);
2285 size = AOP_SIZE(IC_LEFT(sic));
2287 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2289 if (strcmp(l,fReturn[offset]))
2290 pic14_emitcode("mov","%s,%s",
2295 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2300 pic14_emitcode("ret","");
2301 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2304 /* if we need assign a result value */
2305 if ((IS_ITEMP(IC_RESULT(ic)) &&
2306 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2307 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2308 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2311 aopOp(IC_RESULT(ic),ic,FALSE);
2314 assignResultValue(IC_RESULT(ic));
2316 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2319 /* adjust the stack for parameters if
2321 if (ic->parmBytes) {
2323 if (ic->parmBytes > 3) {
2324 pic14_emitcode("mov","a,%s",spname);
2325 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2326 pic14_emitcode("mov","%s,a",spname);
2328 for ( i = 0 ; i < ic->parmBytes ;i++)
2329 pic14_emitcode("dec","%s",spname);
2333 /* if register bank was saved then unsave them */
2335 (SPEC_BANK(currFunc->etype) !=
2337 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2339 /* if we hade saved some registers then
2342 unsaveRegisters (ic);
2346 /*-----------------------------------------------------------------*/
2347 /* resultRemat - result is rematerializable */
2348 /*-----------------------------------------------------------------*/
2349 static int resultRemat (iCode *ic)
2351 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2352 if (SKIP_IC(ic) || ic->op == IFX)
2355 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2356 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2357 if (sym->remat && !POINTER_SET(ic))
2364 #if defined(__BORLANDC__) || defined(_MSC_VER)
2365 #define STRCASECMP stricmp
2367 #define STRCASECMP strcasecmp
2370 /*-----------------------------------------------------------------*/
2371 /* inExcludeList - return 1 if the string is in exclude Reg list */
2372 /*-----------------------------------------------------------------*/
2373 static bool inExcludeList(char *s)
2377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2378 if (options.excludeRegs[i] &&
2379 STRCASECMP(options.excludeRegs[i],"none") == 0)
2382 for ( i = 0 ; options.excludeRegs[i]; i++) {
2383 if (options.excludeRegs[i] &&
2384 STRCASECMP(s,options.excludeRegs[i]) == 0)
2390 /*-----------------------------------------------------------------*/
2391 /* genFunction - generated code for function entry */
2392 /*-----------------------------------------------------------------*/
2393 static void genFunction (iCode *ic)
2398 DEBUGpic14_emitcode ("; ***","%s %d previous max_key=%d ",__FUNCTION__,__LINE__,max_key);
2400 labelOffset += (max_key+2);
2404 /* create the function header */
2405 pic14_emitcode(";","-----------------------------------------");
2406 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2407 pic14_emitcode(";","-----------------------------------------");
2409 pic14_emitcode("","%s:",sym->rname);
2410 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2412 fetype = getSpec(operandType(IC_LEFT(ic)));
2414 /* if critical function then turn interrupts off */
2415 if (SPEC_CRTCL(fetype))
2416 pic14_emitcode("clr","ea");
2418 /* here we need to generate the equates for the
2419 register bank if required */
2421 if (SPEC_BANK(fetype) != rbank) {
2424 rbank = SPEC_BANK(fetype);
2425 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2426 if (strcmp(regspic14[i].base,"0") == 0)
2427 pic14_emitcode("","%s = 0x%02x",
2429 8*rbank+regspic14[i].offset);
2431 pic14_emitcode ("","%s = %s + 0x%02x",
2434 8*rbank+regspic14[i].offset);
2439 /* if this is an interrupt service routine then
2440 save acc, b, dpl, dph */
2441 if (IS_ISR(sym->etype)) {
2443 if (!inExcludeList("acc"))
2444 pic14_emitcode ("push","acc");
2445 if (!inExcludeList("b"))
2446 pic14_emitcode ("push","b");
2447 if (!inExcludeList("dpl"))
2448 pic14_emitcode ("push","dpl");
2449 if (!inExcludeList("dph"))
2450 pic14_emitcode ("push","dph");
2451 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2453 pic14_emitcode ("push", "dpx");
2454 /* Make sure we're using standard DPTR */
2455 pic14_emitcode ("push", "dps");
2456 pic14_emitcode ("mov", "dps, #0x00");
2457 if (options.stack10bit)
2459 /* This ISR could conceivably use DPTR2. Better save it. */
2460 pic14_emitcode ("push", "dpl1");
2461 pic14_emitcode ("push", "dph1");
2462 pic14_emitcode ("push", "dpx1");
2465 /* if this isr has no bank i.e. is going to
2466 run with bank 0 , then we need to save more
2468 if (!SPEC_BANK(sym->etype)) {
2470 /* if this function does not call any other
2471 function then we can be economical and
2472 save only those registers that are used */
2473 if (! sym->hasFcall) {
2476 /* if any registers used */
2477 if (sym->regsUsed) {
2478 /* save the registers used */
2479 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2480 if (bitVectBitValue(sym->regsUsed,i) ||
2481 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2482 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2487 /* this function has a function call cannot
2488 determines register usage so we will have the
2490 saverbank(0,ic,FALSE);
2494 /* if callee-save to be used for this function
2495 then save the registers being used in this function */
2496 if (sym->calleeSave) {
2499 /* if any registers used */
2500 if (sym->regsUsed) {
2501 /* save the registers used */
2502 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2503 if (bitVectBitValue(sym->regsUsed,i) ||
2504 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2505 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2513 /* set the register bank to the desired value */
2514 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2515 pic14_emitcode("push","psw");
2516 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2519 if (IS_RENT(sym->etype) || options.stackAuto) {
2521 if (options.useXstack) {
2522 pic14_emitcode("mov","r0,%s",spname);
2523 pic14_emitcode("mov","a,_bp");
2524 pic14_emitcode("movx","@r0,a");
2525 pic14_emitcode("inc","%s",spname);
2529 /* set up the stack */
2530 pic14_emitcode ("push","_bp"); /* save the callers stack */
2532 pic14_emitcode ("mov","_bp,%s",spname);
2535 /* adjust the stack for the function */
2540 werror(W_STACK_OVERFLOW,sym->name);
2542 if (i > 3 && sym->recvSize < 4) {
2544 pic14_emitcode ("mov","a,sp");
2545 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2546 pic14_emitcode ("mov","sp,a");
2551 pic14_emitcode("inc","sp");
2556 pic14_emitcode ("mov","a,_spx");
2557 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2558 pic14_emitcode ("mov","_spx,a");
2563 /*-----------------------------------------------------------------*/
2564 /* genEndFunction - generates epilogue for functions */
2565 /*-----------------------------------------------------------------*/
2566 static void genEndFunction (iCode *ic)
2568 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2572 if (IS_RENT(sym->etype) || options.stackAuto)
2574 pic14_emitcode ("mov","%s,_bp",spname);
2577 /* if use external stack but some variables were
2578 added to the local stack then decrement the
2580 if (options.useXstack && sym->stack) {
2581 pic14_emitcode("mov","a,sp");
2582 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2583 pic14_emitcode("mov","sp,a");
2587 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2588 if (options.useXstack) {
2589 pic14_emitcode("mov","r0,%s",spname);
2590 pic14_emitcode("movx","a,@r0");
2591 pic14_emitcode("mov","_bp,a");
2592 pic14_emitcode("dec","%s",spname);
2596 pic14_emitcode ("pop","_bp");
2600 /* restore the register bank */
2601 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2602 pic14_emitcode ("pop","psw");
2604 if (IS_ISR(sym->etype)) {
2606 /* now we need to restore the registers */
2607 /* if this isr has no bank i.e. is going to
2608 run with bank 0 , then we need to save more
2610 if (!SPEC_BANK(sym->etype)) {
2612 /* if this function does not call any other
2613 function then we can be economical and
2614 save only those registers that are used */
2615 if (! sym->hasFcall) {
2618 /* if any registers used */
2619 if (sym->regsUsed) {
2620 /* save the registers used */
2621 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2622 if (bitVectBitValue(sym->regsUsed,i) ||
2623 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2624 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2629 /* this function has a function call cannot
2630 determines register usage so we will have the
2632 unsaverbank(0,ic,FALSE);
2636 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2638 if (options.stack10bit)
2640 pic14_emitcode ("pop", "dpx1");
2641 pic14_emitcode ("pop", "dph1");
2642 pic14_emitcode ("pop", "dpl1");
2644 pic14_emitcode ("pop", "dps");
2645 pic14_emitcode ("pop", "dpx");
2647 if (!inExcludeList("dph"))
2648 pic14_emitcode ("pop","dph");
2649 if (!inExcludeList("dpl"))
2650 pic14_emitcode ("pop","dpl");
2651 if (!inExcludeList("b"))
2652 pic14_emitcode ("pop","b");
2653 if (!inExcludeList("acc"))
2654 pic14_emitcode ("pop","acc");
2656 if (SPEC_CRTCL(sym->etype))
2657 pic14_emitcode("setb","ea");
2659 /* if debug then send end of function */
2660 /* if (options.debug && currFunc) { */
2663 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2664 FileBaseName(ic->filename),currFunc->lastLine,
2665 ic->level,ic->block);
2666 if (IS_STATIC(currFunc->etype))
2667 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2669 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2673 pic14_emitcode ("reti","");
2676 if (SPEC_CRTCL(sym->etype))
2677 pic14_emitcode("setb","ea");
2679 if (sym->calleeSave) {
2682 /* if any registers used */
2683 if (sym->regsUsed) {
2684 /* save the registers used */
2685 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2686 if (bitVectBitValue(sym->regsUsed,i) ||
2687 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2688 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2694 /* if debug then send end of function */
2697 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2698 FileBaseName(ic->filename),currFunc->lastLine,
2699 ic->level,ic->block);
2700 if (IS_STATIC(currFunc->etype))
2701 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2703 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2707 pic14_emitcode ("return","");
2708 emitpcodeNULLop(POC_RETURN);
2710 /* Mark the end of a function */
2711 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2716 /*-----------------------------------------------------------------*/
2717 /* genRet - generate code for return statement */
2718 /*-----------------------------------------------------------------*/
2719 static void genRet (iCode *ic)
2721 int size,offset = 0 , pushed = 0;
2723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2724 /* if we have no return value then
2725 just generate the "ret" */
2729 /* we have something to return then
2730 move the return value into place */
2731 aopOp(IC_LEFT(ic),ic,FALSE);
2732 size = AOP_SIZE(IC_LEFT(ic));
2736 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2738 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2740 pic14_emitcode("push","%s",l);
2743 l = aopGet(AOP(IC_LEFT(ic)),offset,
2745 if (strcmp(fReturn[offset],l)) {
2746 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2747 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2748 pic14_emitcode("movlw","%s",l);
2750 pic14_emitcode("movf","%s,w",l);
2752 pic14_emitcode("movwf","%s",fReturn[offset]);
2761 if (strcmp(fReturn[pushed],"a"))
2762 pic14_emitcode("pop",fReturn[pushed]);
2764 pic14_emitcode("pop","acc");
2767 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2770 /* generate a jump to the return label
2771 if the next is not the return statement */
2772 if (!(ic->next && ic->next->op == LABEL &&
2773 IC_LABEL(ic->next) == returnLabel)) {
2775 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2776 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2781 /*-----------------------------------------------------------------*/
2782 /* genLabel - generates a label */
2783 /*-----------------------------------------------------------------*/
2784 static void genLabel (iCode *ic)
2786 /* special case never generate */
2787 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2788 if (IC_LABEL(ic) == entryLabel)
2791 emitpLabel(IC_LABEL(ic)->key);
2792 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2795 /*-----------------------------------------------------------------*/
2796 /* genGoto - generates a goto */
2797 /*-----------------------------------------------------------------*/
2799 static void genGoto (iCode *ic)
2801 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2802 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2805 /*-----------------------------------------------------------------*/
2806 /* findLabelBackwards: walks back through the iCode chain looking */
2807 /* for the given label. Returns number of iCode instructions */
2808 /* between that label and given ic. */
2809 /* Returns zero if label not found. */
2810 /*-----------------------------------------------------------------*/
2812 static int findLabelBackwards(iCode *ic, int key)
2816 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2822 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2824 /* printf("findLabelBackwards = %d\n", count); */
2833 /*-----------------------------------------------------------------*/
2834 /* genMultbits :- multiplication of bits */
2835 /*-----------------------------------------------------------------*/
2836 static void genMultbits (operand *left,
2840 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2842 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2843 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2844 pic14_outBitC(result);
2848 /*-----------------------------------------------------------------*/
2849 /* genMultOneByte : 8 bit multiplication & division */
2850 /*-----------------------------------------------------------------*/
2851 static void genMultOneByte (operand *left,
2855 sym_link *opetype = operandType(result);
2860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2861 /* (if two literals, the value is computed before) */
2862 /* if one literal, literal on the right */
2863 if (AOP_TYPE(left) == AOP_LIT){
2869 size = AOP_SIZE(result);
2870 /* signed or unsigned */
2871 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2872 l = aopGet(AOP(left),0,FALSE,FALSE);
2874 pic14_emitcode("mul","ab");
2875 /* if result size = 1, mul signed = mul unsigned */
2876 aopPut(AOP(result),"a",0);
2878 if (SPEC_USIGN(opetype)){
2879 aopPut(AOP(result),"b",1);
2881 /* for filling the MSBs */
2882 pic14_emitcode("clr","a");
2885 pic14_emitcode("mov","a,b");
2887 /* adjust the MSB if left or right neg */
2889 /* if one literal */
2890 if (AOP_TYPE(right) == AOP_LIT){
2891 /* AND literal negative */
2892 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2893 /* adjust MSB (c==0 after mul) */
2894 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2898 lbl = newiTempLabel(NULL);
2899 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2900 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2901 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2902 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2903 lbl = newiTempLabel(NULL);
2904 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2905 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2906 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2909 lbl = newiTempLabel(NULL);
2910 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2911 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2912 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2913 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2914 lbl = newiTempLabel(NULL);
2915 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2916 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2917 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2919 aopPut(AOP(result),"a",1);
2922 pic14_emitcode("rlc","a");
2923 pic14_emitcode("subb","a,acc");
2930 aopPut(AOP(result),"a",offset++);
2934 /*-----------------------------------------------------------------*/
2935 /* genMult - generates code for multiplication */
2936 /*-----------------------------------------------------------------*/
2937 static void genMult (iCode *ic)
2939 operand *left = IC_LEFT(ic);
2940 operand *right = IC_RIGHT(ic);
2941 operand *result= IC_RESULT(ic);
2943 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2944 /* assign the amsops */
2945 aopOp (left,ic,FALSE);
2946 aopOp (right,ic,FALSE);
2947 aopOp (result,ic,TRUE);
2949 /* special cases first */
2951 if (AOP_TYPE(left) == AOP_CRY &&
2952 AOP_TYPE(right)== AOP_CRY) {
2953 genMultbits(left,right,result);
2957 /* if both are of size == 1 */
2958 if (AOP_SIZE(left) == 1 &&
2959 AOP_SIZE(right) == 1 ) {
2960 genMultOneByte(left,right,result);
2964 /* should have been converted to function call */
2968 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2969 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2970 freeAsmop(result,NULL,ic,TRUE);
2973 /*-----------------------------------------------------------------*/
2974 /* genDivbits :- division of bits */
2975 /*-----------------------------------------------------------------*/
2976 static void genDivbits (operand *left,
2983 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2984 /* the result must be bit */
2985 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2986 l = aopGet(AOP(left),0,FALSE,FALSE);
2990 pic14_emitcode("div","ab");
2991 pic14_emitcode("rrc","a");
2992 aopPut(AOP(result),"c",0);
2995 /*-----------------------------------------------------------------*/
2996 /* genDivOneByte : 8 bit division */
2997 /*-----------------------------------------------------------------*/
2998 static void genDivOneByte (operand *left,
3002 sym_link *opetype = operandType(result);
3007 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3008 size = AOP_SIZE(result) - 1;
3010 /* signed or unsigned */
3011 if (SPEC_USIGN(opetype)) {
3012 /* unsigned is easy */
3013 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3014 l = aopGet(AOP(left),0,FALSE,FALSE);
3016 pic14_emitcode("div","ab");
3017 aopPut(AOP(result),"a",0);
3019 aopPut(AOP(result),zero,offset++);
3023 /* signed is a little bit more difficult */
3025 /* save the signs of the operands */
3026 l = aopGet(AOP(left),0,FALSE,FALSE);
3028 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3029 pic14_emitcode("push","acc"); /* save it on the stack */
3031 /* now sign adjust for both left & right */
3032 l = aopGet(AOP(right),0,FALSE,FALSE);
3034 lbl = newiTempLabel(NULL);
3035 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3036 pic14_emitcode("cpl","a");
3037 pic14_emitcode("inc","a");
3038 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3039 pic14_emitcode("mov","b,a");
3041 /* sign adjust left side */
3042 l = aopGet(AOP(left),0,FALSE,FALSE);
3045 lbl = newiTempLabel(NULL);
3046 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3047 pic14_emitcode("cpl","a");
3048 pic14_emitcode("inc","a");
3049 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3051 /* now the division */
3052 pic14_emitcode("div","ab");
3053 /* we are interested in the lower order
3055 pic14_emitcode("mov","b,a");
3056 lbl = newiTempLabel(NULL);
3057 pic14_emitcode("pop","acc");
3058 /* if there was an over flow we don't
3059 adjust the sign of the result */
3060 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3061 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3063 pic14_emitcode("clr","a");
3064 pic14_emitcode("subb","a,b");
3065 pic14_emitcode("mov","b,a");
3066 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3068 /* now we are done */
3069 aopPut(AOP(result),"b",0);
3071 pic14_emitcode("mov","c,b.7");
3072 pic14_emitcode("subb","a,acc");
3075 aopPut(AOP(result),"a",offset++);
3079 /*-----------------------------------------------------------------*/
3080 /* genDiv - generates code for division */
3081 /*-----------------------------------------------------------------*/
3082 static void genDiv (iCode *ic)
3084 operand *left = IC_LEFT(ic);
3085 operand *right = IC_RIGHT(ic);
3086 operand *result= IC_RESULT(ic);
3088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3089 /* assign the amsops */
3090 aopOp (left,ic,FALSE);
3091 aopOp (right,ic,FALSE);
3092 aopOp (result,ic,TRUE);
3094 /* special cases first */
3096 if (AOP_TYPE(left) == AOP_CRY &&
3097 AOP_TYPE(right)== AOP_CRY) {
3098 genDivbits(left,right,result);
3102 /* if both are of size == 1 */
3103 if (AOP_SIZE(left) == 1 &&
3104 AOP_SIZE(right) == 1 ) {
3105 genDivOneByte(left,right,result);
3109 /* should have been converted to function call */
3112 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3113 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3114 freeAsmop(result,NULL,ic,TRUE);
3117 /*-----------------------------------------------------------------*/
3118 /* genModbits :- modulus of bits */
3119 /*-----------------------------------------------------------------*/
3120 static void genModbits (operand *left,
3127 /* the result must be bit */
3128 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3129 l = aopGet(AOP(left),0,FALSE,FALSE);
3133 pic14_emitcode("div","ab");
3134 pic14_emitcode("mov","a,b");
3135 pic14_emitcode("rrc","a");
3136 aopPut(AOP(result),"c",0);
3139 /*-----------------------------------------------------------------*/
3140 /* genModOneByte : 8 bit modulus */
3141 /*-----------------------------------------------------------------*/
3142 static void genModOneByte (operand *left,
3146 sym_link *opetype = operandType(result);
3150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3151 /* signed or unsigned */
3152 if (SPEC_USIGN(opetype)) {
3153 /* unsigned is easy */
3154 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3155 l = aopGet(AOP(left),0,FALSE,FALSE);
3157 pic14_emitcode("div","ab");
3158 aopPut(AOP(result),"b",0);
3162 /* signed is a little bit more difficult */
3164 /* save the signs of the operands */
3165 l = aopGet(AOP(left),0,FALSE,FALSE);
3168 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3169 pic14_emitcode("push","acc"); /* save it on the stack */
3171 /* now sign adjust for both left & right */
3172 l = aopGet(AOP(right),0,FALSE,FALSE);
3175 lbl = newiTempLabel(NULL);
3176 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3177 pic14_emitcode("cpl","a");
3178 pic14_emitcode("inc","a");
3179 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3180 pic14_emitcode("mov","b,a");
3182 /* sign adjust left side */
3183 l = aopGet(AOP(left),0,FALSE,FALSE);
3186 lbl = newiTempLabel(NULL);
3187 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3188 pic14_emitcode("cpl","a");
3189 pic14_emitcode("inc","a");
3190 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3192 /* now the multiplication */
3193 pic14_emitcode("div","ab");
3194 /* we are interested in the lower order
3196 lbl = newiTempLabel(NULL);
3197 pic14_emitcode("pop","acc");
3198 /* if there was an over flow we don't
3199 adjust the sign of the result */
3200 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3201 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3203 pic14_emitcode("clr","a");
3204 pic14_emitcode("subb","a,b");
3205 pic14_emitcode("mov","b,a");
3206 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3208 /* now we are done */
3209 aopPut(AOP(result),"b",0);
3213 /*-----------------------------------------------------------------*/
3214 /* genMod - generates code for division */
3215 /*-----------------------------------------------------------------*/
3216 static void genMod (iCode *ic)
3218 operand *left = IC_LEFT(ic);
3219 operand *right = IC_RIGHT(ic);
3220 operand *result= IC_RESULT(ic);
3222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3223 /* assign the amsops */
3224 aopOp (left,ic,FALSE);
3225 aopOp (right,ic,FALSE);
3226 aopOp (result,ic,TRUE);
3228 /* special cases first */
3230 if (AOP_TYPE(left) == AOP_CRY &&
3231 AOP_TYPE(right)== AOP_CRY) {
3232 genModbits(left,right,result);
3236 /* if both are of size == 1 */
3237 if (AOP_SIZE(left) == 1 &&
3238 AOP_SIZE(right) == 1 ) {
3239 genModOneByte(left,right,result);
3243 /* should have been converted to function call */
3247 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3248 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3249 freeAsmop(result,NULL,ic,TRUE);
3252 /*-----------------------------------------------------------------*/
3253 /* genIfxJump :- will create a jump depending on the ifx */
3254 /*-----------------------------------------------------------------*/
3256 note: May need to add parameter to indicate when a variable is in bit space.
3258 static void genIfxJump (iCode *ic, char *jval)
3261 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3262 /* if true label then we jump if condition
3264 if ( IC_TRUE(ic) ) {
3266 if(strcmp(jval,"a") == 0)
3268 else if (strcmp(jval,"c") == 0)
3271 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3272 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3275 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3276 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3280 /* false label is present */
3281 if(strcmp(jval,"a") == 0)
3283 else if (strcmp(jval,"c") == 0)
3286 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3287 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3290 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3291 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3296 /* mark the icode as generated */
3300 /*-----------------------------------------------------------------*/
3302 /*-----------------------------------------------------------------*/
3303 static void genSkip(iCode *ifx,int status_bit)
3308 if ( IC_TRUE(ifx) ) {
3309 switch(status_bit) {
3324 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3325 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3329 switch(status_bit) {
3343 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3344 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3350 /*-----------------------------------------------------------------*/
3352 /*-----------------------------------------------------------------*/
3353 static void genSkipc(iCode *ifx, int condition)
3364 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3366 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3369 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3371 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3375 /*-----------------------------------------------------------------*/
3377 /*-----------------------------------------------------------------*/
3378 static void genSkipz(iCode *ifx, int condition)
3389 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3391 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3394 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3396 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3399 /*-----------------------------------------------------------------*/
3400 /* genCmp :- greater or less than comparison */
3401 /*-----------------------------------------------------------------*/
3402 static void genCmp (operand *left,operand *right,
3403 operand *result, iCode *ifx, int sign)
3405 int size, offset = 0 ;
3406 unsigned long lit = 0L,i = 0;
3408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3409 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3410 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3412 /* if left & right are bit variables */
3413 if (AOP_TYPE(left) == AOP_CRY &&
3414 AOP_TYPE(right) == AOP_CRY ) {
3415 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3416 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3418 /* subtract right from left if at the
3419 end the carry flag is set then we know that
3420 left is greater than right */
3421 size = max(AOP_SIZE(left),AOP_SIZE(right));
3423 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3424 if((size == 1) && !sign &&
3425 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3426 symbol *lbl = newiTempLabel(NULL);
3427 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3428 aopGet(AOP(left),offset,FALSE,FALSE),
3429 aopGet(AOP(right),offset,FALSE,FALSE),
3431 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3434 if(AOP_TYPE(right) == AOP_LIT) {
3435 symbol *lbl = newiTempLabel(NULL);
3437 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3439 DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3442 i = (lit >> (size*8)) & 0xff;
3445 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3447 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3449 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3452 emitpcode(POC_MOVLW, popGetLit(i));
3453 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3455 i = (lit >> (size*8)) & 0xff;
3456 emitpcode(POC_MOVLW, popGetLit(i));
3458 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3461 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3463 emitpLabel(lbl->key);
3469 if(AOP_TYPE(left) == AOP_LIT) {
3470 //symbol *lbl = newiTempLabel(NULL);
3472 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3474 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3479 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3481 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3483 if(IC_TRUE(ifx) != NULL)
3484 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3486 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3488 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3489 emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3490 genSkipc(ifx,IC_TRUE(ifx)!=NULL);
3494 i = (lit >> (size*8)) & 0xff;
3498 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3500 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3502 if(IC_TRUE(ifx) != NULL)
3503 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3505 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3508 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3509 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3511 i = (lit >> (size*8)) & 0xff;
3512 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3514 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3516 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3521 emitpLabel(lbl->key);
3529 DEBUGpic14_emitcode(";sign","%d",sign);
3531 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3532 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3534 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3535 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3540 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3542 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3543 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3546 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3548 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3549 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3557 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3558 pic14_outBitC(result);
3560 /* if the result is used in the next
3561 ifx conditional branch then generate
3562 code a little differently */
3564 genIfxJump (ifx,"c");
3566 pic14_outBitC(result);
3567 /* leave the result in acc */
3572 /*-----------------------------------------------------------------*/
3573 /* genCmpGt :- greater than comparison */
3574 /*-----------------------------------------------------------------*/
3575 static void genCmpGt (iCode *ic, iCode *ifx)
3577 operand *left, *right, *result;
3578 sym_link *letype , *retype;
3581 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3583 right= IC_RIGHT(ic);
3584 result = IC_RESULT(ic);
3586 letype = getSpec(operandType(left));
3587 retype =getSpec(operandType(right));
3588 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3589 /* assign the amsops */
3590 aopOp (left,ic,FALSE);
3591 aopOp (right,ic,FALSE);
3592 aopOp (result,ic,TRUE);
3594 genCmp(right, left, result, ifx, sign);
3596 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3597 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3598 freeAsmop(result,NULL,ic,TRUE);
3601 /*-----------------------------------------------------------------*/
3602 /* genCmpLt - less than comparisons */
3603 /*-----------------------------------------------------------------*/
3604 static void genCmpLt (iCode *ic, iCode *ifx)
3606 operand *left, *right, *result;
3607 sym_link *letype , *retype;
3610 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3612 right= IC_RIGHT(ic);
3613 result = IC_RESULT(ic);
3615 letype = getSpec(operandType(left));
3616 retype =getSpec(operandType(right));
3617 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3619 /* assign the amsops */
3620 aopOp (left,ic,FALSE);
3621 aopOp (right,ic,FALSE);
3622 aopOp (result,ic,TRUE);
3624 genCmp(left, right, result, ifx, sign);
3626 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3627 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3628 freeAsmop(result,NULL,ic,TRUE);
3631 /*-----------------------------------------------------------------*/
3632 /* genc16bit2lit - compare a 16 bit value to a literal */
3633 /*-----------------------------------------------------------------*/
3634 static void genc16bit2lit(operand *op, int lit, int offset)
3638 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3639 if( (lit&0xff) == 0)
3644 switch( BYTEofLONG(lit,i)) {
3646 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3649 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3652 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3655 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3656 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3661 switch( BYTEofLONG(lit,i)) {
3663 emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3667 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3671 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3674 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3676 emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3682 /*-----------------------------------------------------------------*/
3683 /* gencjneshort - compare and jump if not equal */
3684 /*-----------------------------------------------------------------*/
3685 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3687 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3689 unsigned long lit = 0L;
3691 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3692 /* if the left side is a literal or
3693 if the right is in a pointer register and left
3695 if ((AOP_TYPE(left) == AOP_LIT) ||
3696 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3701 if(AOP_TYPE(right) == AOP_LIT)
3702 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3704 /* if the right side is a literal then anything goes */
3705 if (AOP_TYPE(right) == AOP_LIT &&
3706 AOP_TYPE(left) != AOP_DIR ) {
3709 genc16bit2lit(left, lit, 0);
3711 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3712 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3717 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3718 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3719 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3720 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3722 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3723 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3727 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3728 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3736 /* if the right side is in a register or in direct space or
3737 if the left is a pointer register & right is not */
3738 else if (AOP_TYPE(right) == AOP_REG ||
3739 AOP_TYPE(right) == AOP_DIR ||
3740 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3741 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3744 genc16bit2lit(left, lit, 0);
3746 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3747 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3751 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3752 ( (lit & 0xff) != 0)) {
3753 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3754 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3755 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3756 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3759 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3760 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3763 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3764 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3770 /* right is a pointer reg need both a & b */
3772 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3774 pic14_emitcode("mov","b,%s",l);
3775 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3776 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3782 /*-----------------------------------------------------------------*/
3783 /* gencjne - compare and jump if not equal */
3784 /*-----------------------------------------------------------------*/
3785 static void gencjne(operand *left, operand *right, symbol *lbl)
3787 symbol *tlbl = newiTempLabel(NULL);
3789 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3790 gencjneshort(left, right, lbl);
3792 pic14_emitcode("mov","a,%s",one);
3793 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3794 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3795 pic14_emitcode("clr","a");
3796 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3798 emitpLabel(lbl->key);
3799 emitpLabel(tlbl->key);
3806 /*-----------------------------------------------------------------*/
3807 /* genCmpEq - generates code for equal to */
3808 /*-----------------------------------------------------------------*/
3809 static void genCmpEq (iCode *ic, iCode *ifx)
3811 operand *left, *right, *result;
3812 unsigned long lit = 0L;
3815 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3818 DEBUGpic14_emitcode ("; ifx is non-null","");
3820 DEBUGpic14_emitcode ("; ifx is null","");
3822 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3823 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3824 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3827 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3828 AopType(AOP_TYPE(IC_RESULT(ic))),
3829 AopType(AOP_TYPE(IC_LEFT(ic))),
3830 AopType(AOP_TYPE(IC_RIGHT(ic))));
3832 size = max(AOP_SIZE(left),AOP_SIZE(right));
3834 /* if literal, literal on the right or
3835 if the right is in a pointer register and left
3837 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3838 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3839 operand *t = IC_RIGHT(ic);
3840 IC_RIGHT(ic) = IC_LEFT(ic);
3844 if(ifx && !AOP_SIZE(result)){
3846 /* if they are both bit variables */
3847 if (AOP_TYPE(left) == AOP_CRY &&
3848 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3849 if(AOP_TYPE(right) == AOP_LIT){
3850 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3852 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3853 pic14_emitcode("cpl","c");
3854 } else if(lit == 1L) {
3855 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3857 pic14_emitcode("clr","c");
3859 /* AOP_TYPE(right) == AOP_CRY */
3861 symbol *lbl = newiTempLabel(NULL);
3862 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3863 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3864 pic14_emitcode("cpl","c");
3865 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3867 /* if true label then we jump if condition
3869 tlbl = newiTempLabel(NULL);
3870 if ( IC_TRUE(ifx) ) {
3871 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3872 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3874 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3875 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3877 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3880 /* They're not both bit variables. Is the right a literal? */
3881 if(AOP_TYPE(right) == AOP_LIT) {
3882 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3888 switch(lit & 0xff) {
3890 if ( IC_TRUE(ifx) ) {
3891 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3893 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3895 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3896 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3900 if ( IC_TRUE(ifx) ) {
3901 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3903 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3905 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3906 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3910 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3912 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3917 /* end of size == 1 */
3921 genc16bit2lit(left,lit,offset);
3924 /* end of size == 2 */
3929 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
3930 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
3931 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
3932 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
3936 /* search for patterns that can be optimized */
3938 genc16bit2lit(left,lit,0);
3941 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3943 genc16bit2lit(left,lit,2);
3945 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
3946 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
3959 } else if(AOP_TYPE(right) == AOP_CRY ) {
3960 /* we know the left is not a bit, but that the right is */
3961 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3962 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3963 popGet(AOP(right),offset,FALSE,FALSE));
3964 emitpcode(POC_XORLW,popGetLit(1));
3966 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3968 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3969 AOP(right)->aopu.aop_dir,
3970 AOP(right)->aopu.aop_dir);
3972 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3973 AOP(right)->aopu.aop_dir,
3974 AOP(right)->aopu.aop_dir);
3976 pic14_emitcode("xorlw","1");
3978 /* if the two are equal, then W will be 0 and the Z bit is set
3979 * we could test Z now, or go ahead and check the high order bytes if
3980 * the variable we're comparing is larger than a byte. */
3983 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3984 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3986 if ( IC_TRUE(ifx) ) {
3988 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3989 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3992 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3993 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3997 /* They're both variables that are larger than bits */
4000 tlbl = newiTempLabel(NULL);
4003 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4004 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4006 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4007 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4009 if ( IC_TRUE(ifx) ) {
4012 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4013 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4016 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4017 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4021 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4022 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4026 if(s>1 && IC_TRUE(ifx)) {
4027 emitpLabel(tlbl->key);
4028 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4032 /* mark the icode as generated */
4037 /* if they are both bit variables */
4038 if (AOP_TYPE(left) == AOP_CRY &&
4039 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4040 if(AOP_TYPE(right) == AOP_LIT){
4041 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4043 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4044 pic14_emitcode("cpl","c");
4045 } else if(lit == 1L) {
4046 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4048 pic14_emitcode("clr","c");
4050 /* AOP_TYPE(right) == AOP_CRY */
4052 symbol *lbl = newiTempLabel(NULL);
4053 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4054 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4055 pic14_emitcode("cpl","c");
4056 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4059 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4060 pic14_outBitC(result);
4064 genIfxJump (ifx,"c");
4067 /* if the result is used in an arithmetic operation
4068 then put the result in place */
4069 pic14_outBitC(result);
4071 gencjne(left,right,newiTempLabel(NULL));
4072 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4073 aopPut(AOP(result),"a",0);
4077 genIfxJump (ifx,"a");
4080 /* if the result is used in an arithmetic operation
4081 then put the result in place */
4082 if (AOP_TYPE(result) != AOP_CRY)
4083 pic14_outAcc(result);
4084 /* leave the result in acc */
4088 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4089 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4090 freeAsmop(result,NULL,ic,TRUE);
4093 /*-----------------------------------------------------------------*/
4094 /* ifxForOp - returns the icode containing the ifx for operand */
4095 /*-----------------------------------------------------------------*/
4096 static iCode *ifxForOp ( operand *op, iCode *ic )
4098 /* if true symbol then needs to be assigned */
4099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4100 if (IS_TRUE_SYMOP(op))
4103 /* if this has register type condition and
4104 the next instruction is ifx with the same operand
4105 and live to of the operand is upto the ifx only then */
4107 ic->next->op == IFX &&
4108 IC_COND(ic->next)->key == op->key &&
4109 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4114 /*-----------------------------------------------------------------*/
4115 /* genAndOp - for && operation */
4116 /*-----------------------------------------------------------------*/
4117 static void genAndOp (iCode *ic)
4119 operand *left,*right, *result;
4122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4123 /* note here that && operations that are in an
4124 if statement are taken away by backPatchLabels
4125 only those used in arthmetic operations remain */
4126 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4127 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4128 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4130 /* if both are bit variables */
4131 if (AOP_TYPE(left) == AOP_CRY &&
4132 AOP_TYPE(right) == AOP_CRY ) {
4133 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4134 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4135 pic14_outBitC(result);
4137 tlbl = newiTempLabel(NULL);
4138 pic14_toBoolean(left);
4139 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4140 pic14_toBoolean(right);
4141 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4142 pic14_outBitAcc(result);
4145 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4146 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4147 freeAsmop(result,NULL,ic,TRUE);
4151 /*-----------------------------------------------------------------*/
4152 /* genOrOp - for || operation */
4153 /*-----------------------------------------------------------------*/
4156 modified this code, but it doesn't appear to ever get called
4159 static void genOrOp (iCode *ic)
4161 operand *left,*right, *result;
4164 /* note here that || operations that are in an
4165 if statement are taken away by backPatchLabels
4166 only those used in arthmetic operations remain */
4167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4168 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4169 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4170 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4172 /* if both are bit variables */
4173 if (AOP_TYPE(left) == AOP_CRY &&
4174 AOP_TYPE(right) == AOP_CRY ) {
4175 pic14_emitcode("clrc","");
4176 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4177 AOP(left)->aopu.aop_dir,
4178 AOP(left)->aopu.aop_dir);
4179 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4180 AOP(right)->aopu.aop_dir,
4181 AOP(right)->aopu.aop_dir);
4182 pic14_emitcode("setc","");
4185 tlbl = newiTempLabel(NULL);
4186 pic14_toBoolean(left);
4188 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4189 pic14_toBoolean(right);
4190 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4192 pic14_outBitAcc(result);
4195 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4196 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4197 freeAsmop(result,NULL,ic,TRUE);
4200 /*-----------------------------------------------------------------*/
4201 /* isLiteralBit - test if lit == 2^n */
4202 /*-----------------------------------------------------------------*/
4203 static int isLiteralBit(unsigned long lit)
4205 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4206 0x100L,0x200L,0x400L,0x800L,
4207 0x1000L,0x2000L,0x4000L,0x8000L,
4208 0x10000L,0x20000L,0x40000L,0x80000L,
4209 0x100000L,0x200000L,0x400000L,0x800000L,
4210 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4211 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4215 for(idx = 0; idx < 32; idx++)
4221 /*-----------------------------------------------------------------*/
4222 /* continueIfTrue - */
4223 /*-----------------------------------------------------------------*/
4224 static void continueIfTrue (iCode *ic)
4226 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4228 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4232 /*-----------------------------------------------------------------*/
4234 /*-----------------------------------------------------------------*/
4235 static void jumpIfTrue (iCode *ic)
4237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4239 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4243 /*-----------------------------------------------------------------*/
4244 /* jmpTrueOrFalse - */
4245 /*-----------------------------------------------------------------*/
4246 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4248 // ugly but optimized by peephole
4249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4251 symbol *nlbl = newiTempLabel(NULL);
4252 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4253 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4254 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4255 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4258 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4259 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4264 /*-----------------------------------------------------------------*/
4265 /* genAnd - code for and */
4266 /*-----------------------------------------------------------------*/
4267 static void genAnd (iCode *ic, iCode *ifx)
4269 operand *left, *right, *result;
4271 unsigned long lit = 0L;
4275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4276 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4277 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4278 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4281 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4283 AOP_TYPE(left), AOP_TYPE(right));
4284 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4286 AOP_SIZE(left), AOP_SIZE(right));
4289 /* if left is a literal & right is not then exchange them */
4290 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4291 AOP_NEEDSACC(left)) {
4292 operand *tmp = right ;
4297 /* if result = right then exchange them */
4298 if(pic14_sameRegs(AOP(result),AOP(right))){
4299 operand *tmp = right ;
4304 /* if right is bit then exchange them */
4305 if (AOP_TYPE(right) == AOP_CRY &&
4306 AOP_TYPE(left) != AOP_CRY){
4307 operand *tmp = right ;
4311 if(AOP_TYPE(right) == AOP_LIT)
4312 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4314 size = AOP_SIZE(result);
4317 // result = bit & yy;
4318 if (AOP_TYPE(left) == AOP_CRY){
4319 // c = bit & literal;
4320 if(AOP_TYPE(right) == AOP_LIT){
4322 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4325 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4328 if(size && (AOP_TYPE(result) == AOP_CRY)){
4329 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4332 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4336 pic14_emitcode("clr","c");
4339 if (AOP_TYPE(right) == AOP_CRY){
4341 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4342 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4345 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4347 pic14_emitcode("rrc","a");
4348 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4354 pic14_outBitC(result);
4356 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4357 genIfxJump(ifx, "c");
4361 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4362 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4363 if((AOP_TYPE(right) == AOP_LIT) &&
4364 (AOP_TYPE(result) == AOP_CRY) &&
4365 (AOP_TYPE(left) != AOP_CRY)){
4366 int posbit = isLiteralBit(lit);
4370 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4373 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4378 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4379 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4381 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4382 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4389 symbol *tlbl = newiTempLabel(NULL);
4390 int sizel = AOP_SIZE(left);
4392 pic14_emitcode("setb","c");
4394 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4395 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4397 if((posbit = isLiteralBit(bytelit)) != 0)
4398 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4400 if(bytelit != 0x0FFL)
4401 pic14_emitcode("anl","a,%s",
4402 aopGet(AOP(right),offset,FALSE,TRUE));
4403 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4408 // bit = left & literal
4410 pic14_emitcode("clr","c");
4411 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4413 // if(left & literal)
4416 jmpTrueOrFalse(ifx, tlbl);
4420 pic14_outBitC(result);
4424 /* if left is same as result */
4425 if(pic14_sameRegs(AOP(result),AOP(left))){
4427 for(;size--; offset++,lit>>=8) {
4428 if(AOP_TYPE(right) == AOP_LIT){
4429 switch(lit & 0xff) {
4431 /* and'ing with 0 has clears the result */
4432 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4433 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4436 /* and'ing with 0xff is a nop when the result and left are the same */
4441 int p = my_powof2( (~lit) & 0xff );
4443 /* only one bit is set in the literal, so use a bcf instruction */
4444 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4445 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4446 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4449 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4450 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4451 if(know_W != (lit&0xff))
4452 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4454 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4459 if (AOP_TYPE(left) == AOP_ACC) {
4460 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4462 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4463 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4470 // left & result in different registers
4471 if(AOP_TYPE(result) == AOP_CRY){
4473 // if(size), result in bit
4474 // if(!size && ifx), conditional oper: if(left & right)
4475 symbol *tlbl = newiTempLabel(NULL);
4476 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4478 pic14_emitcode("setb","c");
4480 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4481 pic14_emitcode("anl","a,%s",
4482 aopGet(AOP(left),offset,FALSE,FALSE));
4483 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4488 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4489 pic14_outBitC(result);
4491 jmpTrueOrFalse(ifx, tlbl);
4493 for(;(size--);offset++) {
4495 // result = left & right
4496 if(AOP_TYPE(right) == AOP_LIT){
4497 int t = (lit >> (offset*8)) & 0x0FFL;
4500 pic14_emitcode("clrf","%s",
4501 aopGet(AOP(result),offset,FALSE,FALSE));
4502 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4505 pic14_emitcode("movf","%s,w",
4506 aopGet(AOP(left),offset,FALSE,FALSE));
4507 pic14_emitcode("movwf","%s",
4508 aopGet(AOP(result),offset,FALSE,FALSE));
4509 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4510 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4513 pic14_emitcode("movlw","0x%x",t);
4514 pic14_emitcode("andwf","%s,w",
4515 aopGet(AOP(left),offset,FALSE,FALSE));
4516 pic14_emitcode("movwf","%s",
4517 aopGet(AOP(result),offset,FALSE,FALSE));
4519 emitpcode(POC_MOVLW, popGetLit(t));
4520 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4521 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4526 if (AOP_TYPE(left) == AOP_ACC) {
4527 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4528 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4530 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4531 pic14_emitcode("andwf","%s,w",
4532 aopGet(AOP(left),offset,FALSE,FALSE));
4533 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4534 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4536 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4537 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4543 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4544 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4545 freeAsmop(result,NULL,ic,TRUE);
4548 /*-----------------------------------------------------------------*/
4549 /* genOr - code for or */
4550 /*-----------------------------------------------------------------*/
4551 static void genOr (iCode *ic, iCode *ifx)
4553 operand *left, *right, *result;
4555 unsigned long lit = 0L;
4557 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4559 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4560 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4561 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4564 /* if left is a literal & right is not then exchange them */
4565 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4566 AOP_NEEDSACC(left)) {
4567 operand *tmp = right ;
4572 /* if result = right then exchange them */
4573 if(pic14_sameRegs(AOP(result),AOP(right))){
4574 operand *tmp = right ;
4579 /* if right is bit then exchange them */
4580 if (AOP_TYPE(right) == AOP_CRY &&
4581 AOP_TYPE(left) != AOP_CRY){
4582 operand *tmp = right ;
4587 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4588 AopType(AOP_TYPE(result)),
4589 AopType(AOP_TYPE(left)),
4590 AopType(AOP_TYPE(right)));
4592 if(AOP_TYPE(right) == AOP_LIT)
4593 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4595 size = AOP_SIZE(result);
4599 if (AOP_TYPE(left) == AOP_CRY){
4600 if(AOP_TYPE(right) == AOP_LIT){
4601 // c = bit & literal;
4603 // lit != 0 => result = 1
4604 if(AOP_TYPE(result) == AOP_CRY){
4606 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4607 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4608 // AOP(result)->aopu.aop_dir,
4609 // AOP(result)->aopu.aop_dir);
4611 continueIfTrue(ifx);
4615 // lit == 0 => result = left
4616 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4618 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4621 if (AOP_TYPE(right) == AOP_CRY){
4622 if(pic14_sameRegs(AOP(result),AOP(left))){
4624 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4625 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4626 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4628 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4629 AOP(result)->aopu.aop_dir,
4630 AOP(result)->aopu.aop_dir);
4631 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4632 AOP(right)->aopu.aop_dir,
4633 AOP(right)->aopu.aop_dir);
4634 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4635 AOP(result)->aopu.aop_dir,
4636 AOP(result)->aopu.aop_dir);
4638 if( AOP_TYPE(result) == AOP_ACC) {
4639 emitpcode(POC_MOVLW, popGetLit(0));
4640 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4641 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4642 emitpcode(POC_MOVLW, popGetLit(1));
4646 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4647 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4648 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4649 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4651 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4652 AOP(result)->aopu.aop_dir,
4653 AOP(result)->aopu.aop_dir);
4654 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4655 AOP(right)->aopu.aop_dir,
4656 AOP(right)->aopu.aop_dir);
4657 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4658 AOP(left)->aopu.aop_dir,
4659 AOP(left)->aopu.aop_dir);
4660 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4661 AOP(result)->aopu.aop_dir,
4662 AOP(result)->aopu.aop_dir);
4667 symbol *tlbl = newiTempLabel(NULL);
4668 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4671 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4672 if( AOP_TYPE(right) == AOP_ACC) {
4673 emitpcode(POC_IORLW, popGetLit(0));
4675 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4676 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4681 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4682 pic14_emitcode(";XXX setb","c");
4683 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4684 AOP(left)->aopu.aop_dir,tlbl->key+100);
4685 pic14_toBoolean(right);
4686 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4687 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4688 jmpTrueOrFalse(ifx, tlbl);
4692 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4699 pic14_outBitC(result);
4701 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4702 genIfxJump(ifx, "c");
4706 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4707 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4708 if((AOP_TYPE(right) == AOP_LIT) &&
4709 (AOP_TYPE(result) == AOP_CRY) &&
4710 (AOP_TYPE(left) != AOP_CRY)){
4712 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4715 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4717 continueIfTrue(ifx);
4720 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4721 // lit = 0, result = boolean(left)
4723 pic14_emitcode(";XXX setb","c");
4724 pic14_toBoolean(right);
4726 symbol *tlbl = newiTempLabel(NULL);
4727 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4729 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4731 genIfxJump (ifx,"a");
4735 pic14_outBitC(result);
4739 /* if left is same as result */
4740 if(pic14_sameRegs(AOP(result),AOP(left))){
4742 for(;size--; offset++,lit>>=8) {
4743 if(AOP_TYPE(right) == AOP_LIT){
4744 if((lit & 0xff) == 0)
4745 /* or'ing with 0 has no effect */
4748 int p = my_powof2(lit & 0xff);
4750 /* only one bit is set in the literal, so use a bsf instruction */
4752 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4754 if(know_W != (lit & 0xff))
4755 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4756 know_W = lit & 0xff;
4757 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4762 if (AOP_TYPE(left) == AOP_ACC) {
4763 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4764 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4766 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4767 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4769 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4770 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4776 // left & result in different registers
4777 if(AOP_TYPE(result) == AOP_CRY){
4779 // if(size), result in bit
4780 // if(!size && ifx), conditional oper: if(left | right)
4781 symbol *tlbl = newiTempLabel(NULL);
4782 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4783 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4787 pic14_emitcode(";XXX setb","c");
4789 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4790 pic14_emitcode(";XXX orl","a,%s",
4791 aopGet(AOP(left),offset,FALSE,FALSE));
4792 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4797 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4798 pic14_outBitC(result);
4800 jmpTrueOrFalse(ifx, tlbl);
4801 } else for(;(size--);offset++){
4803 // result = left & right
4804 if(AOP_TYPE(right) == AOP_LIT){
4805 int t = (lit >> (offset*8)) & 0x0FFL;
4808 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4809 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4811 pic14_emitcode("movf","%s,w",
4812 aopGet(AOP(left),offset,FALSE,FALSE));
4813 pic14_emitcode("movwf","%s",
4814 aopGet(AOP(result),offset,FALSE,FALSE));
4817 emitpcode(POC_MOVLW, popGetLit(t));
4818 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4819 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4821 pic14_emitcode("movlw","0x%x",t);
4822 pic14_emitcode("iorwf","%s,w",
4823 aopGet(AOP(left),offset,FALSE,FALSE));
4824 pic14_emitcode("movwf","%s",
4825 aopGet(AOP(result),offset,FALSE,FALSE));
4831 // faster than result <- left, anl result,right
4832 // and better if result is SFR
4833 if (AOP_TYPE(left) == AOP_ACC) {
4834 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4835 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4837 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4838 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4840 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4841 pic14_emitcode("iorwf","%s,w",
4842 aopGet(AOP(left),offset,FALSE,FALSE));
4844 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4845 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4850 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4851 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4852 freeAsmop(result,NULL,ic,TRUE);
4855 /*-----------------------------------------------------------------*/
4856 /* genXor - code for xclusive or */
4857 /*-----------------------------------------------------------------*/
4858 static void genXor (iCode *ic, iCode *ifx)
4860 operand *left, *right, *result;
4862 unsigned long lit = 0L;
4864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4866 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4867 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4868 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4870 /* if left is a literal & right is not ||
4871 if left needs acc & right does not */
4872 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4873 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4874 operand *tmp = right ;
4879 /* if result = right then exchange them */
4880 if(pic14_sameRegs(AOP(result),AOP(right))){
4881 operand *tmp = right ;
4886 /* if right is bit then exchange them */
4887 if (AOP_TYPE(right) == AOP_CRY &&
4888 AOP_TYPE(left) != AOP_CRY){
4889 operand *tmp = right ;
4893 if(AOP_TYPE(right) == AOP_LIT)
4894 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4896 size = AOP_SIZE(result);
4900 if (AOP_TYPE(left) == AOP_CRY){
4901 if(AOP_TYPE(right) == AOP_LIT){
4902 // c = bit & literal;
4904 // lit>>1 != 0 => result = 1
4905 if(AOP_TYPE(result) == AOP_CRY){
4907 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4909 continueIfTrue(ifx);
4912 pic14_emitcode("setb","c");
4916 // lit == 0, result = left
4917 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4919 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4921 // lit == 1, result = not(left)
4922 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4923 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4926 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4927 pic14_emitcode("cpl","c");
4934 symbol *tlbl = newiTempLabel(NULL);
4935 if (AOP_TYPE(right) == AOP_CRY){
4937 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4940 int sizer = AOP_SIZE(right);
4942 // if val>>1 != 0, result = 1
4943 pic14_emitcode("setb","c");
4945 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4947 // test the msb of the lsb
4948 pic14_emitcode("anl","a,#0xfe");
4949 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4953 pic14_emitcode("rrc","a");
4955 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4956 pic14_emitcode("cpl","c");
4957 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4962 pic14_outBitC(result);
4964 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4965 genIfxJump(ifx, "c");
4969 if(pic14_sameRegs(AOP(result),AOP(left))){
4970 /* if left is same as result */
4971 for(;size--; offset++) {
4972 if(AOP_TYPE(right) == AOP_LIT){
4973 int t = (lit >> (offset*8)) & 0x0FFL;
4977 if (IS_AOP_PREG(left)) {
4978 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4979 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4980 aopPut(AOP(result),"a",offset);
4982 emitpcode(POC_MOVLW, popGetLit(t));
4983 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
4984 pic14_emitcode("xrl","%s,%s",
4985 aopGet(AOP(left),offset,FALSE,TRUE),
4986 aopGet(AOP(right),offset,FALSE,FALSE));
4989 if (AOP_TYPE(left) == AOP_ACC)
4990 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4992 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4993 if (IS_AOP_PREG(left)) {
4994 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4995 aopPut(AOP(result),"a",offset);
4997 pic14_emitcode("xrl","%s,a",
4998 aopGet(AOP(left),offset,FALSE,TRUE));
5003 // left & result in different registers
5004 if(AOP_TYPE(result) == AOP_CRY){
5006 // if(size), result in bit
5007 // if(!size && ifx), conditional oper: if(left ^ right)
5008 symbol *tlbl = newiTempLabel(NULL);
5009 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5011 pic14_emitcode("setb","c");
5013 if((AOP_TYPE(right) == AOP_LIT) &&
5014 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5015 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5017 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5018 pic14_emitcode("xrl","a,%s",
5019 aopGet(AOP(left),offset,FALSE,FALSE));
5021 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5026 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5027 pic14_outBitC(result);
5029 jmpTrueOrFalse(ifx, tlbl);
5030 } else for(;(size--);offset++){
5032 // result = left & right
5033 if(AOP_TYPE(right) == AOP_LIT){
5034 int t = (lit >> (offset*8)) & 0x0FFL;
5037 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5038 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5039 pic14_emitcode("movf","%s,w",
5040 aopGet(AOP(left),offset,FALSE,FALSE));
5041 pic14_emitcode("movwf","%s",
5042 aopGet(AOP(result),offset,FALSE,FALSE));
5045 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5046 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5047 pic14_emitcode("comf","%s,w",
5048 aopGet(AOP(left),offset,FALSE,FALSE));
5049 pic14_emitcode("movwf","%s",
5050 aopGet(AOP(result),offset,FALSE,FALSE));
5053 emitpcode(POC_MOVLW, popGetLit(t));
5054 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5055 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5056 pic14_emitcode("movlw","0x%x",t);
5057 pic14_emitcode("xorwf","%s,w",
5058 aopGet(AOP(left),offset,FALSE,FALSE));
5059 pic14_emitcode("movwf","%s",
5060 aopGet(AOP(result),offset,FALSE,FALSE));
5066 // faster than result <- left, anl result,right
5067 // and better if result is SFR
5068 if (AOP_TYPE(left) == AOP_ACC) {
5069 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5070 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5072 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5073 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5074 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5075 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5077 if ( AOP_TYPE(result) != AOP_ACC){
5078 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5079 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5085 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5086 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5087 freeAsmop(result,NULL,ic,TRUE);
5090 /*-----------------------------------------------------------------*/
5091 /* genInline - write the inline code out */
5092 /*-----------------------------------------------------------------*/
5093 static void genInline (iCode *ic)
5095 char *buffer, *bp, *bp1;
5097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5099 _G.inLine += (!options.asmpeep);
5101 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5102 strcpy(buffer,IC_INLINE(ic));
5104 /* emit each line as a code */
5108 pic14_emitcode(bp1,"");
5115 pic14_emitcode(bp1,"");
5122 pic14_emitcode(bp1,"");
5123 /* pic14_emitcode("",buffer); */
5124 _G.inLine -= (!options.asmpeep);
5127 /*-----------------------------------------------------------------*/
5128 /* genRRC - rotate right with carry */
5129 /*-----------------------------------------------------------------*/
5130 static void genRRC (iCode *ic)
5132 operand *left , *result ;
5133 int size, offset = 0;
5136 /* rotate right with carry */
5138 result=IC_RESULT(ic);
5139 aopOp (left,ic,FALSE);
5140 aopOp (result,ic,FALSE);
5142 /* move it to the result */
5143 size = AOP_SIZE(result);
5147 l = aopGet(AOP(left),offset,FALSE,FALSE);
5149 pic14_emitcode("rrc","a");
5150 if (AOP_SIZE(result) > 1)
5151 aopPut(AOP(result),"a",offset--);
5153 /* now we need to put the carry into the
5154 highest order byte of the result */
5155 if (AOP_SIZE(result) > 1) {
5156 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5159 pic14_emitcode("mov","acc.7,c");
5160 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5161 freeAsmop(left,NULL,ic,TRUE);
5162 freeAsmop(result,NULL,ic,TRUE);
5165 /*-----------------------------------------------------------------*/
5166 /* genRLC - generate code for rotate left with carry */
5167 /*-----------------------------------------------------------------*/
5168 static void genRLC (iCode *ic)
5170 operand *left , *result ;
5171 int size, offset = 0;
5174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5175 /* rotate right with carry */
5177 result=IC_RESULT(ic);
5178 aopOp (left,ic,FALSE);
5179 aopOp (result,ic,FALSE);
5181 /* move it to the result */
5182 size = AOP_SIZE(result);
5185 l = aopGet(AOP(left),offset,FALSE,FALSE);
5187 pic14_emitcode("add","a,acc");
5188 if (AOP_SIZE(result) > 1)
5189 aopPut(AOP(result),"a",offset++);
5191 l = aopGet(AOP(left),offset,FALSE,FALSE);
5193 pic14_emitcode("rlc","a");
5194 if (AOP_SIZE(result) > 1)
5195 aopPut(AOP(result),"a",offset++);
5198 /* now we need to put the carry into the
5199 highest order byte of the result */
5200 if (AOP_SIZE(result) > 1) {
5201 l = aopGet(AOP(result),0,FALSE,FALSE);
5204 pic14_emitcode("mov","acc.0,c");
5205 aopPut(AOP(result),"a",0);
5206 freeAsmop(left,NULL,ic,TRUE);
5207 freeAsmop(result,NULL,ic,TRUE);
5210 /*-----------------------------------------------------------------*/
5211 /* genGetHbit - generates code get highest order bit */
5212 /*-----------------------------------------------------------------*/
5213 static void genGetHbit (iCode *ic)
5215 operand *left, *result;
5217 result=IC_RESULT(ic);
5218 aopOp (left,ic,FALSE);
5219 aopOp (result,ic,FALSE);
5221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5222 /* get the highest order byte into a */
5223 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5224 if(AOP_TYPE(result) == AOP_CRY){
5225 pic14_emitcode("rlc","a");
5226 pic14_outBitC(result);
5229 pic14_emitcode("rl","a");
5230 pic14_emitcode("anl","a,#0x01");
5231 pic14_outAcc(result);
5235 freeAsmop(left,NULL,ic,TRUE);
5236 freeAsmop(result,NULL,ic,TRUE);
5239 /*-----------------------------------------------------------------*/
5240 /* AccRol - rotate left accumulator by known count */
5241 /*-----------------------------------------------------------------*/
5242 static void AccRol (int shCount)
5244 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5245 shCount &= 0x0007; // shCount : 0..7
5250 pic14_emitcode("rl","a");
5253 pic14_emitcode("rl","a");
5254 pic14_emitcode("rl","a");
5257 pic14_emitcode("swap","a");
5258 pic14_emitcode("rr","a");
5261 pic14_emitcode("swap","a");
5264 pic14_emitcode("swap","a");
5265 pic14_emitcode("rl","a");
5268 pic14_emitcode("rr","a");
5269 pic14_emitcode("rr","a");
5272 pic14_emitcode("rr","a");
5277 /*-----------------------------------------------------------------*/
5278 /* AccLsh - left shift accumulator by known count */
5279 /*-----------------------------------------------------------------*/
5280 static void AccLsh (int shCount)
5282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5285 pic14_emitcode("add","a,acc");
5288 pic14_emitcode("add","a,acc");
5289 pic14_emitcode("add","a,acc");
5291 /* rotate left accumulator */
5293 /* and kill the lower order bits */
5294 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5299 /*-----------------------------------------------------------------*/
5300 /* AccRsh - right shift accumulator by known count */
5301 /*-----------------------------------------------------------------*/
5302 static void AccRsh (int shCount)
5304 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5308 pic14_emitcode("rrc","a");
5310 /* rotate right accumulator */
5311 AccRol(8 - shCount);
5312 /* and kill the higher order bits */
5313 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5319 /*-----------------------------------------------------------------*/
5320 /* AccSRsh - signed right shift accumulator by known count */
5321 /*-----------------------------------------------------------------*/
5322 static void AccSRsh (int shCount)
5325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5328 pic14_emitcode("mov","c,acc.7");
5329 pic14_emitcode("rrc","a");
5330 } else if(shCount == 2){
5331 pic14_emitcode("mov","c,acc.7");
5332 pic14_emitcode("rrc","a");
5333 pic14_emitcode("mov","c,acc.7");
5334 pic14_emitcode("rrc","a");
5336 tlbl = newiTempLabel(NULL);
5337 /* rotate right accumulator */
5338 AccRol(8 - shCount);
5339 /* and kill the higher order bits */
5340 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5341 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5342 pic14_emitcode("orl","a,#0x%02x",
5343 (unsigned char)~SRMask[shCount]);
5344 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5349 /*-----------------------------------------------------------------*/
5350 /* shiftR1Left2Result - shift right one byte from left to result */
5351 /*-----------------------------------------------------------------*/
5352 static void shiftR1Left2ResultSigned (operand *left, int offl,
5353 operand *result, int offr,
5358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5360 same = (left == result) || (AOP(left) == AOP(result));
5364 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5366 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5368 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5369 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5379 /*-----------------------------------------------------------------*/
5380 /* shiftR1Left2Result - shift right one byte from left to result */
5381 /*-----------------------------------------------------------------*/
5382 static void shiftR1Left2Result (operand *left, int offl,
5383 operand *result, int offr,
5384 int shCount, int sign)
5388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5390 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5392 /* Copy the msb into the carry if signed. */
5394 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5404 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5406 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5407 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5413 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5415 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5416 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5419 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5424 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5426 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5427 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5430 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5431 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5432 emitpcode(POC_ANDLW, popGetLit(0x1f));
5433 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5437 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5438 emitpcode(POC_ANDLW, popGetLit(0x0f));
5439 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5443 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5444 emitpcode(POC_ANDLW, popGetLit(0x0f));
5445 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5447 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5452 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5453 emitpcode(POC_ANDLW, popGetLit(0x80));
5454 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5455 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5456 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5461 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5462 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5463 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5474 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5476 /* shift right accumulator */
5481 aopPut(AOP(result),"a",offr);
5485 /*-----------------------------------------------------------------*/
5486 /* shiftL1Left2Result - shift left one byte from left to result */
5487 /*-----------------------------------------------------------------*/
5488 static void shiftL1Left2Result (operand *left, int offl,
5489 operand *result, int offr, int shCount)
5494 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5496 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5497 DEBUGpic14_emitcode ("; ***","same = %d",same);
5498 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5500 /* shift left accumulator */
5501 //AccLsh(shCount); // don't comment out just yet...
5502 // aopPut(AOP(result),"a",offr);
5506 /* Shift left 1 bit position */
5507 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5509 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5511 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5512 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5516 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5517 emitpcode(POC_ANDLW,popGetLit(0x7e));
5518 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5519 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5522 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5523 emitpcode(POC_ANDLW,popGetLit(0x3e));
5524 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5525 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5526 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5529 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5530 emitpcode(POC_ANDLW, popGetLit(0xf0));
5531 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5534 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5535 emitpcode(POC_ANDLW, popGetLit(0xf0));
5536 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5537 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5540 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5541 emitpcode(POC_ANDLW, popGetLit(0x30));
5542 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5543 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5544 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5547 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5548 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5549 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5553 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5558 /*-----------------------------------------------------------------*/
5559 /* movLeft2Result - move byte from left to result */
5560 /*-----------------------------------------------------------------*/
5561 static void movLeft2Result (operand *left, int offl,
5562 operand *result, int offr, int sign)
5565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5566 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5567 l = aopGet(AOP(left),offl,FALSE,FALSE);
5569 if (*l == '@' && (IS_AOP_PREG(result))) {
5570 pic14_emitcode("mov","a,%s",l);
5571 aopPut(AOP(result),"a",offr);
5574 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5575 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5577 //aopPut(AOP(result),l,offr);
5579 /* MSB sign in acc.7 ! */
5580 if(pic14_getDataSize(left) == offl+1){
5581 pic14_emitcode("mov","a,%s",l);
5582 aopPut(AOP(result),"a",offr);
5589 /*-----------------------------------------------------------------*/
5590 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5591 /*-----------------------------------------------------------------*/
5592 static void AccAXRrl1 (char *x)
5594 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5595 pic14_emitcode("rrc","a");
5596 pic14_emitcode("xch","a,%s", x);
5597 pic14_emitcode("rrc","a");
5598 pic14_emitcode("xch","a,%s", x);
5601 /*-----------------------------------------------------------------*/
5602 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5603 /*-----------------------------------------------------------------*/
5604 static void AccAXLrl1 (char *x)
5606 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5607 pic14_emitcode("xch","a,%s",x);
5608 pic14_emitcode("rlc","a");
5609 pic14_emitcode("xch","a,%s",x);
5610 pic14_emitcode("rlc","a");
5613 /*-----------------------------------------------------------------*/
5614 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5615 /*-----------------------------------------------------------------*/
5616 static void AccAXLsh1 (char *x)
5618 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5619 pic14_emitcode("xch","a,%s",x);
5620 pic14_emitcode("add","a,acc");
5621 pic14_emitcode("xch","a,%s",x);
5622 pic14_emitcode("rlc","a");
5626 /*-----------------------------------------------------------------*/
5627 /* AccAXLsh - left shift a:x by known count (0..7) */
5628 /*-----------------------------------------------------------------*/
5629 static void AccAXLsh (char *x, int shCount)
5631 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5644 case 5 : // AAAAABBB:CCCCCDDD
5645 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5646 pic14_emitcode("anl","a,#0x%02x",
5647 SLMask[shCount]); // BBB00000:CCCCCDDD
5648 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5649 AccRol(shCount); // DDDCCCCC:BBB00000
5650 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5651 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5652 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5653 pic14_emitcode("anl","a,#0x%02x",
5654 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5655 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5656 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5658 case 6 : // AAAAAABB:CCCCCCDD
5659 pic14_emitcode("anl","a,#0x%02x",
5660 SRMask[shCount]); // 000000BB:CCCCCCDD
5661 pic14_emitcode("mov","c,acc.0"); // c = B
5662 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5663 AccAXRrl1(x); // BCCCCCCD:D000000B
5664 AccAXRrl1(x); // BBCCCCCC:DD000000
5666 case 7 : // a:x <<= 7
5667 pic14_emitcode("anl","a,#0x%02x",
5668 SRMask[shCount]); // 0000000B:CCCCCCCD
5669 pic14_emitcode("mov","c,acc.0"); // c = B
5670 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5671 AccAXRrl1(x); // BCCCCCCC:D0000000
5679 /*-----------------------------------------------------------------*/
5680 /* AccAXRsh - right shift a:x known count (0..7) */
5681 /*-----------------------------------------------------------------*/
5682 static void AccAXRsh (char *x, int shCount)
5684 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5690 AccAXRrl1(x); // 0->a:x
5694 AccAXRrl1(x); // 0->a:x
5696 AccAXRrl1(x); // 0->a:x
5700 case 5 : // AAAAABBB:CCCCCDDD = a:x
5701 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5702 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5703 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5704 pic14_emitcode("anl","a,#0x%02x",
5705 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5706 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5707 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5708 pic14_emitcode("anl","a,#0x%02x",
5709 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5710 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5711 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5712 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5714 case 6 : // AABBBBBB:CCDDDDDD
5715 pic14_emitcode("mov","c,acc.7");
5716 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5717 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5718 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5719 pic14_emitcode("anl","a,#0x%02x",
5720 SRMask[shCount]); // 000000AA:BBBBBBCC
5722 case 7 : // ABBBBBBB:CDDDDDDD
5723 pic14_emitcode("mov","c,acc.7"); // c = A
5724 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5725 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5726 pic14_emitcode("anl","a,#0x%02x",
5727 SRMask[shCount]); // 0000000A:BBBBBBBC
5734 /*-----------------------------------------------------------------*/
5735 /* AccAXRshS - right shift signed a:x known count (0..7) */
5736 /*-----------------------------------------------------------------*/
5737 static void AccAXRshS (char *x, int shCount)
5740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5745 pic14_emitcode("mov","c,acc.7");
5746 AccAXRrl1(x); // s->a:x
5749 pic14_emitcode("mov","c,acc.7");
5750 AccAXRrl1(x); // s->a:x
5751 pic14_emitcode("mov","c,acc.7");
5752 AccAXRrl1(x); // s->a:x
5756 case 5 : // AAAAABBB:CCCCCDDD = a:x
5757 tlbl = newiTempLabel(NULL);
5758 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5759 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5760 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5761 pic14_emitcode("anl","a,#0x%02x",
5762 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5763 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5764 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5765 pic14_emitcode("anl","a,#0x%02x",
5766 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5767 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5768 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5769 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5770 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5771 pic14_emitcode("orl","a,#0x%02x",
5772 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5773 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5774 break; // SSSSAAAA:BBBCCCCC
5775 case 6 : // AABBBBBB:CCDDDDDD
5776 tlbl = newiTempLabel(NULL);
5777 pic14_emitcode("mov","c,acc.7");
5778 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5779 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5780 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5781 pic14_emitcode("anl","a,#0x%02x",
5782 SRMask[shCount]); // 000000AA:BBBBBBCC
5783 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5784 pic14_emitcode("orl","a,#0x%02x",
5785 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5786 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5788 case 7 : // ABBBBBBB:CDDDDDDD
5789 tlbl = newiTempLabel(NULL);
5790 pic14_emitcode("mov","c,acc.7"); // c = A
5791 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5792 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5793 pic14_emitcode("anl","a,#0x%02x",
5794 SRMask[shCount]); // 0000000A:BBBBBBBC
5795 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5796 pic14_emitcode("orl","a,#0x%02x",
5797 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5798 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5805 /*-----------------------------------------------------------------*/
5806 /* shiftL2Left2Result - shift left two bytes from left to result */
5807 /*-----------------------------------------------------------------*/
5808 static void shiftL2Left2Result (operand *left, int offl,
5809 operand *result, int offr, int shCount)
5813 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5815 if(pic14_sameRegs(AOP(result), AOP(left))) {
5823 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5824 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5825 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5829 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5830 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5836 emitpcode(POC_MOVLW, popGetLit(0x0f));
5837 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5838 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5839 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5840 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5841 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5842 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5844 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5845 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5849 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5850 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5851 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5852 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5853 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5854 emitpcode(POC_ANDLW,popGetLit(0xc0));
5855 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5856 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5857 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5858 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5861 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5862 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5863 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5864 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5865 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5875 /* note, use a mov/add for the shift since the mov has a
5876 chance of getting optimized out */
5877 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5878 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5879 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5880 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5881 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5885 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5886 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5892 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5893 emitpcode(POC_ANDLW, popGetLit(0xF0));
5894 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5895 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5896 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5897 emitpcode(POC_ANDLW, popGetLit(0xF0));
5898 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5899 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5903 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5904 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5908 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5909 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5910 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5911 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5913 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5914 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5915 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5916 emitpcode(POC_ANDLW,popGetLit(0xc0));
5917 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5918 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5919 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5920 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5923 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5924 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5925 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5926 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5927 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5932 /*-----------------------------------------------------------------*/
5933 /* shiftR2Left2Result - shift right two bytes from left to result */
5934 /*-----------------------------------------------------------------*/
5935 static void shiftR2Left2Result (operand *left, int offl,
5936 operand *result, int offr,
5937 int shCount, int sign)
5941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5942 same = pic14_sameRegs(AOP(result), AOP(left));
5944 if(same && ((offl + MSB16) == offr)){
5946 /* don't crash result[offr] */
5947 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5948 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5950 movLeft2Result(left,offl, result, offr, 0);
5951 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5953 /* a:x >> shCount (x = lsb(result))*/
5955 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5957 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5967 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5968 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5971 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5972 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5973 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5974 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5979 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5980 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5987 emitpcode(POC_MOVLW, popGetLit(0xf0));
5988 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5989 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5991 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5992 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5993 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5994 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5996 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5997 emitpcode(POC_ANDLW, popGetLit(0x0f));
5998 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6000 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6001 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6002 emitpcode(POC_ANDLW, popGetLit(0xf0));
6003 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6004 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6008 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6009 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6017 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6018 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6020 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6021 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6022 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6023 emitpcode(POC_ANDLW,popGetLit(0x03));
6024 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6025 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6026 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6027 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6029 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6030 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6031 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6032 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6033 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6034 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6035 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6036 emitpcode(POC_ANDLW,popGetLit(0x03));
6037 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6042 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6043 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6044 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6045 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6046 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6051 /*-----------------------------------------------------------------*/
6052 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6053 /*-----------------------------------------------------------------*/
6054 static void shiftLLeftOrResult (operand *left, int offl,
6055 operand *result, int offr, int shCount)
6057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6058 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6059 /* shift left accumulator */
6061 /* or with result */
6062 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6063 /* back to result */
6064 aopPut(AOP(result),"a",offr);
6067 /*-----------------------------------------------------------------*/
6068 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6069 /*-----------------------------------------------------------------*/
6070 static void shiftRLeftOrResult (operand *left, int offl,
6071 operand *result, int offr, int shCount)
6073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6074 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6075 /* shift right accumulator */
6077 /* or with result */
6078 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6079 /* back to result */
6080 aopPut(AOP(result),"a",offr);
6083 /*-----------------------------------------------------------------*/
6084 /* genlshOne - left shift a one byte quantity by known count */
6085 /*-----------------------------------------------------------------*/
6086 static void genlshOne (operand *result, operand *left, int shCount)
6088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6089 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6092 /*-----------------------------------------------------------------*/
6093 /* genlshTwo - left shift two bytes by known amount != 0 */
6094 /*-----------------------------------------------------------------*/
6095 static void genlshTwo (operand *result,operand *left, int shCount)
6099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6100 size = pic14_getDataSize(result);
6102 /* if shCount >= 8 */
6108 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6110 movLeft2Result(left, LSB, result, MSB16, 0);
6112 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6115 /* 1 <= shCount <= 7 */
6118 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6120 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6124 /*-----------------------------------------------------------------*/
6125 /* shiftLLong - shift left one long from left to result */
6126 /* offl = LSB or MSB16 */
6127 /*-----------------------------------------------------------------*/
6128 static void shiftLLong (operand *left, operand *result, int offr )
6131 int size = AOP_SIZE(result);
6133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6134 if(size >= LSB+offr){
6135 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6137 pic14_emitcode("add","a,acc");
6138 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6139 size >= MSB16+offr && offr != LSB )
6140 pic14_emitcode("xch","a,%s",
6141 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6143 aopPut(AOP(result),"a",LSB+offr);
6146 if(size >= MSB16+offr){
6147 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6148 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6151 pic14_emitcode("rlc","a");
6152 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6153 size >= MSB24+offr && offr != LSB)
6154 pic14_emitcode("xch","a,%s",
6155 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6157 aopPut(AOP(result),"a",MSB16+offr);
6160 if(size >= MSB24+offr){
6161 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6162 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6165 pic14_emitcode("rlc","a");
6166 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6167 size >= MSB32+offr && offr != LSB )
6168 pic14_emitcode("xch","a,%s",
6169 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6171 aopPut(AOP(result),"a",MSB24+offr);
6174 if(size > MSB32+offr){
6175 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6176 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6179 pic14_emitcode("rlc","a");
6180 aopPut(AOP(result),"a",MSB32+offr);
6183 aopPut(AOP(result),zero,LSB);
6186 /*-----------------------------------------------------------------*/
6187 /* genlshFour - shift four byte by a known amount != 0 */
6188 /*-----------------------------------------------------------------*/
6189 static void genlshFour (operand *result, operand *left, int shCount)
6193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6194 size = AOP_SIZE(result);
6196 /* if shifting more that 3 bytes */
6197 if (shCount >= 24 ) {
6200 /* lowest order of left goes to the highest
6201 order of the destination */
6202 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6204 movLeft2Result(left, LSB, result, MSB32, 0);
6205 aopPut(AOP(result),zero,LSB);
6206 aopPut(AOP(result),zero,MSB16);
6207 aopPut(AOP(result),zero,MSB32);
6211 /* more than two bytes */
6212 else if ( shCount >= 16 ) {
6213 /* lower order two bytes goes to higher order two bytes */
6215 /* if some more remaining */
6217 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6219 movLeft2Result(left, MSB16, result, MSB32, 0);
6220 movLeft2Result(left, LSB, result, MSB24, 0);
6222 aopPut(AOP(result),zero,MSB16);
6223 aopPut(AOP(result),zero,LSB);
6227 /* if more than 1 byte */
6228 else if ( shCount >= 8 ) {
6229 /* lower order three bytes goes to higher order three bytes */
6233 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6235 movLeft2Result(left, LSB, result, MSB16, 0);
6237 else{ /* size = 4 */
6239 movLeft2Result(left, MSB24, result, MSB32, 0);
6240 movLeft2Result(left, MSB16, result, MSB24, 0);
6241 movLeft2Result(left, LSB, result, MSB16, 0);
6242 aopPut(AOP(result),zero,LSB);
6244 else if(shCount == 1)
6245 shiftLLong(left, result, MSB16);
6247 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6248 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6249 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6250 aopPut(AOP(result),zero,LSB);
6255 /* 1 <= shCount <= 7 */
6256 else if(shCount <= 2){
6257 shiftLLong(left, result, LSB);
6259 shiftLLong(result, result, LSB);
6261 /* 3 <= shCount <= 7, optimize */
6263 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6264 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6265 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6269 /*-----------------------------------------------------------------*/
6270 /* genLeftShiftLiteral - left shifting by known count */
6271 /*-----------------------------------------------------------------*/
6272 static void genLeftShiftLiteral (operand *left,
6277 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6281 freeAsmop(right,NULL,ic,TRUE);
6283 aopOp(left,ic,FALSE);
6284 aopOp(result,ic,FALSE);
6286 size = getSize(operandType(result));
6289 pic14_emitcode("; shift left ","result %d, left %d",size,
6293 /* I suppose that the left size >= result size */
6296 movLeft2Result(left, size, result, size, 0);
6300 else if(shCount >= (size * 8))
6302 aopPut(AOP(result),zero,size);
6306 genlshOne (result,left,shCount);
6311 genlshTwo (result,left,shCount);
6315 genlshFour (result,left,shCount);
6319 freeAsmop(left,NULL,ic,TRUE);
6320 freeAsmop(result,NULL,ic,TRUE);
6323 /*-----------------------------------------------------------------*/
6324 /* genLeftShift - generates code for left shifting */
6325 /*-----------------------------------------------------------------*/
6326 static void genLeftShift (iCode *ic)
6328 operand *left,*right, *result;
6331 symbol *tlbl , *tlbl1;
6333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6335 right = IC_RIGHT(ic);
6337 result = IC_RESULT(ic);
6339 aopOp(right,ic,FALSE);
6341 /* if the shift count is known then do it
6342 as efficiently as possible */
6343 if (AOP_TYPE(right) == AOP_LIT) {
6344 genLeftShiftLiteral (left,right,result,ic);
6348 /* shift count is unknown then we have to form
6349 a loop get the loop count in B : Note: we take
6350 only the lower order byte since shifting
6351 more that 32 bits make no sense anyway, ( the
6352 largest size of an object can be only 32 bits ) */
6355 aopOp(left,ic,FALSE);
6356 aopOp(result,ic,FALSE);
6358 /* now move the left to the result if they are not the
6360 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6361 AOP_SIZE(result) > 1) {
6363 size = AOP_SIZE(result);
6366 l = aopGet(AOP(left),offset,FALSE,TRUE);
6367 if (*l == '@' && (IS_AOP_PREG(result))) {
6369 pic14_emitcode("mov","a,%s",l);
6370 aopPut(AOP(result),"a",offset);
6372 aopPut(AOP(result),l,offset);
6377 size = AOP_SIZE(result);
6379 /* if it is only one byte then */
6381 if(optimized_for_speed) {
6382 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6383 emitpcode(POC_ANDLW, popGetLit(0xf0));
6384 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6385 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6386 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6387 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6388 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6389 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6390 emitpcode(POC_ANDLW, popGetLit(0xfe));
6391 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6392 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6393 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6396 tlbl = newiTempLabel(NULL);
6397 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6398 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6399 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6402 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6403 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6404 emitpLabel(tlbl->key);
6405 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6406 emitpcode(POC_ADDLW, popGetLit(1));
6408 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6414 tlbl = newiTempLabel(NULL);
6416 tlbl1 = newiTempLabel(NULL);
6418 reAdjustPreg(AOP(result));
6420 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6421 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6422 l = aopGet(AOP(result),offset,FALSE,FALSE);
6424 pic14_emitcode("add","a,acc");
6425 aopPut(AOP(result),"a",offset++);
6427 l = aopGet(AOP(result),offset,FALSE,FALSE);
6429 pic14_emitcode("rlc","a");
6430 aopPut(AOP(result),"a",offset++);
6432 reAdjustPreg(AOP(result));
6434 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6435 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6437 freeAsmop (right,NULL,ic,TRUE);
6438 freeAsmop(left,NULL,ic,TRUE);
6439 freeAsmop(result,NULL,ic,TRUE);
6442 /*-----------------------------------------------------------------*/
6443 /* genrshOne - right shift a one byte quantity by known count */
6444 /*-----------------------------------------------------------------*/
6445 static void genrshOne (operand *result, operand *left,
6446 int shCount, int sign)
6448 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6449 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6452 /*-----------------------------------------------------------------*/
6453 /* genrshTwo - right shift two bytes by known amount != 0 */
6454 /*-----------------------------------------------------------------*/
6455 static void genrshTwo (operand *result,operand *left,
6456 int shCount, int sign)
6458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6459 /* if shCount >= 8 */
6463 shiftR1Left2Result(left, MSB16, result, LSB,
6466 movLeft2Result(left, MSB16, result, LSB, sign);
6468 addSign(result, MSB16, sign);
6470 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6474 /* 1 <= shCount <= 7 */
6476 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6479 /*-----------------------------------------------------------------*/
6480 /* shiftRLong - shift right one long from left to result */
6481 /* offl = LSB or MSB16 */
6482 /*-----------------------------------------------------------------*/
6483 static void shiftRLong (operand *left, int offl,
6484 operand *result, int sign)
6486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6488 pic14_emitcode("clr","c");
6489 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6491 pic14_emitcode("mov","c,acc.7");
6492 pic14_emitcode("rrc","a");
6493 aopPut(AOP(result),"a",MSB32-offl);
6495 /* add sign of "a" */
6496 addSign(result, MSB32, sign);
6498 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6499 pic14_emitcode("rrc","a");
6500 aopPut(AOP(result),"a",MSB24-offl);
6502 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6503 pic14_emitcode("rrc","a");
6504 aopPut(AOP(result),"a",MSB16-offl);
6507 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6508 pic14_emitcode("rrc","a");
6509 aopPut(AOP(result),"a",LSB);
6513 /*-----------------------------------------------------------------*/
6514 /* genrshFour - shift four byte by a known amount != 0 */
6515 /*-----------------------------------------------------------------*/
6516 static void genrshFour (operand *result, operand *left,
6517 int shCount, int sign)
6519 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6520 /* if shifting more that 3 bytes */
6521 if(shCount >= 24 ) {
6524 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6526 movLeft2Result(left, MSB32, result, LSB, sign);
6527 addSign(result, MSB16, sign);
6529 else if(shCount >= 16){
6532 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6534 movLeft2Result(left, MSB24, result, LSB, 0);
6535 movLeft2Result(left, MSB32, result, MSB16, sign);
6537 addSign(result, MSB24, sign);
6539 else if(shCount >= 8){
6542 shiftRLong(left, MSB16, result, sign);
6543 else if(shCount == 0){
6544 movLeft2Result(left, MSB16, result, LSB, 0);
6545 movLeft2Result(left, MSB24, result, MSB16, 0);
6546 movLeft2Result(left, MSB32, result, MSB24, sign);
6547 addSign(result, MSB32, sign);
6550 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6551 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6552 /* the last shift is signed */
6553 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6554 addSign(result, MSB32, sign);
6557 else{ /* 1 <= shCount <= 7 */
6559 shiftRLong(left, LSB, result, sign);
6561 shiftRLong(result, LSB, result, sign);
6564 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6565 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6566 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6571 /*-----------------------------------------------------------------*/
6572 /* genRightShiftLiteral - right shifting by known count */
6573 /*-----------------------------------------------------------------*/
6574 static void genRightShiftLiteral (operand *left,
6580 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6583 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6584 freeAsmop(right,NULL,ic,TRUE);
6586 aopOp(left,ic,FALSE);
6587 aopOp(result,ic,FALSE);
6590 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6594 size = pic14_getDataSize(left);
6595 /* test the LEFT size !!! */
6597 /* I suppose that the left size >= result size */
6599 size = pic14_getDataSize(result);
6601 movLeft2Result(left, size, result, size, 0);
6604 else if(shCount >= (size * 8)){
6606 /* get sign in acc.7 */
6607 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6608 addSign(result, LSB, sign);
6612 genrshOne (result,left,shCount,sign);
6616 genrshTwo (result,left,shCount,sign);
6620 genrshFour (result,left,shCount,sign);
6626 freeAsmop(left,NULL,ic,TRUE);
6627 freeAsmop(result,NULL,ic,TRUE);
6631 /*-----------------------------------------------------------------*/
6632 /* genSignedRightShift - right shift of signed number */
6633 /*-----------------------------------------------------------------*/
6634 static void genSignedRightShift (iCode *ic)
6636 operand *right, *left, *result;
6639 symbol *tlbl, *tlbl1 ;
6641 /* we do it the hard way put the shift count in b
6642 and loop thru preserving the sign */
6643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6645 right = IC_RIGHT(ic);
6647 result = IC_RESULT(ic);
6649 aopOp(right,ic,FALSE);
6652 if ( AOP_TYPE(right) == AOP_LIT) {
6653 genRightShiftLiteral (left,right,result,ic,1);
6656 /* shift count is unknown then we have to form
6657 a loop get the loop count in B : Note: we take
6658 only the lower order byte since shifting
6659 more that 32 bits make no sense anyway, ( the
6660 largest size of an object can be only 32 bits ) */
6662 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6663 pic14_emitcode("inc","b");
6664 freeAsmop (right,NULL,ic,TRUE);
6665 aopOp(left,ic,FALSE);
6666 aopOp(result,ic,FALSE);
6668 /* now move the left to the result if they are not the
6670 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6671 AOP_SIZE(result) > 1) {
6673 size = AOP_SIZE(result);
6676 l = aopGet(AOP(left),offset,FALSE,TRUE);
6677 if (*l == '@' && IS_AOP_PREG(result)) {
6679 pic14_emitcode("mov","a,%s",l);
6680 aopPut(AOP(result),"a",offset);
6682 aopPut(AOP(result),l,offset);
6687 /* mov the highest order bit to OVR */
6688 tlbl = newiTempLabel(NULL);
6689 tlbl1= newiTempLabel(NULL);
6691 size = AOP_SIZE(result);
6693 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6694 pic14_emitcode("rlc","a");
6695 pic14_emitcode("mov","ov,c");
6696 /* if it is only one byte then */
6698 l = aopGet(AOP(left),0,FALSE,FALSE);
6700 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6702 pic14_emitcode("mov","c,ov");
6703 pic14_emitcode("rrc","a");
6704 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6705 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6706 aopPut(AOP(result),"a",0);
6710 reAdjustPreg(AOP(result));
6711 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6712 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6713 pic14_emitcode("mov","c,ov");
6715 l = aopGet(AOP(result),offset,FALSE,FALSE);
6717 pic14_emitcode("rrc","a");
6718 aopPut(AOP(result),"a",offset--);
6720 reAdjustPreg(AOP(result));
6721 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6722 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6725 freeAsmop(left,NULL,ic,TRUE);
6726 freeAsmop(result,NULL,ic,TRUE);
6729 /*-----------------------------------------------------------------*/
6730 /* genRightShift - generate code for right shifting */
6731 /*-----------------------------------------------------------------*/
6732 static void genRightShift (iCode *ic)
6734 operand *right, *left, *result;
6738 symbol *tlbl, *tlbl1 ;
6740 /* if signed then we do it the hard way preserve the
6741 sign bit moving it inwards */
6742 retype = getSpec(operandType(IC_RESULT(ic)));
6743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6745 if (!SPEC_USIGN(retype)) {
6746 genSignedRightShift (ic);
6750 /* signed & unsigned types are treated the same : i.e. the
6751 signed is NOT propagated inwards : quoting from the
6752 ANSI - standard : "for E1 >> E2, is equivalent to division
6753 by 2**E2 if unsigned or if it has a non-negative value,
6754 otherwise the result is implementation defined ", MY definition
6755 is that the sign does not get propagated */
6757 right = IC_RIGHT(ic);
6759 result = IC_RESULT(ic);
6761 aopOp(right,ic,FALSE);
6763 /* if the shift count is known then do it
6764 as efficiently as possible */
6765 if (AOP_TYPE(right) == AOP_LIT) {
6766 genRightShiftLiteral (left,right,result,ic, 0);
6770 /* shift count is unknown then we have to form
6771 a loop get the loop count in B : Note: we take
6772 only the lower order byte since shifting
6773 more that 32 bits make no sense anyway, ( the
6774 largest size of an object can be only 32 bits ) */
6776 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6777 pic14_emitcode("inc","b");
6778 aopOp(left,ic,FALSE);
6779 aopOp(result,ic,FALSE);
6781 /* now move the left to the result if they are not the
6783 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6784 AOP_SIZE(result) > 1) {
6786 size = AOP_SIZE(result);
6789 l = aopGet(AOP(left),offset,FALSE,TRUE);
6790 if (*l == '@' && IS_AOP_PREG(result)) {
6792 pic14_emitcode("mov","a,%s",l);
6793 aopPut(AOP(result),"a",offset);
6795 aopPut(AOP(result),l,offset);
6800 tlbl = newiTempLabel(NULL);
6801 tlbl1= newiTempLabel(NULL);
6802 size = AOP_SIZE(result);
6805 /* if it is only one byte then */
6808 l = aopGet(AOP(left),0,FALSE,FALSE);
6810 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6811 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6813 pic14_emitcode("rrc","a");
6814 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6815 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6816 aopPut(AOP(result),"a",0);
6818 tlbl = newiTempLabel(NULL);
6819 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6820 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6821 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6824 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6825 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6826 emitpLabel(tlbl->key);
6827 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6828 emitpcode(POC_ADDLW, popGetLit(1));
6830 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6835 reAdjustPreg(AOP(result));
6836 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6837 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6840 l = aopGet(AOP(result),offset,FALSE,FALSE);
6842 pic14_emitcode("rrc","a");
6843 aopPut(AOP(result),"a",offset--);
6845 reAdjustPreg(AOP(result));
6847 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6848 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6851 freeAsmop(left,NULL,ic,TRUE);
6852 freeAsmop (right,NULL,ic,TRUE);
6853 freeAsmop(result,NULL,ic,TRUE);
6856 /*-----------------------------------------------------------------*/
6857 /* genUnpackBits - generates code for unpacking bits */
6858 /*-----------------------------------------------------------------*/
6859 static void genUnpackBits (operand *result, char *rname, int ptype)
6866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6867 etype = getSpec(operandType(result));
6869 /* read the first byte */
6874 pic14_emitcode("mov","a,@%s",rname);
6878 pic14_emitcode("movx","a,@%s",rname);
6882 pic14_emitcode("movx","a,@dptr");
6886 pic14_emitcode("clr","a");
6887 pic14_emitcode("movc","a","@a+dptr");
6891 pic14_emitcode("lcall","__gptrget");
6895 /* if we have bitdisplacement then it fits */
6896 /* into this byte completely or if length is */
6897 /* less than a byte */
6898 if ((shCnt = SPEC_BSTR(etype)) ||
6899 (SPEC_BLEN(etype) <= 8)) {
6901 /* shift right acc */
6904 pic14_emitcode("anl","a,#0x%02x",
6905 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6906 aopPut(AOP(result),"a",offset);
6910 /* bit field did not fit in a byte */
6911 rlen = SPEC_BLEN(etype) - 8;
6912 aopPut(AOP(result),"a",offset++);
6919 pic14_emitcode("inc","%s",rname);
6920 pic14_emitcode("mov","a,@%s",rname);
6924 pic14_emitcode("inc","%s",rname);
6925 pic14_emitcode("movx","a,@%s",rname);
6929 pic14_emitcode("inc","dptr");
6930 pic14_emitcode("movx","a,@dptr");
6934 pic14_emitcode("clr","a");
6935 pic14_emitcode("inc","dptr");
6936 pic14_emitcode("movc","a","@a+dptr");
6940 pic14_emitcode("inc","dptr");
6941 pic14_emitcode("lcall","__gptrget");
6946 /* if we are done */
6950 aopPut(AOP(result),"a",offset++);
6955 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6956 aopPut(AOP(result),"a",offset);
6963 /*-----------------------------------------------------------------*/
6964 /* genDataPointerGet - generates code when ptr offset is known */
6965 /*-----------------------------------------------------------------*/
6966 static void genDataPointerGet (operand *left,
6970 int size , offset = 0;
6973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6976 /* optimization - most of the time, left and result are the same
6977 * address, but different types. for the pic code, we could omit
6981 aopOp(result,ic,TRUE);
6983 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6985 size = AOP_SIZE(result);
6988 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6992 freeAsmop(left,NULL,ic,TRUE);
6993 freeAsmop(result,NULL,ic,TRUE);
6996 /*-----------------------------------------------------------------*/
6997 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6998 /*-----------------------------------------------------------------*/
6999 static void genNearPointerGet (operand *left,
7006 sym_link *rtype, *retype;
7007 sym_link *ltype = operandType(left);
7010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7012 rtype = operandType(result);
7013 retype= getSpec(rtype);
7015 aopOp(left,ic,FALSE);
7017 /* if left is rematerialisable and
7018 result is not bit variable type and
7019 the left is pointer to data space i.e
7020 lower 128 bytes of space */
7021 if (AOP_TYPE(left) == AOP_IMMD &&
7022 !IS_BITVAR(retype) &&
7023 DCL_TYPE(ltype) == POINTER) {
7024 genDataPointerGet (left,result,ic);
7028 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7030 /* if the value is already in a pointer register
7031 then don't need anything more */
7032 if (!AOP_INPREG(AOP(left))) {
7033 /* otherwise get a free pointer register */
7034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7036 preg = getFreePtr(ic,&aop,FALSE);
7037 pic14_emitcode("mov","%s,%s",
7039 aopGet(AOP(left),0,FALSE,TRUE));
7040 rname = preg->name ;
7042 rname = aopGet(AOP(left),0,FALSE,FALSE);
7044 freeAsmop(left,NULL,ic,TRUE);
7045 aopOp (result,ic,FALSE);
7047 /* if bitfield then unpack the bits */
7048 if (IS_BITVAR(retype))
7049 genUnpackBits (result,rname,POINTER);
7051 /* we have can just get the values */
7052 int size = AOP_SIZE(result);
7055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7057 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7059 pic14_emitcode("mov","a,@%s",rname);
7060 aopPut(AOP(result),"a",offset);
7062 sprintf(buffer,"@%s",rname);
7063 aopPut(AOP(result),buffer,offset);
7067 pic14_emitcode("inc","%s",rname);
7071 /* now some housekeeping stuff */
7073 /* we had to allocate for this iCode */
7074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7075 freeAsmop(NULL,aop,ic,TRUE);
7077 /* we did not allocate which means left
7078 already in a pointer register, then
7079 if size > 0 && this could be used again
7080 we have to point it back to where it
7082 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7083 if (AOP_SIZE(result) > 1 &&
7084 !OP_SYMBOL(left)->remat &&
7085 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7087 int size = AOP_SIZE(result) - 1;
7089 pic14_emitcode("dec","%s",rname);
7094 freeAsmop(result,NULL,ic,TRUE);
7098 /*-----------------------------------------------------------------*/
7099 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7100 /*-----------------------------------------------------------------*/
7101 static void genPagedPointerGet (operand *left,
7108 sym_link *rtype, *retype;
7110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7112 rtype = operandType(result);
7113 retype= getSpec(rtype);
7115 aopOp(left,ic,FALSE);
7117 /* if the value is already in a pointer register
7118 then don't need anything more */
7119 if (!AOP_INPREG(AOP(left))) {
7120 /* otherwise get a free pointer register */
7122 preg = getFreePtr(ic,&aop,FALSE);
7123 pic14_emitcode("mov","%s,%s",
7125 aopGet(AOP(left),0,FALSE,TRUE));
7126 rname = preg->name ;
7128 rname = aopGet(AOP(left),0,FALSE,FALSE);
7130 freeAsmop(left,NULL,ic,TRUE);
7131 aopOp (result,ic,FALSE);
7133 /* if bitfield then unpack the bits */
7134 if (IS_BITVAR(retype))
7135 genUnpackBits (result,rname,PPOINTER);
7137 /* we have can just get the values */
7138 int size = AOP_SIZE(result);
7143 pic14_emitcode("movx","a,@%s",rname);
7144 aopPut(AOP(result),"a",offset);
7149 pic14_emitcode("inc","%s",rname);
7153 /* now some housekeeping stuff */
7155 /* we had to allocate for this iCode */
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 if (AOP_SIZE(result) > 1 &&
7164 !OP_SYMBOL(left)->remat &&
7165 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7167 int size = AOP_SIZE(result) - 1;
7169 pic14_emitcode("dec","%s",rname);
7174 freeAsmop(result,NULL,ic,TRUE);
7179 /*-----------------------------------------------------------------*/
7180 /* genFarPointerGet - gget value from far space */
7181 /*-----------------------------------------------------------------*/
7182 static void genFarPointerGet (operand *left,
7183 operand *result, iCode *ic)
7186 sym_link *retype = getSpec(operandType(result));
7188 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7190 aopOp(left,ic,FALSE);
7192 /* if the operand is already in dptr
7193 then we do nothing else we move the value to dptr */
7194 if (AOP_TYPE(left) != AOP_STR) {
7195 /* if this is remateriazable */
7196 if (AOP_TYPE(left) == AOP_IMMD)
7197 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7198 else { /* we need to get it byte by byte */
7199 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7200 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7201 if (options.model == MODEL_FLAT24)
7203 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7207 /* so dptr know contains the address */
7208 freeAsmop(left,NULL,ic,TRUE);
7209 aopOp(result,ic,FALSE);
7211 /* if bit then unpack */
7212 if (IS_BITVAR(retype))
7213 genUnpackBits(result,"dptr",FPOINTER);
7215 size = AOP_SIZE(result);
7219 pic14_emitcode("movx","a,@dptr");
7220 aopPut(AOP(result),"a",offset++);
7222 pic14_emitcode("inc","dptr");
7226 freeAsmop(result,NULL,ic,TRUE);
7229 /*-----------------------------------------------------------------*/
7230 /* pic14_emitcodePointerGet - gget value from code space */
7231 /*-----------------------------------------------------------------*/
7232 static void pic14_emitcodePointerGet (operand *left,
7233 operand *result, iCode *ic)
7236 sym_link *retype = getSpec(operandType(result));
7238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7240 aopOp(left,ic,FALSE);
7242 /* if the operand is already in dptr
7243 then we do nothing else we move the value to dptr */
7244 if (AOP_TYPE(left) != AOP_STR) {
7245 /* if this is remateriazable */
7246 if (AOP_TYPE(left) == AOP_IMMD)
7247 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7248 else { /* we need to get it byte by byte */
7249 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7250 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7251 if (options.model == MODEL_FLAT24)
7253 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7257 /* so dptr know contains the address */
7258 freeAsmop(left,NULL,ic,TRUE);
7259 aopOp(result,ic,FALSE);
7261 /* if bit then unpack */
7262 if (IS_BITVAR(retype))
7263 genUnpackBits(result,"dptr",CPOINTER);
7265 size = AOP_SIZE(result);
7269 pic14_emitcode("clr","a");
7270 pic14_emitcode("movc","a,@a+dptr");
7271 aopPut(AOP(result),"a",offset++);
7273 pic14_emitcode("inc","dptr");
7277 freeAsmop(result,NULL,ic,TRUE);
7280 /*-----------------------------------------------------------------*/
7281 /* genGenPointerGet - gget value from generic pointer space */
7282 /*-----------------------------------------------------------------*/
7283 static void genGenPointerGet (operand *left,
7284 operand *result, iCode *ic)
7287 sym_link *retype = getSpec(operandType(result));
7289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7290 aopOp(left,ic,FALSE);
7292 /* if the operand is already in dptr
7293 then we do nothing else we move the value to dptr */
7294 if (AOP_TYPE(left) != AOP_STR) {
7295 /* if this is remateriazable */
7296 if (AOP_TYPE(left) == AOP_IMMD) {
7297 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7298 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7300 else { /* we need to get it byte by byte */
7301 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7302 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7303 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7304 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7305 pic14_emitcode("movwf","FSR");
7307 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7308 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7309 if (options.model == MODEL_FLAT24)
7311 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7312 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7316 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7321 /* so dptr know contains the address */
7322 freeAsmop(left,NULL,ic,TRUE);
7323 aopOp(result,ic,FALSE);
7325 /* if bit then unpack */
7326 if (IS_BITVAR(retype))
7327 genUnpackBits(result,"dptr",GPOINTER);
7329 size = AOP_SIZE(result);
7333 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7335 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7337 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7339 pic14_emitcode("movf","indf,w");
7340 pic14_emitcode("movwf","%s",
7341 aopGet(AOP(result),offset++,FALSE,FALSE));
7343 pic14_emitcode("incf","fsr,f");
7348 freeAsmop(result,NULL,ic,TRUE);
7351 /*-----------------------------------------------------------------*/
7352 /* genPointerGet - generate code for pointer get */
7353 /*-----------------------------------------------------------------*/
7354 static void genPointerGet (iCode *ic)
7356 operand *left, *result ;
7357 sym_link *type, *etype;
7360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7363 result = IC_RESULT(ic) ;
7365 /* depending on the type of pointer we need to
7366 move it to the correct pointer register */
7367 type = operandType(left);
7368 etype = getSpec(type);
7369 /* if left is of type of pointer then it is simple */
7370 if (IS_PTR(type) && !IS_FUNC(type->next))
7371 p_type = DCL_TYPE(type);
7373 /* we have to go by the storage class */
7374 p_type = PTR_TYPE(SPEC_OCLS(etype));
7376 /* if (SPEC_OCLS(etype)->codesp ) { */
7377 /* p_type = CPOINTER ; */
7380 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7381 /* p_type = FPOINTER ; */
7383 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7384 /* p_type = PPOINTER; */
7386 /* if (SPEC_OCLS(etype) == idata ) */
7387 /* p_type = IPOINTER; */
7389 /* p_type = POINTER ; */
7392 /* now that we have the pointer type we assign
7393 the pointer values */
7398 genNearPointerGet (left,result,ic);
7402 genPagedPointerGet(left,result,ic);
7406 genFarPointerGet (left,result,ic);
7410 pic14_emitcodePointerGet (left,result,ic);
7414 genGenPointerGet (left,result,ic);
7420 /*-----------------------------------------------------------------*/
7421 /* genPackBits - generates code for packed bit storage */
7422 /*-----------------------------------------------------------------*/
7423 static void genPackBits (sym_link *etype ,
7425 char *rname, int p_type)
7433 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7434 blen = SPEC_BLEN(etype);
7435 bstr = SPEC_BSTR(etype);
7437 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7440 /* if the bit lenth is less than or */
7441 /* it exactly fits a byte then */
7442 if (SPEC_BLEN(etype) <= 8 ) {
7443 shCount = SPEC_BSTR(etype) ;
7445 /* shift left acc */
7448 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7453 pic14_emitcode ("mov","b,a");
7454 pic14_emitcode("mov","a,@%s",rname);
7458 pic14_emitcode ("mov","b,a");
7459 pic14_emitcode("movx","a,@dptr");
7463 pic14_emitcode ("push","b");
7464 pic14_emitcode ("push","acc");
7465 pic14_emitcode ("lcall","__gptrget");
7466 pic14_emitcode ("pop","b");
7470 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7471 ((unsigned char)(0xFF << (blen+bstr)) |
7472 (unsigned char)(0xFF >> (8-bstr)) ) );
7473 pic14_emitcode ("orl","a,b");
7474 if (p_type == GPOINTER)
7475 pic14_emitcode("pop","b");
7481 pic14_emitcode("mov","@%s,a",rname);
7485 pic14_emitcode("movx","@dptr,a");
7489 DEBUGpic14_emitcode(";lcall","__gptrput");
7494 if ( SPEC_BLEN(etype) <= 8 )
7497 pic14_emitcode("inc","%s",rname);
7498 rLen = SPEC_BLEN(etype) ;
7500 /* now generate for lengths greater than one byte */
7503 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7513 pic14_emitcode("mov","@%s,a",rname);
7515 pic14_emitcode("mov","@%s,%s",rname,l);
7520 pic14_emitcode("movx","@dptr,a");
7525 DEBUGpic14_emitcode(";lcall","__gptrput");
7528 pic14_emitcode ("inc","%s",rname);
7533 /* last last was not complete */
7535 /* save the byte & read byte */
7538 pic14_emitcode ("mov","b,a");
7539 pic14_emitcode("mov","a,@%s",rname);
7543 pic14_emitcode ("mov","b,a");
7544 pic14_emitcode("movx","a,@dptr");
7548 pic14_emitcode ("push","b");
7549 pic14_emitcode ("push","acc");
7550 pic14_emitcode ("lcall","__gptrget");
7551 pic14_emitcode ("pop","b");
7555 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7556 pic14_emitcode ("orl","a,b");
7559 if (p_type == GPOINTER)
7560 pic14_emitcode("pop","b");
7565 pic14_emitcode("mov","@%s,a",rname);
7569 pic14_emitcode("movx","@dptr,a");
7573 DEBUGpic14_emitcode(";lcall","__gptrput");
7577 /*-----------------------------------------------------------------*/
7578 /* genDataPointerSet - remat pointer to data space */
7579 /*-----------------------------------------------------------------*/
7580 static void genDataPointerSet(operand *right,
7584 int size, offset = 0 ;
7585 char *l, buffer[256];
7587 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7588 aopOp(right,ic,FALSE);
7590 l = aopGet(AOP(result),0,FALSE,TRUE);
7591 size = AOP_SIZE(right);
7592 // tsd, was l+1 - the underline `_' prefix was being stripped
7595 sprintf(buffer,"(%s + %d)",l,offset);
7597 sprintf(buffer,"%s",l);
7599 if (AOP_TYPE(right) == AOP_LIT) {
7600 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7601 lit = lit >> (8*offset);
7603 pic14_emitcode("movlw","%d",lit);
7604 pic14_emitcode("movwf","%s",buffer);
7606 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7607 emitpcode(POC_MOVWF, popRegFromString(buffer));
7610 pic14_emitcode("clrf","%s",buffer);
7611 emitpcode(POC_CLRF, popRegFromString(buffer));
7614 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7615 pic14_emitcode("movwf","%s",buffer);
7617 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7618 emitpcode(POC_MOVWF, popRegFromString(buffer));
7625 freeAsmop(right,NULL,ic,TRUE);
7626 freeAsmop(result,NULL,ic,TRUE);
7629 /*-----------------------------------------------------------------*/
7630 /* genNearPointerSet - pic14_emitcode for near pointer put */
7631 /*-----------------------------------------------------------------*/
7632 static void genNearPointerSet (operand *right,
7639 sym_link *ptype = operandType(result);
7642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7643 retype= getSpec(operandType(right));
7645 aopOp(result,ic,FALSE);
7647 /* if the result is rematerializable &
7648 in data space & not a bit variable */
7649 if (AOP_TYPE(result) == AOP_IMMD &&
7650 DCL_TYPE(ptype) == POINTER &&
7651 !IS_BITVAR(retype)) {
7652 genDataPointerSet (right,result,ic);
7656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7658 /* if the value is already in a pointer register
7659 then don't need anything more */
7660 if (!AOP_INPREG(AOP(result))) {
7661 /* otherwise get a free pointer register */
7662 //aop = newAsmop(0);
7663 //preg = getFreePtr(ic,&aop,FALSE);
7664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7665 //pic14_emitcode("mov","%s,%s",
7667 // aopGet(AOP(result),0,FALSE,TRUE));
7668 //rname = preg->name ;
7669 pic14_emitcode("movwf","fsr");
7671 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7673 freeAsmop(result,NULL,ic,TRUE);
7674 aopOp (right,ic,FALSE);
7675 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7677 /* if bitfield then unpack the bits */
7678 if (IS_BITVAR(retype)) {
7679 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7680 "The programmer is obviously confused");
7681 //genPackBits (retype,right,rname,POINTER);
7685 /* we have can just get the values */
7686 int size = AOP_SIZE(right);
7689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7691 l = aopGet(AOP(right),offset,FALSE,TRUE);
7694 //pic14_emitcode("mov","@%s,a",rname);
7695 pic14_emitcode("movf","indf,w ;1");
7698 if (AOP_TYPE(right) == AOP_LIT) {
7699 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7701 pic14_emitcode("movlw","%s",l);
7702 pic14_emitcode("movwf","indf ;2");
7704 pic14_emitcode("clrf","indf");
7706 pic14_emitcode("movf","%s,w",l);
7707 pic14_emitcode("movwf","indf ;2");
7709 //pic14_emitcode("mov","@%s,%s",rname,l);
7712 pic14_emitcode("incf","fsr,f ;3");
7713 //pic14_emitcode("inc","%s",rname);
7718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7719 /* now some housekeeping stuff */
7721 /* we had to allocate for this iCode */
7722 freeAsmop(NULL,aop,ic,TRUE);
7724 /* we did not allocate which means left
7725 already in a pointer register, then
7726 if size > 0 && this could be used again
7727 we have to point it back to where it
7729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7730 if (AOP_SIZE(right) > 1 &&
7731 !OP_SYMBOL(result)->remat &&
7732 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7734 int size = AOP_SIZE(right) - 1;
7736 pic14_emitcode("decf","fsr,f");
7737 //pic14_emitcode("dec","%s",rname);
7741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7743 freeAsmop(right,NULL,ic,TRUE);
7748 /*-----------------------------------------------------------------*/
7749 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7750 /*-----------------------------------------------------------------*/
7751 static void genPagedPointerSet (operand *right,
7760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7762 retype= getSpec(operandType(right));
7764 aopOp(result,ic,FALSE);
7766 /* if the value is already in a pointer register
7767 then don't need anything more */
7768 if (!AOP_INPREG(AOP(result))) {
7769 /* otherwise get a free pointer register */
7771 preg = getFreePtr(ic,&aop,FALSE);
7772 pic14_emitcode("mov","%s,%s",
7774 aopGet(AOP(result),0,FALSE,TRUE));
7775 rname = preg->name ;
7777 rname = aopGet(AOP(result),0,FALSE,FALSE);
7779 freeAsmop(result,NULL,ic,TRUE);
7780 aopOp (right,ic,FALSE);
7782 /* if bitfield then unpack the bits */
7783 if (IS_BITVAR(retype))
7784 genPackBits (retype,right,rname,PPOINTER);
7786 /* we have can just get the values */
7787 int size = AOP_SIZE(right);
7791 l = aopGet(AOP(right),offset,FALSE,TRUE);
7794 pic14_emitcode("movx","@%s,a",rname);
7797 pic14_emitcode("inc","%s",rname);
7803 /* now some housekeeping stuff */
7805 /* we had to allocate for this iCode */
7806 freeAsmop(NULL,aop,ic,TRUE);
7808 /* we did not allocate which means left
7809 already in a pointer register, then
7810 if size > 0 && this could be used again
7811 we have to point it back to where it
7813 if (AOP_SIZE(right) > 1 &&
7814 !OP_SYMBOL(result)->remat &&
7815 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7817 int size = AOP_SIZE(right) - 1;
7819 pic14_emitcode("dec","%s",rname);
7824 freeAsmop(right,NULL,ic,TRUE);
7829 /*-----------------------------------------------------------------*/
7830 /* genFarPointerSet - set value from far space */
7831 /*-----------------------------------------------------------------*/
7832 static void genFarPointerSet (operand *right,
7833 operand *result, iCode *ic)
7836 sym_link *retype = getSpec(operandType(right));
7838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7839 aopOp(result,ic,FALSE);
7841 /* if the operand is already in dptr
7842 then we do nothing else we move the value to dptr */
7843 if (AOP_TYPE(result) != AOP_STR) {
7844 /* if this is remateriazable */
7845 if (AOP_TYPE(result) == AOP_IMMD)
7846 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7847 else { /* we need to get it byte by byte */
7848 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7849 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7850 if (options.model == MODEL_FLAT24)
7852 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7856 /* so dptr know contains the address */
7857 freeAsmop(result,NULL,ic,TRUE);
7858 aopOp(right,ic,FALSE);
7860 /* if bit then unpack */
7861 if (IS_BITVAR(retype))
7862 genPackBits(retype,right,"dptr",FPOINTER);
7864 size = AOP_SIZE(right);
7868 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7870 pic14_emitcode("movx","@dptr,a");
7872 pic14_emitcode("inc","dptr");
7876 freeAsmop(right,NULL,ic,TRUE);
7879 /*-----------------------------------------------------------------*/
7880 /* genGenPointerSet - set value from generic pointer space */
7881 /*-----------------------------------------------------------------*/
7882 static void genGenPointerSet (operand *right,
7883 operand *result, iCode *ic)
7886 sym_link *retype = getSpec(operandType(right));
7888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7890 aopOp(result,ic,FALSE);
7892 /* if the operand is already in dptr
7893 then we do nothing else we move the value to dptr */
7894 if (AOP_TYPE(result) != AOP_STR) {
7895 /* if this is remateriazable */
7896 if (AOP_TYPE(result) == AOP_IMMD) {
7897 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7898 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7900 else { /* we need to get it byte by byte */
7901 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7904 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7905 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7908 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7910 pic14_emitcode("movwf","INDF");
7913 /* so dptr know contains the address */
7914 freeAsmop(result,NULL,ic,TRUE);
7915 aopOp(right,ic,FALSE);
7917 /* if bit then unpack */
7918 if (IS_BITVAR(retype))
7919 genPackBits(retype,right,"dptr",GPOINTER);
7921 size = AOP_SIZE(right);
7925 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7927 pic14_emitcode("incf","fsr,f");
7928 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7929 pic14_emitcode("movwf","indf");
7931 //DEBUGpic14_emitcode(";lcall","__gptrput");
7933 // pic14_emitcode("inc","dptr");
7937 freeAsmop(right,NULL,ic,TRUE);
7940 /*-----------------------------------------------------------------*/
7941 /* genPointerSet - stores the value into a pointer location */
7942 /*-----------------------------------------------------------------*/
7943 static void genPointerSet (iCode *ic)
7945 operand *right, *result ;
7946 sym_link *type, *etype;
7949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7951 right = IC_RIGHT(ic);
7952 result = IC_RESULT(ic) ;
7954 /* depending on the type of pointer we need to
7955 move it to the correct pointer register */
7956 type = operandType(result);
7957 etype = getSpec(type);
7958 /* if left is of type of pointer then it is simple */
7959 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7960 p_type = DCL_TYPE(type);
7963 /* we have to go by the storage class */
7964 p_type = PTR_TYPE(SPEC_OCLS(etype));
7966 /* if (SPEC_OCLS(etype)->codesp ) { */
7967 /* p_type = CPOINTER ; */
7970 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7971 /* p_type = FPOINTER ; */
7973 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7974 /* p_type = PPOINTER ; */
7976 /* if (SPEC_OCLS(etype) == idata ) */
7977 /* p_type = IPOINTER ; */
7979 /* p_type = POINTER ; */
7982 /* now that we have the pointer type we assign
7983 the pointer values */
7988 genNearPointerSet (right,result,ic);
7992 genPagedPointerSet (right,result,ic);
7996 genFarPointerSet (right,result,ic);
8000 genGenPointerSet (right,result,ic);
8006 /*-----------------------------------------------------------------*/
8007 /* genIfx - generate code for Ifx statement */
8008 /*-----------------------------------------------------------------*/
8009 static void genIfx (iCode *ic, iCode *popIc)
8011 operand *cond = IC_COND(ic);
8014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8015 aopOp(cond,ic,FALSE);
8017 /* get the value into acc */
8018 if (AOP_TYPE(cond) != AOP_CRY)
8019 pic14_toBoolean(cond);
8022 /* the result is now in the accumulator */
8023 freeAsmop(cond,NULL,ic,TRUE);
8025 /* if there was something to be popped then do it */
8029 /* if the condition is a bit variable */
8030 if (isbit && IS_ITEMP(cond) &&
8032 genIfxJump(ic,SPIL_LOC(cond)->rname);
8033 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8037 if (isbit && !IS_ITEMP(cond))
8038 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
8040 DEBUGpic14_emitcode ("; isbit","a");
8043 if (isbit && !IS_ITEMP(cond))
8044 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8051 /*-----------------------------------------------------------------*/
8052 /* genAddrOf - generates code for address of */
8053 /*-----------------------------------------------------------------*/
8054 static void genAddrOf (iCode *ic)
8056 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8061 aopOp(IC_RESULT(ic),ic,FALSE);
8063 /* if the operand is on the stack then we
8064 need to get the stack offset of this
8067 /* if it has an offset then we need to compute
8070 pic14_emitcode("mov","a,_bp");
8071 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
8072 aopPut(AOP(IC_RESULT(ic)),"a",0);
8074 /* we can just move _bp */
8075 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
8077 /* fill the result with zero */
8078 size = AOP_SIZE(IC_RESULT(ic)) - 1;
8081 if (options.stack10bit && size < (FPTRSIZE - 1))
8084 "*** warning: pointer to stack var truncated.\n");
8091 if (options.stack10bit && offset == 2)
8093 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8097 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8104 /* object not on stack then we need the name */
8105 size = AOP_SIZE(IC_RESULT(ic));
8109 char s[SDCC_NAME_MAX];
8111 sprintf(s,"#(%s >> %d)",
8115 sprintf(s,"#%s",sym->rname);
8116 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8120 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8125 /*-----------------------------------------------------------------*/
8126 /* genFarFarAssign - assignment when both are in far space */
8127 /*-----------------------------------------------------------------*/
8128 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8130 int size = AOP_SIZE(right);
8133 /* first push the right side on to the stack */
8135 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8137 pic14_emitcode ("push","acc");
8140 freeAsmop(right,NULL,ic,FALSE);
8141 /* now assign DPTR to result */
8142 aopOp(result,ic,FALSE);
8143 size = AOP_SIZE(result);
8145 pic14_emitcode ("pop","acc");
8146 aopPut(AOP(result),"a",--offset);
8148 freeAsmop(result,NULL,ic,FALSE);
8153 /*-----------------------------------------------------------------*/
8154 /* genAssign - generate code for assignment */
8155 /*-----------------------------------------------------------------*/
8156 static void genAssign (iCode *ic)
8158 operand *result, *right;
8159 int size, offset,know_W;
8160 unsigned long lit = 0L;
8162 result = IC_RESULT(ic);
8163 right = IC_RIGHT(ic) ;
8165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8167 /* if they are the same */
8168 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8171 aopOp(right,ic,FALSE);
8172 aopOp(result,ic,TRUE);
8174 DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8175 AopType(AOP_TYPE(IC_RESULT(ic))),
8176 AopType(AOP_TYPE(IC_RIGHT(ic))),
8179 /* if they are the same registers */
8180 if (pic14_sameRegs(AOP(right),AOP(result)))
8183 /* if the result is a bit */
8184 if (AOP_TYPE(result) == AOP_CRY) {
8186 /* if the right size is a literal then
8187 we know what the value is */
8188 if (AOP_TYPE(right) == AOP_LIT) {
8190 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8191 popGet(AOP(result),0,FALSE,FALSE));
8193 if (((int) operandLitValue(right)))
8194 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8195 AOP(result)->aopu.aop_dir,
8196 AOP(result)->aopu.aop_dir);
8198 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8199 AOP(result)->aopu.aop_dir,
8200 AOP(result)->aopu.aop_dir);
8204 /* the right is also a bit variable */
8205 if (AOP_TYPE(right) == AOP_CRY) {
8206 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8207 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8208 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8210 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8211 AOP(result)->aopu.aop_dir,
8212 AOP(result)->aopu.aop_dir);
8213 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8214 AOP(right)->aopu.aop_dir,
8215 AOP(right)->aopu.aop_dir);
8216 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8217 AOP(result)->aopu.aop_dir,
8218 AOP(result)->aopu.aop_dir);
8223 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8224 pic14_toBoolean(right);
8226 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8227 //aopPut(AOP(result),"a",0);
8231 /* bit variables done */
8233 size = AOP_SIZE(result);
8235 if(AOP_TYPE(right) == AOP_LIT)
8236 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8240 if(AOP_TYPE(right) == AOP_LIT) {
8242 if(know_W != (lit&0xff))
8243 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8245 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8247 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8251 } else if (AOP_TYPE(right) == AOP_CRY) {
8252 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8254 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8255 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8258 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8259 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8267 freeAsmop (right,NULL,ic,FALSE);
8268 freeAsmop (result,NULL,ic,TRUE);
8271 /*-----------------------------------------------------------------*/
8272 /* genJumpTab - genrates code for jump table */
8273 /*-----------------------------------------------------------------*/
8274 static void genJumpTab (iCode *ic)
8279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8281 aopOp(IC_JTCOND(ic),ic,FALSE);
8282 /* get the condition into accumulator */
8283 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8285 /* multiply by three */
8286 pic14_emitcode("add","a,acc");
8287 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8289 jtab = newiTempLabel(NULL);
8290 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8291 pic14_emitcode("jmp","@a+dptr");
8292 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8294 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8295 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8297 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8298 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8299 emitpLabel(jtab->key);
8301 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8303 /* now generate the jump labels */
8304 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8305 jtab = setNextItem(IC_JTLABELS(ic))) {
8306 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8307 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8313 /*-----------------------------------------------------------------*/
8314 /* genMixedOperation - gen code for operators between mixed types */
8315 /*-----------------------------------------------------------------*/
8317 TSD - Written for the PIC port - but this unfortunately is buggy.
8318 This routine is good in that it is able to efficiently promote
8319 types to different (larger) sizes. Unfortunately, the temporary
8320 variables that are optimized out by this routine are sometimes
8321 used in other places. So until I know how to really parse the
8322 iCode tree, I'm going to not be using this routine :(.
8324 static int genMixedOperation (iCode *ic)
8327 operand *result = IC_RESULT(ic);
8328 sym_link *ctype = operandType(IC_LEFT(ic));
8329 operand *right = IC_RIGHT(ic);
8335 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8337 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8343 nextright = IC_RIGHT(nextic);
8344 nextleft = IC_LEFT(nextic);
8345 nextresult = IC_RESULT(nextic);
8347 aopOp(right,ic,FALSE);
8348 aopOp(result,ic,FALSE);
8349 aopOp(nextright, nextic, FALSE);
8350 aopOp(nextleft, nextic, FALSE);
8351 aopOp(nextresult, nextic, FALSE);
8353 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8359 pic14_emitcode(";remove right +","");
8361 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8367 pic14_emitcode(";remove left +","");
8371 big = AOP_SIZE(nextleft);
8372 small = AOP_SIZE(nextright);
8374 switch(nextic->op) {
8377 pic14_emitcode(";optimize a +","");
8378 /* if unsigned or not an integral type */
8379 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8380 pic14_emitcode(";add a bit to something","");
8383 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8385 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8386 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8387 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8389 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8397 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8398 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8399 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8402 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8404 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8405 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8406 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8407 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8408 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8411 pic14_emitcode("rlf","known_zero,w");
8418 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8419 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8420 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8422 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8432 freeAsmop(right,NULL,ic,TRUE);
8433 freeAsmop(result,NULL,ic,TRUE);
8434 freeAsmop(nextright,NULL,ic,TRUE);
8435 freeAsmop(nextleft,NULL,ic,TRUE);
8437 nextic->generated = 1;
8444 /*-----------------------------------------------------------------*/
8445 /* genCast - gen code for casting */
8446 /*-----------------------------------------------------------------*/
8447 static void genCast (iCode *ic)
8449 operand *result = IC_RESULT(ic);
8450 sym_link *ctype = operandType(IC_LEFT(ic));
8451 operand *right = IC_RIGHT(ic);
8454 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8455 /* if they are equivalent then do nothing */
8456 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8459 aopOp(right,ic,FALSE) ;
8460 aopOp(result,ic,FALSE);
8462 /* if the result is a bit */
8463 if (AOP_TYPE(result) == AOP_CRY) {
8464 /* if the right size is a literal then
8465 we know what the value is */
8466 if (AOP_TYPE(right) == AOP_LIT) {
8468 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8469 popGet(AOP(result),0,FALSE,FALSE));
8471 if (((int) operandLitValue(right)))
8472 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8473 AOP(result)->aopu.aop_dir,
8474 AOP(result)->aopu.aop_dir);
8476 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8477 AOP(result)->aopu.aop_dir,
8478 AOP(result)->aopu.aop_dir);
8483 /* the right is also a bit variable */
8484 if (AOP_TYPE(right) == AOP_CRY) {
8487 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8489 pic14_emitcode("clrc","");
8490 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8491 AOP(right)->aopu.aop_dir,
8492 AOP(right)->aopu.aop_dir);
8493 aopPut(AOP(result),"c",0);
8498 pic14_toBoolean(right);
8499 aopPut(AOP(result),"a",0);
8503 /* if they are the same size : or less */
8504 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8506 /* if they are in the same place */
8507 if (pic14_sameRegs(AOP(right),AOP(result)))
8510 /* if they in different places then copy */
8511 size = AOP_SIZE(result);
8515 aopGet(AOP(right),offset,FALSE,FALSE),
8523 /* if the result is of type pointer */
8524 if (IS_PTR(ctype)) {
8527 sym_link *type = operandType(right);
8528 sym_link *etype = getSpec(type);
8530 /* pointer to generic pointer */
8531 if (IS_GENPTR(ctype)) {
8535 p_type = DCL_TYPE(type);
8537 /* we have to go by the storage class */
8538 p_type = PTR_TYPE(SPEC_OCLS(etype));
8540 /* if (SPEC_OCLS(etype)->codesp ) */
8541 /* p_type = CPOINTER ; */
8543 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8544 /* p_type = FPOINTER ; */
8546 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8547 /* p_type = PPOINTER; */
8549 /* if (SPEC_OCLS(etype) == idata ) */
8550 /* p_type = IPOINTER ; */
8552 /* p_type = POINTER ; */
8555 /* the first two bytes are known */
8556 size = GPTRSIZE - 1;
8560 aopGet(AOP(right),offset,FALSE,FALSE),
8564 /* the last byte depending on type */
8581 /* this should never happen */
8582 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8583 "got unknown pointer type");
8586 aopPut(AOP(result),l, GPTRSIZE - 1);
8590 /* just copy the pointers */
8591 size = AOP_SIZE(result);
8595 aopGet(AOP(right),offset,FALSE,FALSE),
8603 if (AOP_TYPE(right) == AOP_CRY) {
8605 size = AOP_SIZE(right);
8607 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8608 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8609 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8611 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8612 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8613 AOP(right)->aopu.aop_dir,
8614 AOP(right)->aopu.aop_dir);
8615 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8617 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8618 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8623 /* so we now know that the size of destination is greater
8624 than the size of the source.
8625 Now, if the next iCode is an operator then we might be
8626 able to optimize the operation without performing a cast.
8628 if(genMixedOperation(ic))
8632 /* we move to result for the size of source */
8633 size = AOP_SIZE(right);
8636 pic14_emitcode(";","%d",__LINE__);
8637 /* aopPut(AOP(result),
8638 aopGet(AOP(right),offset,FALSE,FALSE),
8640 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8641 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8645 /* now depending on the sign of the destination */
8646 size = AOP_SIZE(result) - AOP_SIZE(right);
8647 /* if unsigned or not an integral type */
8648 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8650 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8651 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8655 /* we need to extend the sign :{ */
8657 emitpcodeNULLop(POC_CLRW);
8660 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8662 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8664 emitpcode(POC_MOVLW, popGetLit(0xff));
8666 pic14_emitcode("clrw","");
8667 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8668 AOP(right)->aopu.aop_dir,
8669 AOP(right)->aopu.aop_dir);
8670 pic14_emitcode("movlw","0xff");
8672 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8673 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8675 // aopPut(AOP(result),"a",offset++);
8680 /* we are done hurray !!!! */
8683 freeAsmop(right,NULL,ic,TRUE);
8684 freeAsmop(result,NULL,ic,TRUE);
8688 /*-----------------------------------------------------------------*/
8689 /* genDjnz - generate decrement & jump if not zero instrucion */
8690 /*-----------------------------------------------------------------*/
8691 static int genDjnz (iCode *ic, iCode *ifx)
8694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8699 /* if the if condition has a false label
8700 then we cannot save */
8704 /* if the minus is not of the form
8706 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8707 !IS_OP_LITERAL(IC_RIGHT(ic)))
8710 if (operandLitValue(IC_RIGHT(ic)) != 1)
8713 /* if the size of this greater than one then no
8715 if (getSize(operandType(IC_RESULT(ic))) > 1)
8718 /* otherwise we can save BIG */
8719 lbl = newiTempLabel(NULL);
8720 lbl1= newiTempLabel(NULL);
8722 aopOp(IC_RESULT(ic),ic,FALSE);
8724 if (IS_AOP_PREG(IC_RESULT(ic))) {
8725 pic14_emitcode("dec","%s",
8726 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8727 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8728 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8732 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8733 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8735 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8736 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8739 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8740 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8741 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8742 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8745 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8750 /*-----------------------------------------------------------------*/
8751 /* genReceive - generate code for a receive iCode */
8752 /*-----------------------------------------------------------------*/
8753 static void genReceive (iCode *ic)
8755 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8757 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8758 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8759 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8761 int size = getSize(operandType(IC_RESULT(ic)));
8762 int offset = fReturnSizePic - size;
8764 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8765 fReturn[fReturnSizePic - offset - 1] : "acc"));
8768 aopOp(IC_RESULT(ic),ic,FALSE);
8769 size = AOP_SIZE(IC_RESULT(ic));
8772 pic14_emitcode ("pop","acc");
8773 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8778 aopOp(IC_RESULT(ic),ic,FALSE);
8780 assignResultValue(IC_RESULT(ic));
8783 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8786 /*-----------------------------------------------------------------*/
8787 /* genpic14Code - generate code for pic14 based controllers */
8788 /*-----------------------------------------------------------------*/
8790 * At this point, ralloc.c has gone through the iCode and attempted
8791 * to optimize in a way suitable for a PIC. Now we've got to generate
8792 * PIC instructions that correspond to the iCode.
8794 * Once the instructions are generated, we'll pass through both the
8795 * peep hole optimizer and the pCode optimizer.
8796 *-----------------------------------------------------------------*/
8798 void genpic14Code (iCode *lic)
8803 lineHead = lineCurr = NULL;
8805 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8808 /* if debug information required */
8809 /* if (options.debug && currFunc) { */
8811 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8813 if (IS_STATIC(currFunc->etype)) {
8814 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8815 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8817 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8818 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8824 for (ic = lic ; ic ; ic = ic->next ) {
8826 DEBUGpic14_emitcode(";ic","");
8827 if ( cln != ic->lineno ) {
8828 if ( options.debug ) {
8830 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8831 FileBaseName(ic->filename),ic->lineno,
8832 ic->level,ic->block);
8835 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8838 /* if the result is marked as
8839 spilt and rematerializable or code for
8840 this has already been generated then
8842 if (resultRemat(ic) || ic->generated )
8845 /* depending on the operation */
8864 /* IPOP happens only when trying to restore a
8865 spilt live range, if there is an ifx statement
8866 following this pop then the if statement might
8867 be using some of the registers being popped which
8868 would destory the contents of the register so
8869 we need to check for this condition and handle it */
8871 ic->next->op == IFX &&
8872 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8873 genIfx (ic->next,ic);
8891 genEndFunction (ic);
8911 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8928 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8932 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8939 /* note these two are xlated by algebraic equivalence
8940 during parsing SDCC.y */
8941 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8942 "got '>=' or '<=' shouldn't have come here");
8946 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8958 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8962 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8966 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8993 case GET_VALUE_AT_ADDRESS:
8998 if (POINTER_SET(ic))
9025 addSet(&_G.sendSet,ic);
9034 /* now we are ready to call the
9035 peep hole optimizer */
9036 if (!options.nopeep) {
9037 printf("peep hole optimizing\n");
9038 peepHole (&lineHead);
9040 /* now do the actual printing */
9041 printLine (lineHead,codeOutFile);
9043 printf("printing pBlock\n\n");
9044 printpBlock(stdout,pb);