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 || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
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 dtype = operandType(IC_LEFT(ic));
1825 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1826 IFFUNC_ISISR(currFunc->type) &&
1829 saverbank(FUNC_REGBANK(dtype),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 dtype = operandType(IC_LEFT(ic));
2144 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2145 IFFUNC_ISISR(currFunc->type) &&
2148 saverbank(FUNC_REGBANK(dtype),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(FUNC_REGBANK(dtype),ic,TRUE);
2227 /* if we hade saved some registers then unsave them */
2228 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
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 dtype = operandType(IC_LEFT(ic));
2253 IFFUNC_ISISR(currFunc->type) &&
2254 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2255 saverbank(FUNC_REGBANK(dtype),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 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2336 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2338 /* if we hade saved some registers then
2341 unsaveRegisters (ic);
2345 /*-----------------------------------------------------------------*/
2346 /* resultRemat - result is rematerializable */
2347 /*-----------------------------------------------------------------*/
2348 static int resultRemat (iCode *ic)
2350 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2351 if (SKIP_IC(ic) || ic->op == IFX)
2354 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2355 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2356 if (sym->remat && !POINTER_SET(ic))
2363 #if defined(__BORLANDC__) || defined(_MSC_VER)
2364 #define STRCASECMP stricmp
2366 #define STRCASECMP strcasecmp
2369 /*-----------------------------------------------------------------*/
2370 /* inExcludeList - return 1 if the string is in exclude Reg list */
2371 /*-----------------------------------------------------------------*/
2372 static bool inExcludeList(char *s)
2376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2377 if (options.excludeRegs[i] &&
2378 STRCASECMP(options.excludeRegs[i],"none") == 0)
2381 for ( i = 0 ; options.excludeRegs[i]; i++) {
2382 if (options.excludeRegs[i] &&
2383 STRCASECMP(s,options.excludeRegs[i]) == 0)
2389 /*-----------------------------------------------------------------*/
2390 /* genFunction - generated code for function entry */
2391 /*-----------------------------------------------------------------*/
2392 static void genFunction (iCode *ic)
2397 DEBUGpic14_emitcode ("; ***","%s %d previous max_key=%d ",__FUNCTION__,__LINE__,max_key);
2399 labelOffset += (max_key+2);
2403 /* create the function header */
2404 pic14_emitcode(";","-----------------------------------------");
2405 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2406 pic14_emitcode(";","-----------------------------------------");
2408 pic14_emitcode("","%s:",sym->rname);
2409 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2411 ftype = operandType(IC_LEFT(ic));
2413 /* if critical function then turn interrupts off */
2414 if (IFFUNC_ISCRITICAL(ftype))
2415 pic14_emitcode("clr","ea");
2417 /* here we need to generate the equates for the
2418 register bank if required */
2420 if (FUNC_REGBANK(ftype) != rbank) {
2423 rbank = FUNC_REGBANK(ftype);
2424 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2425 if (strcmp(regspic14[i].base,"0") == 0)
2426 pic14_emitcode("","%s = 0x%02x",
2428 8*rbank+regspic14[i].offset);
2430 pic14_emitcode ("","%s = %s + 0x%02x",
2433 8*rbank+regspic14[i].offset);
2438 /* if this is an interrupt service routine then
2439 save acc, b, dpl, dph */
2440 if (IFFUNC_ISISR(sym->type)) {
2442 if (!inExcludeList("acc"))
2443 pic14_emitcode ("push","acc");
2444 if (!inExcludeList("b"))
2445 pic14_emitcode ("push","b");
2446 if (!inExcludeList("dpl"))
2447 pic14_emitcode ("push","dpl");
2448 if (!inExcludeList("dph"))
2449 pic14_emitcode ("push","dph");
2450 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2452 pic14_emitcode ("push", "dpx");
2453 /* Make sure we're using standard DPTR */
2454 pic14_emitcode ("push", "dps");
2455 pic14_emitcode ("mov", "dps, #0x00");
2456 if (options.stack10bit)
2458 /* This ISR could conceivably use DPTR2. Better save it. */
2459 pic14_emitcode ("push", "dpl1");
2460 pic14_emitcode ("push", "dph1");
2461 pic14_emitcode ("push", "dpx1");
2464 /* if this isr has no bank i.e. is going to
2465 run with bank 0 , then we need to save more
2467 if (!FUNC_REGBANK(sym->type)) {
2469 /* if this function does not call any other
2470 function then we can be economical and
2471 save only those registers that are used */
2472 if (! IFFUNC_HASFCALL(sym->type)) {
2475 /* if any registers used */
2476 if (sym->regsUsed) {
2477 /* save the registers used */
2478 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2479 if (bitVectBitValue(sym->regsUsed,i) ||
2480 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2481 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2486 /* this function has a function call cannot
2487 determines register usage so we will have the
2489 saverbank(0,ic,FALSE);
2493 /* if callee-save to be used for this function
2494 then save the registers being used in this function */
2495 if (IFFUNC_CALLEESAVES(sym->type)) {
2498 /* if any registers used */
2499 if (sym->regsUsed) {
2500 /* save the registers used */
2501 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2502 if (bitVectBitValue(sym->regsUsed,i) ||
2503 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2504 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2512 /* set the register bank to the desired value */
2513 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2514 pic14_emitcode("push","psw");
2515 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2518 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2520 if (options.useXstack) {
2521 pic14_emitcode("mov","r0,%s",spname);
2522 pic14_emitcode("mov","a,_bp");
2523 pic14_emitcode("movx","@r0,a");
2524 pic14_emitcode("inc","%s",spname);
2528 /* set up the stack */
2529 pic14_emitcode ("push","_bp"); /* save the callers stack */
2531 pic14_emitcode ("mov","_bp,%s",spname);
2534 /* adjust the stack for the function */
2539 werror(W_STACK_OVERFLOW,sym->name);
2541 if (i > 3 && sym->recvSize < 4) {
2543 pic14_emitcode ("mov","a,sp");
2544 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2545 pic14_emitcode ("mov","sp,a");
2550 pic14_emitcode("inc","sp");
2555 pic14_emitcode ("mov","a,_spx");
2556 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2557 pic14_emitcode ("mov","_spx,a");
2562 /*-----------------------------------------------------------------*/
2563 /* genEndFunction - generates epilogue for functions */
2564 /*-----------------------------------------------------------------*/
2565 static void genEndFunction (iCode *ic)
2567 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2571 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2573 pic14_emitcode ("mov","%s,_bp",spname);
2576 /* if use external stack but some variables were
2577 added to the local stack then decrement the
2579 if (options.useXstack && sym->stack) {
2580 pic14_emitcode("mov","a,sp");
2581 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2582 pic14_emitcode("mov","sp,a");
2586 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2587 if (options.useXstack) {
2588 pic14_emitcode("mov","r0,%s",spname);
2589 pic14_emitcode("movx","a,@r0");
2590 pic14_emitcode("mov","_bp,a");
2591 pic14_emitcode("dec","%s",spname);
2595 pic14_emitcode ("pop","_bp");
2599 /* restore the register bank */
2600 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2601 pic14_emitcode ("pop","psw");
2603 if (IFFUNC_ISISR(sym->type)) {
2605 /* now we need to restore the registers */
2606 /* if this isr has no bank i.e. is going to
2607 run with bank 0 , then we need to save more
2609 if (!FUNC_REGBANK(sym->type)) {
2611 /* if this function does not call any other
2612 function then we can be economical and
2613 save only those registers that are used */
2614 if (! IFFUNC_HASFCALL(sym->type)) {
2617 /* if any registers used */
2618 if (sym->regsUsed) {
2619 /* save the registers used */
2620 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2621 if (bitVectBitValue(sym->regsUsed,i) ||
2622 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2623 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2628 /* this function has a function call cannot
2629 determines register usage so we will have the
2631 unsaverbank(0,ic,FALSE);
2635 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2637 if (options.stack10bit)
2639 pic14_emitcode ("pop", "dpx1");
2640 pic14_emitcode ("pop", "dph1");
2641 pic14_emitcode ("pop", "dpl1");
2643 pic14_emitcode ("pop", "dps");
2644 pic14_emitcode ("pop", "dpx");
2646 if (!inExcludeList("dph"))
2647 pic14_emitcode ("pop","dph");
2648 if (!inExcludeList("dpl"))
2649 pic14_emitcode ("pop","dpl");
2650 if (!inExcludeList("b"))
2651 pic14_emitcode ("pop","b");
2652 if (!inExcludeList("acc"))
2653 pic14_emitcode ("pop","acc");
2655 if (IFFUNC_ISCRITICAL(sym->type))
2656 pic14_emitcode("setb","ea");
2658 /* if debug then send end of function */
2659 /* if (options.debug && currFunc) { */
2662 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2663 FileBaseName(ic->filename),currFunc->lastLine,
2664 ic->level,ic->block);
2665 if (IS_STATIC(currFunc->etype))
2666 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2668 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2672 pic14_emitcode ("reti","");
2675 if (IFFUNC_ISCRITICAL(sym->type))
2676 pic14_emitcode("setb","ea");
2678 if (IFFUNC_CALLEESAVES(sym->type)) {
2681 /* if any registers used */
2682 if (sym->regsUsed) {
2683 /* save the registers used */
2684 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2685 if (bitVectBitValue(sym->regsUsed,i) ||
2686 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2687 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2693 /* if debug then send end of function */
2696 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2697 FileBaseName(ic->filename),currFunc->lastLine,
2698 ic->level,ic->block);
2699 if (IS_STATIC(currFunc->etype))
2700 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2702 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2706 pic14_emitcode ("return","");
2707 emitpcodeNULLop(POC_RETURN);
2709 /* Mark the end of a function */
2710 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2715 /*-----------------------------------------------------------------*/
2716 /* genRet - generate code for return statement */
2717 /*-----------------------------------------------------------------*/
2718 static void genRet (iCode *ic)
2720 int size,offset = 0 , pushed = 0;
2722 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2723 /* if we have no return value then
2724 just generate the "ret" */
2728 /* we have something to return then
2729 move the return value into place */
2730 aopOp(IC_LEFT(ic),ic,FALSE);
2731 size = AOP_SIZE(IC_LEFT(ic));
2735 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2737 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2739 pic14_emitcode("push","%s",l);
2742 l = aopGet(AOP(IC_LEFT(ic)),offset,
2744 if (strcmp(fReturn[offset],l)) {
2745 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2746 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2747 pic14_emitcode("movlw","%s",l);
2749 pic14_emitcode("movf","%s,w",l);
2751 pic14_emitcode("movwf","%s",fReturn[offset]);
2760 if (strcmp(fReturn[pushed],"a"))
2761 pic14_emitcode("pop",fReturn[pushed]);
2763 pic14_emitcode("pop","acc");
2766 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2769 /* generate a jump to the return label
2770 if the next is not the return statement */
2771 if (!(ic->next && ic->next->op == LABEL &&
2772 IC_LABEL(ic->next) == returnLabel)) {
2774 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2775 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2780 /*-----------------------------------------------------------------*/
2781 /* genLabel - generates a label */
2782 /*-----------------------------------------------------------------*/
2783 static void genLabel (iCode *ic)
2785 /* special case never generate */
2786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2787 if (IC_LABEL(ic) == entryLabel)
2790 emitpLabel(IC_LABEL(ic)->key);
2791 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2794 /*-----------------------------------------------------------------*/
2795 /* genGoto - generates a goto */
2796 /*-----------------------------------------------------------------*/
2798 static void genGoto (iCode *ic)
2800 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2801 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2804 /*-----------------------------------------------------------------*/
2805 /* findLabelBackwards: walks back through the iCode chain looking */
2806 /* for the given label. Returns number of iCode instructions */
2807 /* between that label and given ic. */
2808 /* Returns zero if label not found. */
2809 /*-----------------------------------------------------------------*/
2811 static int findLabelBackwards(iCode *ic, int key)
2815 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2821 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2823 /* printf("findLabelBackwards = %d\n", count); */
2832 /*-----------------------------------------------------------------*/
2833 /* genMultbits :- multiplication of bits */
2834 /*-----------------------------------------------------------------*/
2835 static void genMultbits (operand *left,
2839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2841 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2842 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2843 pic14_outBitC(result);
2847 /*-----------------------------------------------------------------*/
2848 /* genMultOneByte : 8 bit multiplication & division */
2849 /*-----------------------------------------------------------------*/
2850 static void genMultOneByte (operand *left,
2854 sym_link *opetype = operandType(result);
2859 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2860 /* (if two literals, the value is computed before) */
2861 /* if one literal, literal on the right */
2862 if (AOP_TYPE(left) == AOP_LIT){
2868 size = AOP_SIZE(result);
2869 /* signed or unsigned */
2870 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2871 l = aopGet(AOP(left),0,FALSE,FALSE);
2873 pic14_emitcode("mul","ab");
2874 /* if result size = 1, mul signed = mul unsigned */
2875 aopPut(AOP(result),"a",0);
2877 if (SPEC_USIGN(opetype)){
2878 aopPut(AOP(result),"b",1);
2880 /* for filling the MSBs */
2881 pic14_emitcode("clr","a");
2884 pic14_emitcode("mov","a,b");
2886 /* adjust the MSB if left or right neg */
2888 /* if one literal */
2889 if (AOP_TYPE(right) == AOP_LIT){
2890 /* AND literal negative */
2891 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2892 /* adjust MSB (c==0 after mul) */
2893 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2897 lbl = newiTempLabel(NULL);
2898 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2899 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2900 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2901 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2902 lbl = newiTempLabel(NULL);
2903 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2904 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2905 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2908 lbl = newiTempLabel(NULL);
2909 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2910 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2911 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2912 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2913 lbl = newiTempLabel(NULL);
2914 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2915 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2916 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2918 aopPut(AOP(result),"a",1);
2921 pic14_emitcode("rlc","a");
2922 pic14_emitcode("subb","a,acc");
2929 aopPut(AOP(result),"a",offset++);
2933 /*-----------------------------------------------------------------*/
2934 /* genMult - generates code for multiplication */
2935 /*-----------------------------------------------------------------*/
2936 static void genMult (iCode *ic)
2938 operand *left = IC_LEFT(ic);
2939 operand *right = IC_RIGHT(ic);
2940 operand *result= IC_RESULT(ic);
2942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2943 /* assign the amsops */
2944 aopOp (left,ic,FALSE);
2945 aopOp (right,ic,FALSE);
2946 aopOp (result,ic,TRUE);
2948 /* special cases first */
2950 if (AOP_TYPE(left) == AOP_CRY &&
2951 AOP_TYPE(right)== AOP_CRY) {
2952 genMultbits(left,right,result);
2956 /* if both are of size == 1 */
2957 if (AOP_SIZE(left) == 1 &&
2958 AOP_SIZE(right) == 1 ) {
2959 genMultOneByte(left,right,result);
2963 /* should have been converted to function call */
2967 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2968 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2969 freeAsmop(result,NULL,ic,TRUE);
2972 /*-----------------------------------------------------------------*/
2973 /* genDivbits :- division of bits */
2974 /*-----------------------------------------------------------------*/
2975 static void genDivbits (operand *left,
2982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2983 /* the result must be bit */
2984 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2985 l = aopGet(AOP(left),0,FALSE,FALSE);
2989 pic14_emitcode("div","ab");
2990 pic14_emitcode("rrc","a");
2991 aopPut(AOP(result),"c",0);
2994 /*-----------------------------------------------------------------*/
2995 /* genDivOneByte : 8 bit division */
2996 /*-----------------------------------------------------------------*/
2997 static void genDivOneByte (operand *left,
3001 sym_link *opetype = operandType(result);
3006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3007 size = AOP_SIZE(result) - 1;
3009 /* signed or unsigned */
3010 if (SPEC_USIGN(opetype)) {
3011 /* unsigned is easy */
3012 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3013 l = aopGet(AOP(left),0,FALSE,FALSE);
3015 pic14_emitcode("div","ab");
3016 aopPut(AOP(result),"a",0);
3018 aopPut(AOP(result),zero,offset++);
3022 /* signed is a little bit more difficult */
3024 /* save the signs of the operands */
3025 l = aopGet(AOP(left),0,FALSE,FALSE);
3027 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3028 pic14_emitcode("push","acc"); /* save it on the stack */
3030 /* now sign adjust for both left & right */
3031 l = aopGet(AOP(right),0,FALSE,FALSE);
3033 lbl = newiTempLabel(NULL);
3034 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3035 pic14_emitcode("cpl","a");
3036 pic14_emitcode("inc","a");
3037 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3038 pic14_emitcode("mov","b,a");
3040 /* sign adjust left side */
3041 l = aopGet(AOP(left),0,FALSE,FALSE);
3044 lbl = newiTempLabel(NULL);
3045 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3046 pic14_emitcode("cpl","a");
3047 pic14_emitcode("inc","a");
3048 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3050 /* now the division */
3051 pic14_emitcode("div","ab");
3052 /* we are interested in the lower order
3054 pic14_emitcode("mov","b,a");
3055 lbl = newiTempLabel(NULL);
3056 pic14_emitcode("pop","acc");
3057 /* if there was an over flow we don't
3058 adjust the sign of the result */
3059 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3060 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3062 pic14_emitcode("clr","a");
3063 pic14_emitcode("subb","a,b");
3064 pic14_emitcode("mov","b,a");
3065 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3067 /* now we are done */
3068 aopPut(AOP(result),"b",0);
3070 pic14_emitcode("mov","c,b.7");
3071 pic14_emitcode("subb","a,acc");
3074 aopPut(AOP(result),"a",offset++);
3078 /*-----------------------------------------------------------------*/
3079 /* genDiv - generates code for division */
3080 /*-----------------------------------------------------------------*/
3081 static void genDiv (iCode *ic)
3083 operand *left = IC_LEFT(ic);
3084 operand *right = IC_RIGHT(ic);
3085 operand *result= IC_RESULT(ic);
3087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3088 /* assign the amsops */
3089 aopOp (left,ic,FALSE);
3090 aopOp (right,ic,FALSE);
3091 aopOp (result,ic,TRUE);
3093 /* special cases first */
3095 if (AOP_TYPE(left) == AOP_CRY &&
3096 AOP_TYPE(right)== AOP_CRY) {
3097 genDivbits(left,right,result);
3101 /* if both are of size == 1 */
3102 if (AOP_SIZE(left) == 1 &&
3103 AOP_SIZE(right) == 1 ) {
3104 genDivOneByte(left,right,result);
3108 /* should have been converted to function call */
3111 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3112 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3113 freeAsmop(result,NULL,ic,TRUE);
3116 /*-----------------------------------------------------------------*/
3117 /* genModbits :- modulus of bits */
3118 /*-----------------------------------------------------------------*/
3119 static void genModbits (operand *left,
3126 /* the result must be bit */
3127 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3128 l = aopGet(AOP(left),0,FALSE,FALSE);
3132 pic14_emitcode("div","ab");
3133 pic14_emitcode("mov","a,b");
3134 pic14_emitcode("rrc","a");
3135 aopPut(AOP(result),"c",0);
3138 /*-----------------------------------------------------------------*/
3139 /* genModOneByte : 8 bit modulus */
3140 /*-----------------------------------------------------------------*/
3141 static void genModOneByte (operand *left,
3145 sym_link *opetype = operandType(result);
3149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3150 /* signed or unsigned */
3151 if (SPEC_USIGN(opetype)) {
3152 /* unsigned is easy */
3153 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3154 l = aopGet(AOP(left),0,FALSE,FALSE);
3156 pic14_emitcode("div","ab");
3157 aopPut(AOP(result),"b",0);
3161 /* signed is a little bit more difficult */
3163 /* save the signs of the operands */
3164 l = aopGet(AOP(left),0,FALSE,FALSE);
3167 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3168 pic14_emitcode("push","acc"); /* save it on the stack */
3170 /* now sign adjust for both left & right */
3171 l = aopGet(AOP(right),0,FALSE,FALSE);
3174 lbl = newiTempLabel(NULL);
3175 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3176 pic14_emitcode("cpl","a");
3177 pic14_emitcode("inc","a");
3178 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3179 pic14_emitcode("mov","b,a");
3181 /* sign adjust left side */
3182 l = aopGet(AOP(left),0,FALSE,FALSE);
3185 lbl = newiTempLabel(NULL);
3186 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3187 pic14_emitcode("cpl","a");
3188 pic14_emitcode("inc","a");
3189 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3191 /* now the multiplication */
3192 pic14_emitcode("div","ab");
3193 /* we are interested in the lower order
3195 lbl = newiTempLabel(NULL);
3196 pic14_emitcode("pop","acc");
3197 /* if there was an over flow we don't
3198 adjust the sign of the result */
3199 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3200 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3202 pic14_emitcode("clr","a");
3203 pic14_emitcode("subb","a,b");
3204 pic14_emitcode("mov","b,a");
3205 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3207 /* now we are done */
3208 aopPut(AOP(result),"b",0);
3212 /*-----------------------------------------------------------------*/
3213 /* genMod - generates code for division */
3214 /*-----------------------------------------------------------------*/
3215 static void genMod (iCode *ic)
3217 operand *left = IC_LEFT(ic);
3218 operand *right = IC_RIGHT(ic);
3219 operand *result= IC_RESULT(ic);
3221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3222 /* assign the amsops */
3223 aopOp (left,ic,FALSE);
3224 aopOp (right,ic,FALSE);
3225 aopOp (result,ic,TRUE);
3227 /* special cases first */
3229 if (AOP_TYPE(left) == AOP_CRY &&
3230 AOP_TYPE(right)== AOP_CRY) {
3231 genModbits(left,right,result);
3235 /* if both are of size == 1 */
3236 if (AOP_SIZE(left) == 1 &&
3237 AOP_SIZE(right) == 1 ) {
3238 genModOneByte(left,right,result);
3242 /* should have been converted to function call */
3246 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3247 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3248 freeAsmop(result,NULL,ic,TRUE);
3251 /*-----------------------------------------------------------------*/
3252 /* genIfxJump :- will create a jump depending on the ifx */
3253 /*-----------------------------------------------------------------*/
3255 note: May need to add parameter to indicate when a variable is in bit space.
3257 static void genIfxJump (iCode *ic, char *jval)
3260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3261 /* if true label then we jump if condition
3263 if ( IC_TRUE(ic) ) {
3265 if(strcmp(jval,"a") == 0)
3267 else if (strcmp(jval,"c") == 0)
3270 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3271 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3274 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3275 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3279 /* false label is present */
3280 if(strcmp(jval,"a") == 0)
3282 else if (strcmp(jval,"c") == 0)
3285 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3286 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3289 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3290 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3295 /* mark the icode as generated */
3299 /*-----------------------------------------------------------------*/
3301 /*-----------------------------------------------------------------*/
3302 static void genSkip(iCode *ifx,int status_bit)
3307 if ( IC_TRUE(ifx) ) {
3308 switch(status_bit) {
3323 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3324 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3328 switch(status_bit) {
3342 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3343 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3349 /*-----------------------------------------------------------------*/
3351 /*-----------------------------------------------------------------*/
3352 static void genSkipc(iCode *ifx, int condition)
3363 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3365 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3368 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3370 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3374 /*-----------------------------------------------------------------*/
3376 /*-----------------------------------------------------------------*/
3377 static void genSkipz(iCode *ifx, int condition)
3388 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3390 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3393 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3395 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3398 /*-----------------------------------------------------------------*/
3399 /* genCmp :- greater or less than comparison */
3400 /*-----------------------------------------------------------------*/
3401 static void genCmp (operand *left,operand *right,
3402 operand *result, iCode *ifx, int sign)
3404 int size, offset = 0 ;
3405 unsigned long lit = 0L,i = 0;
3407 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3408 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3409 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3411 /* if left & right are bit variables */
3412 if (AOP_TYPE(left) == AOP_CRY &&
3413 AOP_TYPE(right) == AOP_CRY ) {
3414 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3415 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3417 /* subtract right from left if at the
3418 end the carry flag is set then we know that
3419 left is greater than right */
3420 size = max(AOP_SIZE(left),AOP_SIZE(right));
3422 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3423 if((size == 1) && !sign &&
3424 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3425 symbol *lbl = newiTempLabel(NULL);
3426 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3427 aopGet(AOP(left),offset,FALSE,FALSE),
3428 aopGet(AOP(right),offset,FALSE,FALSE),
3430 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3433 if(AOP_TYPE(right) == AOP_LIT) {
3434 symbol *lbl = newiTempLabel(NULL);
3436 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3438 DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3441 i = (lit >> (size*8)) & 0xff;
3444 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3446 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3448 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3451 emitpcode(POC_MOVLW, popGetLit(i));
3452 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3454 i = (lit >> (size*8)) & 0xff;
3455 emitpcode(POC_MOVLW, popGetLit(i));
3457 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3460 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3462 emitpLabel(lbl->key);
3468 if(AOP_TYPE(left) == AOP_LIT) {
3469 //symbol *lbl = newiTempLabel(NULL);
3471 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3473 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3478 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3480 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3482 if(IC_TRUE(ifx) != NULL)
3483 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3485 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3487 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3488 emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3489 genSkipc(ifx,IC_TRUE(ifx)!=NULL);
3493 i = (lit >> (size*8)) & 0xff;
3497 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3499 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3501 if(IC_TRUE(ifx) != NULL)
3502 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3504 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3507 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3508 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3510 i = (lit >> (size*8)) & 0xff;
3511 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3513 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3515 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3520 emitpLabel(lbl->key);
3528 DEBUGpic14_emitcode(";sign","%d",sign);
3530 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3531 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3533 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3534 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3539 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3541 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3542 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3545 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3547 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3548 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3556 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3557 pic14_outBitC(result);
3559 /* if the result is used in the next
3560 ifx conditional branch then generate
3561 code a little differently */
3563 genIfxJump (ifx,"c");
3565 pic14_outBitC(result);
3566 /* leave the result in acc */
3571 /*-----------------------------------------------------------------*/
3572 /* genCmpGt :- greater than comparison */
3573 /*-----------------------------------------------------------------*/
3574 static void genCmpGt (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));
3588 /* assign the amsops */
3589 aopOp (left,ic,FALSE);
3590 aopOp (right,ic,FALSE);
3591 aopOp (result,ic,TRUE);
3593 genCmp(right, left, result, ifx, sign);
3595 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3596 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3597 freeAsmop(result,NULL,ic,TRUE);
3600 /*-----------------------------------------------------------------*/
3601 /* genCmpLt - less than comparisons */
3602 /*-----------------------------------------------------------------*/
3603 static void genCmpLt (iCode *ic, iCode *ifx)
3605 operand *left, *right, *result;
3606 sym_link *letype , *retype;
3609 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3611 right= IC_RIGHT(ic);
3612 result = IC_RESULT(ic);
3614 letype = getSpec(operandType(left));
3615 retype =getSpec(operandType(right));
3616 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3618 /* assign the amsops */
3619 aopOp (left,ic,FALSE);
3620 aopOp (right,ic,FALSE);
3621 aopOp (result,ic,TRUE);
3623 genCmp(left, right, result, ifx, sign);
3625 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3626 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3627 freeAsmop(result,NULL,ic,TRUE);
3630 /*-----------------------------------------------------------------*/
3631 /* genc16bit2lit - compare a 16 bit value to a literal */
3632 /*-----------------------------------------------------------------*/
3633 static void genc16bit2lit(operand *op, int lit, int offset)
3637 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3638 if( (lit&0xff) == 0)
3643 switch( BYTEofLONG(lit,i)) {
3645 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3648 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3651 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3654 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3655 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3660 switch( BYTEofLONG(lit,i)) {
3662 emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3666 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3670 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3673 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3675 emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3681 /*-----------------------------------------------------------------*/
3682 /* gencjneshort - compare and jump if not equal */
3683 /*-----------------------------------------------------------------*/
3684 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3686 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3688 unsigned long lit = 0L;
3690 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3691 /* if the left side is a literal or
3692 if the right is in a pointer register and left
3694 if ((AOP_TYPE(left) == AOP_LIT) ||
3695 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3700 if(AOP_TYPE(right) == AOP_LIT)
3701 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3703 /* if the right side is a literal then anything goes */
3704 if (AOP_TYPE(right) == AOP_LIT &&
3705 AOP_TYPE(left) != AOP_DIR ) {
3708 genc16bit2lit(left, lit, 0);
3710 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3711 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3716 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3717 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3718 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3719 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3721 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3722 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3726 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3727 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3735 /* if the right side is in a register or in direct space or
3736 if the left is a pointer register & right is not */
3737 else if (AOP_TYPE(right) == AOP_REG ||
3738 AOP_TYPE(right) == AOP_DIR ||
3739 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3740 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3743 genc16bit2lit(left, lit, 0);
3745 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3746 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3750 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3751 ( (lit & 0xff) != 0)) {
3752 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3753 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3754 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3755 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3758 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3759 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3762 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3763 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3769 /* right is a pointer reg need both a & b */
3771 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3773 pic14_emitcode("mov","b,%s",l);
3774 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3775 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3781 /*-----------------------------------------------------------------*/
3782 /* gencjne - compare and jump if not equal */
3783 /*-----------------------------------------------------------------*/
3784 static void gencjne(operand *left, operand *right, symbol *lbl)
3786 symbol *tlbl = newiTempLabel(NULL);
3788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3789 gencjneshort(left, right, lbl);
3791 pic14_emitcode("mov","a,%s",one);
3792 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3793 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3794 pic14_emitcode("clr","a");
3795 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3797 emitpLabel(lbl->key);
3798 emitpLabel(tlbl->key);
3805 /*-----------------------------------------------------------------*/
3806 /* genCmpEq - generates code for equal to */
3807 /*-----------------------------------------------------------------*/
3808 static void genCmpEq (iCode *ic, iCode *ifx)
3810 operand *left, *right, *result;
3811 unsigned long lit = 0L;
3814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3817 DEBUGpic14_emitcode ("; ifx is non-null","");
3819 DEBUGpic14_emitcode ("; ifx is null","");
3821 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3822 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3823 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3826 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3827 AopType(AOP_TYPE(IC_RESULT(ic))),
3828 AopType(AOP_TYPE(IC_LEFT(ic))),
3829 AopType(AOP_TYPE(IC_RIGHT(ic))));
3831 size = max(AOP_SIZE(left),AOP_SIZE(right));
3833 /* if literal, literal on the right or
3834 if the right is in a pointer register and left
3836 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3837 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3838 operand *t = IC_RIGHT(ic);
3839 IC_RIGHT(ic) = IC_LEFT(ic);
3843 if(ifx && !AOP_SIZE(result)){
3845 /* if they are both bit variables */
3846 if (AOP_TYPE(left) == AOP_CRY &&
3847 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3848 if(AOP_TYPE(right) == AOP_LIT){
3849 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3851 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3852 pic14_emitcode("cpl","c");
3853 } else if(lit == 1L) {
3854 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3856 pic14_emitcode("clr","c");
3858 /* AOP_TYPE(right) == AOP_CRY */
3860 symbol *lbl = newiTempLabel(NULL);
3861 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3862 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3863 pic14_emitcode("cpl","c");
3864 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3866 /* if true label then we jump if condition
3868 tlbl = newiTempLabel(NULL);
3869 if ( IC_TRUE(ifx) ) {
3870 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3871 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3873 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3874 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3876 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3879 /* They're not both bit variables. Is the right a literal? */
3880 if(AOP_TYPE(right) == AOP_LIT) {
3881 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3887 switch(lit & 0xff) {
3889 if ( IC_TRUE(ifx) ) {
3890 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3892 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3894 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3895 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3899 if ( IC_TRUE(ifx) ) {
3900 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3902 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3904 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3905 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3909 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3911 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3916 /* end of size == 1 */
3920 genc16bit2lit(left,lit,offset);
3923 /* end of size == 2 */
3928 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
3929 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
3930 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
3931 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
3935 /* search for patterns that can be optimized */
3937 genc16bit2lit(left,lit,0);
3940 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3942 genc16bit2lit(left,lit,2);
3944 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
3945 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
3958 } else if(AOP_TYPE(right) == AOP_CRY ) {
3959 /* we know the left is not a bit, but that the right is */
3960 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3961 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3962 popGet(AOP(right),offset,FALSE,FALSE));
3963 emitpcode(POC_XORLW,popGetLit(1));
3965 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3967 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3968 AOP(right)->aopu.aop_dir,
3969 AOP(right)->aopu.aop_dir);
3971 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3972 AOP(right)->aopu.aop_dir,
3973 AOP(right)->aopu.aop_dir);
3975 pic14_emitcode("xorlw","1");
3977 /* if the two are equal, then W will be 0 and the Z bit is set
3978 * we could test Z now, or go ahead and check the high order bytes if
3979 * the variable we're comparing is larger than a byte. */
3982 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3983 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3985 if ( IC_TRUE(ifx) ) {
3987 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3988 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 /* They're both variables that are larger than bits */
3999 tlbl = newiTempLabel(NULL);
4002 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4003 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4005 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4006 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4008 if ( IC_TRUE(ifx) ) {
4011 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4012 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4015 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4016 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4020 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4021 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4025 if(s>1 && IC_TRUE(ifx)) {
4026 emitpLabel(tlbl->key);
4027 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4031 /* mark the icode as generated */
4036 /* if they are both bit variables */
4037 if (AOP_TYPE(left) == AOP_CRY &&
4038 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4039 if(AOP_TYPE(right) == AOP_LIT){
4040 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4042 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4043 pic14_emitcode("cpl","c");
4044 } else if(lit == 1L) {
4045 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4047 pic14_emitcode("clr","c");
4049 /* AOP_TYPE(right) == AOP_CRY */
4051 symbol *lbl = newiTempLabel(NULL);
4052 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4053 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4054 pic14_emitcode("cpl","c");
4055 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4058 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4059 pic14_outBitC(result);
4063 genIfxJump (ifx,"c");
4066 /* if the result is used in an arithmetic operation
4067 then put the result in place */
4068 pic14_outBitC(result);
4070 gencjne(left,right,newiTempLabel(NULL));
4071 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4072 aopPut(AOP(result),"a",0);
4076 genIfxJump (ifx,"a");
4079 /* if the result is used in an arithmetic operation
4080 then put the result in place */
4081 if (AOP_TYPE(result) != AOP_CRY)
4082 pic14_outAcc(result);
4083 /* leave the result in acc */
4087 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4088 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4089 freeAsmop(result,NULL,ic,TRUE);
4092 /*-----------------------------------------------------------------*/
4093 /* ifxForOp - returns the icode containing the ifx for operand */
4094 /*-----------------------------------------------------------------*/
4095 static iCode *ifxForOp ( operand *op, iCode *ic )
4097 /* if true symbol then needs to be assigned */
4098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4099 if (IS_TRUE_SYMOP(op))
4102 /* if this has register type condition and
4103 the next instruction is ifx with the same operand
4104 and live to of the operand is upto the ifx only then */
4106 ic->next->op == IFX &&
4107 IC_COND(ic->next)->key == op->key &&
4108 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4113 /*-----------------------------------------------------------------*/
4114 /* genAndOp - for && operation */
4115 /*-----------------------------------------------------------------*/
4116 static void genAndOp (iCode *ic)
4118 operand *left,*right, *result;
4121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4122 /* note here that && operations that are in an
4123 if statement are taken away by backPatchLabels
4124 only those used in arthmetic operations remain */
4125 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4126 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4127 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4129 /* if both are bit variables */
4130 if (AOP_TYPE(left) == AOP_CRY &&
4131 AOP_TYPE(right) == AOP_CRY ) {
4132 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4133 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4134 pic14_outBitC(result);
4136 tlbl = newiTempLabel(NULL);
4137 pic14_toBoolean(left);
4138 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4139 pic14_toBoolean(right);
4140 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4141 pic14_outBitAcc(result);
4144 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4145 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4146 freeAsmop(result,NULL,ic,TRUE);
4150 /*-----------------------------------------------------------------*/
4151 /* genOrOp - for || operation */
4152 /*-----------------------------------------------------------------*/
4155 modified this code, but it doesn't appear to ever get called
4158 static void genOrOp (iCode *ic)
4160 operand *left,*right, *result;
4163 /* note here that || operations that are in an
4164 if statement are taken away by backPatchLabels
4165 only those used in arthmetic operations remain */
4166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4167 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4168 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4169 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4171 /* if both are bit variables */
4172 if (AOP_TYPE(left) == AOP_CRY &&
4173 AOP_TYPE(right) == AOP_CRY ) {
4174 pic14_emitcode("clrc","");
4175 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4176 AOP(left)->aopu.aop_dir,
4177 AOP(left)->aopu.aop_dir);
4178 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4179 AOP(right)->aopu.aop_dir,
4180 AOP(right)->aopu.aop_dir);
4181 pic14_emitcode("setc","");
4184 tlbl = newiTempLabel(NULL);
4185 pic14_toBoolean(left);
4187 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4188 pic14_toBoolean(right);
4189 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4191 pic14_outBitAcc(result);
4194 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4195 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4196 freeAsmop(result,NULL,ic,TRUE);
4199 /*-----------------------------------------------------------------*/
4200 /* isLiteralBit - test if lit == 2^n */
4201 /*-----------------------------------------------------------------*/
4202 static int isLiteralBit(unsigned long lit)
4204 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4205 0x100L,0x200L,0x400L,0x800L,
4206 0x1000L,0x2000L,0x4000L,0x8000L,
4207 0x10000L,0x20000L,0x40000L,0x80000L,
4208 0x100000L,0x200000L,0x400000L,0x800000L,
4209 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4210 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4213 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4214 for(idx = 0; idx < 32; idx++)
4220 /*-----------------------------------------------------------------*/
4221 /* continueIfTrue - */
4222 /*-----------------------------------------------------------------*/
4223 static void continueIfTrue (iCode *ic)
4225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4227 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4231 /*-----------------------------------------------------------------*/
4233 /*-----------------------------------------------------------------*/
4234 static void jumpIfTrue (iCode *ic)
4236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4238 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4242 /*-----------------------------------------------------------------*/
4243 /* jmpTrueOrFalse - */
4244 /*-----------------------------------------------------------------*/
4245 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4247 // ugly but optimized by peephole
4248 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4250 symbol *nlbl = newiTempLabel(NULL);
4251 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4252 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4253 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4254 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4257 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4258 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4263 /*-----------------------------------------------------------------*/
4264 /* genAnd - code for and */
4265 /*-----------------------------------------------------------------*/
4266 static void genAnd (iCode *ic, iCode *ifx)
4268 operand *left, *right, *result;
4270 unsigned long lit = 0L;
4274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4275 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4276 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4277 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4280 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4282 AOP_TYPE(left), AOP_TYPE(right));
4283 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4285 AOP_SIZE(left), AOP_SIZE(right));
4288 /* if left is a literal & right is not then exchange them */
4289 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4290 AOP_NEEDSACC(left)) {
4291 operand *tmp = right ;
4296 /* if result = right then exchange them */
4297 if(pic14_sameRegs(AOP(result),AOP(right))){
4298 operand *tmp = right ;
4303 /* if right is bit then exchange them */
4304 if (AOP_TYPE(right) == AOP_CRY &&
4305 AOP_TYPE(left) != AOP_CRY){
4306 operand *tmp = right ;
4310 if(AOP_TYPE(right) == AOP_LIT)
4311 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4313 size = AOP_SIZE(result);
4316 // result = bit & yy;
4317 if (AOP_TYPE(left) == AOP_CRY){
4318 // c = bit & literal;
4319 if(AOP_TYPE(right) == AOP_LIT){
4321 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4324 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4327 if(size && (AOP_TYPE(result) == AOP_CRY)){
4328 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4331 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4335 pic14_emitcode("clr","c");
4338 if (AOP_TYPE(right) == AOP_CRY){
4340 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4341 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4344 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4346 pic14_emitcode("rrc","a");
4347 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4353 pic14_outBitC(result);
4355 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4356 genIfxJump(ifx, "c");
4360 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4361 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4362 if((AOP_TYPE(right) == AOP_LIT) &&
4363 (AOP_TYPE(result) == AOP_CRY) &&
4364 (AOP_TYPE(left) != AOP_CRY)){
4365 int posbit = isLiteralBit(lit);
4369 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4372 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4377 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4378 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4380 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4381 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4388 symbol *tlbl = newiTempLabel(NULL);
4389 int sizel = AOP_SIZE(left);
4391 pic14_emitcode("setb","c");
4393 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4394 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4396 if((posbit = isLiteralBit(bytelit)) != 0)
4397 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4399 if(bytelit != 0x0FFL)
4400 pic14_emitcode("anl","a,%s",
4401 aopGet(AOP(right),offset,FALSE,TRUE));
4402 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4407 // bit = left & literal
4409 pic14_emitcode("clr","c");
4410 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4412 // if(left & literal)
4415 jmpTrueOrFalse(ifx, tlbl);
4419 pic14_outBitC(result);
4423 /* if left is same as result */
4424 if(pic14_sameRegs(AOP(result),AOP(left))){
4426 for(;size--; offset++,lit>>=8) {
4427 if(AOP_TYPE(right) == AOP_LIT){
4428 switch(lit & 0xff) {
4430 /* and'ing with 0 has clears the result */
4431 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4432 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4435 /* and'ing with 0xff is a nop when the result and left are the same */
4440 int p = my_powof2( (~lit) & 0xff );
4442 /* only one bit is set in the literal, so use a bcf instruction */
4443 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4444 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4445 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4448 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4449 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4450 if(know_W != (lit&0xff))
4451 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4453 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4458 if (AOP_TYPE(left) == AOP_ACC) {
4459 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4461 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4462 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4469 // left & result in different registers
4470 if(AOP_TYPE(result) == AOP_CRY){
4472 // if(size), result in bit
4473 // if(!size && ifx), conditional oper: if(left & right)
4474 symbol *tlbl = newiTempLabel(NULL);
4475 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4477 pic14_emitcode("setb","c");
4479 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4480 pic14_emitcode("anl","a,%s",
4481 aopGet(AOP(left),offset,FALSE,FALSE));
4482 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4487 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4488 pic14_outBitC(result);
4490 jmpTrueOrFalse(ifx, tlbl);
4492 for(;(size--);offset++) {
4494 // result = left & right
4495 if(AOP_TYPE(right) == AOP_LIT){
4496 int t = (lit >> (offset*8)) & 0x0FFL;
4499 pic14_emitcode("clrf","%s",
4500 aopGet(AOP(result),offset,FALSE,FALSE));
4501 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4504 pic14_emitcode("movf","%s,w",
4505 aopGet(AOP(left),offset,FALSE,FALSE));
4506 pic14_emitcode("movwf","%s",
4507 aopGet(AOP(result),offset,FALSE,FALSE));
4508 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4509 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4512 pic14_emitcode("movlw","0x%x",t);
4513 pic14_emitcode("andwf","%s,w",
4514 aopGet(AOP(left),offset,FALSE,FALSE));
4515 pic14_emitcode("movwf","%s",
4516 aopGet(AOP(result),offset,FALSE,FALSE));
4518 emitpcode(POC_MOVLW, popGetLit(t));
4519 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4520 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4525 if (AOP_TYPE(left) == AOP_ACC) {
4526 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4527 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4529 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4530 pic14_emitcode("andwf","%s,w",
4531 aopGet(AOP(left),offset,FALSE,FALSE));
4532 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4533 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4535 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4536 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4542 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4543 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4544 freeAsmop(result,NULL,ic,TRUE);
4547 /*-----------------------------------------------------------------*/
4548 /* genOr - code for or */
4549 /*-----------------------------------------------------------------*/
4550 static void genOr (iCode *ic, iCode *ifx)
4552 operand *left, *right, *result;
4554 unsigned long lit = 0L;
4556 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4558 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4559 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4560 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4563 /* if left is a literal & right is not then exchange them */
4564 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4565 AOP_NEEDSACC(left)) {
4566 operand *tmp = right ;
4571 /* if result = right then exchange them */
4572 if(pic14_sameRegs(AOP(result),AOP(right))){
4573 operand *tmp = right ;
4578 /* if right is bit then exchange them */
4579 if (AOP_TYPE(right) == AOP_CRY &&
4580 AOP_TYPE(left) != AOP_CRY){
4581 operand *tmp = right ;
4586 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4587 AopType(AOP_TYPE(result)),
4588 AopType(AOP_TYPE(left)),
4589 AopType(AOP_TYPE(right)));
4591 if(AOP_TYPE(right) == AOP_LIT)
4592 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4594 size = AOP_SIZE(result);
4598 if (AOP_TYPE(left) == AOP_CRY){
4599 if(AOP_TYPE(right) == AOP_LIT){
4600 // c = bit & literal;
4602 // lit != 0 => result = 1
4603 if(AOP_TYPE(result) == AOP_CRY){
4605 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4606 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4607 // AOP(result)->aopu.aop_dir,
4608 // AOP(result)->aopu.aop_dir);
4610 continueIfTrue(ifx);
4614 // lit == 0 => result = left
4615 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4617 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4620 if (AOP_TYPE(right) == AOP_CRY){
4621 if(pic14_sameRegs(AOP(result),AOP(left))){
4623 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4624 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4625 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4627 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4628 AOP(result)->aopu.aop_dir,
4629 AOP(result)->aopu.aop_dir);
4630 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4631 AOP(right)->aopu.aop_dir,
4632 AOP(right)->aopu.aop_dir);
4633 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4634 AOP(result)->aopu.aop_dir,
4635 AOP(result)->aopu.aop_dir);
4637 if( AOP_TYPE(result) == AOP_ACC) {
4638 emitpcode(POC_MOVLW, popGetLit(0));
4639 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4640 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4641 emitpcode(POC_MOVLW, popGetLit(1));
4645 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4646 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4647 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4648 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4650 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4651 AOP(result)->aopu.aop_dir,
4652 AOP(result)->aopu.aop_dir);
4653 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4654 AOP(right)->aopu.aop_dir,
4655 AOP(right)->aopu.aop_dir);
4656 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4657 AOP(left)->aopu.aop_dir,
4658 AOP(left)->aopu.aop_dir);
4659 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4660 AOP(result)->aopu.aop_dir,
4661 AOP(result)->aopu.aop_dir);
4666 symbol *tlbl = newiTempLabel(NULL);
4667 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4670 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4671 if( AOP_TYPE(right) == AOP_ACC) {
4672 emitpcode(POC_IORLW, popGetLit(0));
4674 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4675 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4680 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4681 pic14_emitcode(";XXX setb","c");
4682 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4683 AOP(left)->aopu.aop_dir,tlbl->key+100);
4684 pic14_toBoolean(right);
4685 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4686 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4687 jmpTrueOrFalse(ifx, tlbl);
4691 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4698 pic14_outBitC(result);
4700 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4701 genIfxJump(ifx, "c");
4705 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4706 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4707 if((AOP_TYPE(right) == AOP_LIT) &&
4708 (AOP_TYPE(result) == AOP_CRY) &&
4709 (AOP_TYPE(left) != AOP_CRY)){
4711 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4714 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4716 continueIfTrue(ifx);
4719 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4720 // lit = 0, result = boolean(left)
4722 pic14_emitcode(";XXX setb","c");
4723 pic14_toBoolean(right);
4725 symbol *tlbl = newiTempLabel(NULL);
4726 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4728 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4730 genIfxJump (ifx,"a");
4734 pic14_outBitC(result);
4738 /* if left is same as result */
4739 if(pic14_sameRegs(AOP(result),AOP(left))){
4741 for(;size--; offset++,lit>>=8) {
4742 if(AOP_TYPE(right) == AOP_LIT){
4743 if((lit & 0xff) == 0)
4744 /* or'ing with 0 has no effect */
4747 int p = my_powof2(lit & 0xff);
4749 /* only one bit is set in the literal, so use a bsf instruction */
4751 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4753 if(know_W != (lit & 0xff))
4754 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4755 know_W = lit & 0xff;
4756 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4761 if (AOP_TYPE(left) == AOP_ACC) {
4762 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4763 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4765 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4766 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4768 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4769 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4775 // left & result in different registers
4776 if(AOP_TYPE(result) == AOP_CRY){
4778 // if(size), result in bit
4779 // if(!size && ifx), conditional oper: if(left | right)
4780 symbol *tlbl = newiTempLabel(NULL);
4781 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4782 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4786 pic14_emitcode(";XXX setb","c");
4788 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4789 pic14_emitcode(";XXX orl","a,%s",
4790 aopGet(AOP(left),offset,FALSE,FALSE));
4791 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4796 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4797 pic14_outBitC(result);
4799 jmpTrueOrFalse(ifx, tlbl);
4800 } else for(;(size--);offset++){
4802 // result = left & right
4803 if(AOP_TYPE(right) == AOP_LIT){
4804 int t = (lit >> (offset*8)) & 0x0FFL;
4807 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4808 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4810 pic14_emitcode("movf","%s,w",
4811 aopGet(AOP(left),offset,FALSE,FALSE));
4812 pic14_emitcode("movwf","%s",
4813 aopGet(AOP(result),offset,FALSE,FALSE));
4816 emitpcode(POC_MOVLW, popGetLit(t));
4817 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4818 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4820 pic14_emitcode("movlw","0x%x",t);
4821 pic14_emitcode("iorwf","%s,w",
4822 aopGet(AOP(left),offset,FALSE,FALSE));
4823 pic14_emitcode("movwf","%s",
4824 aopGet(AOP(result),offset,FALSE,FALSE));
4830 // faster than result <- left, anl result,right
4831 // and better if result is SFR
4832 if (AOP_TYPE(left) == AOP_ACC) {
4833 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4834 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4836 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4837 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4839 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4840 pic14_emitcode("iorwf","%s,w",
4841 aopGet(AOP(left),offset,FALSE,FALSE));
4843 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4844 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4849 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4850 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4851 freeAsmop(result,NULL,ic,TRUE);
4854 /*-----------------------------------------------------------------*/
4855 /* genXor - code for xclusive or */
4856 /*-----------------------------------------------------------------*/
4857 static void genXor (iCode *ic, iCode *ifx)
4859 operand *left, *right, *result;
4861 unsigned long lit = 0L;
4863 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4865 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4866 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4867 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4869 /* if left is a literal & right is not ||
4870 if left needs acc & right does not */
4871 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4872 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4873 operand *tmp = right ;
4878 /* if result = right then exchange them */
4879 if(pic14_sameRegs(AOP(result),AOP(right))){
4880 operand *tmp = right ;
4885 /* if right is bit then exchange them */
4886 if (AOP_TYPE(right) == AOP_CRY &&
4887 AOP_TYPE(left) != AOP_CRY){
4888 operand *tmp = right ;
4892 if(AOP_TYPE(right) == AOP_LIT)
4893 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4895 size = AOP_SIZE(result);
4899 if (AOP_TYPE(left) == AOP_CRY){
4900 if(AOP_TYPE(right) == AOP_LIT){
4901 // c = bit & literal;
4903 // lit>>1 != 0 => result = 1
4904 if(AOP_TYPE(result) == AOP_CRY){
4906 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4908 continueIfTrue(ifx);
4911 pic14_emitcode("setb","c");
4915 // lit == 0, result = left
4916 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4918 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4920 // lit == 1, result = not(left)
4921 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4922 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4925 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4926 pic14_emitcode("cpl","c");
4933 symbol *tlbl = newiTempLabel(NULL);
4934 if (AOP_TYPE(right) == AOP_CRY){
4936 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4939 int sizer = AOP_SIZE(right);
4941 // if val>>1 != 0, result = 1
4942 pic14_emitcode("setb","c");
4944 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4946 // test the msb of the lsb
4947 pic14_emitcode("anl","a,#0xfe");
4948 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4952 pic14_emitcode("rrc","a");
4954 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4955 pic14_emitcode("cpl","c");
4956 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4961 pic14_outBitC(result);
4963 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4964 genIfxJump(ifx, "c");
4968 if(pic14_sameRegs(AOP(result),AOP(left))){
4969 /* if left is same as result */
4970 for(;size--; offset++) {
4971 if(AOP_TYPE(right) == AOP_LIT){
4972 int t = (lit >> (offset*8)) & 0x0FFL;
4976 if (IS_AOP_PREG(left)) {
4977 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4978 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4979 aopPut(AOP(result),"a",offset);
4981 emitpcode(POC_MOVLW, popGetLit(t));
4982 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
4983 pic14_emitcode("xrl","%s,%s",
4984 aopGet(AOP(left),offset,FALSE,TRUE),
4985 aopGet(AOP(right),offset,FALSE,FALSE));
4988 if (AOP_TYPE(left) == AOP_ACC)
4989 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4991 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4992 if (IS_AOP_PREG(left)) {
4993 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4994 aopPut(AOP(result),"a",offset);
4996 pic14_emitcode("xrl","%s,a",
4997 aopGet(AOP(left),offset,FALSE,TRUE));
5002 // left & result in different registers
5003 if(AOP_TYPE(result) == AOP_CRY){
5005 // if(size), result in bit
5006 // if(!size && ifx), conditional oper: if(left ^ right)
5007 symbol *tlbl = newiTempLabel(NULL);
5008 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5010 pic14_emitcode("setb","c");
5012 if((AOP_TYPE(right) == AOP_LIT) &&
5013 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5014 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5016 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5017 pic14_emitcode("xrl","a,%s",
5018 aopGet(AOP(left),offset,FALSE,FALSE));
5020 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5025 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5026 pic14_outBitC(result);
5028 jmpTrueOrFalse(ifx, tlbl);
5029 } else for(;(size--);offset++){
5031 // result = left & right
5032 if(AOP_TYPE(right) == AOP_LIT){
5033 int t = (lit >> (offset*8)) & 0x0FFL;
5036 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5037 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5038 pic14_emitcode("movf","%s,w",
5039 aopGet(AOP(left),offset,FALSE,FALSE));
5040 pic14_emitcode("movwf","%s",
5041 aopGet(AOP(result),offset,FALSE,FALSE));
5044 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5045 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5046 pic14_emitcode("comf","%s,w",
5047 aopGet(AOP(left),offset,FALSE,FALSE));
5048 pic14_emitcode("movwf","%s",
5049 aopGet(AOP(result),offset,FALSE,FALSE));
5052 emitpcode(POC_MOVLW, popGetLit(t));
5053 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5054 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5055 pic14_emitcode("movlw","0x%x",t);
5056 pic14_emitcode("xorwf","%s,w",
5057 aopGet(AOP(left),offset,FALSE,FALSE));
5058 pic14_emitcode("movwf","%s",
5059 aopGet(AOP(result),offset,FALSE,FALSE));
5065 // faster than result <- left, anl result,right
5066 // and better if result is SFR
5067 if (AOP_TYPE(left) == AOP_ACC) {
5068 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5069 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5071 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5072 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5073 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5074 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5076 if ( AOP_TYPE(result) != AOP_ACC){
5077 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5078 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5084 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5085 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5086 freeAsmop(result,NULL,ic,TRUE);
5089 /*-----------------------------------------------------------------*/
5090 /* genInline - write the inline code out */
5091 /*-----------------------------------------------------------------*/
5092 static void genInline (iCode *ic)
5094 char *buffer, *bp, *bp1;
5096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5098 _G.inLine += (!options.asmpeep);
5100 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5101 strcpy(buffer,IC_INLINE(ic));
5103 /* emit each line as a code */
5107 pic14_emitcode(bp1,"");
5114 pic14_emitcode(bp1,"");
5121 pic14_emitcode(bp1,"");
5122 /* pic14_emitcode("",buffer); */
5123 _G.inLine -= (!options.asmpeep);
5126 /*-----------------------------------------------------------------*/
5127 /* genRRC - rotate right with carry */
5128 /*-----------------------------------------------------------------*/
5129 static void genRRC (iCode *ic)
5131 operand *left , *result ;
5132 int size, offset = 0;
5135 /* rotate right with carry */
5137 result=IC_RESULT(ic);
5138 aopOp (left,ic,FALSE);
5139 aopOp (result,ic,FALSE);
5141 /* move it to the result */
5142 size = AOP_SIZE(result);
5146 l = aopGet(AOP(left),offset,FALSE,FALSE);
5148 pic14_emitcode("rrc","a");
5149 if (AOP_SIZE(result) > 1)
5150 aopPut(AOP(result),"a",offset--);
5152 /* now we need to put the carry into the
5153 highest order byte of the result */
5154 if (AOP_SIZE(result) > 1) {
5155 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5158 pic14_emitcode("mov","acc.7,c");
5159 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5160 freeAsmop(left,NULL,ic,TRUE);
5161 freeAsmop(result,NULL,ic,TRUE);
5164 /*-----------------------------------------------------------------*/
5165 /* genRLC - generate code for rotate left with carry */
5166 /*-----------------------------------------------------------------*/
5167 static void genRLC (iCode *ic)
5169 operand *left , *result ;
5170 int size, offset = 0;
5173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5174 /* rotate right with carry */
5176 result=IC_RESULT(ic);
5177 aopOp (left,ic,FALSE);
5178 aopOp (result,ic,FALSE);
5180 /* move it to the result */
5181 size = AOP_SIZE(result);
5184 l = aopGet(AOP(left),offset,FALSE,FALSE);
5186 pic14_emitcode("add","a,acc");
5187 if (AOP_SIZE(result) > 1)
5188 aopPut(AOP(result),"a",offset++);
5190 l = aopGet(AOP(left),offset,FALSE,FALSE);
5192 pic14_emitcode("rlc","a");
5193 if (AOP_SIZE(result) > 1)
5194 aopPut(AOP(result),"a",offset++);
5197 /* now we need to put the carry into the
5198 highest order byte of the result */
5199 if (AOP_SIZE(result) > 1) {
5200 l = aopGet(AOP(result),0,FALSE,FALSE);
5203 pic14_emitcode("mov","acc.0,c");
5204 aopPut(AOP(result),"a",0);
5205 freeAsmop(left,NULL,ic,TRUE);
5206 freeAsmop(result,NULL,ic,TRUE);
5209 /*-----------------------------------------------------------------*/
5210 /* genGetHbit - generates code get highest order bit */
5211 /*-----------------------------------------------------------------*/
5212 static void genGetHbit (iCode *ic)
5214 operand *left, *result;
5216 result=IC_RESULT(ic);
5217 aopOp (left,ic,FALSE);
5218 aopOp (result,ic,FALSE);
5220 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5221 /* get the highest order byte into a */
5222 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5223 if(AOP_TYPE(result) == AOP_CRY){
5224 pic14_emitcode("rlc","a");
5225 pic14_outBitC(result);
5228 pic14_emitcode("rl","a");
5229 pic14_emitcode("anl","a,#0x01");
5230 pic14_outAcc(result);
5234 freeAsmop(left,NULL,ic,TRUE);
5235 freeAsmop(result,NULL,ic,TRUE);
5238 /*-----------------------------------------------------------------*/
5239 /* AccRol - rotate left accumulator by known count */
5240 /*-----------------------------------------------------------------*/
5241 static void AccRol (int shCount)
5243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5244 shCount &= 0x0007; // shCount : 0..7
5249 pic14_emitcode("rl","a");
5252 pic14_emitcode("rl","a");
5253 pic14_emitcode("rl","a");
5256 pic14_emitcode("swap","a");
5257 pic14_emitcode("rr","a");
5260 pic14_emitcode("swap","a");
5263 pic14_emitcode("swap","a");
5264 pic14_emitcode("rl","a");
5267 pic14_emitcode("rr","a");
5268 pic14_emitcode("rr","a");
5271 pic14_emitcode("rr","a");
5276 /*-----------------------------------------------------------------*/
5277 /* AccLsh - left shift accumulator by known count */
5278 /*-----------------------------------------------------------------*/
5279 static void AccLsh (int shCount)
5281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5284 pic14_emitcode("add","a,acc");
5287 pic14_emitcode("add","a,acc");
5288 pic14_emitcode("add","a,acc");
5290 /* rotate left accumulator */
5292 /* and kill the lower order bits */
5293 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5298 /*-----------------------------------------------------------------*/
5299 /* AccRsh - right shift accumulator by known count */
5300 /*-----------------------------------------------------------------*/
5301 static void AccRsh (int shCount)
5303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5307 pic14_emitcode("rrc","a");
5309 /* rotate right accumulator */
5310 AccRol(8 - shCount);
5311 /* and kill the higher order bits */
5312 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5318 /*-----------------------------------------------------------------*/
5319 /* AccSRsh - signed right shift accumulator by known count */
5320 /*-----------------------------------------------------------------*/
5321 static void AccSRsh (int shCount)
5324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5327 pic14_emitcode("mov","c,acc.7");
5328 pic14_emitcode("rrc","a");
5329 } else if(shCount == 2){
5330 pic14_emitcode("mov","c,acc.7");
5331 pic14_emitcode("rrc","a");
5332 pic14_emitcode("mov","c,acc.7");
5333 pic14_emitcode("rrc","a");
5335 tlbl = newiTempLabel(NULL);
5336 /* rotate right accumulator */
5337 AccRol(8 - shCount);
5338 /* and kill the higher order bits */
5339 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5340 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5341 pic14_emitcode("orl","a,#0x%02x",
5342 (unsigned char)~SRMask[shCount]);
5343 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5348 /*-----------------------------------------------------------------*/
5349 /* shiftR1Left2Result - shift right one byte from left to result */
5350 /*-----------------------------------------------------------------*/
5351 static void shiftR1Left2ResultSigned (operand *left, int offl,
5352 operand *result, int offr,
5357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5359 same = (left == result) || (AOP(left) == AOP(result));
5363 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5365 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5367 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5368 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5378 /*-----------------------------------------------------------------*/
5379 /* shiftR1Left2Result - shift right one byte from left to result */
5380 /*-----------------------------------------------------------------*/
5381 static void shiftR1Left2Result (operand *left, int offl,
5382 operand *result, int offr,
5383 int shCount, int sign)
5387 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5389 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5391 /* Copy the msb into the carry if signed. */
5393 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5403 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5405 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5406 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5412 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5414 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5415 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5418 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5423 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5425 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5426 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5429 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5430 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5431 emitpcode(POC_ANDLW, popGetLit(0x1f));
5432 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5436 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5437 emitpcode(POC_ANDLW, popGetLit(0x0f));
5438 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5442 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5443 emitpcode(POC_ANDLW, popGetLit(0x0f));
5444 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5446 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5451 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5452 emitpcode(POC_ANDLW, popGetLit(0x80));
5453 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5454 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5455 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5460 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5461 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5462 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5473 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5475 /* shift right accumulator */
5480 aopPut(AOP(result),"a",offr);
5484 /*-----------------------------------------------------------------*/
5485 /* shiftL1Left2Result - shift left one byte from left to result */
5486 /*-----------------------------------------------------------------*/
5487 static void shiftL1Left2Result (operand *left, int offl,
5488 operand *result, int offr, int shCount)
5493 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5495 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5496 DEBUGpic14_emitcode ("; ***","same = %d",same);
5497 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5499 /* shift left accumulator */
5500 //AccLsh(shCount); // don't comment out just yet...
5501 // aopPut(AOP(result),"a",offr);
5505 /* Shift left 1 bit position */
5506 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5508 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5510 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5511 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5515 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5516 emitpcode(POC_ANDLW,popGetLit(0x7e));
5517 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5518 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5521 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5522 emitpcode(POC_ANDLW,popGetLit(0x3e));
5523 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5524 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5525 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5528 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5529 emitpcode(POC_ANDLW, popGetLit(0xf0));
5530 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5533 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5534 emitpcode(POC_ANDLW, popGetLit(0xf0));
5535 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5536 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5539 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5540 emitpcode(POC_ANDLW, popGetLit(0x30));
5541 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5542 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5543 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5546 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5547 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5548 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5552 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5557 /*-----------------------------------------------------------------*/
5558 /* movLeft2Result - move byte from left to result */
5559 /*-----------------------------------------------------------------*/
5560 static void movLeft2Result (operand *left, int offl,
5561 operand *result, int offr, int sign)
5564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5565 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5566 l = aopGet(AOP(left),offl,FALSE,FALSE);
5568 if (*l == '@' && (IS_AOP_PREG(result))) {
5569 pic14_emitcode("mov","a,%s",l);
5570 aopPut(AOP(result),"a",offr);
5573 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5574 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5576 //aopPut(AOP(result),l,offr);
5578 /* MSB sign in acc.7 ! */
5579 if(pic14_getDataSize(left) == offl+1){
5580 pic14_emitcode("mov","a,%s",l);
5581 aopPut(AOP(result),"a",offr);
5588 /*-----------------------------------------------------------------*/
5589 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5590 /*-----------------------------------------------------------------*/
5591 static void AccAXRrl1 (char *x)
5593 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5594 pic14_emitcode("rrc","a");
5595 pic14_emitcode("xch","a,%s", x);
5596 pic14_emitcode("rrc","a");
5597 pic14_emitcode("xch","a,%s", x);
5600 /*-----------------------------------------------------------------*/
5601 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5602 /*-----------------------------------------------------------------*/
5603 static void AccAXLrl1 (char *x)
5605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5606 pic14_emitcode("xch","a,%s",x);
5607 pic14_emitcode("rlc","a");
5608 pic14_emitcode("xch","a,%s",x);
5609 pic14_emitcode("rlc","a");
5612 /*-----------------------------------------------------------------*/
5613 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5614 /*-----------------------------------------------------------------*/
5615 static void AccAXLsh1 (char *x)
5617 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5618 pic14_emitcode("xch","a,%s",x);
5619 pic14_emitcode("add","a,acc");
5620 pic14_emitcode("xch","a,%s",x);
5621 pic14_emitcode("rlc","a");
5625 /*-----------------------------------------------------------------*/
5626 /* AccAXLsh - left shift a:x by known count (0..7) */
5627 /*-----------------------------------------------------------------*/
5628 static void AccAXLsh (char *x, int shCount)
5630 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5643 case 5 : // AAAAABBB:CCCCCDDD
5644 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5645 pic14_emitcode("anl","a,#0x%02x",
5646 SLMask[shCount]); // BBB00000:CCCCCDDD
5647 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5648 AccRol(shCount); // DDDCCCCC:BBB00000
5649 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5650 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5651 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5652 pic14_emitcode("anl","a,#0x%02x",
5653 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5654 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5655 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5657 case 6 : // AAAAAABB:CCCCCCDD
5658 pic14_emitcode("anl","a,#0x%02x",
5659 SRMask[shCount]); // 000000BB:CCCCCCDD
5660 pic14_emitcode("mov","c,acc.0"); // c = B
5661 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5662 AccAXRrl1(x); // BCCCCCCD:D000000B
5663 AccAXRrl1(x); // BBCCCCCC:DD000000
5665 case 7 : // a:x <<= 7
5666 pic14_emitcode("anl","a,#0x%02x",
5667 SRMask[shCount]); // 0000000B:CCCCCCCD
5668 pic14_emitcode("mov","c,acc.0"); // c = B
5669 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5670 AccAXRrl1(x); // BCCCCCCC:D0000000
5678 /*-----------------------------------------------------------------*/
5679 /* AccAXRsh - right shift a:x known count (0..7) */
5680 /*-----------------------------------------------------------------*/
5681 static void AccAXRsh (char *x, int shCount)
5683 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5689 AccAXRrl1(x); // 0->a:x
5693 AccAXRrl1(x); // 0->a:x
5695 AccAXRrl1(x); // 0->a:x
5699 case 5 : // AAAAABBB:CCCCCDDD = a:x
5700 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5701 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5702 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5703 pic14_emitcode("anl","a,#0x%02x",
5704 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5705 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5706 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5707 pic14_emitcode("anl","a,#0x%02x",
5708 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5709 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5710 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5711 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5713 case 6 : // AABBBBBB:CCDDDDDD
5714 pic14_emitcode("mov","c,acc.7");
5715 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5716 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5717 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5718 pic14_emitcode("anl","a,#0x%02x",
5719 SRMask[shCount]); // 000000AA:BBBBBBCC
5721 case 7 : // ABBBBBBB:CDDDDDDD
5722 pic14_emitcode("mov","c,acc.7"); // c = A
5723 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5724 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5725 pic14_emitcode("anl","a,#0x%02x",
5726 SRMask[shCount]); // 0000000A:BBBBBBBC
5733 /*-----------------------------------------------------------------*/
5734 /* AccAXRshS - right shift signed a:x known count (0..7) */
5735 /*-----------------------------------------------------------------*/
5736 static void AccAXRshS (char *x, int shCount)
5739 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5744 pic14_emitcode("mov","c,acc.7");
5745 AccAXRrl1(x); // s->a:x
5748 pic14_emitcode("mov","c,acc.7");
5749 AccAXRrl1(x); // s->a:x
5750 pic14_emitcode("mov","c,acc.7");
5751 AccAXRrl1(x); // s->a:x
5755 case 5 : // AAAAABBB:CCCCCDDD = a:x
5756 tlbl = newiTempLabel(NULL);
5757 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5758 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5759 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5760 pic14_emitcode("anl","a,#0x%02x",
5761 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5762 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5763 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5764 pic14_emitcode("anl","a,#0x%02x",
5765 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5766 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5767 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5768 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5769 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5770 pic14_emitcode("orl","a,#0x%02x",
5771 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5772 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5773 break; // SSSSAAAA:BBBCCCCC
5774 case 6 : // AABBBBBB:CCDDDDDD
5775 tlbl = newiTempLabel(NULL);
5776 pic14_emitcode("mov","c,acc.7");
5777 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5778 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5779 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5780 pic14_emitcode("anl","a,#0x%02x",
5781 SRMask[shCount]); // 000000AA:BBBBBBCC
5782 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5783 pic14_emitcode("orl","a,#0x%02x",
5784 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5785 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5787 case 7 : // ABBBBBBB:CDDDDDDD
5788 tlbl = newiTempLabel(NULL);
5789 pic14_emitcode("mov","c,acc.7"); // c = A
5790 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5791 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5792 pic14_emitcode("anl","a,#0x%02x",
5793 SRMask[shCount]); // 0000000A:BBBBBBBC
5794 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5795 pic14_emitcode("orl","a,#0x%02x",
5796 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5797 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5804 /*-----------------------------------------------------------------*/
5805 /* shiftL2Left2Result - shift left two bytes from left to result */
5806 /*-----------------------------------------------------------------*/
5807 static void shiftL2Left2Result (operand *left, int offl,
5808 operand *result, int offr, int shCount)
5812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5814 if(pic14_sameRegs(AOP(result), AOP(left))) {
5822 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5823 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5824 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5828 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5829 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5835 emitpcode(POC_MOVLW, popGetLit(0x0f));
5836 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5837 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5838 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5839 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5840 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5841 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5843 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5844 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5848 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5849 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5850 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5851 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5852 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5853 emitpcode(POC_ANDLW,popGetLit(0xc0));
5854 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5855 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5856 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5857 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5860 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5861 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5862 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5863 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5864 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5874 /* note, use a mov/add for the shift since the mov has a
5875 chance of getting optimized out */
5876 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5877 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5878 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5879 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5880 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5884 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5885 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5891 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5892 emitpcode(POC_ANDLW, popGetLit(0xF0));
5893 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5894 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5895 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5896 emitpcode(POC_ANDLW, popGetLit(0xF0));
5897 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5898 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5902 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5903 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5907 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5908 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5909 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5910 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5912 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5913 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5914 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5915 emitpcode(POC_ANDLW,popGetLit(0xc0));
5916 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5917 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5918 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5919 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5922 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5923 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5924 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5925 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5926 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5931 /*-----------------------------------------------------------------*/
5932 /* shiftR2Left2Result - shift right two bytes from left to result */
5933 /*-----------------------------------------------------------------*/
5934 static void shiftR2Left2Result (operand *left, int offl,
5935 operand *result, int offr,
5936 int shCount, int sign)
5940 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5941 same = pic14_sameRegs(AOP(result), AOP(left));
5943 if(same && ((offl + MSB16) == offr)){
5945 /* don't crash result[offr] */
5946 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5947 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5949 movLeft2Result(left,offl, result, offr, 0);
5950 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5952 /* a:x >> shCount (x = lsb(result))*/
5954 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5956 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5966 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5967 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5970 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5971 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5972 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5973 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5978 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5979 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5986 emitpcode(POC_MOVLW, popGetLit(0xf0));
5987 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5988 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5990 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5991 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5992 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5993 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5995 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5996 emitpcode(POC_ANDLW, popGetLit(0x0f));
5997 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5999 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6000 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6001 emitpcode(POC_ANDLW, popGetLit(0xf0));
6002 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6003 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6007 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6008 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6016 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6017 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6019 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6020 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6021 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6022 emitpcode(POC_ANDLW,popGetLit(0x03));
6023 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6024 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6025 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6026 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6028 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6029 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6030 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6031 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6032 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6033 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6034 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6035 emitpcode(POC_ANDLW,popGetLit(0x03));
6036 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6041 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6042 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6043 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6044 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6045 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6050 /*-----------------------------------------------------------------*/
6051 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6052 /*-----------------------------------------------------------------*/
6053 static void shiftLLeftOrResult (operand *left, int offl,
6054 operand *result, int offr, int shCount)
6056 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6057 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6058 /* shift left accumulator */
6060 /* or with result */
6061 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6062 /* back to result */
6063 aopPut(AOP(result),"a",offr);
6066 /*-----------------------------------------------------------------*/
6067 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6068 /*-----------------------------------------------------------------*/
6069 static void shiftRLeftOrResult (operand *left, int offl,
6070 operand *result, int offr, int shCount)
6072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6073 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6074 /* shift right accumulator */
6076 /* or with result */
6077 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6078 /* back to result */
6079 aopPut(AOP(result),"a",offr);
6082 /*-----------------------------------------------------------------*/
6083 /* genlshOne - left shift a one byte quantity by known count */
6084 /*-----------------------------------------------------------------*/
6085 static void genlshOne (operand *result, operand *left, int shCount)
6087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6088 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6091 /*-----------------------------------------------------------------*/
6092 /* genlshTwo - left shift two bytes by known amount != 0 */
6093 /*-----------------------------------------------------------------*/
6094 static void genlshTwo (operand *result,operand *left, int shCount)
6098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6099 size = pic14_getDataSize(result);
6101 /* if shCount >= 8 */
6107 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6109 movLeft2Result(left, LSB, result, MSB16, 0);
6111 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6114 /* 1 <= shCount <= 7 */
6117 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6119 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6123 /*-----------------------------------------------------------------*/
6124 /* shiftLLong - shift left one long from left to result */
6125 /* offl = LSB or MSB16 */
6126 /*-----------------------------------------------------------------*/
6127 static void shiftLLong (operand *left, operand *result, int offr )
6130 int size = AOP_SIZE(result);
6132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6133 if(size >= LSB+offr){
6134 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6136 pic14_emitcode("add","a,acc");
6137 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6138 size >= MSB16+offr && offr != LSB )
6139 pic14_emitcode("xch","a,%s",
6140 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6142 aopPut(AOP(result),"a",LSB+offr);
6145 if(size >= MSB16+offr){
6146 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6147 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6150 pic14_emitcode("rlc","a");
6151 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6152 size >= MSB24+offr && offr != LSB)
6153 pic14_emitcode("xch","a,%s",
6154 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6156 aopPut(AOP(result),"a",MSB16+offr);
6159 if(size >= MSB24+offr){
6160 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6161 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6164 pic14_emitcode("rlc","a");
6165 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6166 size >= MSB32+offr && offr != LSB )
6167 pic14_emitcode("xch","a,%s",
6168 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6170 aopPut(AOP(result),"a",MSB24+offr);
6173 if(size > MSB32+offr){
6174 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6175 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6178 pic14_emitcode("rlc","a");
6179 aopPut(AOP(result),"a",MSB32+offr);
6182 aopPut(AOP(result),zero,LSB);
6185 /*-----------------------------------------------------------------*/
6186 /* genlshFour - shift four byte by a known amount != 0 */
6187 /*-----------------------------------------------------------------*/
6188 static void genlshFour (operand *result, operand *left, int shCount)
6192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6193 size = AOP_SIZE(result);
6195 /* if shifting more that 3 bytes */
6196 if (shCount >= 24 ) {
6199 /* lowest order of left goes to the highest
6200 order of the destination */
6201 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6203 movLeft2Result(left, LSB, result, MSB32, 0);
6204 aopPut(AOP(result),zero,LSB);
6205 aopPut(AOP(result),zero,MSB16);
6206 aopPut(AOP(result),zero,MSB32);
6210 /* more than two bytes */
6211 else if ( shCount >= 16 ) {
6212 /* lower order two bytes goes to higher order two bytes */
6214 /* if some more remaining */
6216 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6218 movLeft2Result(left, MSB16, result, MSB32, 0);
6219 movLeft2Result(left, LSB, result, MSB24, 0);
6221 aopPut(AOP(result),zero,MSB16);
6222 aopPut(AOP(result),zero,LSB);
6226 /* if more than 1 byte */
6227 else if ( shCount >= 8 ) {
6228 /* lower order three bytes goes to higher order three bytes */
6232 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6234 movLeft2Result(left, LSB, result, MSB16, 0);
6236 else{ /* size = 4 */
6238 movLeft2Result(left, MSB24, result, MSB32, 0);
6239 movLeft2Result(left, MSB16, result, MSB24, 0);
6240 movLeft2Result(left, LSB, result, MSB16, 0);
6241 aopPut(AOP(result),zero,LSB);
6243 else if(shCount == 1)
6244 shiftLLong(left, result, MSB16);
6246 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6247 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6248 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6249 aopPut(AOP(result),zero,LSB);
6254 /* 1 <= shCount <= 7 */
6255 else if(shCount <= 2){
6256 shiftLLong(left, result, LSB);
6258 shiftLLong(result, result, LSB);
6260 /* 3 <= shCount <= 7, optimize */
6262 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6263 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6264 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6268 /*-----------------------------------------------------------------*/
6269 /* genLeftShiftLiteral - left shifting by known count */
6270 /*-----------------------------------------------------------------*/
6271 static void genLeftShiftLiteral (operand *left,
6276 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6280 freeAsmop(right,NULL,ic,TRUE);
6282 aopOp(left,ic,FALSE);
6283 aopOp(result,ic,FALSE);
6285 size = getSize(operandType(result));
6288 pic14_emitcode("; shift left ","result %d, left %d",size,
6292 /* I suppose that the left size >= result size */
6295 movLeft2Result(left, size, result, size, 0);
6299 else if(shCount >= (size * 8))
6301 aopPut(AOP(result),zero,size);
6305 genlshOne (result,left,shCount);
6310 genlshTwo (result,left,shCount);
6314 genlshFour (result,left,shCount);
6318 freeAsmop(left,NULL,ic,TRUE);
6319 freeAsmop(result,NULL,ic,TRUE);
6322 /*-----------------------------------------------------------------*/
6323 /* genLeftShift - generates code for left shifting */
6324 /*-----------------------------------------------------------------*/
6325 static void genLeftShift (iCode *ic)
6327 operand *left,*right, *result;
6330 symbol *tlbl , *tlbl1;
6332 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6334 right = IC_RIGHT(ic);
6336 result = IC_RESULT(ic);
6338 aopOp(right,ic,FALSE);
6340 /* if the shift count is known then do it
6341 as efficiently as possible */
6342 if (AOP_TYPE(right) == AOP_LIT) {
6343 genLeftShiftLiteral (left,right,result,ic);
6347 /* shift count is unknown then we have to form
6348 a loop get the loop count in B : Note: we take
6349 only the lower order byte since shifting
6350 more that 32 bits make no sense anyway, ( the
6351 largest size of an object can be only 32 bits ) */
6354 aopOp(left,ic,FALSE);
6355 aopOp(result,ic,FALSE);
6357 /* now move the left to the result if they are not the
6359 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6360 AOP_SIZE(result) > 1) {
6362 size = AOP_SIZE(result);
6365 l = aopGet(AOP(left),offset,FALSE,TRUE);
6366 if (*l == '@' && (IS_AOP_PREG(result))) {
6368 pic14_emitcode("mov","a,%s",l);
6369 aopPut(AOP(result),"a",offset);
6371 aopPut(AOP(result),l,offset);
6376 size = AOP_SIZE(result);
6378 /* if it is only one byte then */
6380 if(optimized_for_speed) {
6381 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6382 emitpcode(POC_ANDLW, popGetLit(0xf0));
6383 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6384 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6385 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6386 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6387 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6388 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6389 emitpcode(POC_ANDLW, popGetLit(0xfe));
6390 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6391 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6392 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6395 tlbl = newiTempLabel(NULL);
6396 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6397 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6398 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6401 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6402 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6403 emitpLabel(tlbl->key);
6404 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6405 emitpcode(POC_ADDLW, popGetLit(1));
6407 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6413 tlbl = newiTempLabel(NULL);
6415 tlbl1 = newiTempLabel(NULL);
6417 reAdjustPreg(AOP(result));
6419 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6420 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6421 l = aopGet(AOP(result),offset,FALSE,FALSE);
6423 pic14_emitcode("add","a,acc");
6424 aopPut(AOP(result),"a",offset++);
6426 l = aopGet(AOP(result),offset,FALSE,FALSE);
6428 pic14_emitcode("rlc","a");
6429 aopPut(AOP(result),"a",offset++);
6431 reAdjustPreg(AOP(result));
6433 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6434 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6436 freeAsmop (right,NULL,ic,TRUE);
6437 freeAsmop(left,NULL,ic,TRUE);
6438 freeAsmop(result,NULL,ic,TRUE);
6441 /*-----------------------------------------------------------------*/
6442 /* genrshOne - right shift a one byte quantity by known count */
6443 /*-----------------------------------------------------------------*/
6444 static void genrshOne (operand *result, operand *left,
6445 int shCount, int sign)
6447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6448 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6451 /*-----------------------------------------------------------------*/
6452 /* genrshTwo - right shift two bytes by known amount != 0 */
6453 /*-----------------------------------------------------------------*/
6454 static void genrshTwo (operand *result,operand *left,
6455 int shCount, int sign)
6457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6458 /* if shCount >= 8 */
6462 shiftR1Left2Result(left, MSB16, result, LSB,
6465 movLeft2Result(left, MSB16, result, LSB, sign);
6467 addSign(result, MSB16, sign);
6469 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6473 /* 1 <= shCount <= 7 */
6475 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6478 /*-----------------------------------------------------------------*/
6479 /* shiftRLong - shift right one long from left to result */
6480 /* offl = LSB or MSB16 */
6481 /*-----------------------------------------------------------------*/
6482 static void shiftRLong (operand *left, int offl,
6483 operand *result, int sign)
6485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6487 pic14_emitcode("clr","c");
6488 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6490 pic14_emitcode("mov","c,acc.7");
6491 pic14_emitcode("rrc","a");
6492 aopPut(AOP(result),"a",MSB32-offl);
6494 /* add sign of "a" */
6495 addSign(result, MSB32, sign);
6497 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6498 pic14_emitcode("rrc","a");
6499 aopPut(AOP(result),"a",MSB24-offl);
6501 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6502 pic14_emitcode("rrc","a");
6503 aopPut(AOP(result),"a",MSB16-offl);
6506 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6507 pic14_emitcode("rrc","a");
6508 aopPut(AOP(result),"a",LSB);
6512 /*-----------------------------------------------------------------*/
6513 /* genrshFour - shift four byte by a known amount != 0 */
6514 /*-----------------------------------------------------------------*/
6515 static void genrshFour (operand *result, operand *left,
6516 int shCount, int sign)
6518 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6519 /* if shifting more that 3 bytes */
6520 if(shCount >= 24 ) {
6523 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6525 movLeft2Result(left, MSB32, result, LSB, sign);
6526 addSign(result, MSB16, sign);
6528 else if(shCount >= 16){
6531 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6533 movLeft2Result(left, MSB24, result, LSB, 0);
6534 movLeft2Result(left, MSB32, result, MSB16, sign);
6536 addSign(result, MSB24, sign);
6538 else if(shCount >= 8){
6541 shiftRLong(left, MSB16, result, sign);
6542 else if(shCount == 0){
6543 movLeft2Result(left, MSB16, result, LSB, 0);
6544 movLeft2Result(left, MSB24, result, MSB16, 0);
6545 movLeft2Result(left, MSB32, result, MSB24, sign);
6546 addSign(result, MSB32, sign);
6549 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6550 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6551 /* the last shift is signed */
6552 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6553 addSign(result, MSB32, sign);
6556 else{ /* 1 <= shCount <= 7 */
6558 shiftRLong(left, LSB, result, sign);
6560 shiftRLong(result, LSB, result, sign);
6563 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6564 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6565 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6570 /*-----------------------------------------------------------------*/
6571 /* genRightShiftLiteral - right shifting by known count */
6572 /*-----------------------------------------------------------------*/
6573 static void genRightShiftLiteral (operand *left,
6579 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6582 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6583 freeAsmop(right,NULL,ic,TRUE);
6585 aopOp(left,ic,FALSE);
6586 aopOp(result,ic,FALSE);
6589 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6593 size = pic14_getDataSize(left);
6594 /* test the LEFT size !!! */
6596 /* I suppose that the left size >= result size */
6598 size = pic14_getDataSize(result);
6600 movLeft2Result(left, size, result, size, 0);
6603 else if(shCount >= (size * 8)){
6605 /* get sign in acc.7 */
6606 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6607 addSign(result, LSB, sign);
6611 genrshOne (result,left,shCount,sign);
6615 genrshTwo (result,left,shCount,sign);
6619 genrshFour (result,left,shCount,sign);
6625 freeAsmop(left,NULL,ic,TRUE);
6626 freeAsmop(result,NULL,ic,TRUE);
6630 /*-----------------------------------------------------------------*/
6631 /* genSignedRightShift - right shift of signed number */
6632 /*-----------------------------------------------------------------*/
6633 static void genSignedRightShift (iCode *ic)
6635 operand *right, *left, *result;
6638 symbol *tlbl, *tlbl1 ;
6640 /* we do it the hard way put the shift count in b
6641 and loop thru preserving the sign */
6642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6644 right = IC_RIGHT(ic);
6646 result = IC_RESULT(ic);
6648 aopOp(right,ic,FALSE);
6651 if ( AOP_TYPE(right) == AOP_LIT) {
6652 genRightShiftLiteral (left,right,result,ic,1);
6655 /* shift count is unknown then we have to form
6656 a loop get the loop count in B : Note: we take
6657 only the lower order byte since shifting
6658 more that 32 bits make no sense anyway, ( the
6659 largest size of an object can be only 32 bits ) */
6661 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6662 pic14_emitcode("inc","b");
6663 freeAsmop (right,NULL,ic,TRUE);
6664 aopOp(left,ic,FALSE);
6665 aopOp(result,ic,FALSE);
6667 /* now move the left to the result if they are not the
6669 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6670 AOP_SIZE(result) > 1) {
6672 size = AOP_SIZE(result);
6675 l = aopGet(AOP(left),offset,FALSE,TRUE);
6676 if (*l == '@' && IS_AOP_PREG(result)) {
6678 pic14_emitcode("mov","a,%s",l);
6679 aopPut(AOP(result),"a",offset);
6681 aopPut(AOP(result),l,offset);
6686 /* mov the highest order bit to OVR */
6687 tlbl = newiTempLabel(NULL);
6688 tlbl1= newiTempLabel(NULL);
6690 size = AOP_SIZE(result);
6692 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6693 pic14_emitcode("rlc","a");
6694 pic14_emitcode("mov","ov,c");
6695 /* if it is only one byte then */
6697 l = aopGet(AOP(left),0,FALSE,FALSE);
6699 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6700 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6701 pic14_emitcode("mov","c,ov");
6702 pic14_emitcode("rrc","a");
6703 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6704 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6705 aopPut(AOP(result),"a",0);
6709 reAdjustPreg(AOP(result));
6710 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6711 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6712 pic14_emitcode("mov","c,ov");
6714 l = aopGet(AOP(result),offset,FALSE,FALSE);
6716 pic14_emitcode("rrc","a");
6717 aopPut(AOP(result),"a",offset--);
6719 reAdjustPreg(AOP(result));
6720 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6721 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6724 freeAsmop(left,NULL,ic,TRUE);
6725 freeAsmop(result,NULL,ic,TRUE);
6728 /*-----------------------------------------------------------------*/
6729 /* genRightShift - generate code for right shifting */
6730 /*-----------------------------------------------------------------*/
6731 static void genRightShift (iCode *ic)
6733 operand *right, *left, *result;
6737 symbol *tlbl, *tlbl1 ;
6739 /* if signed then we do it the hard way preserve the
6740 sign bit moving it inwards */
6741 retype = getSpec(operandType(IC_RESULT(ic)));
6742 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6744 if (!SPEC_USIGN(retype)) {
6745 genSignedRightShift (ic);
6749 /* signed & unsigned types are treated the same : i.e. the
6750 signed is NOT propagated inwards : quoting from the
6751 ANSI - standard : "for E1 >> E2, is equivalent to division
6752 by 2**E2 if unsigned or if it has a non-negative value,
6753 otherwise the result is implementation defined ", MY definition
6754 is that the sign does not get propagated */
6756 right = IC_RIGHT(ic);
6758 result = IC_RESULT(ic);
6760 aopOp(right,ic,FALSE);
6762 /* if the shift count is known then do it
6763 as efficiently as possible */
6764 if (AOP_TYPE(right) == AOP_LIT) {
6765 genRightShiftLiteral (left,right,result,ic, 0);
6769 /* shift count is unknown then we have to form
6770 a loop get the loop count in B : Note: we take
6771 only the lower order byte since shifting
6772 more that 32 bits make no sense anyway, ( the
6773 largest size of an object can be only 32 bits ) */
6775 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6776 pic14_emitcode("inc","b");
6777 aopOp(left,ic,FALSE);
6778 aopOp(result,ic,FALSE);
6780 /* now move the left to the result if they are not the
6782 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6783 AOP_SIZE(result) > 1) {
6785 size = AOP_SIZE(result);
6788 l = aopGet(AOP(left),offset,FALSE,TRUE);
6789 if (*l == '@' && IS_AOP_PREG(result)) {
6791 pic14_emitcode("mov","a,%s",l);
6792 aopPut(AOP(result),"a",offset);
6794 aopPut(AOP(result),l,offset);
6799 tlbl = newiTempLabel(NULL);
6800 tlbl1= newiTempLabel(NULL);
6801 size = AOP_SIZE(result);
6804 /* if it is only one byte then */
6807 l = aopGet(AOP(left),0,FALSE,FALSE);
6809 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6810 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6812 pic14_emitcode("rrc","a");
6813 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6814 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6815 aopPut(AOP(result),"a",0);
6817 tlbl = newiTempLabel(NULL);
6818 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6819 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6820 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6823 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6824 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6825 emitpLabel(tlbl->key);
6826 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6827 emitpcode(POC_ADDLW, popGetLit(1));
6829 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6834 reAdjustPreg(AOP(result));
6835 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6836 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6839 l = aopGet(AOP(result),offset,FALSE,FALSE);
6841 pic14_emitcode("rrc","a");
6842 aopPut(AOP(result),"a",offset--);
6844 reAdjustPreg(AOP(result));
6846 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6847 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6850 freeAsmop(left,NULL,ic,TRUE);
6851 freeAsmop (right,NULL,ic,TRUE);
6852 freeAsmop(result,NULL,ic,TRUE);
6855 /*-----------------------------------------------------------------*/
6856 /* genUnpackBits - generates code for unpacking bits */
6857 /*-----------------------------------------------------------------*/
6858 static void genUnpackBits (operand *result, char *rname, int ptype)
6865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6866 etype = getSpec(operandType(result));
6868 /* read the first byte */
6873 pic14_emitcode("mov","a,@%s",rname);
6877 pic14_emitcode("movx","a,@%s",rname);
6881 pic14_emitcode("movx","a,@dptr");
6885 pic14_emitcode("clr","a");
6886 pic14_emitcode("movc","a","@a+dptr");
6890 pic14_emitcode("lcall","__gptrget");
6894 /* if we have bitdisplacement then it fits */
6895 /* into this byte completely or if length is */
6896 /* less than a byte */
6897 if ((shCnt = SPEC_BSTR(etype)) ||
6898 (SPEC_BLEN(etype) <= 8)) {
6900 /* shift right acc */
6903 pic14_emitcode("anl","a,#0x%02x",
6904 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6905 aopPut(AOP(result),"a",offset);
6909 /* bit field did not fit in a byte */
6910 rlen = SPEC_BLEN(etype) - 8;
6911 aopPut(AOP(result),"a",offset++);
6918 pic14_emitcode("inc","%s",rname);
6919 pic14_emitcode("mov","a,@%s",rname);
6923 pic14_emitcode("inc","%s",rname);
6924 pic14_emitcode("movx","a,@%s",rname);
6928 pic14_emitcode("inc","dptr");
6929 pic14_emitcode("movx","a,@dptr");
6933 pic14_emitcode("clr","a");
6934 pic14_emitcode("inc","dptr");
6935 pic14_emitcode("movc","a","@a+dptr");
6939 pic14_emitcode("inc","dptr");
6940 pic14_emitcode("lcall","__gptrget");
6945 /* if we are done */
6949 aopPut(AOP(result),"a",offset++);
6954 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6955 aopPut(AOP(result),"a",offset);
6962 /*-----------------------------------------------------------------*/
6963 /* genDataPointerGet - generates code when ptr offset is known */
6964 /*-----------------------------------------------------------------*/
6965 static void genDataPointerGet (operand *left,
6969 int size , offset = 0;
6972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6975 /* optimization - most of the time, left and result are the same
6976 * address, but different types. for the pic code, we could omit
6980 aopOp(result,ic,TRUE);
6982 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6984 size = AOP_SIZE(result);
6987 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6991 freeAsmop(left,NULL,ic,TRUE);
6992 freeAsmop(result,NULL,ic,TRUE);
6995 /*-----------------------------------------------------------------*/
6996 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6997 /*-----------------------------------------------------------------*/
6998 static void genNearPointerGet (operand *left,
7005 sym_link *rtype, *retype;
7006 sym_link *ltype = operandType(left);
7009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7011 rtype = operandType(result);
7012 retype= getSpec(rtype);
7014 aopOp(left,ic,FALSE);
7016 /* if left is rematerialisable and
7017 result is not bit variable type and
7018 the left is pointer to data space i.e
7019 lower 128 bytes of space */
7020 if (AOP_TYPE(left) == AOP_IMMD &&
7021 !IS_BITVAR(retype) &&
7022 DCL_TYPE(ltype) == POINTER) {
7023 genDataPointerGet (left,result,ic);
7027 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7029 /* if the value is already in a pointer register
7030 then don't need anything more */
7031 if (!AOP_INPREG(AOP(left))) {
7032 /* otherwise get a free pointer register */
7033 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7035 preg = getFreePtr(ic,&aop,FALSE);
7036 pic14_emitcode("mov","%s,%s",
7038 aopGet(AOP(left),0,FALSE,TRUE));
7039 rname = preg->name ;
7041 rname = aopGet(AOP(left),0,FALSE,FALSE);
7043 freeAsmop(left,NULL,ic,TRUE);
7044 aopOp (result,ic,FALSE);
7046 /* if bitfield then unpack the bits */
7047 if (IS_BITVAR(retype))
7048 genUnpackBits (result,rname,POINTER);
7050 /* we have can just get the values */
7051 int size = AOP_SIZE(result);
7054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7056 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7058 pic14_emitcode("mov","a,@%s",rname);
7059 aopPut(AOP(result),"a",offset);
7061 sprintf(buffer,"@%s",rname);
7062 aopPut(AOP(result),buffer,offset);
7066 pic14_emitcode("inc","%s",rname);
7070 /* now some housekeeping stuff */
7072 /* we had to allocate for this iCode */
7073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7074 freeAsmop(NULL,aop,ic,TRUE);
7076 /* we did not allocate which means left
7077 already in a pointer register, then
7078 if size > 0 && this could be used again
7079 we have to point it back to where it
7081 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7082 if (AOP_SIZE(result) > 1 &&
7083 !OP_SYMBOL(left)->remat &&
7084 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7086 int size = AOP_SIZE(result) - 1;
7088 pic14_emitcode("dec","%s",rname);
7093 freeAsmop(result,NULL,ic,TRUE);
7097 /*-----------------------------------------------------------------*/
7098 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7099 /*-----------------------------------------------------------------*/
7100 static void genPagedPointerGet (operand *left,
7107 sym_link *rtype, *retype;
7109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7111 rtype = operandType(result);
7112 retype= getSpec(rtype);
7114 aopOp(left,ic,FALSE);
7116 /* if the value is already in a pointer register
7117 then don't need anything more */
7118 if (!AOP_INPREG(AOP(left))) {
7119 /* otherwise get a free pointer register */
7121 preg = getFreePtr(ic,&aop,FALSE);
7122 pic14_emitcode("mov","%s,%s",
7124 aopGet(AOP(left),0,FALSE,TRUE));
7125 rname = preg->name ;
7127 rname = aopGet(AOP(left),0,FALSE,FALSE);
7129 freeAsmop(left,NULL,ic,TRUE);
7130 aopOp (result,ic,FALSE);
7132 /* if bitfield then unpack the bits */
7133 if (IS_BITVAR(retype))
7134 genUnpackBits (result,rname,PPOINTER);
7136 /* we have can just get the values */
7137 int size = AOP_SIZE(result);
7142 pic14_emitcode("movx","a,@%s",rname);
7143 aopPut(AOP(result),"a",offset);
7148 pic14_emitcode("inc","%s",rname);
7152 /* now some housekeeping stuff */
7154 /* we had to allocate for this iCode */
7155 freeAsmop(NULL,aop,ic,TRUE);
7157 /* we did not allocate which means left
7158 already in a pointer register, then
7159 if size > 0 && this could be used again
7160 we have to point it back to where it
7162 if (AOP_SIZE(result) > 1 &&
7163 !OP_SYMBOL(left)->remat &&
7164 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7166 int size = AOP_SIZE(result) - 1;
7168 pic14_emitcode("dec","%s",rname);
7173 freeAsmop(result,NULL,ic,TRUE);
7178 /*-----------------------------------------------------------------*/
7179 /* genFarPointerGet - gget value from far space */
7180 /*-----------------------------------------------------------------*/
7181 static void genFarPointerGet (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",FPOINTER);
7214 size = AOP_SIZE(result);
7218 pic14_emitcode("movx","a,@dptr");
7219 aopPut(AOP(result),"a",offset++);
7221 pic14_emitcode("inc","dptr");
7225 freeAsmop(result,NULL,ic,TRUE);
7228 /*-----------------------------------------------------------------*/
7229 /* pic14_emitcodePointerGet - gget value from code space */
7230 /*-----------------------------------------------------------------*/
7231 static void pic14_emitcodePointerGet (operand *left,
7232 operand *result, iCode *ic)
7235 sym_link *retype = getSpec(operandType(result));
7237 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 else { /* we need to get it byte by byte */
7248 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7249 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7250 if (options.model == MODEL_FLAT24)
7252 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7256 /* so dptr know contains the address */
7257 freeAsmop(left,NULL,ic,TRUE);
7258 aopOp(result,ic,FALSE);
7260 /* if bit then unpack */
7261 if (IS_BITVAR(retype))
7262 genUnpackBits(result,"dptr",CPOINTER);
7264 size = AOP_SIZE(result);
7268 pic14_emitcode("clr","a");
7269 pic14_emitcode("movc","a,@a+dptr");
7270 aopPut(AOP(result),"a",offset++);
7272 pic14_emitcode("inc","dptr");
7276 freeAsmop(result,NULL,ic,TRUE);
7279 /*-----------------------------------------------------------------*/
7280 /* genGenPointerGet - gget value from generic pointer space */
7281 /*-----------------------------------------------------------------*/
7282 static void genGenPointerGet (operand *left,
7283 operand *result, iCode *ic)
7286 sym_link *retype = getSpec(operandType(result));
7288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7289 aopOp(left,ic,FALSE);
7291 /* if the operand is already in dptr
7292 then we do nothing else we move the value to dptr */
7293 if (AOP_TYPE(left) != AOP_STR) {
7294 /* if this is remateriazable */
7295 if (AOP_TYPE(left) == AOP_IMMD) {
7296 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7297 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7299 else { /* we need to get it byte by byte */
7300 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7301 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7302 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7303 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7304 pic14_emitcode("movwf","FSR");
7306 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7307 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7308 if (options.model == MODEL_FLAT24)
7310 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7311 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7315 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7320 /* so dptr know contains the address */
7321 freeAsmop(left,NULL,ic,TRUE);
7322 aopOp(result,ic,FALSE);
7324 /* if bit then unpack */
7325 if (IS_BITVAR(retype))
7326 genUnpackBits(result,"dptr",GPOINTER);
7328 size = AOP_SIZE(result);
7332 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7334 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7336 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7338 pic14_emitcode("movf","indf,w");
7339 pic14_emitcode("movwf","%s",
7340 aopGet(AOP(result),offset++,FALSE,FALSE));
7342 pic14_emitcode("incf","fsr,f");
7347 freeAsmop(result,NULL,ic,TRUE);
7350 /*-----------------------------------------------------------------*/
7351 /* genPointerGet - generate code for pointer get */
7352 /*-----------------------------------------------------------------*/
7353 static void genPointerGet (iCode *ic)
7355 operand *left, *result ;
7356 sym_link *type, *etype;
7359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7362 result = IC_RESULT(ic) ;
7364 /* depending on the type of pointer we need to
7365 move it to the correct pointer register */
7366 type = operandType(left);
7367 etype = getSpec(type);
7368 /* if left is of type of pointer then it is simple */
7369 if (IS_PTR(type) && !IS_FUNC(type->next))
7370 p_type = DCL_TYPE(type);
7372 /* we have to go by the storage class */
7373 p_type = PTR_TYPE(SPEC_OCLS(etype));
7375 /* if (SPEC_OCLS(etype)->codesp ) { */
7376 /* p_type = CPOINTER ; */
7379 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7380 /* p_type = FPOINTER ; */
7382 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7383 /* p_type = PPOINTER; */
7385 /* if (SPEC_OCLS(etype) == idata ) */
7386 /* p_type = IPOINTER; */
7388 /* p_type = POINTER ; */
7391 /* now that we have the pointer type we assign
7392 the pointer values */
7397 genNearPointerGet (left,result,ic);
7401 genPagedPointerGet(left,result,ic);
7405 genFarPointerGet (left,result,ic);
7409 pic14_emitcodePointerGet (left,result,ic);
7413 genGenPointerGet (left,result,ic);
7419 /*-----------------------------------------------------------------*/
7420 /* genPackBits - generates code for packed bit storage */
7421 /*-----------------------------------------------------------------*/
7422 static void genPackBits (sym_link *etype ,
7424 char *rname, int p_type)
7432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7433 blen = SPEC_BLEN(etype);
7434 bstr = SPEC_BSTR(etype);
7436 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7439 /* if the bit lenth is less than or */
7440 /* it exactly fits a byte then */
7441 if (SPEC_BLEN(etype) <= 8 ) {
7442 shCount = SPEC_BSTR(etype) ;
7444 /* shift left acc */
7447 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7452 pic14_emitcode ("mov","b,a");
7453 pic14_emitcode("mov","a,@%s",rname);
7457 pic14_emitcode ("mov","b,a");
7458 pic14_emitcode("movx","a,@dptr");
7462 pic14_emitcode ("push","b");
7463 pic14_emitcode ("push","acc");
7464 pic14_emitcode ("lcall","__gptrget");
7465 pic14_emitcode ("pop","b");
7469 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7470 ((unsigned char)(0xFF << (blen+bstr)) |
7471 (unsigned char)(0xFF >> (8-bstr)) ) );
7472 pic14_emitcode ("orl","a,b");
7473 if (p_type == GPOINTER)
7474 pic14_emitcode("pop","b");
7480 pic14_emitcode("mov","@%s,a",rname);
7484 pic14_emitcode("movx","@dptr,a");
7488 DEBUGpic14_emitcode(";lcall","__gptrput");
7493 if ( SPEC_BLEN(etype) <= 8 )
7496 pic14_emitcode("inc","%s",rname);
7497 rLen = SPEC_BLEN(etype) ;
7499 /* now generate for lengths greater than one byte */
7502 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7512 pic14_emitcode("mov","@%s,a",rname);
7514 pic14_emitcode("mov","@%s,%s",rname,l);
7519 pic14_emitcode("movx","@dptr,a");
7524 DEBUGpic14_emitcode(";lcall","__gptrput");
7527 pic14_emitcode ("inc","%s",rname);
7532 /* last last was not complete */
7534 /* save the byte & read byte */
7537 pic14_emitcode ("mov","b,a");
7538 pic14_emitcode("mov","a,@%s",rname);
7542 pic14_emitcode ("mov","b,a");
7543 pic14_emitcode("movx","a,@dptr");
7547 pic14_emitcode ("push","b");
7548 pic14_emitcode ("push","acc");
7549 pic14_emitcode ("lcall","__gptrget");
7550 pic14_emitcode ("pop","b");
7554 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7555 pic14_emitcode ("orl","a,b");
7558 if (p_type == GPOINTER)
7559 pic14_emitcode("pop","b");
7564 pic14_emitcode("mov","@%s,a",rname);
7568 pic14_emitcode("movx","@dptr,a");
7572 DEBUGpic14_emitcode(";lcall","__gptrput");
7576 /*-----------------------------------------------------------------*/
7577 /* genDataPointerSet - remat pointer to data space */
7578 /*-----------------------------------------------------------------*/
7579 static void genDataPointerSet(operand *right,
7583 int size, offset = 0 ;
7584 char *l, buffer[256];
7586 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7587 aopOp(right,ic,FALSE);
7589 l = aopGet(AOP(result),0,FALSE,TRUE);
7590 size = AOP_SIZE(right);
7591 // tsd, was l+1 - the underline `_' prefix was being stripped
7594 sprintf(buffer,"(%s + %d)",l,offset);
7596 sprintf(buffer,"%s",l);
7598 if (AOP_TYPE(right) == AOP_LIT) {
7599 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7600 lit = lit >> (8*offset);
7602 pic14_emitcode("movlw","%d",lit);
7603 pic14_emitcode("movwf","%s",buffer);
7605 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7606 emitpcode(POC_MOVWF, popRegFromString(buffer));
7609 pic14_emitcode("clrf","%s",buffer);
7610 emitpcode(POC_CLRF, popRegFromString(buffer));
7613 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7614 pic14_emitcode("movwf","%s",buffer);
7616 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7617 emitpcode(POC_MOVWF, popRegFromString(buffer));
7624 freeAsmop(right,NULL,ic,TRUE);
7625 freeAsmop(result,NULL,ic,TRUE);
7628 /*-----------------------------------------------------------------*/
7629 /* genNearPointerSet - pic14_emitcode for near pointer put */
7630 /*-----------------------------------------------------------------*/
7631 static void genNearPointerSet (operand *right,
7638 sym_link *ptype = operandType(result);
7641 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7642 retype= getSpec(operandType(right));
7644 aopOp(result,ic,FALSE);
7646 /* if the result is rematerializable &
7647 in data space & not a bit variable */
7648 if (AOP_TYPE(result) == AOP_IMMD &&
7649 DCL_TYPE(ptype) == POINTER &&
7650 !IS_BITVAR(retype)) {
7651 genDataPointerSet (right,result,ic);
7655 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7657 /* if the value is already in a pointer register
7658 then don't need anything more */
7659 if (!AOP_INPREG(AOP(result))) {
7660 /* otherwise get a free pointer register */
7661 //aop = newAsmop(0);
7662 //preg = getFreePtr(ic,&aop,FALSE);
7663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7664 //pic14_emitcode("mov","%s,%s",
7666 // aopGet(AOP(result),0,FALSE,TRUE));
7667 //rname = preg->name ;
7668 pic14_emitcode("movwf","fsr");
7670 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7672 freeAsmop(result,NULL,ic,TRUE);
7673 aopOp (right,ic,FALSE);
7674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7676 /* if bitfield then unpack the bits */
7677 if (IS_BITVAR(retype)) {
7678 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7679 "The programmer is obviously confused");
7680 //genPackBits (retype,right,rname,POINTER);
7684 /* we have can just get the values */
7685 int size = AOP_SIZE(right);
7688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7690 l = aopGet(AOP(right),offset,FALSE,TRUE);
7693 //pic14_emitcode("mov","@%s,a",rname);
7694 pic14_emitcode("movf","indf,w ;1");
7697 if (AOP_TYPE(right) == AOP_LIT) {
7698 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7700 pic14_emitcode("movlw","%s",l);
7701 pic14_emitcode("movwf","indf ;2");
7703 pic14_emitcode("clrf","indf");
7705 pic14_emitcode("movf","%s,w",l);
7706 pic14_emitcode("movwf","indf ;2");
7708 //pic14_emitcode("mov","@%s,%s",rname,l);
7711 pic14_emitcode("incf","fsr,f ;3");
7712 //pic14_emitcode("inc","%s",rname);
7717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7718 /* now some housekeeping stuff */
7720 /* we had to allocate for this iCode */
7721 freeAsmop(NULL,aop,ic,TRUE);
7723 /* we did not allocate which means left
7724 already in a pointer register, then
7725 if size > 0 && this could be used again
7726 we have to point it back to where it
7728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7729 if (AOP_SIZE(right) > 1 &&
7730 !OP_SYMBOL(result)->remat &&
7731 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7733 int size = AOP_SIZE(right) - 1;
7735 pic14_emitcode("decf","fsr,f");
7736 //pic14_emitcode("dec","%s",rname);
7740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7742 freeAsmop(right,NULL,ic,TRUE);
7747 /*-----------------------------------------------------------------*/
7748 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7749 /*-----------------------------------------------------------------*/
7750 static void genPagedPointerSet (operand *right,
7759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7761 retype= getSpec(operandType(right));
7763 aopOp(result,ic,FALSE);
7765 /* if the value is already in a pointer register
7766 then don't need anything more */
7767 if (!AOP_INPREG(AOP(result))) {
7768 /* otherwise get a free pointer register */
7770 preg = getFreePtr(ic,&aop,FALSE);
7771 pic14_emitcode("mov","%s,%s",
7773 aopGet(AOP(result),0,FALSE,TRUE));
7774 rname = preg->name ;
7776 rname = aopGet(AOP(result),0,FALSE,FALSE);
7778 freeAsmop(result,NULL,ic,TRUE);
7779 aopOp (right,ic,FALSE);
7781 /* if bitfield then unpack the bits */
7782 if (IS_BITVAR(retype))
7783 genPackBits (retype,right,rname,PPOINTER);
7785 /* we have can just get the values */
7786 int size = AOP_SIZE(right);
7790 l = aopGet(AOP(right),offset,FALSE,TRUE);
7793 pic14_emitcode("movx","@%s,a",rname);
7796 pic14_emitcode("inc","%s",rname);
7802 /* now some housekeeping stuff */
7804 /* we had to allocate for this iCode */
7805 freeAsmop(NULL,aop,ic,TRUE);
7807 /* we did not allocate which means left
7808 already in a pointer register, then
7809 if size > 0 && this could be used again
7810 we have to point it back to where it
7812 if (AOP_SIZE(right) > 1 &&
7813 !OP_SYMBOL(result)->remat &&
7814 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7816 int size = AOP_SIZE(right) - 1;
7818 pic14_emitcode("dec","%s",rname);
7823 freeAsmop(right,NULL,ic,TRUE);
7828 /*-----------------------------------------------------------------*/
7829 /* genFarPointerSet - set value from far space */
7830 /*-----------------------------------------------------------------*/
7831 static void genFarPointerSet (operand *right,
7832 operand *result, iCode *ic)
7835 sym_link *retype = getSpec(operandType(right));
7837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7838 aopOp(result,ic,FALSE);
7840 /* if the operand is already in dptr
7841 then we do nothing else we move the value to dptr */
7842 if (AOP_TYPE(result) != AOP_STR) {
7843 /* if this is remateriazable */
7844 if (AOP_TYPE(result) == AOP_IMMD)
7845 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7846 else { /* we need to get it byte by byte */
7847 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7848 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7849 if (options.model == MODEL_FLAT24)
7851 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7855 /* so dptr know contains the address */
7856 freeAsmop(result,NULL,ic,TRUE);
7857 aopOp(right,ic,FALSE);
7859 /* if bit then unpack */
7860 if (IS_BITVAR(retype))
7861 genPackBits(retype,right,"dptr",FPOINTER);
7863 size = AOP_SIZE(right);
7867 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7869 pic14_emitcode("movx","@dptr,a");
7871 pic14_emitcode("inc","dptr");
7875 freeAsmop(right,NULL,ic,TRUE);
7878 /*-----------------------------------------------------------------*/
7879 /* genGenPointerSet - set value from generic pointer space */
7880 /*-----------------------------------------------------------------*/
7881 static void genGenPointerSet (operand *right,
7882 operand *result, iCode *ic)
7885 sym_link *retype = getSpec(operandType(right));
7887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7889 aopOp(result,ic,FALSE);
7891 /* if the operand is already in dptr
7892 then we do nothing else we move the value to dptr */
7893 if (AOP_TYPE(result) != AOP_STR) {
7894 /* if this is remateriazable */
7895 if (AOP_TYPE(result) == AOP_IMMD) {
7896 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7897 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7899 else { /* we need to get it byte by byte */
7900 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7903 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7904 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7907 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7909 pic14_emitcode("movwf","INDF");
7912 /* so dptr know contains the address */
7913 freeAsmop(result,NULL,ic,TRUE);
7914 aopOp(right,ic,FALSE);
7916 /* if bit then unpack */
7917 if (IS_BITVAR(retype))
7918 genPackBits(retype,right,"dptr",GPOINTER);
7920 size = AOP_SIZE(right);
7924 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7926 pic14_emitcode("incf","fsr,f");
7927 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7928 pic14_emitcode("movwf","indf");
7930 //DEBUGpic14_emitcode(";lcall","__gptrput");
7932 // pic14_emitcode("inc","dptr");
7936 freeAsmop(right,NULL,ic,TRUE);
7939 /*-----------------------------------------------------------------*/
7940 /* genPointerSet - stores the value into a pointer location */
7941 /*-----------------------------------------------------------------*/
7942 static void genPointerSet (iCode *ic)
7944 operand *right, *result ;
7945 sym_link *type, *etype;
7948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7950 right = IC_RIGHT(ic);
7951 result = IC_RESULT(ic) ;
7953 /* depending on the type of pointer we need to
7954 move it to the correct pointer register */
7955 type = operandType(result);
7956 etype = getSpec(type);
7957 /* if left is of type of pointer then it is simple */
7958 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7959 p_type = DCL_TYPE(type);
7962 /* we have to go by the storage class */
7963 p_type = PTR_TYPE(SPEC_OCLS(etype));
7965 /* if (SPEC_OCLS(etype)->codesp ) { */
7966 /* p_type = CPOINTER ; */
7969 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7970 /* p_type = FPOINTER ; */
7972 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7973 /* p_type = PPOINTER ; */
7975 /* if (SPEC_OCLS(etype) == idata ) */
7976 /* p_type = IPOINTER ; */
7978 /* p_type = POINTER ; */
7981 /* now that we have the pointer type we assign
7982 the pointer values */
7987 genNearPointerSet (right,result,ic);
7991 genPagedPointerSet (right,result,ic);
7995 genFarPointerSet (right,result,ic);
7999 genGenPointerSet (right,result,ic);
8005 /*-----------------------------------------------------------------*/
8006 /* genIfx - generate code for Ifx statement */
8007 /*-----------------------------------------------------------------*/
8008 static void genIfx (iCode *ic, iCode *popIc)
8010 operand *cond = IC_COND(ic);
8013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8014 aopOp(cond,ic,FALSE);
8016 /* get the value into acc */
8017 if (AOP_TYPE(cond) != AOP_CRY)
8018 pic14_toBoolean(cond);
8021 /* the result is now in the accumulator */
8022 freeAsmop(cond,NULL,ic,TRUE);
8024 /* if there was something to be popped then do it */
8028 /* if the condition is a bit variable */
8029 if (isbit && IS_ITEMP(cond) &&
8031 genIfxJump(ic,SPIL_LOC(cond)->rname);
8032 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8036 if (isbit && !IS_ITEMP(cond))
8037 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
8039 DEBUGpic14_emitcode ("; isbit","a");
8042 if (isbit && !IS_ITEMP(cond))
8043 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8050 /*-----------------------------------------------------------------*/
8051 /* genAddrOf - generates code for address of */
8052 /*-----------------------------------------------------------------*/
8053 static void genAddrOf (iCode *ic)
8055 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8060 aopOp(IC_RESULT(ic),ic,FALSE);
8062 /* if the operand is on the stack then we
8063 need to get the stack offset of this
8066 /* if it has an offset then we need to compute
8069 pic14_emitcode("mov","a,_bp");
8070 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
8071 aopPut(AOP(IC_RESULT(ic)),"a",0);
8073 /* we can just move _bp */
8074 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
8076 /* fill the result with zero */
8077 size = AOP_SIZE(IC_RESULT(ic)) - 1;
8080 if (options.stack10bit && size < (FPTRSIZE - 1))
8083 "*** warning: pointer to stack var truncated.\n");
8090 if (options.stack10bit && offset == 2)
8092 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8096 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8103 /* object not on stack then we need the name */
8104 size = AOP_SIZE(IC_RESULT(ic));
8108 char s[SDCC_NAME_MAX];
8110 sprintf(s,"#(%s >> %d)",
8114 sprintf(s,"#%s",sym->rname);
8115 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8119 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8124 /*-----------------------------------------------------------------*/
8125 /* genFarFarAssign - assignment when both are in far space */
8126 /*-----------------------------------------------------------------*/
8127 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8129 int size = AOP_SIZE(right);
8132 /* first push the right side on to the stack */
8134 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8136 pic14_emitcode ("push","acc");
8139 freeAsmop(right,NULL,ic,FALSE);
8140 /* now assign DPTR to result */
8141 aopOp(result,ic,FALSE);
8142 size = AOP_SIZE(result);
8144 pic14_emitcode ("pop","acc");
8145 aopPut(AOP(result),"a",--offset);
8147 freeAsmop(result,NULL,ic,FALSE);
8152 /*-----------------------------------------------------------------*/
8153 /* genAssign - generate code for assignment */
8154 /*-----------------------------------------------------------------*/
8155 static void genAssign (iCode *ic)
8157 operand *result, *right;
8158 int size, offset,know_W;
8159 unsigned long lit = 0L;
8161 result = IC_RESULT(ic);
8162 right = IC_RIGHT(ic) ;
8164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8166 /* if they are the same */
8167 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8170 aopOp(right,ic,FALSE);
8171 aopOp(result,ic,TRUE);
8173 DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8174 AopType(AOP_TYPE(IC_RESULT(ic))),
8175 AopType(AOP_TYPE(IC_RIGHT(ic))),
8178 /* if they are the same registers */
8179 if (pic14_sameRegs(AOP(right),AOP(result)))
8182 /* if the result is a bit */
8183 if (AOP_TYPE(result) == AOP_CRY) {
8185 /* if the right size is a literal then
8186 we know what the value is */
8187 if (AOP_TYPE(right) == AOP_LIT) {
8189 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8190 popGet(AOP(result),0,FALSE,FALSE));
8192 if (((int) operandLitValue(right)))
8193 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8194 AOP(result)->aopu.aop_dir,
8195 AOP(result)->aopu.aop_dir);
8197 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8198 AOP(result)->aopu.aop_dir,
8199 AOP(result)->aopu.aop_dir);
8203 /* the right is also a bit variable */
8204 if (AOP_TYPE(right) == AOP_CRY) {
8205 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8206 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8207 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8209 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8210 AOP(result)->aopu.aop_dir,
8211 AOP(result)->aopu.aop_dir);
8212 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8213 AOP(right)->aopu.aop_dir,
8214 AOP(right)->aopu.aop_dir);
8215 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8216 AOP(result)->aopu.aop_dir,
8217 AOP(result)->aopu.aop_dir);
8222 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8223 pic14_toBoolean(right);
8225 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8226 //aopPut(AOP(result),"a",0);
8230 /* bit variables done */
8232 size = AOP_SIZE(result);
8234 if(AOP_TYPE(right) == AOP_LIT)
8235 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8239 if(AOP_TYPE(right) == AOP_LIT) {
8241 if(know_W != (lit&0xff))
8242 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8244 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8246 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8250 } else if (AOP_TYPE(right) == AOP_CRY) {
8251 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8253 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8254 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8257 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8258 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8266 freeAsmop (right,NULL,ic,FALSE);
8267 freeAsmop (result,NULL,ic,TRUE);
8270 /*-----------------------------------------------------------------*/
8271 /* genJumpTab - genrates code for jump table */
8272 /*-----------------------------------------------------------------*/
8273 static void genJumpTab (iCode *ic)
8278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8280 aopOp(IC_JTCOND(ic),ic,FALSE);
8281 /* get the condition into accumulator */
8282 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8284 /* multiply by three */
8285 pic14_emitcode("add","a,acc");
8286 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8288 jtab = newiTempLabel(NULL);
8289 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8290 pic14_emitcode("jmp","@a+dptr");
8291 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8293 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8294 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8296 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8297 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8298 emitpLabel(jtab->key);
8300 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8302 /* now generate the jump labels */
8303 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8304 jtab = setNextItem(IC_JTLABELS(ic))) {
8305 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8306 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8312 /*-----------------------------------------------------------------*/
8313 /* genMixedOperation - gen code for operators between mixed types */
8314 /*-----------------------------------------------------------------*/
8316 TSD - Written for the PIC port - but this unfortunately is buggy.
8317 This routine is good in that it is able to efficiently promote
8318 types to different (larger) sizes. Unfortunately, the temporary
8319 variables that are optimized out by this routine are sometimes
8320 used in other places. So until I know how to really parse the
8321 iCode tree, I'm going to not be using this routine :(.
8323 static int genMixedOperation (iCode *ic)
8326 operand *result = IC_RESULT(ic);
8327 sym_link *ctype = operandType(IC_LEFT(ic));
8328 operand *right = IC_RIGHT(ic);
8334 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8336 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8342 nextright = IC_RIGHT(nextic);
8343 nextleft = IC_LEFT(nextic);
8344 nextresult = IC_RESULT(nextic);
8346 aopOp(right,ic,FALSE);
8347 aopOp(result,ic,FALSE);
8348 aopOp(nextright, nextic, FALSE);
8349 aopOp(nextleft, nextic, FALSE);
8350 aopOp(nextresult, nextic, FALSE);
8352 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8358 pic14_emitcode(";remove right +","");
8360 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8366 pic14_emitcode(";remove left +","");
8370 big = AOP_SIZE(nextleft);
8371 small = AOP_SIZE(nextright);
8373 switch(nextic->op) {
8376 pic14_emitcode(";optimize a +","");
8377 /* if unsigned or not an integral type */
8378 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8379 pic14_emitcode(";add a bit to something","");
8382 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8384 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8385 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8386 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8388 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8396 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8397 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8398 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8401 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8403 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8404 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8405 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8406 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8407 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8410 pic14_emitcode("rlf","known_zero,w");
8417 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8418 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8419 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8421 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8431 freeAsmop(right,NULL,ic,TRUE);
8432 freeAsmop(result,NULL,ic,TRUE);
8433 freeAsmop(nextright,NULL,ic,TRUE);
8434 freeAsmop(nextleft,NULL,ic,TRUE);
8436 nextic->generated = 1;
8443 /*-----------------------------------------------------------------*/
8444 /* genCast - gen code for casting */
8445 /*-----------------------------------------------------------------*/
8446 static void genCast (iCode *ic)
8448 operand *result = IC_RESULT(ic);
8449 sym_link *ctype = operandType(IC_LEFT(ic));
8450 operand *right = IC_RIGHT(ic);
8453 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8454 /* if they are equivalent then do nothing */
8455 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8458 aopOp(right,ic,FALSE) ;
8459 aopOp(result,ic,FALSE);
8461 /* if the result is a bit */
8462 if (AOP_TYPE(result) == AOP_CRY) {
8463 /* if the right size is a literal then
8464 we know what the value is */
8465 if (AOP_TYPE(right) == AOP_LIT) {
8467 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8468 popGet(AOP(result),0,FALSE,FALSE));
8470 if (((int) operandLitValue(right)))
8471 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8472 AOP(result)->aopu.aop_dir,
8473 AOP(result)->aopu.aop_dir);
8475 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8476 AOP(result)->aopu.aop_dir,
8477 AOP(result)->aopu.aop_dir);
8482 /* the right is also a bit variable */
8483 if (AOP_TYPE(right) == AOP_CRY) {
8486 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8488 pic14_emitcode("clrc","");
8489 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8490 AOP(right)->aopu.aop_dir,
8491 AOP(right)->aopu.aop_dir);
8492 aopPut(AOP(result),"c",0);
8497 pic14_toBoolean(right);
8498 aopPut(AOP(result),"a",0);
8502 /* if they are the same size : or less */
8503 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8505 /* if they are in the same place */
8506 if (pic14_sameRegs(AOP(right),AOP(result)))
8509 /* if they in different places then copy */
8510 size = AOP_SIZE(result);
8514 aopGet(AOP(right),offset,FALSE,FALSE),
8522 /* if the result is of type pointer */
8523 if (IS_PTR(ctype)) {
8526 sym_link *type = operandType(right);
8527 sym_link *etype = getSpec(type);
8529 /* pointer to generic pointer */
8530 if (IS_GENPTR(ctype)) {
8534 p_type = DCL_TYPE(type);
8536 /* we have to go by the storage class */
8537 p_type = PTR_TYPE(SPEC_OCLS(etype));
8539 /* if (SPEC_OCLS(etype)->codesp ) */
8540 /* p_type = CPOINTER ; */
8542 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8543 /* p_type = FPOINTER ; */
8545 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8546 /* p_type = PPOINTER; */
8548 /* if (SPEC_OCLS(etype) == idata ) */
8549 /* p_type = IPOINTER ; */
8551 /* p_type = POINTER ; */
8554 /* the first two bytes are known */
8555 size = GPTRSIZE - 1;
8559 aopGet(AOP(right),offset,FALSE,FALSE),
8563 /* the last byte depending on type */
8580 /* this should never happen */
8581 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8582 "got unknown pointer type");
8585 aopPut(AOP(result),l, GPTRSIZE - 1);
8589 /* just copy the pointers */
8590 size = AOP_SIZE(result);
8594 aopGet(AOP(right),offset,FALSE,FALSE),
8602 if (AOP_TYPE(right) == AOP_CRY) {
8604 size = AOP_SIZE(right);
8606 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8607 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8608 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8610 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8611 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8612 AOP(right)->aopu.aop_dir,
8613 AOP(right)->aopu.aop_dir);
8614 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8616 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8617 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8622 /* so we now know that the size of destination is greater
8623 than the size of the source.
8624 Now, if the next iCode is an operator then we might be
8625 able to optimize the operation without performing a cast.
8627 if(genMixedOperation(ic))
8631 /* we move to result for the size of source */
8632 size = AOP_SIZE(right);
8635 pic14_emitcode(";","%d",__LINE__);
8636 /* aopPut(AOP(result),
8637 aopGet(AOP(right),offset,FALSE,FALSE),
8639 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8640 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8644 /* now depending on the sign of the destination */
8645 size = AOP_SIZE(result) - AOP_SIZE(right);
8646 /* if unsigned or not an integral type */
8647 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8649 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8650 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8654 /* we need to extend the sign :{ */
8656 emitpcodeNULLop(POC_CLRW);
8659 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8661 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8663 emitpcode(POC_MOVLW, popGetLit(0xff));
8665 pic14_emitcode("clrw","");
8666 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8667 AOP(right)->aopu.aop_dir,
8668 AOP(right)->aopu.aop_dir);
8669 pic14_emitcode("movlw","0xff");
8671 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8672 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8674 // aopPut(AOP(result),"a",offset++);
8679 /* we are done hurray !!!! */
8682 freeAsmop(right,NULL,ic,TRUE);
8683 freeAsmop(result,NULL,ic,TRUE);
8687 /*-----------------------------------------------------------------*/
8688 /* genDjnz - generate decrement & jump if not zero instrucion */
8689 /*-----------------------------------------------------------------*/
8690 static int genDjnz (iCode *ic, iCode *ifx)
8693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8698 /* if the if condition has a false label
8699 then we cannot save */
8703 /* if the minus is not of the form
8705 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8706 !IS_OP_LITERAL(IC_RIGHT(ic)))
8709 if (operandLitValue(IC_RIGHT(ic)) != 1)
8712 /* if the size of this greater than one then no
8714 if (getSize(operandType(IC_RESULT(ic))) > 1)
8717 /* otherwise we can save BIG */
8718 lbl = newiTempLabel(NULL);
8719 lbl1= newiTempLabel(NULL);
8721 aopOp(IC_RESULT(ic),ic,FALSE);
8723 if (IS_AOP_PREG(IC_RESULT(ic))) {
8724 pic14_emitcode("dec","%s",
8725 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8726 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8727 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8731 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8732 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8734 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8735 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8738 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8739 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8740 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8741 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8744 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8749 /*-----------------------------------------------------------------*/
8750 /* genReceive - generate code for a receive iCode */
8751 /*-----------------------------------------------------------------*/
8752 static void genReceive (iCode *ic)
8754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8756 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8757 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8758 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8760 int size = getSize(operandType(IC_RESULT(ic)));
8761 int offset = fReturnSizePic - size;
8763 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8764 fReturn[fReturnSizePic - offset - 1] : "acc"));
8767 aopOp(IC_RESULT(ic),ic,FALSE);
8768 size = AOP_SIZE(IC_RESULT(ic));
8771 pic14_emitcode ("pop","acc");
8772 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8777 aopOp(IC_RESULT(ic),ic,FALSE);
8779 assignResultValue(IC_RESULT(ic));
8782 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8785 /*-----------------------------------------------------------------*/
8786 /* genpic14Code - generate code for pic14 based controllers */
8787 /*-----------------------------------------------------------------*/
8789 * At this point, ralloc.c has gone through the iCode and attempted
8790 * to optimize in a way suitable for a PIC. Now we've got to generate
8791 * PIC instructions that correspond to the iCode.
8793 * Once the instructions are generated, we'll pass through both the
8794 * peep hole optimizer and the pCode optimizer.
8795 *-----------------------------------------------------------------*/
8797 void genpic14Code (iCode *lic)
8802 lineHead = lineCurr = NULL;
8804 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8807 /* if debug information required */
8808 /* if (options.debug && currFunc) { */
8810 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8812 if (IS_STATIC(currFunc->etype)) {
8813 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8814 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8816 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8817 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8823 for (ic = lic ; ic ; ic = ic->next ) {
8825 DEBUGpic14_emitcode(";ic","");
8826 if ( cln != ic->lineno ) {
8827 if ( options.debug ) {
8829 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8830 FileBaseName(ic->filename),ic->lineno,
8831 ic->level,ic->block);
8834 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8837 /* if the result is marked as
8838 spilt and rematerializable or code for
8839 this has already been generated then
8841 if (resultRemat(ic) || ic->generated )
8844 /* depending on the operation */
8863 /* IPOP happens only when trying to restore a
8864 spilt live range, if there is an ifx statement
8865 following this pop then the if statement might
8866 be using some of the registers being popped which
8867 would destory the contents of the register so
8868 we need to check for this condition and handle it */
8870 ic->next->op == IFX &&
8871 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8872 genIfx (ic->next,ic);
8890 genEndFunction (ic);
8910 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8927 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8931 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8938 /* note these two are xlated by algebraic equivalence
8939 during parsing SDCC.y */
8940 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8941 "got '>=' or '<=' shouldn't have come here");
8945 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8957 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8961 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8965 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8992 case GET_VALUE_AT_ADDRESS:
8997 if (POINTER_SET(ic))
9024 addSet(&_G.sendSet,ic);
9033 /* now we are ready to call the
9034 peep hole optimizer */
9035 if (!options.nopeep) {
9036 printf("peep hole optimizing\n");
9037 peepHole (&lineHead);
9039 /* now do the actual printing */
9040 printLine (lineHead,codeOutFile);
9042 printf("printing pBlock\n\n");
9043 printpBlock(stdout,pb);