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 /* if left & right are bit variables */
3410 if (AOP_TYPE(left) == AOP_CRY &&
3411 AOP_TYPE(right) == AOP_CRY ) {
3412 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3413 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3415 /* subtract right from left if at the
3416 end the carry flag is set then we know that
3417 left is greater than right */
3418 size = max(AOP_SIZE(left),AOP_SIZE(right));
3420 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3421 if((size == 1) && !sign &&
3422 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3423 symbol *lbl = newiTempLabel(NULL);
3424 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3425 aopGet(AOP(left),offset,FALSE,FALSE),
3426 aopGet(AOP(right),offset,FALSE,FALSE),
3428 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3431 if(AOP_TYPE(right) == AOP_LIT) {
3433 DEBUGpic14_emitcode(";right lit","%d",sign);
3435 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3438 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
3440 emitpcode(POC_IORFW, popGet(AOP(left),++offset,FALSE,FALSE));
3442 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3446 i = (lit >> (size*8)) & 0xff;
3448 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3449 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3451 emitpcode(POC_MOVLW, popGetLit(i));
3452 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3453 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3461 if(AOP_TYPE(left) == AOP_LIT) {
3463 DEBUGpic14_emitcode(";left lit","%d",sign);
3466 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3469 emitpcode(POC_MOVFW, popGet(AOP(right),0,FALSE,FALSE));
3471 emitpcode(POC_IORFW, popGet(AOP(right),++offset,FALSE,FALSE));
3473 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3477 i = (lit >> (size*8)) & 0xff;
3479 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3480 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3481 } else if( i == 1 ) {
3482 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3483 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3486 emitpcode(POC_MOVLW, popGetLit(i));
3487 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3489 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3499 DEBUGpic14_emitcode(";sign","%d",sign);
3501 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3502 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3504 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3505 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3510 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3512 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3513 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3516 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3518 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3519 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3527 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3528 pic14_outBitC(result);
3530 /* if the result is used in the next
3531 ifx conditional branch then generate
3532 code a little differently */
3534 genIfxJump (ifx,"c");
3536 pic14_outBitC(result);
3537 /* leave the result in acc */
3542 /*-----------------------------------------------------------------*/
3543 /* genCmpGt :- greater than comparison */
3544 /*-----------------------------------------------------------------*/
3545 static void genCmpGt (iCode *ic, iCode *ifx)
3547 operand *left, *right, *result;
3548 sym_link *letype , *retype;
3551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3553 right= IC_RIGHT(ic);
3554 result = IC_RESULT(ic);
3556 letype = getSpec(operandType(left));
3557 retype =getSpec(operandType(right));
3558 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3559 /* assign the amsops */
3560 aopOp (left,ic,FALSE);
3561 aopOp (right,ic,FALSE);
3562 aopOp (result,ic,TRUE);
3564 genCmp(right, left, result, ifx, sign);
3566 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3567 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3568 freeAsmop(result,NULL,ic,TRUE);
3571 /*-----------------------------------------------------------------*/
3572 /* genCmpLt - less than comparisons */
3573 /*-----------------------------------------------------------------*/
3574 static void genCmpLt (iCode *ic, iCode *ifx)
3576 operand *left, *right, *result;
3577 sym_link *letype , *retype;
3580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3582 right= IC_RIGHT(ic);
3583 result = IC_RESULT(ic);
3585 letype = getSpec(operandType(left));
3586 retype =getSpec(operandType(right));
3587 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(left, right, 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 /* genc16bit2lit - compare a 16 bit value to a literal */
3603 /*-----------------------------------------------------------------*/
3604 static void genc16bit2lit(operand *op, int lit, int offset)
3608 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3609 if( (lit&0xff) == 0)
3614 switch( BYTEofLONG(lit,i)) {
3616 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3619 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3622 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3625 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3626 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3631 switch( BYTEofLONG(lit,i)) {
3633 emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3637 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3641 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3644 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3646 emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3652 /*-----------------------------------------------------------------*/
3653 /* gencjneshort - compare and jump if not equal */
3654 /*-----------------------------------------------------------------*/
3655 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3657 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3659 unsigned long lit = 0L;
3661 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3662 /* if the left side is a literal or
3663 if the right is in a pointer register and left
3665 if ((AOP_TYPE(left) == AOP_LIT) ||
3666 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3671 if(AOP_TYPE(right) == AOP_LIT)
3672 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3674 /* if the right side is a literal then anything goes */
3675 if (AOP_TYPE(right) == AOP_LIT &&
3676 AOP_TYPE(left) != AOP_DIR ) {
3679 genc16bit2lit(left, lit, 0);
3681 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3682 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3687 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3688 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3689 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3690 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3692 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3693 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3697 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3698 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3706 /* if the right side is in a register or in direct space or
3707 if the left is a pointer register & right is not */
3708 else if (AOP_TYPE(right) == AOP_REG ||
3709 AOP_TYPE(right) == AOP_DIR ||
3710 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3711 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3714 genc16bit2lit(left, lit, 0);
3716 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3717 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3721 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3722 ( (lit & 0xff) != 0)) {
3723 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3724 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3725 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3726 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3729 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3730 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3733 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3734 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3740 /* right is a pointer reg need both a & b */
3742 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3744 pic14_emitcode("mov","b,%s",l);
3745 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3746 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3752 /*-----------------------------------------------------------------*/
3753 /* gencjne - compare and jump if not equal */
3754 /*-----------------------------------------------------------------*/
3755 static void gencjne(operand *left, operand *right, symbol *lbl)
3757 symbol *tlbl = newiTempLabel(NULL);
3759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3760 gencjneshort(left, right, lbl);
3762 pic14_emitcode("mov","a,%s",one);
3763 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3764 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3765 pic14_emitcode("clr","a");
3766 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3768 emitpLabel(lbl->key);
3769 emitpLabel(tlbl->key);
3776 /*-----------------------------------------------------------------*/
3777 /* genCmpEq - generates code for equal to */
3778 /*-----------------------------------------------------------------*/
3779 static void genCmpEq (iCode *ic, iCode *ifx)
3781 operand *left, *right, *result;
3782 unsigned long lit = 0L;
3785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3788 DEBUGpic14_emitcode ("; ifx is non-null","");
3790 DEBUGpic14_emitcode ("; ifx is null","");
3792 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3793 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3794 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3797 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3798 AopType(AOP_TYPE(IC_RESULT(ic))),
3799 AopType(AOP_TYPE(IC_LEFT(ic))),
3800 AopType(AOP_TYPE(IC_RIGHT(ic))));
3802 size = max(AOP_SIZE(left),AOP_SIZE(right));
3804 /* if literal, literal on the right or
3805 if the right is in a pointer register and left
3807 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3808 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3809 operand *t = IC_RIGHT(ic);
3810 IC_RIGHT(ic) = IC_LEFT(ic);
3814 if(ifx && !AOP_SIZE(result)){
3816 /* if they are both bit variables */
3817 if (AOP_TYPE(left) == AOP_CRY &&
3818 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3819 if(AOP_TYPE(right) == AOP_LIT){
3820 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3822 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3823 pic14_emitcode("cpl","c");
3824 } else if(lit == 1L) {
3825 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3827 pic14_emitcode("clr","c");
3829 /* AOP_TYPE(right) == AOP_CRY */
3831 symbol *lbl = newiTempLabel(NULL);
3832 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3833 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3834 pic14_emitcode("cpl","c");
3835 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3837 /* if true label then we jump if condition
3839 tlbl = newiTempLabel(NULL);
3840 if ( IC_TRUE(ifx) ) {
3841 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3842 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3844 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3845 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3847 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3850 /* They're not both bit variables. Is the right a literal? */
3851 if(AOP_TYPE(right) == AOP_LIT) {
3852 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3858 switch(lit & 0xff) {
3860 if ( IC_TRUE(ifx) ) {
3861 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3863 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3865 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3866 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3870 if ( IC_TRUE(ifx) ) {
3871 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3873 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3875 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3876 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3880 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3882 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3887 /* end of size == 1 */
3891 genc16bit2lit(left,lit,offset);
3894 /* end of size == 2 */
3899 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
3900 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
3901 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
3902 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
3906 /* search for patterns that can be optimized */
3908 genc16bit2lit(left,lit,0);
3911 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3913 genc16bit2lit(left,lit,2);
3915 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
3916 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
3929 } else if(AOP_TYPE(right) == AOP_CRY ) {
3930 /* we know the left is not a bit, but that the right is */
3931 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3932 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3933 popGet(AOP(right),offset,FALSE,FALSE));
3934 emitpcode(POC_XORLW,popGetLit(1));
3936 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3938 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3939 AOP(right)->aopu.aop_dir,
3940 AOP(right)->aopu.aop_dir);
3942 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3943 AOP(right)->aopu.aop_dir,
3944 AOP(right)->aopu.aop_dir);
3946 pic14_emitcode("xorlw","1");
3948 /* if the two are equal, then W will be 0 and the Z bit is set
3949 * we could test Z now, or go ahead and check the high order bytes if
3950 * the variable we're comparing is larger than a byte. */
3953 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3954 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3956 if ( IC_TRUE(ifx) ) {
3958 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3959 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3962 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3963 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3967 /* They're both variables that are larger than bits */
3970 tlbl = newiTempLabel(NULL);
3973 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3974 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3976 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3977 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3979 if ( IC_TRUE(ifx) ) {
3982 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3983 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3986 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3987 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3991 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3992 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3996 if(s>1 && IC_TRUE(ifx)) {
3997 emitpLabel(tlbl->key);
3998 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4002 /* mark the icode as generated */
4007 /* if they are both bit variables */
4008 if (AOP_TYPE(left) == AOP_CRY &&
4009 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4010 if(AOP_TYPE(right) == AOP_LIT){
4011 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4013 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4014 pic14_emitcode("cpl","c");
4015 } else if(lit == 1L) {
4016 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4018 pic14_emitcode("clr","c");
4020 /* AOP_TYPE(right) == AOP_CRY */
4022 symbol *lbl = newiTempLabel(NULL);
4023 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4024 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4025 pic14_emitcode("cpl","c");
4026 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4029 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4030 pic14_outBitC(result);
4034 genIfxJump (ifx,"c");
4037 /* if the result is used in an arithmetic operation
4038 then put the result in place */
4039 pic14_outBitC(result);
4041 gencjne(left,right,newiTempLabel(NULL));
4042 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4043 aopPut(AOP(result),"a",0);
4047 genIfxJump (ifx,"a");
4050 /* if the result is used in an arithmetic operation
4051 then put the result in place */
4052 if (AOP_TYPE(result) != AOP_CRY)
4053 pic14_outAcc(result);
4054 /* leave the result in acc */
4058 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4059 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4060 freeAsmop(result,NULL,ic,TRUE);
4063 /*-----------------------------------------------------------------*/
4064 /* ifxForOp - returns the icode containing the ifx for operand */
4065 /*-----------------------------------------------------------------*/
4066 static iCode *ifxForOp ( operand *op, iCode *ic )
4068 /* if true symbol then needs to be assigned */
4069 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4070 if (IS_TRUE_SYMOP(op))
4073 /* if this has register type condition and
4074 the next instruction is ifx with the same operand
4075 and live to of the operand is upto the ifx only then */
4077 ic->next->op == IFX &&
4078 IC_COND(ic->next)->key == op->key &&
4079 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4084 /*-----------------------------------------------------------------*/
4085 /* genAndOp - for && operation */
4086 /*-----------------------------------------------------------------*/
4087 static void genAndOp (iCode *ic)
4089 operand *left,*right, *result;
4092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4093 /* note here that && operations that are in an
4094 if statement are taken away by backPatchLabels
4095 only those used in arthmetic operations remain */
4096 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4097 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4098 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4100 /* if both are bit variables */
4101 if (AOP_TYPE(left) == AOP_CRY &&
4102 AOP_TYPE(right) == AOP_CRY ) {
4103 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4104 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4105 pic14_outBitC(result);
4107 tlbl = newiTempLabel(NULL);
4108 pic14_toBoolean(left);
4109 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4110 pic14_toBoolean(right);
4111 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4112 pic14_outBitAcc(result);
4115 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4116 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4117 freeAsmop(result,NULL,ic,TRUE);
4121 /*-----------------------------------------------------------------*/
4122 /* genOrOp - for || operation */
4123 /*-----------------------------------------------------------------*/
4126 modified this code, but it doesn't appear to ever get called
4129 static void genOrOp (iCode *ic)
4131 operand *left,*right, *result;
4134 /* note here that || operations that are in an
4135 if statement are taken away by backPatchLabels
4136 only those used in arthmetic operations remain */
4137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4138 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4139 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4140 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4142 /* if both are bit variables */
4143 if (AOP_TYPE(left) == AOP_CRY &&
4144 AOP_TYPE(right) == AOP_CRY ) {
4145 pic14_emitcode("clrc","");
4146 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4147 AOP(left)->aopu.aop_dir,
4148 AOP(left)->aopu.aop_dir);
4149 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4150 AOP(right)->aopu.aop_dir,
4151 AOP(right)->aopu.aop_dir);
4152 pic14_emitcode("setc","");
4155 tlbl = newiTempLabel(NULL);
4156 pic14_toBoolean(left);
4158 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4159 pic14_toBoolean(right);
4160 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4162 pic14_outBitAcc(result);
4165 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4166 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4167 freeAsmop(result,NULL,ic,TRUE);
4170 /*-----------------------------------------------------------------*/
4171 /* isLiteralBit - test if lit == 2^n */
4172 /*-----------------------------------------------------------------*/
4173 static int isLiteralBit(unsigned long lit)
4175 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4176 0x100L,0x200L,0x400L,0x800L,
4177 0x1000L,0x2000L,0x4000L,0x8000L,
4178 0x10000L,0x20000L,0x40000L,0x80000L,
4179 0x100000L,0x200000L,0x400000L,0x800000L,
4180 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4181 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4185 for(idx = 0; idx < 32; idx++)
4191 /*-----------------------------------------------------------------*/
4192 /* continueIfTrue - */
4193 /*-----------------------------------------------------------------*/
4194 static void continueIfTrue (iCode *ic)
4196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4198 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4202 /*-----------------------------------------------------------------*/
4204 /*-----------------------------------------------------------------*/
4205 static void jumpIfTrue (iCode *ic)
4207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4209 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4213 /*-----------------------------------------------------------------*/
4214 /* jmpTrueOrFalse - */
4215 /*-----------------------------------------------------------------*/
4216 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4218 // ugly but optimized by peephole
4219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4221 symbol *nlbl = newiTempLabel(NULL);
4222 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4223 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4224 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4225 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4228 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4229 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4234 /*-----------------------------------------------------------------*/
4235 /* genAnd - code for and */
4236 /*-----------------------------------------------------------------*/
4237 static void genAnd (iCode *ic, iCode *ifx)
4239 operand *left, *right, *result;
4241 unsigned long lit = 0L;
4245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4246 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4247 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4248 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4251 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4253 AOP_TYPE(left), AOP_TYPE(right));
4254 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4256 AOP_SIZE(left), AOP_SIZE(right));
4259 /* if left is a literal & right is not then exchange them */
4260 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4261 AOP_NEEDSACC(left)) {
4262 operand *tmp = right ;
4267 /* if result = right then exchange them */
4268 if(pic14_sameRegs(AOP(result),AOP(right))){
4269 operand *tmp = right ;
4274 /* if right is bit then exchange them */
4275 if (AOP_TYPE(right) == AOP_CRY &&
4276 AOP_TYPE(left) != AOP_CRY){
4277 operand *tmp = right ;
4281 if(AOP_TYPE(right) == AOP_LIT)
4282 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4284 size = AOP_SIZE(result);
4287 // result = bit & yy;
4288 if (AOP_TYPE(left) == AOP_CRY){
4289 // c = bit & literal;
4290 if(AOP_TYPE(right) == AOP_LIT){
4292 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4295 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4298 if(size && (AOP_TYPE(result) == AOP_CRY)){
4299 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4302 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4306 pic14_emitcode("clr","c");
4309 if (AOP_TYPE(right) == AOP_CRY){
4311 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4312 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4315 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4317 pic14_emitcode("rrc","a");
4318 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4324 pic14_outBitC(result);
4326 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4327 genIfxJump(ifx, "c");
4331 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4332 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4333 if((AOP_TYPE(right) == AOP_LIT) &&
4334 (AOP_TYPE(result) == AOP_CRY) &&
4335 (AOP_TYPE(left) != AOP_CRY)){
4336 int posbit = isLiteralBit(lit);
4340 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4343 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4348 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4349 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4351 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4352 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4359 symbol *tlbl = newiTempLabel(NULL);
4360 int sizel = AOP_SIZE(left);
4362 pic14_emitcode("setb","c");
4364 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4365 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4367 if((posbit = isLiteralBit(bytelit)) != 0)
4368 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4370 if(bytelit != 0x0FFL)
4371 pic14_emitcode("anl","a,%s",
4372 aopGet(AOP(right),offset,FALSE,TRUE));
4373 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4378 // bit = left & literal
4380 pic14_emitcode("clr","c");
4381 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4383 // if(left & literal)
4386 jmpTrueOrFalse(ifx, tlbl);
4390 pic14_outBitC(result);
4394 /* if left is same as result */
4395 if(pic14_sameRegs(AOP(result),AOP(left))){
4397 for(;size--; offset++,lit>>=8) {
4398 if(AOP_TYPE(right) == AOP_LIT){
4399 switch(lit & 0xff) {
4401 /* and'ing with 0 has clears the result */
4402 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4403 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4406 /* and'ing with 0xff is a nop when the result and left are the same */
4411 int p = my_powof2( (~lit) & 0xff );
4413 /* only one bit is set in the literal, so use a bcf instruction */
4414 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4415 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4416 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4419 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4420 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4421 if(know_W != (lit&0xff))
4422 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4424 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4429 if (AOP_TYPE(left) == AOP_ACC) {
4430 pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4431 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4434 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4435 pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4436 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4437 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4444 // left & result in different registers
4445 if(AOP_TYPE(result) == AOP_CRY){
4447 // if(size), result in bit
4448 // if(!size && ifx), conditional oper: if(left & right)
4449 symbol *tlbl = newiTempLabel(NULL);
4450 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4452 pic14_emitcode("setb","c");
4454 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4455 pic14_emitcode("anl","a,%s",
4456 aopGet(AOP(left),offset,FALSE,FALSE));
4457 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4462 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4463 pic14_outBitC(result);
4465 jmpTrueOrFalse(ifx, tlbl);
4467 for(;(size--);offset++) {
4469 // result = left & right
4470 if(AOP_TYPE(right) == AOP_LIT){
4471 int t = (lit >> (offset*8)) & 0x0FFL;
4474 pic14_emitcode("clrf","%s",
4475 aopGet(AOP(result),offset,FALSE,FALSE));
4476 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4479 pic14_emitcode("movf","%s,w",
4480 aopGet(AOP(left),offset,FALSE,FALSE));
4481 pic14_emitcode("movwf","%s",
4482 aopGet(AOP(result),offset,FALSE,FALSE));
4483 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4484 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4487 pic14_emitcode("movlw","0x%x",t);
4488 pic14_emitcode("andwf","%s,w",
4489 aopGet(AOP(left),offset,FALSE,FALSE));
4490 pic14_emitcode("movwf","%s",
4491 aopGet(AOP(result),offset,FALSE,FALSE));
4493 emitpcode(POC_MOVLW, popGetLit(t));
4494 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4495 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4500 if (AOP_TYPE(left) == AOP_ACC) {
4501 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4502 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4504 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4505 pic14_emitcode("andwf","%s,w",
4506 aopGet(AOP(left),offset,FALSE,FALSE));
4507 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4508 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4510 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4511 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4517 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4518 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4519 freeAsmop(result,NULL,ic,TRUE);
4522 /*-----------------------------------------------------------------*/
4523 /* genOr - code for or */
4524 /*-----------------------------------------------------------------*/
4525 static void genOr (iCode *ic, iCode *ifx)
4527 operand *left, *right, *result;
4529 unsigned long lit = 0L;
4531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4533 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4534 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4535 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4538 /* if left is a literal & right is not then exchange them */
4539 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4540 AOP_NEEDSACC(left)) {
4541 operand *tmp = right ;
4546 /* if result = right then exchange them */
4547 if(pic14_sameRegs(AOP(result),AOP(right))){
4548 operand *tmp = right ;
4553 /* if right is bit then exchange them */
4554 if (AOP_TYPE(right) == AOP_CRY &&
4555 AOP_TYPE(left) != AOP_CRY){
4556 operand *tmp = right ;
4561 if(AOP_TYPE(right) == AOP_LIT)
4562 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4564 size = AOP_SIZE(result);
4568 if (AOP_TYPE(left) == AOP_CRY){
4569 if(AOP_TYPE(right) == AOP_LIT){
4570 // c = bit & literal;
4572 // lit != 0 => result = 1
4573 if(AOP_TYPE(result) == AOP_CRY){
4575 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4576 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4577 // AOP(result)->aopu.aop_dir,
4578 // AOP(result)->aopu.aop_dir);
4580 continueIfTrue(ifx);
4584 // lit == 0 => result = left
4585 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4587 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4590 if (AOP_TYPE(right) == AOP_CRY){
4591 if(pic14_sameRegs(AOP(result),AOP(left))){
4593 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4594 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4595 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4597 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4598 AOP(result)->aopu.aop_dir,
4599 AOP(result)->aopu.aop_dir);
4600 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4601 AOP(right)->aopu.aop_dir,
4602 AOP(right)->aopu.aop_dir);
4603 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4604 AOP(result)->aopu.aop_dir,
4605 AOP(result)->aopu.aop_dir);
4608 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4609 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4610 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4611 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4613 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4614 AOP(result)->aopu.aop_dir,
4615 AOP(result)->aopu.aop_dir);
4616 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4617 AOP(right)->aopu.aop_dir,
4618 AOP(right)->aopu.aop_dir);
4619 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4620 AOP(left)->aopu.aop_dir,
4621 AOP(left)->aopu.aop_dir);
4622 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4623 AOP(result)->aopu.aop_dir,
4624 AOP(result)->aopu.aop_dir);
4629 symbol *tlbl = newiTempLabel(NULL);
4630 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4631 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4632 pic14_emitcode(";XXX setb","c");
4633 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4634 AOP(left)->aopu.aop_dir,tlbl->key+100);
4635 pic14_toBoolean(right);
4636 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4637 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4638 jmpTrueOrFalse(ifx, tlbl);
4642 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4649 pic14_outBitC(result);
4651 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4652 genIfxJump(ifx, "c");
4656 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4657 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4658 if((AOP_TYPE(right) == AOP_LIT) &&
4659 (AOP_TYPE(result) == AOP_CRY) &&
4660 (AOP_TYPE(left) != AOP_CRY)){
4662 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4665 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4667 continueIfTrue(ifx);
4670 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4671 // lit = 0, result = boolean(left)
4673 pic14_emitcode(";XXX setb","c");
4674 pic14_toBoolean(right);
4676 symbol *tlbl = newiTempLabel(NULL);
4677 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4679 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4681 genIfxJump (ifx,"a");
4685 pic14_outBitC(result);
4689 /* if left is same as result */
4690 if(pic14_sameRegs(AOP(result),AOP(left))){
4691 for(;size--; offset++,lit>>=8) {
4692 if(AOP_TYPE(right) == AOP_LIT){
4693 if((lit & 0xff) == 0)
4694 /* or'ing with 0 has no effect */
4697 int p = my_powof2(lit & 0xff);
4699 /* only one bit is set in the literal, so use a bsf instruction */
4700 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4701 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4703 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4704 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4706 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4707 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4712 if (AOP_TYPE(left) == AOP_ACC) {
4713 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4714 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4716 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4717 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4719 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4720 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4726 // left & result in different registers
4727 if(AOP_TYPE(result) == AOP_CRY){
4729 // if(size), result in bit
4730 // if(!size && ifx), conditional oper: if(left | right)
4731 symbol *tlbl = newiTempLabel(NULL);
4732 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4733 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4736 pic14_emitcode(";XXX setb","c");
4738 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4739 pic14_emitcode(";XXX orl","a,%s",
4740 aopGet(AOP(left),offset,FALSE,FALSE));
4741 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4746 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4747 pic14_outBitC(result);
4749 jmpTrueOrFalse(ifx, tlbl);
4750 } else for(;(size--);offset++){
4752 // result = left & right
4753 if(AOP_TYPE(right) == AOP_LIT){
4754 int t = (lit >> (offset*8)) & 0x0FFL;
4757 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4758 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4760 pic14_emitcode("movf","%s,w",
4761 aopGet(AOP(left),offset,FALSE,FALSE));
4762 pic14_emitcode("movwf","%s",
4763 aopGet(AOP(result),offset,FALSE,FALSE));
4766 emitpcode(POC_MOVLW, popGetLit(t));
4767 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4768 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4770 pic14_emitcode("movlw","0x%x",t);
4771 pic14_emitcode("iorwf","%s,w",
4772 aopGet(AOP(left),offset,FALSE,FALSE));
4773 pic14_emitcode("movwf","%s",
4774 aopGet(AOP(result),offset,FALSE,FALSE));
4780 // faster than result <- left, anl result,right
4781 // and better if result is SFR
4782 if (AOP_TYPE(left) == AOP_ACC) {
4783 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4784 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4786 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4787 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4789 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4790 pic14_emitcode("iorwf","%s,w",
4791 aopGet(AOP(left),offset,FALSE,FALSE));
4793 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4794 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4799 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4800 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4801 freeAsmop(result,NULL,ic,TRUE);
4804 /*-----------------------------------------------------------------*/
4805 /* genXor - code for xclusive or */
4806 /*-----------------------------------------------------------------*/
4807 static void genXor (iCode *ic, iCode *ifx)
4809 operand *left, *right, *result;
4811 unsigned long lit = 0L;
4813 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4815 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4816 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4817 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4819 /* if left is a literal & right is not ||
4820 if left needs acc & right does not */
4821 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4822 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4823 operand *tmp = right ;
4828 /* if result = right then exchange them */
4829 if(pic14_sameRegs(AOP(result),AOP(right))){
4830 operand *tmp = right ;
4835 /* if right is bit then exchange them */
4836 if (AOP_TYPE(right) == AOP_CRY &&
4837 AOP_TYPE(left) != AOP_CRY){
4838 operand *tmp = right ;
4842 if(AOP_TYPE(right) == AOP_LIT)
4843 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4845 size = AOP_SIZE(result);
4849 if (AOP_TYPE(left) == AOP_CRY){
4850 if(AOP_TYPE(right) == AOP_LIT){
4851 // c = bit & literal;
4853 // lit>>1 != 0 => result = 1
4854 if(AOP_TYPE(result) == AOP_CRY){
4856 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4858 continueIfTrue(ifx);
4861 pic14_emitcode("setb","c");
4865 // lit == 0, result = left
4866 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4868 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4870 // lit == 1, result = not(left)
4871 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4872 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4875 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4876 pic14_emitcode("cpl","c");
4883 symbol *tlbl = newiTempLabel(NULL);
4884 if (AOP_TYPE(right) == AOP_CRY){
4886 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4889 int sizer = AOP_SIZE(right);
4891 // if val>>1 != 0, result = 1
4892 pic14_emitcode("setb","c");
4894 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4896 // test the msb of the lsb
4897 pic14_emitcode("anl","a,#0xfe");
4898 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4902 pic14_emitcode("rrc","a");
4904 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4905 pic14_emitcode("cpl","c");
4906 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4911 pic14_outBitC(result);
4913 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4914 genIfxJump(ifx, "c");
4918 if(pic14_sameRegs(AOP(result),AOP(left))){
4919 /* if left is same as result */
4920 for(;size--; offset++) {
4921 if(AOP_TYPE(right) == AOP_LIT){
4922 int t = (lit >> (offset*8)) & 0x0FFL;
4926 if (IS_AOP_PREG(left)) {
4927 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4928 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4929 aopPut(AOP(result),"a",offset);
4931 emitpcode(POC_MOVLW, popGetLit(t));
4932 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
4933 pic14_emitcode("xrl","%s,%s",
4934 aopGet(AOP(left),offset,FALSE,TRUE),
4935 aopGet(AOP(right),offset,FALSE,FALSE));
4938 if (AOP_TYPE(left) == AOP_ACC)
4939 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4941 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4942 if (IS_AOP_PREG(left)) {
4943 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4944 aopPut(AOP(result),"a",offset);
4946 pic14_emitcode("xrl","%s,a",
4947 aopGet(AOP(left),offset,FALSE,TRUE));
4952 // left & result in different registers
4953 if(AOP_TYPE(result) == AOP_CRY){
4955 // if(size), result in bit
4956 // if(!size && ifx), conditional oper: if(left ^ right)
4957 symbol *tlbl = newiTempLabel(NULL);
4958 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4960 pic14_emitcode("setb","c");
4962 if((AOP_TYPE(right) == AOP_LIT) &&
4963 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4964 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4966 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4967 pic14_emitcode("xrl","a,%s",
4968 aopGet(AOP(left),offset,FALSE,FALSE));
4970 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4975 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4976 pic14_outBitC(result);
4978 jmpTrueOrFalse(ifx, tlbl);
4979 } else for(;(size--);offset++){
4981 // result = left & right
4982 if(AOP_TYPE(right) == AOP_LIT){
4983 int t = (lit >> (offset*8)) & 0x0FFL;
4986 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4987 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4988 pic14_emitcode("movf","%s,w",
4989 aopGet(AOP(left),offset,FALSE,FALSE));
4990 pic14_emitcode("movwf","%s",
4991 aopGet(AOP(result),offset,FALSE,FALSE));
4994 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
4995 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4996 pic14_emitcode("comf","%s,w",
4997 aopGet(AOP(left),offset,FALSE,FALSE));
4998 pic14_emitcode("movwf","%s",
4999 aopGet(AOP(result),offset,FALSE,FALSE));
5002 emitpcode(POC_MOVLW, popGetLit(t));
5003 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5004 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5005 pic14_emitcode("movlw","0x%x",t);
5006 pic14_emitcode("xorwf","%s,w",
5007 aopGet(AOP(left),offset,FALSE,FALSE));
5008 pic14_emitcode("movwf","%s",
5009 aopGet(AOP(result),offset,FALSE,FALSE));
5015 // faster than result <- left, anl result,right
5016 // and better if result is SFR
5017 if (AOP_TYPE(left) == AOP_ACC) {
5018 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5019 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5021 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5022 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5023 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5024 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5026 if ( AOP_TYPE(result) != AOP_ACC){
5027 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5028 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5034 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5036 freeAsmop(result,NULL,ic,TRUE);
5039 /*-----------------------------------------------------------------*/
5040 /* genInline - write the inline code out */
5041 /*-----------------------------------------------------------------*/
5042 static void genInline (iCode *ic)
5044 char *buffer, *bp, *bp1;
5046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5048 _G.inLine += (!options.asmpeep);
5050 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5051 strcpy(buffer,IC_INLINE(ic));
5053 /* emit each line as a code */
5057 pic14_emitcode(bp1,"");
5064 pic14_emitcode(bp1,"");
5071 pic14_emitcode(bp1,"");
5072 /* pic14_emitcode("",buffer); */
5073 _G.inLine -= (!options.asmpeep);
5076 /*-----------------------------------------------------------------*/
5077 /* genRRC - rotate right with carry */
5078 /*-----------------------------------------------------------------*/
5079 static void genRRC (iCode *ic)
5081 operand *left , *result ;
5082 int size, offset = 0;
5085 /* rotate right with carry */
5087 result=IC_RESULT(ic);
5088 aopOp (left,ic,FALSE);
5089 aopOp (result,ic,FALSE);
5091 /* move it to the result */
5092 size = AOP_SIZE(result);
5096 l = aopGet(AOP(left),offset,FALSE,FALSE);
5098 pic14_emitcode("rrc","a");
5099 if (AOP_SIZE(result) > 1)
5100 aopPut(AOP(result),"a",offset--);
5102 /* now we need to put the carry into the
5103 highest order byte of the result */
5104 if (AOP_SIZE(result) > 1) {
5105 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5108 pic14_emitcode("mov","acc.7,c");
5109 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5110 freeAsmop(left,NULL,ic,TRUE);
5111 freeAsmop(result,NULL,ic,TRUE);
5114 /*-----------------------------------------------------------------*/
5115 /* genRLC - generate code for rotate left with carry */
5116 /*-----------------------------------------------------------------*/
5117 static void genRLC (iCode *ic)
5119 operand *left , *result ;
5120 int size, offset = 0;
5123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5124 /* rotate right with carry */
5126 result=IC_RESULT(ic);
5127 aopOp (left,ic,FALSE);
5128 aopOp (result,ic,FALSE);
5130 /* move it to the result */
5131 size = AOP_SIZE(result);
5134 l = aopGet(AOP(left),offset,FALSE,FALSE);
5136 pic14_emitcode("add","a,acc");
5137 if (AOP_SIZE(result) > 1)
5138 aopPut(AOP(result),"a",offset++);
5140 l = aopGet(AOP(left),offset,FALSE,FALSE);
5142 pic14_emitcode("rlc","a");
5143 if (AOP_SIZE(result) > 1)
5144 aopPut(AOP(result),"a",offset++);
5147 /* now we need to put the carry into the
5148 highest order byte of the result */
5149 if (AOP_SIZE(result) > 1) {
5150 l = aopGet(AOP(result),0,FALSE,FALSE);
5153 pic14_emitcode("mov","acc.0,c");
5154 aopPut(AOP(result),"a",0);
5155 freeAsmop(left,NULL,ic,TRUE);
5156 freeAsmop(result,NULL,ic,TRUE);
5159 /*-----------------------------------------------------------------*/
5160 /* genGetHbit - generates code get highest order bit */
5161 /*-----------------------------------------------------------------*/
5162 static void genGetHbit (iCode *ic)
5164 operand *left, *result;
5166 result=IC_RESULT(ic);
5167 aopOp (left,ic,FALSE);
5168 aopOp (result,ic,FALSE);
5170 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5171 /* get the highest order byte into a */
5172 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5173 if(AOP_TYPE(result) == AOP_CRY){
5174 pic14_emitcode("rlc","a");
5175 pic14_outBitC(result);
5178 pic14_emitcode("rl","a");
5179 pic14_emitcode("anl","a,#0x01");
5180 pic14_outAcc(result);
5184 freeAsmop(left,NULL,ic,TRUE);
5185 freeAsmop(result,NULL,ic,TRUE);
5188 /*-----------------------------------------------------------------*/
5189 /* AccRol - rotate left accumulator by known count */
5190 /*-----------------------------------------------------------------*/
5191 static void AccRol (int shCount)
5193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5194 shCount &= 0x0007; // shCount : 0..7
5199 pic14_emitcode("rl","a");
5202 pic14_emitcode("rl","a");
5203 pic14_emitcode("rl","a");
5206 pic14_emitcode("swap","a");
5207 pic14_emitcode("rr","a");
5210 pic14_emitcode("swap","a");
5213 pic14_emitcode("swap","a");
5214 pic14_emitcode("rl","a");
5217 pic14_emitcode("rr","a");
5218 pic14_emitcode("rr","a");
5221 pic14_emitcode("rr","a");
5226 /*-----------------------------------------------------------------*/
5227 /* AccLsh - left shift accumulator by known count */
5228 /*-----------------------------------------------------------------*/
5229 static void AccLsh (int shCount)
5231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5234 pic14_emitcode("add","a,acc");
5237 pic14_emitcode("add","a,acc");
5238 pic14_emitcode("add","a,acc");
5240 /* rotate left accumulator */
5242 /* and kill the lower order bits */
5243 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5248 /*-----------------------------------------------------------------*/
5249 /* AccRsh - right shift accumulator by known count */
5250 /*-----------------------------------------------------------------*/
5251 static void AccRsh (int shCount)
5253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5257 pic14_emitcode("rrc","a");
5259 /* rotate right accumulator */
5260 AccRol(8 - shCount);
5261 /* and kill the higher order bits */
5262 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5268 /*-----------------------------------------------------------------*/
5269 /* AccSRsh - signed right shift accumulator by known count */
5270 /*-----------------------------------------------------------------*/
5271 static void AccSRsh (int shCount)
5274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5277 pic14_emitcode("mov","c,acc.7");
5278 pic14_emitcode("rrc","a");
5279 } else if(shCount == 2){
5280 pic14_emitcode("mov","c,acc.7");
5281 pic14_emitcode("rrc","a");
5282 pic14_emitcode("mov","c,acc.7");
5283 pic14_emitcode("rrc","a");
5285 tlbl = newiTempLabel(NULL);
5286 /* rotate right accumulator */
5287 AccRol(8 - shCount);
5288 /* and kill the higher order bits */
5289 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5290 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5291 pic14_emitcode("orl","a,#0x%02x",
5292 (unsigned char)~SRMask[shCount]);
5293 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5298 /*-----------------------------------------------------------------*/
5299 /* shiftR1Left2Result - shift right one byte from left to result */
5300 /*-----------------------------------------------------------------*/
5301 static void shiftR1Left2ResultSigned (operand *left, int offl,
5302 operand *result, int offr,
5307 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5309 same = (left == result) || (AOP(left) == AOP(result));
5313 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5315 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5317 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5318 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5328 /*-----------------------------------------------------------------*/
5329 /* shiftR1Left2Result - shift right one byte from left to result */
5330 /*-----------------------------------------------------------------*/
5331 static void shiftR1Left2Result (operand *left, int offl,
5332 operand *result, int offr,
5333 int shCount, int sign)
5337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5339 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5341 /* Copy the msb into the carry if signed. */
5343 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5353 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5355 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5356 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5362 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5364 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5365 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5368 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5373 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5375 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5376 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5379 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5380 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5381 emitpcode(POC_ANDLW, popGetLit(0x1f));
5382 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5386 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5387 emitpcode(POC_ANDLW, popGetLit(0x0f));
5388 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5392 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5393 emitpcode(POC_ANDLW, popGetLit(0x0f));
5394 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5396 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5401 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5402 emitpcode(POC_ANDLW, popGetLit(0x80));
5403 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5404 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5405 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5410 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5411 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5412 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5423 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5425 /* shift right accumulator */
5430 aopPut(AOP(result),"a",offr);
5434 /*-----------------------------------------------------------------*/
5435 /* shiftL1Left2Result - shift left one byte from left to result */
5436 /*-----------------------------------------------------------------*/
5437 static void shiftL1Left2Result (operand *left, int offl,
5438 operand *result, int offr, int shCount)
5443 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5445 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5446 DEBUGpic14_emitcode ("; ***","same = %d",same);
5447 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5449 /* shift left accumulator */
5450 //AccLsh(shCount); // don't comment out just yet...
5451 // aopPut(AOP(result),"a",offr);
5455 /* Shift left 1 bit position */
5456 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5458 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5460 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5461 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5465 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5466 emitpcode(POC_ANDLW,popGetLit(0x7e));
5467 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5468 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5471 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5472 emitpcode(POC_ANDLW,popGetLit(0x3e));
5473 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5474 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5475 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5478 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5479 emitpcode(POC_ANDLW, popGetLit(0xf0));
5480 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5483 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5484 emitpcode(POC_ANDLW, popGetLit(0xf0));
5485 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5486 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5489 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5490 emitpcode(POC_ANDLW, popGetLit(0x30));
5491 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5492 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5493 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5496 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5497 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5498 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5502 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5507 /*-----------------------------------------------------------------*/
5508 /* movLeft2Result - move byte from left to result */
5509 /*-----------------------------------------------------------------*/
5510 static void movLeft2Result (operand *left, int offl,
5511 operand *result, int offr, int sign)
5514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5515 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5516 l = aopGet(AOP(left),offl,FALSE,FALSE);
5518 if (*l == '@' && (IS_AOP_PREG(result))) {
5519 pic14_emitcode("mov","a,%s",l);
5520 aopPut(AOP(result),"a",offr);
5523 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5524 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5526 //aopPut(AOP(result),l,offr);
5528 /* MSB sign in acc.7 ! */
5529 if(pic14_getDataSize(left) == offl+1){
5530 pic14_emitcode("mov","a,%s",l);
5531 aopPut(AOP(result),"a",offr);
5538 /*-----------------------------------------------------------------*/
5539 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5540 /*-----------------------------------------------------------------*/
5541 static void AccAXRrl1 (char *x)
5543 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5544 pic14_emitcode("rrc","a");
5545 pic14_emitcode("xch","a,%s", x);
5546 pic14_emitcode("rrc","a");
5547 pic14_emitcode("xch","a,%s", x);
5550 /*-----------------------------------------------------------------*/
5551 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5552 /*-----------------------------------------------------------------*/
5553 static void AccAXLrl1 (char *x)
5555 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5556 pic14_emitcode("xch","a,%s",x);
5557 pic14_emitcode("rlc","a");
5558 pic14_emitcode("xch","a,%s",x);
5559 pic14_emitcode("rlc","a");
5562 /*-----------------------------------------------------------------*/
5563 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5564 /*-----------------------------------------------------------------*/
5565 static void AccAXLsh1 (char *x)
5567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5568 pic14_emitcode("xch","a,%s",x);
5569 pic14_emitcode("add","a,acc");
5570 pic14_emitcode("xch","a,%s",x);
5571 pic14_emitcode("rlc","a");
5575 /*-----------------------------------------------------------------*/
5576 /* AccAXLsh - left shift a:x by known count (0..7) */
5577 /*-----------------------------------------------------------------*/
5578 static void AccAXLsh (char *x, int shCount)
5580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5593 case 5 : // AAAAABBB:CCCCCDDD
5594 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5595 pic14_emitcode("anl","a,#0x%02x",
5596 SLMask[shCount]); // BBB00000:CCCCCDDD
5597 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5598 AccRol(shCount); // DDDCCCCC:BBB00000
5599 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5600 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5601 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5602 pic14_emitcode("anl","a,#0x%02x",
5603 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5604 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5605 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5607 case 6 : // AAAAAABB:CCCCCCDD
5608 pic14_emitcode("anl","a,#0x%02x",
5609 SRMask[shCount]); // 000000BB:CCCCCCDD
5610 pic14_emitcode("mov","c,acc.0"); // c = B
5611 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5612 AccAXRrl1(x); // BCCCCCCD:D000000B
5613 AccAXRrl1(x); // BBCCCCCC:DD000000
5615 case 7 : // a:x <<= 7
5616 pic14_emitcode("anl","a,#0x%02x",
5617 SRMask[shCount]); // 0000000B:CCCCCCCD
5618 pic14_emitcode("mov","c,acc.0"); // c = B
5619 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5620 AccAXRrl1(x); // BCCCCCCC:D0000000
5628 /*-----------------------------------------------------------------*/
5629 /* AccAXRsh - right shift a:x known count (0..7) */
5630 /*-----------------------------------------------------------------*/
5631 static void AccAXRsh (char *x, int shCount)
5633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5639 AccAXRrl1(x); // 0->a:x
5643 AccAXRrl1(x); // 0->a:x
5645 AccAXRrl1(x); // 0->a:x
5649 case 5 : // AAAAABBB:CCCCCDDD = a:x
5650 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5651 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5652 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5653 pic14_emitcode("anl","a,#0x%02x",
5654 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5655 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5656 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5657 pic14_emitcode("anl","a,#0x%02x",
5658 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5659 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5660 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5661 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5663 case 6 : // AABBBBBB:CCDDDDDD
5664 pic14_emitcode("mov","c,acc.7");
5665 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5666 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5667 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5668 pic14_emitcode("anl","a,#0x%02x",
5669 SRMask[shCount]); // 000000AA:BBBBBBCC
5671 case 7 : // ABBBBBBB:CDDDDDDD
5672 pic14_emitcode("mov","c,acc.7"); // c = A
5673 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5674 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5675 pic14_emitcode("anl","a,#0x%02x",
5676 SRMask[shCount]); // 0000000A:BBBBBBBC
5683 /*-----------------------------------------------------------------*/
5684 /* AccAXRshS - right shift signed a:x known count (0..7) */
5685 /*-----------------------------------------------------------------*/
5686 static void AccAXRshS (char *x, int shCount)
5689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5694 pic14_emitcode("mov","c,acc.7");
5695 AccAXRrl1(x); // s->a:x
5698 pic14_emitcode("mov","c,acc.7");
5699 AccAXRrl1(x); // s->a:x
5700 pic14_emitcode("mov","c,acc.7");
5701 AccAXRrl1(x); // s->a:x
5705 case 5 : // AAAAABBB:CCCCCDDD = a:x
5706 tlbl = newiTempLabel(NULL);
5707 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5708 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5709 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5710 pic14_emitcode("anl","a,#0x%02x",
5711 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5712 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5713 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5714 pic14_emitcode("anl","a,#0x%02x",
5715 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5716 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5717 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5718 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5719 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5720 pic14_emitcode("orl","a,#0x%02x",
5721 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5722 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5723 break; // SSSSAAAA:BBBCCCCC
5724 case 6 : // AABBBBBB:CCDDDDDD
5725 tlbl = newiTempLabel(NULL);
5726 pic14_emitcode("mov","c,acc.7");
5727 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5728 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5729 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5730 pic14_emitcode("anl","a,#0x%02x",
5731 SRMask[shCount]); // 000000AA:BBBBBBCC
5732 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5733 pic14_emitcode("orl","a,#0x%02x",
5734 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5735 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5737 case 7 : // ABBBBBBB:CDDDDDDD
5738 tlbl = newiTempLabel(NULL);
5739 pic14_emitcode("mov","c,acc.7"); // c = A
5740 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5741 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5742 pic14_emitcode("anl","a,#0x%02x",
5743 SRMask[shCount]); // 0000000A:BBBBBBBC
5744 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5745 pic14_emitcode("orl","a,#0x%02x",
5746 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5747 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5754 /*-----------------------------------------------------------------*/
5755 /* shiftL2Left2Result - shift left two bytes from left to result */
5756 /*-----------------------------------------------------------------*/
5757 static void shiftL2Left2Result (operand *left, int offl,
5758 operand *result, int offr, int shCount)
5762 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5764 if(pic14_sameRegs(AOP(result), AOP(left))) {
5772 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5773 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5774 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5778 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5779 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5785 emitpcode(POC_MOVLW, popGetLit(0x0f));
5786 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5787 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5788 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5789 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5790 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5791 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5793 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5794 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5798 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5799 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5800 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5801 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5802 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5803 emitpcode(POC_ANDLW,popGetLit(0xc0));
5804 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5805 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5806 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5807 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5810 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5811 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5812 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5813 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5814 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5824 /* note, use a mov/add for the shift since the mov has a
5825 chance of getting optimized out */
5826 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5827 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5828 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5829 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5830 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5834 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5835 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5841 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5842 emitpcode(POC_ANDLW, popGetLit(0xF0));
5843 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5844 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5845 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5846 emitpcode(POC_ANDLW, popGetLit(0xF0));
5847 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5848 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5852 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5853 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5857 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5858 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5859 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5860 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5862 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5863 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5864 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5865 emitpcode(POC_ANDLW,popGetLit(0xc0));
5866 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5867 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5868 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5869 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5872 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5873 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5874 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5875 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5876 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5881 /*-----------------------------------------------------------------*/
5882 /* shiftR2Left2Result - shift right two bytes from left to result */
5883 /*-----------------------------------------------------------------*/
5884 static void shiftR2Left2Result (operand *left, int offl,
5885 operand *result, int offr,
5886 int shCount, int sign)
5890 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5891 same = pic14_sameRegs(AOP(result), AOP(left));
5893 if(same && ((offl + MSB16) == offr)){
5895 /* don't crash result[offr] */
5896 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5897 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5899 movLeft2Result(left,offl, result, offr, 0);
5900 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5902 /* a:x >> shCount (x = lsb(result))*/
5904 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5906 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5916 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5917 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5920 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5921 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5922 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5923 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5928 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5929 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5936 emitpcode(POC_MOVLW, popGetLit(0xf0));
5937 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5938 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5940 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5941 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5942 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5943 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5945 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5946 emitpcode(POC_ANDLW, popGetLit(0x0f));
5947 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5949 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5950 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5951 emitpcode(POC_ANDLW, popGetLit(0xf0));
5952 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5953 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5957 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5958 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5966 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5967 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5969 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5970 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5971 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5972 emitpcode(POC_ANDLW,popGetLit(0x03));
5973 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5974 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5975 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5976 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5978 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5979 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5980 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
5981 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5982 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5983 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5984 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5985 emitpcode(POC_ANDLW,popGetLit(0x03));
5986 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5991 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5992 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5993 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5994 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5995 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6000 /*-----------------------------------------------------------------*/
6001 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6002 /*-----------------------------------------------------------------*/
6003 static void shiftLLeftOrResult (operand *left, int offl,
6004 operand *result, int offr, int shCount)
6006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6007 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6008 /* shift left accumulator */
6010 /* or with result */
6011 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6012 /* back to result */
6013 aopPut(AOP(result),"a",offr);
6016 /*-----------------------------------------------------------------*/
6017 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6018 /*-----------------------------------------------------------------*/
6019 static void shiftRLeftOrResult (operand *left, int offl,
6020 operand *result, int offr, int shCount)
6022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6023 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6024 /* shift right accumulator */
6026 /* or with result */
6027 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6028 /* back to result */
6029 aopPut(AOP(result),"a",offr);
6032 /*-----------------------------------------------------------------*/
6033 /* genlshOne - left shift a one byte quantity by known count */
6034 /*-----------------------------------------------------------------*/
6035 static void genlshOne (operand *result, operand *left, int shCount)
6037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6038 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6041 /*-----------------------------------------------------------------*/
6042 /* genlshTwo - left shift two bytes by known amount != 0 */
6043 /*-----------------------------------------------------------------*/
6044 static void genlshTwo (operand *result,operand *left, int shCount)
6048 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6049 size = pic14_getDataSize(result);
6051 /* if shCount >= 8 */
6057 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6059 movLeft2Result(left, LSB, result, MSB16, 0);
6061 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6064 /* 1 <= shCount <= 7 */
6067 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6069 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6073 /*-----------------------------------------------------------------*/
6074 /* shiftLLong - shift left one long from left to result */
6075 /* offl = LSB or MSB16 */
6076 /*-----------------------------------------------------------------*/
6077 static void shiftLLong (operand *left, operand *result, int offr )
6080 int size = AOP_SIZE(result);
6082 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6083 if(size >= LSB+offr){
6084 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6086 pic14_emitcode("add","a,acc");
6087 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6088 size >= MSB16+offr && offr != LSB )
6089 pic14_emitcode("xch","a,%s",
6090 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6092 aopPut(AOP(result),"a",LSB+offr);
6095 if(size >= MSB16+offr){
6096 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6097 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6100 pic14_emitcode("rlc","a");
6101 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6102 size >= MSB24+offr && offr != LSB)
6103 pic14_emitcode("xch","a,%s",
6104 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6106 aopPut(AOP(result),"a",MSB16+offr);
6109 if(size >= MSB24+offr){
6110 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6111 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6114 pic14_emitcode("rlc","a");
6115 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6116 size >= MSB32+offr && offr != LSB )
6117 pic14_emitcode("xch","a,%s",
6118 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6120 aopPut(AOP(result),"a",MSB24+offr);
6123 if(size > MSB32+offr){
6124 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6125 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6128 pic14_emitcode("rlc","a");
6129 aopPut(AOP(result),"a",MSB32+offr);
6132 aopPut(AOP(result),zero,LSB);
6135 /*-----------------------------------------------------------------*/
6136 /* genlshFour - shift four byte by a known amount != 0 */
6137 /*-----------------------------------------------------------------*/
6138 static void genlshFour (operand *result, operand *left, int shCount)
6142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6143 size = AOP_SIZE(result);
6145 /* if shifting more that 3 bytes */
6146 if (shCount >= 24 ) {
6149 /* lowest order of left goes to the highest
6150 order of the destination */
6151 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6153 movLeft2Result(left, LSB, result, MSB32, 0);
6154 aopPut(AOP(result),zero,LSB);
6155 aopPut(AOP(result),zero,MSB16);
6156 aopPut(AOP(result),zero,MSB32);
6160 /* more than two bytes */
6161 else if ( shCount >= 16 ) {
6162 /* lower order two bytes goes to higher order two bytes */
6164 /* if some more remaining */
6166 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6168 movLeft2Result(left, MSB16, result, MSB32, 0);
6169 movLeft2Result(left, LSB, result, MSB24, 0);
6171 aopPut(AOP(result),zero,MSB16);
6172 aopPut(AOP(result),zero,LSB);
6176 /* if more than 1 byte */
6177 else if ( shCount >= 8 ) {
6178 /* lower order three bytes goes to higher order three bytes */
6182 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6184 movLeft2Result(left, LSB, result, MSB16, 0);
6186 else{ /* size = 4 */
6188 movLeft2Result(left, MSB24, result, MSB32, 0);
6189 movLeft2Result(left, MSB16, result, MSB24, 0);
6190 movLeft2Result(left, LSB, result, MSB16, 0);
6191 aopPut(AOP(result),zero,LSB);
6193 else if(shCount == 1)
6194 shiftLLong(left, result, MSB16);
6196 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6197 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6198 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6199 aopPut(AOP(result),zero,LSB);
6204 /* 1 <= shCount <= 7 */
6205 else if(shCount <= 2){
6206 shiftLLong(left, result, LSB);
6208 shiftLLong(result, result, LSB);
6210 /* 3 <= shCount <= 7, optimize */
6212 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6213 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6214 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6218 /*-----------------------------------------------------------------*/
6219 /* genLeftShiftLiteral - left shifting by known count */
6220 /*-----------------------------------------------------------------*/
6221 static void genLeftShiftLiteral (operand *left,
6226 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6230 freeAsmop(right,NULL,ic,TRUE);
6232 aopOp(left,ic,FALSE);
6233 aopOp(result,ic,FALSE);
6235 size = getSize(operandType(result));
6238 pic14_emitcode("; shift left ","result %d, left %d",size,
6242 /* I suppose that the left size >= result size */
6245 movLeft2Result(left, size, result, size, 0);
6249 else if(shCount >= (size * 8))
6251 aopPut(AOP(result),zero,size);
6255 genlshOne (result,left,shCount);
6260 genlshTwo (result,left,shCount);
6264 genlshFour (result,left,shCount);
6268 freeAsmop(left,NULL,ic,TRUE);
6269 freeAsmop(result,NULL,ic,TRUE);
6272 /*-----------------------------------------------------------------*/
6273 /* genLeftShift - generates code for left shifting */
6274 /*-----------------------------------------------------------------*/
6275 static void genLeftShift (iCode *ic)
6277 operand *left,*right, *result;
6280 symbol *tlbl , *tlbl1;
6282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6284 right = IC_RIGHT(ic);
6286 result = IC_RESULT(ic);
6288 aopOp(right,ic,FALSE);
6290 /* if the shift count is known then do it
6291 as efficiently as possible */
6292 if (AOP_TYPE(right) == AOP_LIT) {
6293 genLeftShiftLiteral (left,right,result,ic);
6297 /* shift count is unknown then we have to form
6298 a loop get the loop count in B : Note: we take
6299 only the lower order byte since shifting
6300 more that 32 bits make no sense anyway, ( the
6301 largest size of an object can be only 32 bits ) */
6304 aopOp(left,ic,FALSE);
6305 aopOp(result,ic,FALSE);
6307 /* now move the left to the result if they are not the
6309 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6310 AOP_SIZE(result) > 1) {
6312 size = AOP_SIZE(result);
6315 l = aopGet(AOP(left),offset,FALSE,TRUE);
6316 if (*l == '@' && (IS_AOP_PREG(result))) {
6318 pic14_emitcode("mov","a,%s",l);
6319 aopPut(AOP(result),"a",offset);
6321 aopPut(AOP(result),l,offset);
6326 size = AOP_SIZE(result);
6328 /* if it is only one byte then */
6330 if(optimized_for_speed) {
6331 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6332 emitpcode(POC_ANDLW, popGetLit(0xf0));
6333 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6334 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6335 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6336 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6337 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6338 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6339 emitpcode(POC_ANDLW, popGetLit(0xfe));
6340 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6341 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6342 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6345 tlbl = newiTempLabel(NULL);
6346 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6347 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6348 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6351 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6352 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6353 emitpLabel(tlbl->key);
6354 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6355 emitpcode(POC_ADDLW, popGetLit(1));
6357 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6363 tlbl = newiTempLabel(NULL);
6365 tlbl1 = newiTempLabel(NULL);
6367 reAdjustPreg(AOP(result));
6369 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6370 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6371 l = aopGet(AOP(result),offset,FALSE,FALSE);
6373 pic14_emitcode("add","a,acc");
6374 aopPut(AOP(result),"a",offset++);
6376 l = aopGet(AOP(result),offset,FALSE,FALSE);
6378 pic14_emitcode("rlc","a");
6379 aopPut(AOP(result),"a",offset++);
6381 reAdjustPreg(AOP(result));
6383 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6384 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6386 freeAsmop (right,NULL,ic,TRUE);
6387 freeAsmop(left,NULL,ic,TRUE);
6388 freeAsmop(result,NULL,ic,TRUE);
6391 /*-----------------------------------------------------------------*/
6392 /* genrshOne - right shift a one byte quantity by known count */
6393 /*-----------------------------------------------------------------*/
6394 static void genrshOne (operand *result, operand *left,
6395 int shCount, int sign)
6397 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6398 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6401 /*-----------------------------------------------------------------*/
6402 /* genrshTwo - right shift two bytes by known amount != 0 */
6403 /*-----------------------------------------------------------------*/
6404 static void genrshTwo (operand *result,operand *left,
6405 int shCount, int sign)
6407 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6408 /* if shCount >= 8 */
6412 shiftR1Left2Result(left, MSB16, result, LSB,
6415 movLeft2Result(left, MSB16, result, LSB, sign);
6417 addSign(result, MSB16, sign);
6419 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6423 /* 1 <= shCount <= 7 */
6425 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6428 /*-----------------------------------------------------------------*/
6429 /* shiftRLong - shift right one long from left to result */
6430 /* offl = LSB or MSB16 */
6431 /*-----------------------------------------------------------------*/
6432 static void shiftRLong (operand *left, int offl,
6433 operand *result, int sign)
6435 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6437 pic14_emitcode("clr","c");
6438 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6440 pic14_emitcode("mov","c,acc.7");
6441 pic14_emitcode("rrc","a");
6442 aopPut(AOP(result),"a",MSB32-offl);
6444 /* add sign of "a" */
6445 addSign(result, MSB32, sign);
6447 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6448 pic14_emitcode("rrc","a");
6449 aopPut(AOP(result),"a",MSB24-offl);
6451 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6452 pic14_emitcode("rrc","a");
6453 aopPut(AOP(result),"a",MSB16-offl);
6456 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6457 pic14_emitcode("rrc","a");
6458 aopPut(AOP(result),"a",LSB);
6462 /*-----------------------------------------------------------------*/
6463 /* genrshFour - shift four byte by a known amount != 0 */
6464 /*-----------------------------------------------------------------*/
6465 static void genrshFour (operand *result, operand *left,
6466 int shCount, int sign)
6468 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6469 /* if shifting more that 3 bytes */
6470 if(shCount >= 24 ) {
6473 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6475 movLeft2Result(left, MSB32, result, LSB, sign);
6476 addSign(result, MSB16, sign);
6478 else if(shCount >= 16){
6481 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6483 movLeft2Result(left, MSB24, result, LSB, 0);
6484 movLeft2Result(left, MSB32, result, MSB16, sign);
6486 addSign(result, MSB24, sign);
6488 else if(shCount >= 8){
6491 shiftRLong(left, MSB16, result, sign);
6492 else if(shCount == 0){
6493 movLeft2Result(left, MSB16, result, LSB, 0);
6494 movLeft2Result(left, MSB24, result, MSB16, 0);
6495 movLeft2Result(left, MSB32, result, MSB24, sign);
6496 addSign(result, MSB32, sign);
6499 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6500 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6501 /* the last shift is signed */
6502 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6503 addSign(result, MSB32, sign);
6506 else{ /* 1 <= shCount <= 7 */
6508 shiftRLong(left, LSB, result, sign);
6510 shiftRLong(result, LSB, result, sign);
6513 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6514 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6515 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6520 /*-----------------------------------------------------------------*/
6521 /* genRightShiftLiteral - right shifting by known count */
6522 /*-----------------------------------------------------------------*/
6523 static void genRightShiftLiteral (operand *left,
6529 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6533 freeAsmop(right,NULL,ic,TRUE);
6535 aopOp(left,ic,FALSE);
6536 aopOp(result,ic,FALSE);
6539 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6543 size = pic14_getDataSize(left);
6544 /* test the LEFT size !!! */
6546 /* I suppose that the left size >= result size */
6548 size = pic14_getDataSize(result);
6550 movLeft2Result(left, size, result, size, 0);
6553 else if(shCount >= (size * 8)){
6555 /* get sign in acc.7 */
6556 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6557 addSign(result, LSB, sign);
6561 genrshOne (result,left,shCount,sign);
6565 genrshTwo (result,left,shCount,sign);
6569 genrshFour (result,left,shCount,sign);
6575 freeAsmop(left,NULL,ic,TRUE);
6576 freeAsmop(result,NULL,ic,TRUE);
6580 /*-----------------------------------------------------------------*/
6581 /* genSignedRightShift - right shift of signed number */
6582 /*-----------------------------------------------------------------*/
6583 static void genSignedRightShift (iCode *ic)
6585 operand *right, *left, *result;
6588 symbol *tlbl, *tlbl1 ;
6590 /* we do it the hard way put the shift count in b
6591 and loop thru preserving the sign */
6592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6594 right = IC_RIGHT(ic);
6596 result = IC_RESULT(ic);
6598 aopOp(right,ic,FALSE);
6601 if ( AOP_TYPE(right) == AOP_LIT) {
6602 genRightShiftLiteral (left,right,result,ic,1);
6605 /* shift count is unknown then we have to form
6606 a loop get the loop count in B : Note: we take
6607 only the lower order byte since shifting
6608 more that 32 bits make no sense anyway, ( the
6609 largest size of an object can be only 32 bits ) */
6611 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6612 pic14_emitcode("inc","b");
6613 freeAsmop (right,NULL,ic,TRUE);
6614 aopOp(left,ic,FALSE);
6615 aopOp(result,ic,FALSE);
6617 /* now move the left to the result if they are not the
6619 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6620 AOP_SIZE(result) > 1) {
6622 size = AOP_SIZE(result);
6625 l = aopGet(AOP(left),offset,FALSE,TRUE);
6626 if (*l == '@' && IS_AOP_PREG(result)) {
6628 pic14_emitcode("mov","a,%s",l);
6629 aopPut(AOP(result),"a",offset);
6631 aopPut(AOP(result),l,offset);
6636 /* mov the highest order bit to OVR */
6637 tlbl = newiTempLabel(NULL);
6638 tlbl1= newiTempLabel(NULL);
6640 size = AOP_SIZE(result);
6642 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6643 pic14_emitcode("rlc","a");
6644 pic14_emitcode("mov","ov,c");
6645 /* if it is only one byte then */
6647 l = aopGet(AOP(left),0,FALSE,FALSE);
6649 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6650 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6651 pic14_emitcode("mov","c,ov");
6652 pic14_emitcode("rrc","a");
6653 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6654 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6655 aopPut(AOP(result),"a",0);
6659 reAdjustPreg(AOP(result));
6660 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6661 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6662 pic14_emitcode("mov","c,ov");
6664 l = aopGet(AOP(result),offset,FALSE,FALSE);
6666 pic14_emitcode("rrc","a");
6667 aopPut(AOP(result),"a",offset--);
6669 reAdjustPreg(AOP(result));
6670 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6671 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6674 freeAsmop(left,NULL,ic,TRUE);
6675 freeAsmop(result,NULL,ic,TRUE);
6678 /*-----------------------------------------------------------------*/
6679 /* genRightShift - generate code for right shifting */
6680 /*-----------------------------------------------------------------*/
6681 static void genRightShift (iCode *ic)
6683 operand *right, *left, *result;
6687 symbol *tlbl, *tlbl1 ;
6689 /* if signed then we do it the hard way preserve the
6690 sign bit moving it inwards */
6691 retype = getSpec(operandType(IC_RESULT(ic)));
6692 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6694 if (!SPEC_USIGN(retype)) {
6695 genSignedRightShift (ic);
6699 /* signed & unsigned types are treated the same : i.e. the
6700 signed is NOT propagated inwards : quoting from the
6701 ANSI - standard : "for E1 >> E2, is equivalent to division
6702 by 2**E2 if unsigned or if it has a non-negative value,
6703 otherwise the result is implementation defined ", MY definition
6704 is that the sign does not get propagated */
6706 right = IC_RIGHT(ic);
6708 result = IC_RESULT(ic);
6710 aopOp(right,ic,FALSE);
6712 /* if the shift count is known then do it
6713 as efficiently as possible */
6714 if (AOP_TYPE(right) == AOP_LIT) {
6715 genRightShiftLiteral (left,right,result,ic, 0);
6719 /* shift count is unknown then we have to form
6720 a loop get the loop count in B : Note: we take
6721 only the lower order byte since shifting
6722 more that 32 bits make no sense anyway, ( the
6723 largest size of an object can be only 32 bits ) */
6725 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6726 pic14_emitcode("inc","b");
6727 aopOp(left,ic,FALSE);
6728 aopOp(result,ic,FALSE);
6730 /* now move the left to the result if they are not the
6732 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6733 AOP_SIZE(result) > 1) {
6735 size = AOP_SIZE(result);
6738 l = aopGet(AOP(left),offset,FALSE,TRUE);
6739 if (*l == '@' && IS_AOP_PREG(result)) {
6741 pic14_emitcode("mov","a,%s",l);
6742 aopPut(AOP(result),"a",offset);
6744 aopPut(AOP(result),l,offset);
6749 tlbl = newiTempLabel(NULL);
6750 tlbl1= newiTempLabel(NULL);
6751 size = AOP_SIZE(result);
6754 /* if it is only one byte then */
6757 l = aopGet(AOP(left),0,FALSE,FALSE);
6759 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6760 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6762 pic14_emitcode("rrc","a");
6763 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6764 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6765 aopPut(AOP(result),"a",0);
6767 tlbl = newiTempLabel(NULL);
6768 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6769 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6770 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6773 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6774 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6775 emitpLabel(tlbl->key);
6776 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6777 emitpcode(POC_ADDLW, popGetLit(1));
6779 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6784 reAdjustPreg(AOP(result));
6785 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6786 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6789 l = aopGet(AOP(result),offset,FALSE,FALSE);
6791 pic14_emitcode("rrc","a");
6792 aopPut(AOP(result),"a",offset--);
6794 reAdjustPreg(AOP(result));
6796 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6797 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6800 freeAsmop(left,NULL,ic,TRUE);
6801 freeAsmop (right,NULL,ic,TRUE);
6802 freeAsmop(result,NULL,ic,TRUE);
6805 /*-----------------------------------------------------------------*/
6806 /* genUnpackBits - generates code for unpacking bits */
6807 /*-----------------------------------------------------------------*/
6808 static void genUnpackBits (operand *result, char *rname, int ptype)
6815 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6816 etype = getSpec(operandType(result));
6818 /* read the first byte */
6823 pic14_emitcode("mov","a,@%s",rname);
6827 pic14_emitcode("movx","a,@%s",rname);
6831 pic14_emitcode("movx","a,@dptr");
6835 pic14_emitcode("clr","a");
6836 pic14_emitcode("movc","a","@a+dptr");
6840 pic14_emitcode("lcall","__gptrget");
6844 /* if we have bitdisplacement then it fits */
6845 /* into this byte completely or if length is */
6846 /* less than a byte */
6847 if ((shCnt = SPEC_BSTR(etype)) ||
6848 (SPEC_BLEN(etype) <= 8)) {
6850 /* shift right acc */
6853 pic14_emitcode("anl","a,#0x%02x",
6854 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6855 aopPut(AOP(result),"a",offset);
6859 /* bit field did not fit in a byte */
6860 rlen = SPEC_BLEN(etype) - 8;
6861 aopPut(AOP(result),"a",offset++);
6868 pic14_emitcode("inc","%s",rname);
6869 pic14_emitcode("mov","a,@%s",rname);
6873 pic14_emitcode("inc","%s",rname);
6874 pic14_emitcode("movx","a,@%s",rname);
6878 pic14_emitcode("inc","dptr");
6879 pic14_emitcode("movx","a,@dptr");
6883 pic14_emitcode("clr","a");
6884 pic14_emitcode("inc","dptr");
6885 pic14_emitcode("movc","a","@a+dptr");
6889 pic14_emitcode("inc","dptr");
6890 pic14_emitcode("lcall","__gptrget");
6895 /* if we are done */
6899 aopPut(AOP(result),"a",offset++);
6904 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6905 aopPut(AOP(result),"a",offset);
6912 /*-----------------------------------------------------------------*/
6913 /* genDataPointerGet - generates code when ptr offset is known */
6914 /*-----------------------------------------------------------------*/
6915 static void genDataPointerGet (operand *left,
6919 int size , offset = 0;
6922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6925 /* optimization - most of the time, left and result are the same
6926 * address, but different types. for the pic code, we could omit
6930 aopOp(result,ic,TRUE);
6932 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6934 size = AOP_SIZE(result);
6937 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6941 freeAsmop(left,NULL,ic,TRUE);
6942 freeAsmop(result,NULL,ic,TRUE);
6945 /*-----------------------------------------------------------------*/
6946 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6947 /*-----------------------------------------------------------------*/
6948 static void genNearPointerGet (operand *left,
6955 sym_link *rtype, *retype;
6956 sym_link *ltype = operandType(left);
6959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6961 rtype = operandType(result);
6962 retype= getSpec(rtype);
6964 aopOp(left,ic,FALSE);
6966 /* if left is rematerialisable and
6967 result is not bit variable type and
6968 the left is pointer to data space i.e
6969 lower 128 bytes of space */
6970 if (AOP_TYPE(left) == AOP_IMMD &&
6971 !IS_BITVAR(retype) &&
6972 DCL_TYPE(ltype) == POINTER) {
6973 genDataPointerGet (left,result,ic);
6977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6979 /* if the value is already in a pointer register
6980 then don't need anything more */
6981 if (!AOP_INPREG(AOP(left))) {
6982 /* otherwise get a free pointer register */
6983 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6985 preg = getFreePtr(ic,&aop,FALSE);
6986 pic14_emitcode("mov","%s,%s",
6988 aopGet(AOP(left),0,FALSE,TRUE));
6989 rname = preg->name ;
6991 rname = aopGet(AOP(left),0,FALSE,FALSE);
6993 freeAsmop(left,NULL,ic,TRUE);
6994 aopOp (result,ic,FALSE);
6996 /* if bitfield then unpack the bits */
6997 if (IS_BITVAR(retype))
6998 genUnpackBits (result,rname,POINTER);
7000 /* we have can just get the values */
7001 int size = AOP_SIZE(result);
7004 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7006 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7008 pic14_emitcode("mov","a,@%s",rname);
7009 aopPut(AOP(result),"a",offset);
7011 sprintf(buffer,"@%s",rname);
7012 aopPut(AOP(result),buffer,offset);
7016 pic14_emitcode("inc","%s",rname);
7020 /* now some housekeeping stuff */
7022 /* we had to allocate for this iCode */
7023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7024 freeAsmop(NULL,aop,ic,TRUE);
7026 /* we did not allocate which means left
7027 already in a pointer register, then
7028 if size > 0 && this could be used again
7029 we have to point it back to where it
7031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7032 if (AOP_SIZE(result) > 1 &&
7033 !OP_SYMBOL(left)->remat &&
7034 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7036 int size = AOP_SIZE(result) - 1;
7038 pic14_emitcode("dec","%s",rname);
7043 freeAsmop(result,NULL,ic,TRUE);
7047 /*-----------------------------------------------------------------*/
7048 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7049 /*-----------------------------------------------------------------*/
7050 static void genPagedPointerGet (operand *left,
7057 sym_link *rtype, *retype;
7059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7061 rtype = operandType(result);
7062 retype= getSpec(rtype);
7064 aopOp(left,ic,FALSE);
7066 /* if the value is already in a pointer register
7067 then don't need anything more */
7068 if (!AOP_INPREG(AOP(left))) {
7069 /* otherwise get a free pointer register */
7071 preg = getFreePtr(ic,&aop,FALSE);
7072 pic14_emitcode("mov","%s,%s",
7074 aopGet(AOP(left),0,FALSE,TRUE));
7075 rname = preg->name ;
7077 rname = aopGet(AOP(left),0,FALSE,FALSE);
7079 freeAsmop(left,NULL,ic,TRUE);
7080 aopOp (result,ic,FALSE);
7082 /* if bitfield then unpack the bits */
7083 if (IS_BITVAR(retype))
7084 genUnpackBits (result,rname,PPOINTER);
7086 /* we have can just get the values */
7087 int size = AOP_SIZE(result);
7092 pic14_emitcode("movx","a,@%s",rname);
7093 aopPut(AOP(result),"a",offset);
7098 pic14_emitcode("inc","%s",rname);
7102 /* now some housekeeping stuff */
7104 /* we had to allocate for this iCode */
7105 freeAsmop(NULL,aop,ic,TRUE);
7107 /* we did not allocate which means left
7108 already in a pointer register, then
7109 if size > 0 && this could be used again
7110 we have to point it back to where it
7112 if (AOP_SIZE(result) > 1 &&
7113 !OP_SYMBOL(left)->remat &&
7114 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7116 int size = AOP_SIZE(result) - 1;
7118 pic14_emitcode("dec","%s",rname);
7123 freeAsmop(result,NULL,ic,TRUE);
7128 /*-----------------------------------------------------------------*/
7129 /* genFarPointerGet - gget value from far space */
7130 /*-----------------------------------------------------------------*/
7131 static void genFarPointerGet (operand *left,
7132 operand *result, iCode *ic)
7135 sym_link *retype = getSpec(operandType(result));
7137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7139 aopOp(left,ic,FALSE);
7141 /* if the operand is already in dptr
7142 then we do nothing else we move the value to dptr */
7143 if (AOP_TYPE(left) != AOP_STR) {
7144 /* if this is remateriazable */
7145 if (AOP_TYPE(left) == AOP_IMMD)
7146 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7147 else { /* we need to get it byte by byte */
7148 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7149 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7150 if (options.model == MODEL_FLAT24)
7152 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7156 /* so dptr know contains the address */
7157 freeAsmop(left,NULL,ic,TRUE);
7158 aopOp(result,ic,FALSE);
7160 /* if bit then unpack */
7161 if (IS_BITVAR(retype))
7162 genUnpackBits(result,"dptr",FPOINTER);
7164 size = AOP_SIZE(result);
7168 pic14_emitcode("movx","a,@dptr");
7169 aopPut(AOP(result),"a",offset++);
7171 pic14_emitcode("inc","dptr");
7175 freeAsmop(result,NULL,ic,TRUE);
7178 /*-----------------------------------------------------------------*/
7179 /* pic14_emitcodePointerGet - gget value from code space */
7180 /*-----------------------------------------------------------------*/
7181 static void pic14_emitcodePointerGet (operand *left,
7182 operand *result, iCode *ic)
7185 sym_link *retype = getSpec(operandType(result));
7187 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7189 aopOp(left,ic,FALSE);
7191 /* if the operand is already in dptr
7192 then we do nothing else we move the value to dptr */
7193 if (AOP_TYPE(left) != AOP_STR) {
7194 /* if this is remateriazable */
7195 if (AOP_TYPE(left) == AOP_IMMD)
7196 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7197 else { /* we need to get it byte by byte */
7198 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7199 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7200 if (options.model == MODEL_FLAT24)
7202 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7206 /* so dptr know contains the address */
7207 freeAsmop(left,NULL,ic,TRUE);
7208 aopOp(result,ic,FALSE);
7210 /* if bit then unpack */
7211 if (IS_BITVAR(retype))
7212 genUnpackBits(result,"dptr",CPOINTER);
7214 size = AOP_SIZE(result);
7218 pic14_emitcode("clr","a");
7219 pic14_emitcode("movc","a,@a+dptr");
7220 aopPut(AOP(result),"a",offset++);
7222 pic14_emitcode("inc","dptr");
7226 freeAsmop(result,NULL,ic,TRUE);
7229 /*-----------------------------------------------------------------*/
7230 /* genGenPointerGet - gget value from generic pointer space */
7231 /*-----------------------------------------------------------------*/
7232 static void genGenPointerGet (operand *left,
7233 operand *result, iCode *ic)
7236 sym_link *retype = getSpec(operandType(result));
7238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7239 aopOp(left,ic,FALSE);
7241 /* if the operand is already in dptr
7242 then we do nothing else we move the value to dptr */
7243 if (AOP_TYPE(left) != AOP_STR) {
7244 /* if this is remateriazable */
7245 if (AOP_TYPE(left) == AOP_IMMD) {
7246 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7247 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7249 else { /* we need to get it byte by byte */
7250 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7251 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7252 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7253 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7254 pic14_emitcode("movwf","FSR");
7256 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7257 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7258 if (options.model == MODEL_FLAT24)
7260 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7261 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7265 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7270 /* so dptr know contains the address */
7271 freeAsmop(left,NULL,ic,TRUE);
7272 aopOp(result,ic,FALSE);
7274 /* if bit then unpack */
7275 if (IS_BITVAR(retype))
7276 genUnpackBits(result,"dptr",GPOINTER);
7278 size = AOP_SIZE(result);
7282 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7284 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7286 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7288 pic14_emitcode("movf","indf,w");
7289 pic14_emitcode("movwf","%s",
7290 aopGet(AOP(result),offset++,FALSE,FALSE));
7292 pic14_emitcode("incf","fsr,f");
7297 freeAsmop(result,NULL,ic,TRUE);
7300 /*-----------------------------------------------------------------*/
7301 /* genPointerGet - generate code for pointer get */
7302 /*-----------------------------------------------------------------*/
7303 static void genPointerGet (iCode *ic)
7305 operand *left, *result ;
7306 sym_link *type, *etype;
7309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7312 result = IC_RESULT(ic) ;
7314 /* depending on the type of pointer we need to
7315 move it to the correct pointer register */
7316 type = operandType(left);
7317 etype = getSpec(type);
7318 /* if left is of type of pointer then it is simple */
7319 if (IS_PTR(type) && !IS_FUNC(type->next))
7320 p_type = DCL_TYPE(type);
7322 /* we have to go by the storage class */
7323 p_type = PTR_TYPE(SPEC_OCLS(etype));
7325 /* if (SPEC_OCLS(etype)->codesp ) { */
7326 /* p_type = CPOINTER ; */
7329 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7330 /* p_type = FPOINTER ; */
7332 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7333 /* p_type = PPOINTER; */
7335 /* if (SPEC_OCLS(etype) == idata ) */
7336 /* p_type = IPOINTER; */
7338 /* p_type = POINTER ; */
7341 /* now that we have the pointer type we assign
7342 the pointer values */
7347 genNearPointerGet (left,result,ic);
7351 genPagedPointerGet(left,result,ic);
7355 genFarPointerGet (left,result,ic);
7359 pic14_emitcodePointerGet (left,result,ic);
7363 genGenPointerGet (left,result,ic);
7369 /*-----------------------------------------------------------------*/
7370 /* genPackBits - generates code for packed bit storage */
7371 /*-----------------------------------------------------------------*/
7372 static void genPackBits (sym_link *etype ,
7374 char *rname, int p_type)
7382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7383 blen = SPEC_BLEN(etype);
7384 bstr = SPEC_BSTR(etype);
7386 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7389 /* if the bit lenth is less than or */
7390 /* it exactly fits a byte then */
7391 if (SPEC_BLEN(etype) <= 8 ) {
7392 shCount = SPEC_BSTR(etype) ;
7394 /* shift left acc */
7397 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7402 pic14_emitcode ("mov","b,a");
7403 pic14_emitcode("mov","a,@%s",rname);
7407 pic14_emitcode ("mov","b,a");
7408 pic14_emitcode("movx","a,@dptr");
7412 pic14_emitcode ("push","b");
7413 pic14_emitcode ("push","acc");
7414 pic14_emitcode ("lcall","__gptrget");
7415 pic14_emitcode ("pop","b");
7419 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7420 ((unsigned char)(0xFF << (blen+bstr)) |
7421 (unsigned char)(0xFF >> (8-bstr)) ) );
7422 pic14_emitcode ("orl","a,b");
7423 if (p_type == GPOINTER)
7424 pic14_emitcode("pop","b");
7430 pic14_emitcode("mov","@%s,a",rname);
7434 pic14_emitcode("movx","@dptr,a");
7438 DEBUGpic14_emitcode(";lcall","__gptrput");
7443 if ( SPEC_BLEN(etype) <= 8 )
7446 pic14_emitcode("inc","%s",rname);
7447 rLen = SPEC_BLEN(etype) ;
7449 /* now generate for lengths greater than one byte */
7452 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7462 pic14_emitcode("mov","@%s,a",rname);
7464 pic14_emitcode("mov","@%s,%s",rname,l);
7469 pic14_emitcode("movx","@dptr,a");
7474 DEBUGpic14_emitcode(";lcall","__gptrput");
7477 pic14_emitcode ("inc","%s",rname);
7482 /* last last was not complete */
7484 /* save the byte & read byte */
7487 pic14_emitcode ("mov","b,a");
7488 pic14_emitcode("mov","a,@%s",rname);
7492 pic14_emitcode ("mov","b,a");
7493 pic14_emitcode("movx","a,@dptr");
7497 pic14_emitcode ("push","b");
7498 pic14_emitcode ("push","acc");
7499 pic14_emitcode ("lcall","__gptrget");
7500 pic14_emitcode ("pop","b");
7504 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7505 pic14_emitcode ("orl","a,b");
7508 if (p_type == GPOINTER)
7509 pic14_emitcode("pop","b");
7514 pic14_emitcode("mov","@%s,a",rname);
7518 pic14_emitcode("movx","@dptr,a");
7522 DEBUGpic14_emitcode(";lcall","__gptrput");
7526 /*-----------------------------------------------------------------*/
7527 /* genDataPointerSet - remat pointer to data space */
7528 /*-----------------------------------------------------------------*/
7529 static void genDataPointerSet(operand *right,
7533 int size, offset = 0 ;
7534 char *l, buffer[256];
7536 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7537 aopOp(right,ic,FALSE);
7539 l = aopGet(AOP(result),0,FALSE,TRUE);
7540 size = AOP_SIZE(right);
7541 // tsd, was l+1 - the underline `_' prefix was being stripped
7544 sprintf(buffer,"(%s + %d)",l,offset);
7546 sprintf(buffer,"%s",l);
7548 if (AOP_TYPE(right) == AOP_LIT) {
7549 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7550 lit = lit >> (8*offset);
7552 pic14_emitcode("movlw","%d",lit);
7553 pic14_emitcode("movwf","%s",buffer);
7555 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7556 emitpcode(POC_MOVWF, popRegFromString(buffer));
7559 pic14_emitcode("clrf","%s",buffer);
7560 emitpcode(POC_CLRF, popRegFromString(buffer));
7563 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7564 pic14_emitcode("movwf","%s",buffer);
7566 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7567 emitpcode(POC_MOVWF, popRegFromString(buffer));
7574 freeAsmop(right,NULL,ic,TRUE);
7575 freeAsmop(result,NULL,ic,TRUE);
7578 /*-----------------------------------------------------------------*/
7579 /* genNearPointerSet - pic14_emitcode for near pointer put */
7580 /*-----------------------------------------------------------------*/
7581 static void genNearPointerSet (operand *right,
7588 sym_link *ptype = operandType(result);
7591 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7592 retype= getSpec(operandType(right));
7594 aopOp(result,ic,FALSE);
7596 /* if the result is rematerializable &
7597 in data space & not a bit variable */
7598 if (AOP_TYPE(result) == AOP_IMMD &&
7599 DCL_TYPE(ptype) == POINTER &&
7600 !IS_BITVAR(retype)) {
7601 genDataPointerSet (right,result,ic);
7605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7607 /* if the value is already in a pointer register
7608 then don't need anything more */
7609 if (!AOP_INPREG(AOP(result))) {
7610 /* otherwise get a free pointer register */
7611 //aop = newAsmop(0);
7612 //preg = getFreePtr(ic,&aop,FALSE);
7613 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7614 //pic14_emitcode("mov","%s,%s",
7616 // aopGet(AOP(result),0,FALSE,TRUE));
7617 //rname = preg->name ;
7618 pic14_emitcode("movwf","fsr");
7620 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7622 freeAsmop(result,NULL,ic,TRUE);
7623 aopOp (right,ic,FALSE);
7624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7626 /* if bitfield then unpack the bits */
7627 if (IS_BITVAR(retype)) {
7628 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7629 "The programmer is obviously confused");
7630 //genPackBits (retype,right,rname,POINTER);
7634 /* we have can just get the values */
7635 int size = AOP_SIZE(right);
7638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7640 l = aopGet(AOP(right),offset,FALSE,TRUE);
7643 //pic14_emitcode("mov","@%s,a",rname);
7644 pic14_emitcode("movf","indf,w ;1");
7647 if (AOP_TYPE(right) == AOP_LIT) {
7648 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7650 pic14_emitcode("movlw","%s",l);
7651 pic14_emitcode("movwf","indf ;2");
7653 pic14_emitcode("clrf","indf");
7655 pic14_emitcode("movf","%s,w",l);
7656 pic14_emitcode("movwf","indf ;2");
7658 //pic14_emitcode("mov","@%s,%s",rname,l);
7661 pic14_emitcode("incf","fsr,f ;3");
7662 //pic14_emitcode("inc","%s",rname);
7667 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7668 /* now some housekeeping stuff */
7670 /* we had to allocate for this iCode */
7671 freeAsmop(NULL,aop,ic,TRUE);
7673 /* we did not allocate which means left
7674 already in a pointer register, then
7675 if size > 0 && this could be used again
7676 we have to point it back to where it
7678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7679 if (AOP_SIZE(right) > 1 &&
7680 !OP_SYMBOL(result)->remat &&
7681 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7683 int size = AOP_SIZE(right) - 1;
7685 pic14_emitcode("decf","fsr,f");
7686 //pic14_emitcode("dec","%s",rname);
7690 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7692 freeAsmop(right,NULL,ic,TRUE);
7697 /*-----------------------------------------------------------------*/
7698 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7699 /*-----------------------------------------------------------------*/
7700 static void genPagedPointerSet (operand *right,
7709 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7711 retype= getSpec(operandType(right));
7713 aopOp(result,ic,FALSE);
7715 /* if the value is already in a pointer register
7716 then don't need anything more */
7717 if (!AOP_INPREG(AOP(result))) {
7718 /* otherwise get a free pointer register */
7720 preg = getFreePtr(ic,&aop,FALSE);
7721 pic14_emitcode("mov","%s,%s",
7723 aopGet(AOP(result),0,FALSE,TRUE));
7724 rname = preg->name ;
7726 rname = aopGet(AOP(result),0,FALSE,FALSE);
7728 freeAsmop(result,NULL,ic,TRUE);
7729 aopOp (right,ic,FALSE);
7731 /* if bitfield then unpack the bits */
7732 if (IS_BITVAR(retype))
7733 genPackBits (retype,right,rname,PPOINTER);
7735 /* we have can just get the values */
7736 int size = AOP_SIZE(right);
7740 l = aopGet(AOP(right),offset,FALSE,TRUE);
7743 pic14_emitcode("movx","@%s,a",rname);
7746 pic14_emitcode("inc","%s",rname);
7752 /* now some housekeeping stuff */
7754 /* we had to allocate for this iCode */
7755 freeAsmop(NULL,aop,ic,TRUE);
7757 /* we did not allocate which means left
7758 already in a pointer register, then
7759 if size > 0 && this could be used again
7760 we have to point it back to where it
7762 if (AOP_SIZE(right) > 1 &&
7763 !OP_SYMBOL(result)->remat &&
7764 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7766 int size = AOP_SIZE(right) - 1;
7768 pic14_emitcode("dec","%s",rname);
7773 freeAsmop(right,NULL,ic,TRUE);
7778 /*-----------------------------------------------------------------*/
7779 /* genFarPointerSet - set value from far space */
7780 /*-----------------------------------------------------------------*/
7781 static void genFarPointerSet (operand *right,
7782 operand *result, iCode *ic)
7785 sym_link *retype = getSpec(operandType(right));
7787 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7788 aopOp(result,ic,FALSE);
7790 /* if the operand is already in dptr
7791 then we do nothing else we move the value to dptr */
7792 if (AOP_TYPE(result) != AOP_STR) {
7793 /* if this is remateriazable */
7794 if (AOP_TYPE(result) == AOP_IMMD)
7795 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7796 else { /* we need to get it byte by byte */
7797 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7798 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7799 if (options.model == MODEL_FLAT24)
7801 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7805 /* so dptr know contains the address */
7806 freeAsmop(result,NULL,ic,TRUE);
7807 aopOp(right,ic,FALSE);
7809 /* if bit then unpack */
7810 if (IS_BITVAR(retype))
7811 genPackBits(retype,right,"dptr",FPOINTER);
7813 size = AOP_SIZE(right);
7817 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7819 pic14_emitcode("movx","@dptr,a");
7821 pic14_emitcode("inc","dptr");
7825 freeAsmop(right,NULL,ic,TRUE);
7828 /*-----------------------------------------------------------------*/
7829 /* genGenPointerSet - set value from generic pointer space */
7830 /*-----------------------------------------------------------------*/
7831 static void genGenPointerSet (operand *right,
7832 operand *result, iCode *ic)
7835 sym_link *retype = getSpec(operandType(right));
7837 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 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7849 else { /* we need to get it byte by byte */
7850 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7853 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7854 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7857 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7859 pic14_emitcode("movwf","INDF");
7862 /* so dptr know contains the address */
7863 freeAsmop(result,NULL,ic,TRUE);
7864 aopOp(right,ic,FALSE);
7866 /* if bit then unpack */
7867 if (IS_BITVAR(retype))
7868 genPackBits(retype,right,"dptr",GPOINTER);
7870 size = AOP_SIZE(right);
7874 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7876 pic14_emitcode("incf","fsr,f");
7877 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7878 pic14_emitcode("movwf","indf");
7880 //DEBUGpic14_emitcode(";lcall","__gptrput");
7882 // pic14_emitcode("inc","dptr");
7886 freeAsmop(right,NULL,ic,TRUE);
7889 /*-----------------------------------------------------------------*/
7890 /* genPointerSet - stores the value into a pointer location */
7891 /*-----------------------------------------------------------------*/
7892 static void genPointerSet (iCode *ic)
7894 operand *right, *result ;
7895 sym_link *type, *etype;
7898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7900 right = IC_RIGHT(ic);
7901 result = IC_RESULT(ic) ;
7903 /* depending on the type of pointer we need to
7904 move it to the correct pointer register */
7905 type = operandType(result);
7906 etype = getSpec(type);
7907 /* if left is of type of pointer then it is simple */
7908 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7909 p_type = DCL_TYPE(type);
7912 /* we have to go by the storage class */
7913 p_type = PTR_TYPE(SPEC_OCLS(etype));
7915 /* if (SPEC_OCLS(etype)->codesp ) { */
7916 /* p_type = CPOINTER ; */
7919 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7920 /* p_type = FPOINTER ; */
7922 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7923 /* p_type = PPOINTER ; */
7925 /* if (SPEC_OCLS(etype) == idata ) */
7926 /* p_type = IPOINTER ; */
7928 /* p_type = POINTER ; */
7931 /* now that we have the pointer type we assign
7932 the pointer values */
7937 genNearPointerSet (right,result,ic);
7941 genPagedPointerSet (right,result,ic);
7945 genFarPointerSet (right,result,ic);
7949 genGenPointerSet (right,result,ic);
7955 /*-----------------------------------------------------------------*/
7956 /* genIfx - generate code for Ifx statement */
7957 /*-----------------------------------------------------------------*/
7958 static void genIfx (iCode *ic, iCode *popIc)
7960 operand *cond = IC_COND(ic);
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7964 aopOp(cond,ic,FALSE);
7966 /* get the value into acc */
7967 if (AOP_TYPE(cond) != AOP_CRY)
7968 pic14_toBoolean(cond);
7971 /* the result is now in the accumulator */
7972 freeAsmop(cond,NULL,ic,TRUE);
7974 /* if there was something to be popped then do it */
7978 /* if the condition is a bit variable */
7979 if (isbit && IS_ITEMP(cond) &&
7981 genIfxJump(ic,SPIL_LOC(cond)->rname);
7982 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7986 if (isbit && !IS_ITEMP(cond))
7987 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7989 DEBUGpic14_emitcode ("; isbit","a");
7992 if (isbit && !IS_ITEMP(cond))
7993 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8000 /*-----------------------------------------------------------------*/
8001 /* genAddrOf - generates code for address of */
8002 /*-----------------------------------------------------------------*/
8003 static void genAddrOf (iCode *ic)
8005 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8010 aopOp(IC_RESULT(ic),ic,FALSE);
8012 /* if the operand is on the stack then we
8013 need to get the stack offset of this
8016 /* if it has an offset then we need to compute
8019 pic14_emitcode("mov","a,_bp");
8020 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
8021 aopPut(AOP(IC_RESULT(ic)),"a",0);
8023 /* we can just move _bp */
8024 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
8026 /* fill the result with zero */
8027 size = AOP_SIZE(IC_RESULT(ic)) - 1;
8030 if (options.stack10bit && size < (FPTRSIZE - 1))
8033 "*** warning: pointer to stack var truncated.\n");
8040 if (options.stack10bit && offset == 2)
8042 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8046 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8053 /* object not on stack then we need the name */
8054 size = AOP_SIZE(IC_RESULT(ic));
8058 char s[SDCC_NAME_MAX];
8060 sprintf(s,"#(%s >> %d)",
8064 sprintf(s,"#%s",sym->rname);
8065 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8069 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8074 /*-----------------------------------------------------------------*/
8075 /* genFarFarAssign - assignment when both are in far space */
8076 /*-----------------------------------------------------------------*/
8077 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8079 int size = AOP_SIZE(right);
8082 /* first push the right side on to the stack */
8084 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8086 pic14_emitcode ("push","acc");
8089 freeAsmop(right,NULL,ic,FALSE);
8090 /* now assign DPTR to result */
8091 aopOp(result,ic,FALSE);
8092 size = AOP_SIZE(result);
8094 pic14_emitcode ("pop","acc");
8095 aopPut(AOP(result),"a",--offset);
8097 freeAsmop(result,NULL,ic,FALSE);
8102 /*-----------------------------------------------------------------*/
8103 /* genAssign - generate code for assignment */
8104 /*-----------------------------------------------------------------*/
8105 static void genAssign (iCode *ic)
8107 operand *result, *right;
8109 unsigned long lit = 0L;
8111 result = IC_RESULT(ic);
8112 right = IC_RIGHT(ic) ;
8114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8116 /* if they are the same */
8117 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8120 aopOp(right,ic,FALSE);
8121 aopOp(result,ic,TRUE);
8123 /* if they are the same registers */
8124 if (pic14_sameRegs(AOP(right),AOP(result)))
8127 /* if the result is a bit */
8128 if (AOP_TYPE(result) == AOP_CRY) {
8130 /* if the right size is a literal then
8131 we know what the value is */
8132 if (AOP_TYPE(right) == AOP_LIT) {
8134 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8135 popGet(AOP(result),0,FALSE,FALSE));
8137 if (((int) operandLitValue(right)))
8138 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8139 AOP(result)->aopu.aop_dir,
8140 AOP(result)->aopu.aop_dir);
8142 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8143 AOP(result)->aopu.aop_dir,
8144 AOP(result)->aopu.aop_dir);
8148 /* the right is also a bit variable */
8149 if (AOP_TYPE(right) == AOP_CRY) {
8150 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8151 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8152 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8154 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8155 AOP(result)->aopu.aop_dir,
8156 AOP(result)->aopu.aop_dir);
8157 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8158 AOP(right)->aopu.aop_dir,
8159 AOP(right)->aopu.aop_dir);
8160 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8161 AOP(result)->aopu.aop_dir,
8162 AOP(result)->aopu.aop_dir);
8167 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8168 pic14_toBoolean(right);
8170 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8171 //aopPut(AOP(result),"a",0);
8175 /* bit variables done */
8177 size = AOP_SIZE(result);
8179 if(AOP_TYPE(right) == AOP_LIT)
8180 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8181 if((AOP_TYPE(result) != AOP_REG) &&
8182 (AOP_TYPE(right) == AOP_LIT) &&
8183 !IS_FLOAT(operandType(right)) &&
8187 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8188 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8189 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8191 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8192 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8193 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8194 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8199 if(AOP_TYPE(right) == AOP_LIT) {
8200 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8201 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8203 } else if (AOP_TYPE(right) == AOP_CRY) {
8204 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8206 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8207 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8210 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8211 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8214 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8220 freeAsmop (right,NULL,ic,FALSE);
8221 freeAsmop (result,NULL,ic,TRUE);
8224 /*-----------------------------------------------------------------*/
8225 /* genJumpTab - genrates code for jump table */
8226 /*-----------------------------------------------------------------*/
8227 static void genJumpTab (iCode *ic)
8232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8234 aopOp(IC_JTCOND(ic),ic,FALSE);
8235 /* get the condition into accumulator */
8236 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8238 /* multiply by three */
8239 pic14_emitcode("add","a,acc");
8240 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8242 jtab = newiTempLabel(NULL);
8243 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8244 pic14_emitcode("jmp","@a+dptr");
8245 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8247 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8248 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8250 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8251 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8252 emitpLabel(jtab->key);
8254 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8256 /* now generate the jump labels */
8257 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8258 jtab = setNextItem(IC_JTLABELS(ic))) {
8259 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8260 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8266 /*-----------------------------------------------------------------*/
8267 /* genMixedOperation - gen code for operators between mixed types */
8268 /*-----------------------------------------------------------------*/
8270 TSD - Written for the PIC port - but this unfortunately is buggy.
8271 This routine is good in that it is able to efficiently promote
8272 types to different (larger) sizes. Unfortunately, the temporary
8273 variables that are optimized out by this routine are sometimes
8274 used in other places. So until I know how to really parse the
8275 iCode tree, I'm going to not be using this routine :(.
8277 static int genMixedOperation (iCode *ic)
8280 operand *result = IC_RESULT(ic);
8281 sym_link *ctype = operandType(IC_LEFT(ic));
8282 operand *right = IC_RIGHT(ic);
8288 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8290 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8296 nextright = IC_RIGHT(nextic);
8297 nextleft = IC_LEFT(nextic);
8298 nextresult = IC_RESULT(nextic);
8300 aopOp(right,ic,FALSE);
8301 aopOp(result,ic,FALSE);
8302 aopOp(nextright, nextic, FALSE);
8303 aopOp(nextleft, nextic, FALSE);
8304 aopOp(nextresult, nextic, FALSE);
8306 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8312 pic14_emitcode(";remove right +","");
8314 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8320 pic14_emitcode(";remove left +","");
8324 big = AOP_SIZE(nextleft);
8325 small = AOP_SIZE(nextright);
8327 switch(nextic->op) {
8330 pic14_emitcode(";optimize a +","");
8331 /* if unsigned or not an integral type */
8332 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8333 pic14_emitcode(";add a bit to something","");
8336 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8338 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8339 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8340 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8342 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8350 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8351 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8352 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8355 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8357 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8358 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8359 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8360 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8361 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8364 pic14_emitcode("rlf","known_zero,w");
8371 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8372 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8373 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8375 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8385 freeAsmop(right,NULL,ic,TRUE);
8386 freeAsmop(result,NULL,ic,TRUE);
8387 freeAsmop(nextright,NULL,ic,TRUE);
8388 freeAsmop(nextleft,NULL,ic,TRUE);
8390 nextic->generated = 1;
8397 /*-----------------------------------------------------------------*/
8398 /* genCast - gen code for casting */
8399 /*-----------------------------------------------------------------*/
8400 static void genCast (iCode *ic)
8402 operand *result = IC_RESULT(ic);
8403 sym_link *ctype = operandType(IC_LEFT(ic));
8404 operand *right = IC_RIGHT(ic);
8407 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8408 /* if they are equivalent then do nothing */
8409 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8412 aopOp(right,ic,FALSE) ;
8413 aopOp(result,ic,FALSE);
8415 /* if the result is a bit */
8416 if (AOP_TYPE(result) == AOP_CRY) {
8417 /* if the right size is a literal then
8418 we know what the value is */
8419 if (AOP_TYPE(right) == AOP_LIT) {
8421 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8422 popGet(AOP(result),0,FALSE,FALSE));
8424 if (((int) operandLitValue(right)))
8425 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8426 AOP(result)->aopu.aop_dir,
8427 AOP(result)->aopu.aop_dir);
8429 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8430 AOP(result)->aopu.aop_dir,
8431 AOP(result)->aopu.aop_dir);
8436 /* the right is also a bit variable */
8437 if (AOP_TYPE(right) == AOP_CRY) {
8440 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8442 pic14_emitcode("clrc","");
8443 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8444 AOP(right)->aopu.aop_dir,
8445 AOP(right)->aopu.aop_dir);
8446 aopPut(AOP(result),"c",0);
8451 pic14_toBoolean(right);
8452 aopPut(AOP(result),"a",0);
8456 /* if they are the same size : or less */
8457 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8459 /* if they are in the same place */
8460 if (pic14_sameRegs(AOP(right),AOP(result)))
8463 /* if they in different places then copy */
8464 size = AOP_SIZE(result);
8468 aopGet(AOP(right),offset,FALSE,FALSE),
8476 /* if the result is of type pointer */
8477 if (IS_PTR(ctype)) {
8480 sym_link *type = operandType(right);
8481 sym_link *etype = getSpec(type);
8483 /* pointer to generic pointer */
8484 if (IS_GENPTR(ctype)) {
8488 p_type = DCL_TYPE(type);
8490 /* we have to go by the storage class */
8491 p_type = PTR_TYPE(SPEC_OCLS(etype));
8493 /* if (SPEC_OCLS(etype)->codesp ) */
8494 /* p_type = CPOINTER ; */
8496 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8497 /* p_type = FPOINTER ; */
8499 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8500 /* p_type = PPOINTER; */
8502 /* if (SPEC_OCLS(etype) == idata ) */
8503 /* p_type = IPOINTER ; */
8505 /* p_type = POINTER ; */
8508 /* the first two bytes are known */
8509 size = GPTRSIZE - 1;
8513 aopGet(AOP(right),offset,FALSE,FALSE),
8517 /* the last byte depending on type */
8534 /* this should never happen */
8535 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8536 "got unknown pointer type");
8539 aopPut(AOP(result),l, GPTRSIZE - 1);
8543 /* just copy the pointers */
8544 size = AOP_SIZE(result);
8548 aopGet(AOP(right),offset,FALSE,FALSE),
8556 if (AOP_TYPE(right) == AOP_CRY) {
8558 size = AOP_SIZE(right);
8560 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8561 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8562 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8564 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8565 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8566 AOP(right)->aopu.aop_dir,
8567 AOP(right)->aopu.aop_dir);
8568 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8570 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8571 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8576 /* so we now know that the size of destination is greater
8577 than the size of the source.
8578 Now, if the next iCode is an operator then we might be
8579 able to optimize the operation without performing a cast.
8581 if(genMixedOperation(ic))
8585 /* we move to result for the size of source */
8586 size = AOP_SIZE(right);
8589 pic14_emitcode(";","%d",__LINE__);
8590 /* aopPut(AOP(result),
8591 aopGet(AOP(right),offset,FALSE,FALSE),
8593 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8594 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8598 /* now depending on the sign of the destination */
8599 size = AOP_SIZE(result) - AOP_SIZE(right);
8600 /* if unsigned or not an integral type */
8601 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8603 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8604 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8608 /* we need to extend the sign :{ */
8610 emitpcodeNULLop(POC_CLRW);
8613 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8615 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8617 emitpcode(POC_MOVLW, popGetLit(0xff));
8619 pic14_emitcode("clrw","");
8620 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8621 AOP(right)->aopu.aop_dir,
8622 AOP(right)->aopu.aop_dir);
8623 pic14_emitcode("movlw","0xff");
8625 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8626 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8628 // aopPut(AOP(result),"a",offset++);
8633 /* we are done hurray !!!! */
8636 freeAsmop(right,NULL,ic,TRUE);
8637 freeAsmop(result,NULL,ic,TRUE);
8641 /*-----------------------------------------------------------------*/
8642 /* genDjnz - generate decrement & jump if not zero instrucion */
8643 /*-----------------------------------------------------------------*/
8644 static int genDjnz (iCode *ic, iCode *ifx)
8647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8652 /* if the if condition has a false label
8653 then we cannot save */
8657 /* if the minus is not of the form
8659 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8660 !IS_OP_LITERAL(IC_RIGHT(ic)))
8663 if (operandLitValue(IC_RIGHT(ic)) != 1)
8666 /* if the size of this greater than one then no
8668 if (getSize(operandType(IC_RESULT(ic))) > 1)
8671 /* otherwise we can save BIG */
8672 lbl = newiTempLabel(NULL);
8673 lbl1= newiTempLabel(NULL);
8675 aopOp(IC_RESULT(ic),ic,FALSE);
8677 if (IS_AOP_PREG(IC_RESULT(ic))) {
8678 pic14_emitcode("dec","%s",
8679 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8680 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8681 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8685 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8686 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8688 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8689 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8692 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8693 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8694 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8695 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8698 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8703 /*-----------------------------------------------------------------*/
8704 /* genReceive - generate code for a receive iCode */
8705 /*-----------------------------------------------------------------*/
8706 static void genReceive (iCode *ic)
8708 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8710 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8711 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8712 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8714 int size = getSize(operandType(IC_RESULT(ic)));
8715 int offset = fReturnSizePic - size;
8717 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8718 fReturn[fReturnSizePic - offset - 1] : "acc"));
8721 aopOp(IC_RESULT(ic),ic,FALSE);
8722 size = AOP_SIZE(IC_RESULT(ic));
8725 pic14_emitcode ("pop","acc");
8726 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8731 aopOp(IC_RESULT(ic),ic,FALSE);
8733 assignResultValue(IC_RESULT(ic));
8736 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8739 /*-----------------------------------------------------------------*/
8740 /* genpic14Code - generate code for pic14 based controllers */
8741 /*-----------------------------------------------------------------*/
8743 * At this point, ralloc.c has gone through the iCode and attempted
8744 * to optimize in a way suitable for a PIC. Now we've got to generate
8745 * PIC instructions that correspond to the iCode.
8747 * Once the instructions are generated, we'll pass through both the
8748 * peep hole optimizer and the pCode optimizer.
8749 *-----------------------------------------------------------------*/
8751 void genpic14Code (iCode *lic)
8756 lineHead = lineCurr = NULL;
8758 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8761 /* if debug information required */
8762 /* if (options.debug && currFunc) { */
8764 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8766 if (IS_STATIC(currFunc->etype)) {
8767 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8768 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8770 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8771 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8777 for (ic = lic ; ic ; ic = ic->next ) {
8779 DEBUGpic14_emitcode(";ic","");
8780 if ( cln != ic->lineno ) {
8781 if ( options.debug ) {
8783 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8784 FileBaseName(ic->filename),ic->lineno,
8785 ic->level,ic->block);
8788 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8791 /* if the result is marked as
8792 spilt and rematerializable or code for
8793 this has already been generated then
8795 if (resultRemat(ic) || ic->generated )
8798 /* depending on the operation */
8817 /* IPOP happens only when trying to restore a
8818 spilt live range, if there is an ifx statement
8819 following this pop then the if statement might
8820 be using some of the registers being popped which
8821 would destory the contents of the register so
8822 we need to check for this condition and handle it */
8824 ic->next->op == IFX &&
8825 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8826 genIfx (ic->next,ic);
8844 genEndFunction (ic);
8864 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8881 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8885 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8892 /* note these two are xlated by algebraic equivalence
8893 during parsing SDCC.y */
8894 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8895 "got '>=' or '<=' shouldn't have come here");
8899 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8911 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8915 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8919 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8946 case GET_VALUE_AT_ADDRESS:
8951 if (POINTER_SET(ic))
8978 addSet(&_G.sendSet,ic);
8987 /* now we are ready to call the
8988 peep hole optimizer */
8989 if (!options.nopeep) {
8990 printf("peep hole optimizing\n");
8991 peepHole (&lineHead);
8993 /* now do the actual printing */
8994 printLine (lineHead,codeOutFile);
8996 printf("printing pBlock\n\n");
8997 printpBlock(stdout,pb);