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>
45 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
46 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
47 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
53 #include "SDCCpeeph.h"
58 static int labelOffset=0;
59 static int debug_verbose=1;
61 unsigned int pic14aopLiteral (value *val, int offset);
63 /* this is the down and dirty file with all kinds of
64 kludgy & hacky stuff. This is what it is all about
65 CODE GENERATION for a specific MCU . some of the
66 routines may be reusable, will have to see */
68 static char *zero = "#0x00";
69 static char *one = "#0x01";
70 static char *spname = "sp";
72 char *fReturnpic14[] = {"FSR","dph","b","a" };
73 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
74 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
75 static char **fReturn = fReturnpic14;
77 static char *accUse[] = {"a","b"};
79 //static short rbank = -1;
91 char *Safe_strdup(char *str); // in pcode.c
93 extern int pic14_ptrRegReq ;
94 extern int pic14_nRegs;
95 extern FILE *codeOutFile;
96 static void saverbank (int, iCode *,bool);
98 static lineNode *lineHead = NULL;
99 static lineNode *lineCurr = NULL;
101 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
102 0xE0, 0xC0, 0x80, 0x00};
103 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
104 0x07, 0x03, 0x01, 0x00};
108 /*-----------------------------------------------------------------*/
109 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
110 /* exponent of 2 is returned, otherwise -1 is */
112 /* note that this is similar to the function `powof2' in SDCCsymt */
116 /*-----------------------------------------------------------------*/
117 static int my_powof2 (unsigned long num)
120 if( (num & (num-1)) == 0) {
133 static void emitpLabel(int key)
135 addpCode2pBlock(pb,newpCodeLabel(key));
138 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
141 addpCode2pBlock(pb,newpCode(poc,pcop));
144 /*-----------------------------------------------------------------*/
145 /* pic14_emitcode - writes the code into a file : for now it is simple */
146 /*-----------------------------------------------------------------*/
147 void pic14_emitcode (char *inst,char *fmt, ...)
150 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;
174 addpCode2pBlock(pb,newpCodeCharP(lb));
179 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
182 char lb[INITIAL_INLINEASM];
192 sprintf(lb,"%s\t",inst);
194 sprintf(lb,"%s",inst);
195 vsprintf(lb+(strlen(lb)),fmt,ap);
199 while (isspace(*lbp)) lbp++;
202 lineCurr = (lineCurr ?
203 connectLine(lineCurr,newLineNode(lb)) :
204 (lineHead = newLineNode(lb)));
205 lineCurr->isInline = _G.inLine;
206 lineCurr->isDebug = _G.debugLine;
208 addpCode2pBlock(pb,newpCodeCharP(lb));
214 /*-----------------------------------------------------------------*/
215 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
216 /*-----------------------------------------------------------------*/
217 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
219 bool r0iu = FALSE , r1iu = FALSE;
220 bool r0ou = FALSE , r1ou = FALSE;
222 /* the logic: if r0 & r1 used in the instruction
223 then we are in trouble otherwise */
225 /* first check if r0 & r1 are used by this
226 instruction, in which case we are in trouble */
227 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
228 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
233 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
234 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
236 /* if no usage of r0 then return it */
237 if (!r0iu && !r0ou) {
238 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
239 (*aopp)->type = AOP_R0;
241 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
244 /* if no usage of r1 then return it */
245 if (!r1iu && !r1ou) {
246 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
247 (*aopp)->type = AOP_R1;
249 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
252 /* now we know they both have usage */
253 /* if r0 not used in this instruction */
255 /* push it if not already pushed */
257 pic14_emitcode ("push","%s",
258 pic14_regWithIdx(R0_IDX)->dname);
262 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
263 (*aopp)->type = AOP_R0;
265 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
268 /* if r1 not used then */
271 /* push it if not already pushed */
273 pic14_emitcode ("push","%s",
274 pic14_regWithIdx(R1_IDX)->dname);
278 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
279 (*aopp)->type = AOP_R1;
280 return pic14_regWithIdx(R1_IDX);
284 /* I said end of world but not quite end of world yet */
285 /* if this is a result then we can push it on the stack*/
287 (*aopp)->type = AOP_STK;
291 /* other wise this is true end of the world */
292 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
293 "getFreePtr should never reach here");
297 /*-----------------------------------------------------------------*/
298 /* newAsmop - creates a new asmOp */
299 /*-----------------------------------------------------------------*/
300 asmop *newAsmop (short type)
304 aop = Safe_calloc(1,sizeof(asmop));
309 static void genSetDPTR(int n)
313 pic14_emitcode(";", "Select standard DPTR");
314 pic14_emitcode("mov", "dps, #0x00");
318 pic14_emitcode(";", "Select alternate DPTR");
319 pic14_emitcode("mov", "dps, #0x01");
323 /*-----------------------------------------------------------------*/
324 /* pointerCode - returns the code for a pointer type */
325 /*-----------------------------------------------------------------*/
326 static int pointerCode (sym_link *etype)
329 return PTR_TYPE(SPEC_OCLS(etype));
333 /*-----------------------------------------------------------------*/
334 /* aopForSym - for a true symbol */
335 /*-----------------------------------------------------------------*/
336 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
339 memmap *space= SPEC_OCLS(sym->etype);
341 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
342 /* if already has one */
346 /* assign depending on the storage class */
347 /* if it is on the stack or indirectly addressable */
348 /* space we need to assign either r0 or r1 to it */
349 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
350 sym->aop = aop = newAsmop(0);
351 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
352 aop->size = getSize(sym->type);
354 /* now assign the address of the variable to
355 the pointer register */
356 if (aop->type != AOP_STK) {
360 pic14_emitcode("push","acc");
362 pic14_emitcode("mov","a,_bp");
363 pic14_emitcode("add","a,#0x%02x",
365 ((char)(sym->stack - _G.nRegsSaved )) :
366 ((char)sym->stack)) & 0xff);
367 pic14_emitcode("mov","%s,a",
368 aop->aopu.aop_ptr->name);
371 pic14_emitcode("pop","acc");
373 pic14_emitcode("mov","%s,#%s",
374 aop->aopu.aop_ptr->name,
376 aop->paged = space->paged;
378 aop->aopu.aop_stk = sym->stack;
382 if (sym->onStack && options.stack10bit)
384 /* It's on the 10 bit stack, which is located in
388 //DEBUGpic14_emitcode(";","%d",__LINE__);
391 pic14_emitcode("push","acc");
393 pic14_emitcode("mov","a,_bp");
394 pic14_emitcode("add","a,#0x%02x",
396 ((char)(sym->stack - _G.nRegsSaved )) :
397 ((char)sym->stack)) & 0xff);
400 pic14_emitcode ("mov","dpx1,#0x40");
401 pic14_emitcode ("mov","dph1,#0x00");
402 pic14_emitcode ("mov","dpl1, a");
406 pic14_emitcode("pop","acc");
408 sym->aop = aop = newAsmop(AOP_DPTR2);
409 aop->size = getSize(sym->type);
413 //DEBUGpic14_emitcode(";","%d",__LINE__);
414 /* if in bit space */
415 if (IN_BITSPACE(space)) {
416 sym->aop = aop = newAsmop (AOP_CRY);
417 aop->aopu.aop_dir = sym->rname ;
418 aop->size = getSize(sym->type);
419 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
422 /* if it is in direct space */
423 if (IN_DIRSPACE(space)) {
424 sym->aop = aop = newAsmop (AOP_DIR);
425 aop->aopu.aop_dir = sym->rname ;
426 aop->size = getSize(sym->type);
427 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
431 /* special case for a function */
432 if (IS_FUNC(sym->type)) {
433 sym->aop = aop = newAsmop(AOP_IMMD);
434 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
435 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
436 strcpy(aop->aopu.aop_immd,sym->rname);
437 aop->size = FPTRSIZE;
442 /* only remaining is far space */
443 /* in which case DPTR gets the address */
444 sym->aop = aop = newAsmop(AOP_DPTR);
445 pic14_emitcode ("mov","dptr,#%s", sym->rname);
446 aop->size = getSize(sym->type);
448 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
449 /* if it is in code space */
450 if (IN_CODESPACE(space))
456 /*-----------------------------------------------------------------*/
457 /* aopForRemat - rematerialzes an object */
458 /*-----------------------------------------------------------------*/
459 static asmop *aopForRemat (symbol *sym)
461 iCode *ic = sym->rematiCode;
462 asmop *aop = newAsmop(AOP_IMMD);
464 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
467 val += (int) operandLitValue(IC_RIGHT(ic));
468 else if (ic->op == '-')
469 val -= (int) operandLitValue(IC_RIGHT(ic));
473 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
477 sprintf(buffer,"(%s %c 0x%04x)",
478 OP_SYMBOL(IC_LEFT(ic))->rname,
479 val >= 0 ? '+' : '-',
482 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
484 //DEBUGpic14_emitcode(";","%s",buffer);
485 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
486 strcpy(aop->aopu.aop_immd,buffer);
490 /*-----------------------------------------------------------------*/
491 /* regsInCommon - two operands have some registers in common */
492 /*-----------------------------------------------------------------*/
493 static bool regsInCommon (operand *op1, operand *op2)
498 /* if they have registers in common */
499 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
502 sym1 = OP_SYMBOL(op1);
503 sym2 = OP_SYMBOL(op2);
505 if (sym1->nRegs == 0 || sym2->nRegs == 0)
508 for (i = 0 ; i < sym1->nRegs ; i++) {
513 for (j = 0 ; j < sym2->nRegs ;j++ ) {
517 if (sym2->regs[j] == sym1->regs[i])
525 /*-----------------------------------------------------------------*/
526 /* operandsEqu - equivalent */
527 /*-----------------------------------------------------------------*/
528 static bool operandsEqu ( operand *op1, operand *op2)
532 /* if they not symbols */
533 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
536 sym1 = OP_SYMBOL(op1);
537 sym2 = OP_SYMBOL(op2);
539 /* if both are itemps & one is spilt
540 and the other is not then false */
541 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
542 sym1->isspilt != sym2->isspilt )
545 /* if they are the same */
549 if (strcmp(sym1->rname,sym2->rname) == 0)
553 /* if left is a tmp & right is not */
557 (sym1->usl.spillLoc == sym2))
564 (sym2->usl.spillLoc == sym1))
570 /*-----------------------------------------------------------------*/
571 /* pic14_sameRegs - two asmops have the same registers */
572 /*-----------------------------------------------------------------*/
573 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
580 if (aop1->type != AOP_REG ||
581 aop2->type != AOP_REG )
584 if (aop1->size != aop2->size )
587 for (i = 0 ; i < aop1->size ; i++ )
588 if (aop1->aopu.aop_reg[i] !=
589 aop2->aopu.aop_reg[i] )
595 /*-----------------------------------------------------------------*/
596 /* aopOp - allocates an asmop for an operand : */
597 /*-----------------------------------------------------------------*/
598 void aopOp (operand *op, iCode *ic, bool result)
607 DEBUGpic14_emitcode(";","%d",__LINE__);
608 /* if this a literal */
609 if (IS_OP_LITERAL(op)) {
610 DEBUGpic14_emitcode(";","%d",__LINE__);
611 op->aop = aop = newAsmop(AOP_LIT);
612 aop->aopu.aop_lit = op->operand.valOperand;
613 aop->size = getSize(operandType(op));
617 /* if already has a asmop then continue */
621 /* if the underlying symbol has a aop */
622 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
623 DEBUGpic14_emitcode(";","%d",__LINE__);
624 op->aop = OP_SYMBOL(op)->aop;
628 /* if this is a true symbol */
629 if (IS_TRUE_SYMOP(op)) {
630 DEBUGpic14_emitcode(";","%d",__LINE__);
631 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
635 /* this is a temporary : this has
641 e) can be a return use only */
646 /* if the type is a conditional */
647 if (sym->regType == REG_CND) {
648 DEBUGpic14_emitcode(";","%d",__LINE__);
649 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
654 /* if it is spilt then two situations
656 b) has a spill location */
657 if (sym->isspilt || sym->nRegs == 0) {
659 DEBUGpic14_emitcode(";","%d",__LINE__);
660 /* rematerialize it NOW */
662 sym->aop = op->aop = aop =
664 aop->size = getSize(sym->type);
665 DEBUGpic14_emitcode(";","%d",__LINE__);
671 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
672 aop->size = getSize(sym->type);
673 for ( i = 0 ; i < 2 ; i++ )
674 aop->aopu.aop_str[i] = accUse[i];
675 DEBUGpic14_emitcode(";","%d",__LINE__);
681 aop = op->aop = sym->aop = newAsmop(AOP_STR);
682 aop->size = getSize(sym->type);
683 for ( i = 0 ; i < fReturnSizePic ; i++ )
684 aop->aopu.aop_str[i] = fReturn[i];
685 DEBUGpic14_emitcode(";","%d",__LINE__);
689 /* else spill location */
690 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
691 sym->aop = op->aop = aop =
692 aopForSym(ic,sym->usl.spillLoc,result);
693 aop->size = getSize(sym->type);
697 /* must be in a register */
698 sym->aop = op->aop = aop = newAsmop(AOP_REG);
699 aop->size = sym->nRegs;
700 for ( i = 0 ; i < sym->nRegs ;i++)
701 aop->aopu.aop_reg[i] = sym->regs[i];
704 /*-----------------------------------------------------------------*/
705 /* freeAsmop - free up the asmop given to an operand */
706 /*----------------------------------------------------------------*/
707 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
724 /* depending on the asmop type only three cases need work AOP_RO
725 , AOP_R1 && AOP_STK */
730 pic14_emitcode ("pop","ar0");
734 bitVectUnSetBit(ic->rUsed,R0_IDX);
740 pic14_emitcode ("pop","ar1");
744 bitVectUnSetBit(ic->rUsed,R1_IDX);
750 int stk = aop->aopu.aop_stk + aop->size;
751 bitVectUnSetBit(ic->rUsed,R0_IDX);
752 bitVectUnSetBit(ic->rUsed,R1_IDX);
754 getFreePtr(ic,&aop,FALSE);
756 if (options.stack10bit)
758 /* I'm not sure what to do here yet... */
761 "*** Warning: probably generating bad code for "
762 "10 bit stack mode.\n");
766 pic14_emitcode ("mov","a,_bp");
767 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
768 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
770 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
774 pic14_emitcode("pop","acc");
775 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
777 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
780 freeAsmop(op,NULL,ic,TRUE);
782 pic14_emitcode("pop","ar0");
787 pic14_emitcode("pop","ar1");
794 /* all other cases just dealloc */
798 OP_SYMBOL(op)->aop = NULL;
799 /* if the symbol has a spill */
801 SPIL_LOC(op)->aop = NULL;
806 /*-----------------------------------------------------------------*/
807 /* aopGet - for fetching value of the aop */
808 /*-----------------------------------------------------------------*/
809 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
814 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
815 /* offset is greater than
817 if (offset > (aop->size - 1) &&
818 aop->type != AOP_LIT)
821 /* depending on type */
826 DEBUGpic14_emitcode(";","%d",__LINE__);
827 /* if we need to increment it */
828 while (offset > aop->coff) {
829 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
833 while (offset < aop->coff) {
834 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
840 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
841 return (dname ? "acc" : "a");
843 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
844 rs = Safe_calloc(1,strlen(s)+1);
850 DEBUGpic14_emitcode(";","%d",__LINE__);
851 if (aop->type == AOP_DPTR2)
856 while (offset > aop->coff) {
857 pic14_emitcode ("inc","dptr");
861 while (offset < aop->coff) {
862 pic14_emitcode("lcall","__decdptr");
868 pic14_emitcode("clr","a");
869 pic14_emitcode("movc","a,@a+dptr");
872 pic14_emitcode("movx","a,@dptr");
875 if (aop->type == AOP_DPTR2)
880 return (dname ? "acc" : "a");
884 DEBUGpic14_emitcode(";","%d",__LINE__);
886 sprintf (s,"%s",aop->aopu.aop_immd);
889 sprintf(s,"(%s >> %d)",
895 rs = Safe_calloc(1,strlen(s)+1);
901 sprintf(s,"(%s + %d)",
905 sprintf(s,"%s",aop->aopu.aop_dir);
906 rs = Safe_calloc(1,strlen(s)+1);
911 DEBUGpic14_emitcode(";","%d",__LINE__);
913 return aop->aopu.aop_reg[offset]->dname;
915 return aop->aopu.aop_reg[offset]->name;
918 pic14_emitcode(";","%d",__LINE__);
919 //pic14_emitcode("clr","a");
920 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
921 //pic14_emitcode("rlc","a") ;
922 //return (dname ? "acc" : "a");
923 return aop->aopu.aop_dir;
926 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
927 //if (!offset && dname)
929 //return aop->aopu.aop_str[offset];
930 return "AOP_accumulator_bug";
933 DEBUGpic14_emitcode(";","%d",__LINE__);
934 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
935 rs = Safe_calloc(1,strlen(s)+1);
940 DEBUGpic14_emitcode(";","%d",__LINE__);
942 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
946 return aop->aopu.aop_str[offset];
950 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
951 "aopget got unsupported aop->type");
955 /*-----------------------------------------------------------------*/
956 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
957 /*-----------------------------------------------------------------*/
958 pCodeOp *popGetLabel(unsigned int key)
960 return newpCodeOpLabel(key+100+labelOffset);
963 /*-----------------------------------------------------------------*/
964 /* popCopyReg - copy a pcode operator */
965 /*-----------------------------------------------------------------*/
966 pCodeOp *popCopyReg(pCodeOpReg *pc)
970 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
971 pcor->pcop.type = pc->pcop.type;
972 if(!(pcor->pcop.name = strdup(pc->pcop.name)))
973 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
975 pcor->rIdx = pc->rIdx;
981 /*-----------------------------------------------------------------*/
982 /* popCopy - copy a pcode operator */
983 /*-----------------------------------------------------------------*/
984 pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval)
988 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
990 if(!(pcop->name = strdup(pc->pcop.name)))
991 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
992 ((pCodeOpBit *)pcop)->bit = bitval;
994 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
999 /*-----------------------------------------------------------------*/
1000 /* popGet - asm operator to pcode operator conversion */
1001 /*-----------------------------------------------------------------*/
1002 pCodeOp *popGetLit(unsigned int lit)
1005 return newpCodeOpLit(lit);
1009 /*-----------------------------------------------------------------*/
1010 /* popGet - asm operator to pcode operator conversion */
1011 /*-----------------------------------------------------------------*/
1012 pCodeOp *popGetWithString(char *str)
1018 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1022 pcop = newpCodeOp(str,PO_STR);
1027 pCodeOp *popRegFromString(char *str)
1030 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1031 pcop->type = PO_GPR_REGISTER;
1033 PCOR(pcop)->rIdx = -1;
1034 PCOR(pcop)->r = NULL;
1036 DEBUGpic14_emitcode(";","%d",__LINE__);
1037 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1042 /*-----------------------------------------------------------------*/
1043 /* popGet - asm operator to pcode operator conversion */
1044 /*-----------------------------------------------------------------*/
1045 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1052 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1053 /* offset is greater than
1056 if (offset > (aop->size - 1) &&
1057 aop->type != AOP_LIT)
1058 return NULL; //zero;
1060 /* depending on type */
1061 switch (aop->type) {
1068 DEBUGpic14_emitcode(";8051 legacy","%d",__LINE__);
1069 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1070 pcop->type = PO_SFR_REGISTER;
1072 PCOR(pcop)->rIdx = -1;
1073 PCOR(pcop)->r = NULL;
1074 // Really nasty hack to check for temporary registers
1076 pcop->name = Safe_strdup("BAD_REGISTER");
1081 DEBUGpic14_emitcode(";","%d",__LINE__);
1082 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1083 pcop->type = PO_IMMEDIATE;
1085 sprintf (s,"%s",aop->aopu.aop_immd);
1088 sprintf(s,"(%s >> %d)",
1093 aop->aopu.aop_immd);
1094 pcop->name = Safe_calloc(1,strlen(s)+1);
1095 strcpy(pcop->name,s);
1099 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1100 pcop->type = PO_DIR;
1102 sprintf(s,"(%s + %d)",
1106 sprintf(s,"%s",aop->aopu.aop_dir);
1107 pcop->name = Safe_calloc(1,strlen(s)+1);
1108 strcpy(pcop->name,s);
1113 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1115 DEBUGpic14_emitcode(";","%d",__LINE__);
1116 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1117 pcop->type = PO_GPR_REGISTER;
1118 PCOR(pcop)->rIdx = rIdx;
1119 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1120 pcop->type = PCOR(pcop)->r->pc_type;
1123 rs = aop->aopu.aop_reg[offset]->dname;
1125 rs = aop->aopu.aop_reg[offset]->name;
1127 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1133 pcop = newpCodeOpBit(aop->aopu.aop_dir,0);
1137 DEBUGpic14_emitcode(";","%d",__LINE__);
1138 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1141 DEBUGpic14_emitcode(";","%d",__LINE__);
1143 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1144 pcop->type = PO_STR;
1146 //aop->coff = offset ;
1147 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1148 sprintf(s,"%s","acc");
1150 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1151 pcop->name = Safe_calloc(1,strlen(s)+1);
1152 strcpy(pcop->name,s);
1157 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1158 "popGet got unsupported aop->type");
1161 /*-----------------------------------------------------------------*/
1162 /* aopPut - puts a string for a aop */
1163 /*-----------------------------------------------------------------*/
1164 void aopPut (asmop *aop, char *s, int offset)
1169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1171 if (aop->size && offset > ( aop->size - 1)) {
1172 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1173 "aopPut got offset > aop->size");
1177 /* will assign value to value */
1178 /* depending on where it is ofcourse */
1179 switch (aop->type) {
1182 sprintf(d,"(%s + %d)",
1183 aop->aopu.aop_dir,offset);
1185 sprintf(d,"%s",aop->aopu.aop_dir);
1188 DEBUGpic14_emitcode(";","%d",__LINE__);
1190 pic14_emitcode("movf","%s,w",s);
1191 pic14_emitcode("movwf","%s",d);
1194 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1195 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1202 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1203 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1206 strcmp(s,"r0") == 0 ||
1207 strcmp(s,"r1") == 0 ||
1208 strcmp(s,"r2") == 0 ||
1209 strcmp(s,"r3") == 0 ||
1210 strcmp(s,"r4") == 0 ||
1211 strcmp(s,"r5") == 0 ||
1212 strcmp(s,"r6") == 0 ||
1213 strcmp(s,"r7") == 0 )
1214 pic14_emitcode("mov","%s,%s ; %d",
1215 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1220 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1222 pic14_emitcode("movwf","%s",
1223 aop->aopu.aop_reg[offset]->name);
1226 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1227 pcop->type = PO_GPR_REGISTER;
1229 PCOR(pcop)->rIdx = -1;
1230 PCOR(pcop)->r = NULL;
1232 DEBUGpic14_emitcode(";","%d",__LINE__);
1233 pcop->name = Safe_strdup(s);
1234 emitpcode(POC_MOVFW,pcop);
1236 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1244 if (aop->type == AOP_DPTR2)
1250 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1251 "aopPut writting to code space");
1255 while (offset > aop->coff) {
1257 pic14_emitcode ("inc","dptr");
1260 while (offset < aop->coff) {
1262 pic14_emitcode("lcall","__decdptr");
1267 /* if not in accumulater */
1270 pic14_emitcode ("movx","@dptr,a");
1272 if (aop->type == AOP_DPTR2)
1280 while (offset > aop->coff) {
1282 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1284 while (offset < aop->coff) {
1286 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1292 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1297 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1299 if (strcmp(s,"r0") == 0 ||
1300 strcmp(s,"r1") == 0 ||
1301 strcmp(s,"r2") == 0 ||
1302 strcmp(s,"r3") == 0 ||
1303 strcmp(s,"r4") == 0 ||
1304 strcmp(s,"r5") == 0 ||
1305 strcmp(s,"r6") == 0 ||
1306 strcmp(s,"r7") == 0 ) {
1308 sprintf(buffer,"a%s",s);
1309 pic14_emitcode("mov","@%s,%s",
1310 aop->aopu.aop_ptr->name,buffer);
1312 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1317 if (strcmp(s,"a") == 0)
1318 pic14_emitcode("push","acc");
1320 pic14_emitcode("push","%s",s);
1325 /* if bit variable */
1326 if (!aop->aopu.aop_dir) {
1327 pic14_emitcode("clr","a");
1328 pic14_emitcode("rlc","a");
1331 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1334 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1337 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1339 lbl = newiTempLabel(NULL);
1341 if (strcmp(s,"a")) {
1344 pic14_emitcode("clr","c");
1345 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1346 pic14_emitcode("cpl","c");
1347 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1348 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1355 if (strcmp(aop->aopu.aop_str[offset],s))
1356 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1361 if (!offset && (strcmp(s,"acc") == 0))
1364 if (strcmp(aop->aopu.aop_str[offset],s))
1365 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1369 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1370 "aopPut got unsupported aop->type");
1376 /*-----------------------------------------------------------------*/
1377 /* reAdjustPreg - points a register back to where it should */
1378 /*-----------------------------------------------------------------*/
1379 static void reAdjustPreg (asmop *aop)
1383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1385 if ((size = aop->size) <= 1)
1388 switch (aop->type) {
1392 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1396 if (aop->type == AOP_DPTR2)
1402 pic14_emitcode("lcall","__decdptr");
1405 if (aop->type == AOP_DPTR2)
1415 /*-----------------------------------------------------------------*/
1416 /* genNotFloat - generates not for float operations */
1417 /*-----------------------------------------------------------------*/
1418 static void genNotFloat (operand *op, operand *res)
1424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1425 /* we will put 127 in the first byte of
1427 aopPut(AOP(res),"#127",0);
1428 size = AOP_SIZE(op) - 1;
1431 l = aopGet(op->aop,offset++,FALSE,FALSE);
1435 pic14_emitcode("orl","a,%s",
1437 offset++,FALSE,FALSE));
1439 tlbl = newiTempLabel(NULL);
1441 tlbl = newiTempLabel(NULL);
1442 aopPut(res->aop,one,1);
1443 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1444 aopPut(res->aop,zero,1);
1445 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1447 size = res->aop->size - 2;
1449 /* put zeros in the rest */
1451 aopPut(res->aop,zero,offset++);
1455 /*-----------------------------------------------------------------*/
1456 /* opIsGptr: returns non-zero if the passed operand is */
1457 /* a generic pointer type. */
1458 /*-----------------------------------------------------------------*/
1459 static int opIsGptr(operand *op)
1461 sym_link *type = operandType(op);
1463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1464 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1472 /*-----------------------------------------------------------------*/
1473 /* pic14_getDataSize - get the operand data size */
1474 /*-----------------------------------------------------------------*/
1475 int pic14_getDataSize(operand *op)
1477 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1480 return AOP_SIZE(op);
1482 // tsd- in the pic port, the genptr size is 1, so this code here
1483 // fails. ( in the 8051 port, the size was 4).
1486 size = AOP_SIZE(op);
1487 if (size == GPTRSIZE)
1489 sym_link *type = operandType(op);
1490 if (IS_GENPTR(type))
1492 /* generic pointer; arithmetic operations
1493 * should ignore the high byte (pointer type).
1496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1503 /*-----------------------------------------------------------------*/
1504 /* pic14_outAcc - output Acc */
1505 /*-----------------------------------------------------------------*/
1506 void pic14_outAcc(operand *result)
1509 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1510 size = pic14_getDataSize(result);
1512 aopPut(AOP(result),"a",0);
1515 /* unsigned or positive */
1517 aopPut(AOP(result),zero,offset++);
1522 /*-----------------------------------------------------------------*/
1523 /* pic14_outBitC - output a bit C */
1524 /*-----------------------------------------------------------------*/
1525 void pic14_outBitC(operand *result)
1528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1529 /* if the result is bit */
1530 if (AOP_TYPE(result) == AOP_CRY)
1531 aopPut(AOP(result),"c",0);
1533 pic14_emitcode("clr","a ; %d", __LINE__);
1534 pic14_emitcode("rlc","a");
1535 pic14_outAcc(result);
1539 /*-----------------------------------------------------------------*/
1540 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1541 /*-----------------------------------------------------------------*/
1542 void pic14_toBoolean(operand *oper)
1544 int size = AOP_SIZE(oper) - 1;
1547 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1549 if ( AOP_TYPE(oper) != AOP_ACC) {
1550 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1551 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1554 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1555 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1560 /*-----------------------------------------------------------------*/
1561 /* genNot - generate code for ! operation */
1562 /*-----------------------------------------------------------------*/
1563 static void genNot (iCode *ic)
1566 sym_link *optype = operandType(IC_LEFT(ic));
1568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1569 /* assign asmOps to operand & result */
1570 aopOp (IC_LEFT(ic),ic,FALSE);
1571 aopOp (IC_RESULT(ic),ic,TRUE);
1573 /* if in bit space then a special case */
1574 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1575 pic14_emitcode("movlw","1<<%s");
1576 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1577 //pic14_emitcode("cpl","c");
1578 //pic14_outBitC(IC_RESULT(ic));
1582 /* if type float then do float */
1583 if (IS_FLOAT(optype)) {
1584 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1588 pic14_toBoolean(IC_LEFT(ic));
1590 tlbl = newiTempLabel(NULL);
1591 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1592 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1593 pic14_outBitC(IC_RESULT(ic));
1596 /* release the aops */
1597 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1598 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1602 /*-----------------------------------------------------------------*/
1603 /* genCpl - generate code for complement */
1604 /*-----------------------------------------------------------------*/
1605 static void genCpl (iCode *ic)
1611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1612 /* assign asmOps to operand & result */
1613 aopOp (IC_LEFT(ic),ic,FALSE);
1614 aopOp (IC_RESULT(ic),ic,TRUE);
1616 /* if both are in bit space then
1618 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1619 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1621 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1622 pic14_emitcode("cpl","c");
1623 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1627 size = AOP_SIZE(IC_RESULT(ic));
1629 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1631 pic14_emitcode("cpl","a");
1632 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1637 /* release the aops */
1638 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1639 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1642 /*-----------------------------------------------------------------*/
1643 /* genUminusFloat - unary minus for floating points */
1644 /*-----------------------------------------------------------------*/
1645 static void genUminusFloat(operand *op,operand *result)
1647 int size ,offset =0 ;
1650 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1651 /* for this we just need to flip the
1652 first it then copy the rest in place */
1653 size = AOP_SIZE(op) - 1;
1654 l = aopGet(AOP(op),3,FALSE,FALSE);
1658 pic14_emitcode("cpl","acc.7");
1659 aopPut(AOP(result),"a",3);
1663 aopGet(AOP(op),offset,FALSE,FALSE),
1669 /*-----------------------------------------------------------------*/
1670 /* genUminus - unary minus code generation */
1671 /*-----------------------------------------------------------------*/
1672 static void genUminus (iCode *ic)
1675 sym_link *optype, *rtype;
1678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1680 aopOp(IC_LEFT(ic),ic,FALSE);
1681 aopOp(IC_RESULT(ic),ic,TRUE);
1683 /* if both in bit space then special
1685 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1686 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1688 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1689 pic14_emitcode("cpl","c");
1690 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1694 optype = operandType(IC_LEFT(ic));
1695 rtype = operandType(IC_RESULT(ic));
1697 /* if float then do float stuff */
1698 if (IS_FLOAT(optype)) {
1699 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1703 /* otherwise subtract from zero */
1704 size = AOP_SIZE(IC_LEFT(ic));
1708 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1709 if (!strcmp(l,"a")) {
1710 pic14_emitcode("cpl","a");
1711 pic14_emitcode("inc","a");
1713 pic14_emitcode("clr","a");
1714 pic14_emitcode("subb","a,%s",l);
1716 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1719 /* if any remaining bytes in the result */
1720 /* we just need to propagate the sign */
1721 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1722 pic14_emitcode("rlc","a");
1723 pic14_emitcode("subb","a,acc");
1725 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1729 /* release the aops */
1730 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1731 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1734 /*-----------------------------------------------------------------*/
1735 /* saveRegisters - will look for a call and save the registers */
1736 /*-----------------------------------------------------------------*/
1737 static void saveRegisters(iCode *lic)
1744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1746 for (ic = lic ; ic ; ic = ic->next)
1747 if (ic->op == CALL || ic->op == PCALL)
1751 fprintf(stderr,"found parameter push with no function call\n");
1755 /* if the registers have been saved already then
1757 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1760 /* find the registers in use at this time
1761 and push them away to safety */
1762 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1766 if (options.useXstack) {
1767 if (bitVectBitValue(rsave,R0_IDX))
1768 pic14_emitcode("mov","b,r0");
1769 pic14_emitcode("mov","r0,%s",spname);
1770 for (i = 0 ; i < pic14_nRegs ; i++) {
1771 if (bitVectBitValue(rsave,i)) {
1773 pic14_emitcode("mov","a,b");
1775 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1776 pic14_emitcode("movx","@r0,a");
1777 pic14_emitcode("inc","r0");
1780 pic14_emitcode("mov","%s,r0",spname);
1781 if (bitVectBitValue(rsave,R0_IDX))
1782 pic14_emitcode("mov","r0,b");
1784 for (i = 0 ; i < pic14_nRegs ; i++) {
1785 if (bitVectBitValue(rsave,i))
1786 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1789 detype = getSpec(operandType(IC_LEFT(ic)));
1791 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1792 IS_ISR(currFunc->etype) &&
1795 saverbank(SPEC_BANK(detype),ic,TRUE);
1798 /*-----------------------------------------------------------------*/
1799 /* unsaveRegisters - pop the pushed registers */
1800 /*-----------------------------------------------------------------*/
1801 static void unsaveRegisters (iCode *ic)
1806 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1807 /* find the registers in use at this time
1808 and push them away to safety */
1809 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1812 if (options.useXstack) {
1813 pic14_emitcode("mov","r0,%s",spname);
1814 for (i = pic14_nRegs ; i >= 0 ; i--) {
1815 if (bitVectBitValue(rsave,i)) {
1816 pic14_emitcode("dec","r0");
1817 pic14_emitcode("movx","a,@r0");
1819 pic14_emitcode("mov","b,a");
1821 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1825 pic14_emitcode("mov","%s,r0",spname);
1826 if (bitVectBitValue(rsave,R0_IDX))
1827 pic14_emitcode("mov","r0,b");
1829 for (i = pic14_nRegs ; i >= 0 ; i--) {
1830 if (bitVectBitValue(rsave,i))
1831 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1837 /*-----------------------------------------------------------------*/
1839 /*-----------------------------------------------------------------*/
1840 static void pushSide(operand * oper, int size)
1843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1845 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1846 if (AOP_TYPE(oper) != AOP_REG &&
1847 AOP_TYPE(oper) != AOP_DIR &&
1849 pic14_emitcode("mov","a,%s",l);
1850 pic14_emitcode("push","acc");
1852 pic14_emitcode("push","%s",l);
1856 /*-----------------------------------------------------------------*/
1857 /* assignResultValue - */
1858 /*-----------------------------------------------------------------*/
1859 static void assignResultValue(operand * oper)
1862 int size = AOP_SIZE(oper);
1864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1866 // The last byte in the assignment is in W
1867 aopPut(AOP(oper),"W",size-1);
1871 aopPut(AOP(oper),fReturn[offset],offset);
1879 /*-----------------------------------------------------------------*/
1880 /* genXpush - pushes onto the external stack */
1881 /*-----------------------------------------------------------------*/
1882 static void genXpush (iCode *ic)
1884 asmop *aop = newAsmop(0);
1886 int size,offset = 0;
1888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1889 aopOp(IC_LEFT(ic),ic,FALSE);
1890 r = getFreePtr(ic,&aop,FALSE);
1893 pic14_emitcode("mov","%s,_spx",r->name);
1895 size = AOP_SIZE(IC_LEFT(ic));
1898 char *l = aopGet(AOP(IC_LEFT(ic)),
1899 offset++,FALSE,FALSE);
1901 pic14_emitcode("movx","@%s,a",r->name);
1902 pic14_emitcode("inc","%s",r->name);
1907 pic14_emitcode("mov","_spx,%s",r->name);
1909 freeAsmop(NULL,aop,ic,TRUE);
1910 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1913 /*-----------------------------------------------------------------*/
1914 /* genIpush - genrate code for pushing this gets a little complex */
1915 /*-----------------------------------------------------------------*/
1916 static void genIpush (iCode *ic)
1918 int size, offset = 0 ;
1922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1923 /* if this is not a parm push : ie. it is spill push
1924 and spill push is always done on the local stack */
1925 if (!ic->parmPush) {
1927 /* and the item is spilt then do nothing */
1928 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1931 aopOp(IC_LEFT(ic),ic,FALSE);
1932 size = AOP_SIZE(IC_LEFT(ic));
1933 /* push it on the stack */
1935 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1940 pic14_emitcode("push","%s",l);
1945 /* this is a paramter push: in this case we call
1946 the routine to find the call and save those
1947 registers that need to be saved */
1950 /* if use external stack then call the external
1951 stack pushing routine */
1952 if (options.useXstack) {
1957 /* then do the push */
1958 aopOp(IC_LEFT(ic),ic,FALSE);
1961 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1962 size = AOP_SIZE(IC_LEFT(ic));
1965 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1966 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1967 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
1969 pic14_emitcode("mov","a,%s",l);
1970 pic14_emitcode("push","acc");
1972 pic14_emitcode("push","%s",l);
1975 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1978 /*-----------------------------------------------------------------*/
1979 /* genIpop - recover the registers: can happen only for spilling */
1980 /*-----------------------------------------------------------------*/
1981 static void genIpop (iCode *ic)
1986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1987 /* if the temp was not pushed then */
1988 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1991 aopOp(IC_LEFT(ic),ic,FALSE);
1992 size = AOP_SIZE(IC_LEFT(ic));
1995 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
1998 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2001 /*-----------------------------------------------------------------*/
2002 /* unsaverbank - restores the resgister bank from stack */
2003 /*-----------------------------------------------------------------*/
2004 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2012 if (options.useXstack) {
2014 r = getFreePtr(ic,&aop,FALSE);
2017 pic14_emitcode("mov","%s,_spx",r->name);
2018 pic14_emitcode("movx","a,@%s",r->name);
2019 pic14_emitcode("mov","psw,a");
2020 pic14_emitcode("dec","%s",r->name);
2023 pic14_emitcode ("pop","psw");
2026 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2027 if (options.useXstack) {
2028 pic14_emitcode("movx","a,@%s",r->name);
2029 //pic14_emitcode("mov","(%s+%d),a",
2030 // regspic14[i].base,8*bank+regspic14[i].offset);
2031 pic14_emitcode("dec","%s",r->name);
2034 pic14_emitcode("pop",""); //"(%s+%d)",
2035 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2038 if (options.useXstack) {
2040 pic14_emitcode("mov","_spx,%s",r->name);
2041 freeAsmop(NULL,aop,ic,TRUE);
2046 /*-----------------------------------------------------------------*/
2047 /* saverbank - saves an entire register bank on the stack */
2048 /*-----------------------------------------------------------------*/
2049 static void saverbank (int bank, iCode *ic, bool pushPsw)
2055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2056 if (options.useXstack) {
2059 r = getFreePtr(ic,&aop,FALSE);
2060 pic14_emitcode("mov","%s,_spx",r->name);
2064 for (i = 0 ; i < pic14_nRegs ;i++) {
2065 if (options.useXstack) {
2066 pic14_emitcode("inc","%s",r->name);
2067 //pic14_emitcode("mov","a,(%s+%d)",
2068 // regspic14[i].base,8*bank+regspic14[i].offset);
2069 pic14_emitcode("movx","@%s,a",r->name);
2071 pic14_emitcode("push","");// "(%s+%d)",
2072 //regspic14[i].base,8*bank+regspic14[i].offset);
2076 if (options.useXstack) {
2077 pic14_emitcode("mov","a,psw");
2078 pic14_emitcode("movx","@%s,a",r->name);
2079 pic14_emitcode("inc","%s",r->name);
2080 pic14_emitcode("mov","_spx,%s",r->name);
2081 freeAsmop (NULL,aop,ic,TRUE);
2084 pic14_emitcode("push","psw");
2086 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2092 /*-----------------------------------------------------------------*/
2093 /* genCall - generates a call statement */
2094 /*-----------------------------------------------------------------*/
2095 static void genCall (iCode *ic)
2099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2101 /* if caller saves & we have not saved then */
2105 /* if we are calling a function that is not using
2106 the same register bank then we need to save the
2107 destination registers on the stack */
2108 detype = getSpec(operandType(IC_LEFT(ic)));
2110 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2111 IS_ISR(currFunc->etype) &&
2114 saverbank(SPEC_BANK(detype),ic,TRUE);
2116 /* if send set is not empty the assign */
2120 for (sic = setFirstItem(_G.sendSet) ; sic ;
2121 sic = setNextItem(_G.sendSet)) {
2122 int size, offset = 0;
2124 aopOp(IC_LEFT(sic),sic,FALSE);
2125 size = AOP_SIZE(IC_LEFT(sic));
2127 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2129 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2131 if (strcmp(l,fReturn[offset])) {
2133 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2134 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2135 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2136 //pic14_emitcode("movlw","%s",l);
2138 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2139 //pic14_emitcode("movf","%s,w",l);
2141 // The last one is passed in W
2143 pic14_emitcode("movwf","%s",fReturn[offset]);
2147 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2152 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2153 OP_SYMBOL(IC_LEFT(ic))->rname :
2154 OP_SYMBOL(IC_LEFT(ic))->name));
2156 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2157 OP_SYMBOL(IC_LEFT(ic))->rname :
2158 OP_SYMBOL(IC_LEFT(ic))->name));
2160 /* if we need assign a result value */
2161 if ((IS_ITEMP(IC_RESULT(ic)) &&
2162 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2163 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2164 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2167 aopOp(IC_RESULT(ic),ic,FALSE);
2170 assignResultValue(IC_RESULT(ic));
2172 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2175 /* adjust the stack for parameters if
2177 if (ic->parmBytes) {
2179 if (ic->parmBytes > 3) {
2180 pic14_emitcode("mov","a,%s",spname);
2181 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2182 pic14_emitcode("mov","%s,a",spname);
2184 for ( i = 0 ; i < ic->parmBytes ;i++)
2185 pic14_emitcode("dec","%s",spname);
2189 /* if register bank was saved then pop them */
2191 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2193 /* if we hade saved some registers then unsave them */
2194 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2195 unsaveRegisters (ic);
2200 /*-----------------------------------------------------------------*/
2201 /* genPcall - generates a call by pointer statement */
2202 /*-----------------------------------------------------------------*/
2203 static void genPcall (iCode *ic)
2206 symbol *rlbl = newiTempLabel(NULL);
2209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2210 /* if caller saves & we have not saved then */
2214 /* if we are calling a function that is not using
2215 the same register bank then we need to save the
2216 destination registers on the stack */
2217 detype = getSpec(operandType(IC_LEFT(ic)));
2219 IS_ISR(currFunc->etype) &&
2220 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2221 saverbank(SPEC_BANK(detype),ic,TRUE);
2224 /* push the return address on to the stack */
2225 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2226 pic14_emitcode("push","acc");
2227 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2228 pic14_emitcode("push","acc");
2230 if (options.model == MODEL_FLAT24)
2232 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2233 pic14_emitcode("push","acc");
2236 /* now push the calling address */
2237 aopOp(IC_LEFT(ic),ic,FALSE);
2239 pushSide(IC_LEFT(ic), FPTRSIZE);
2241 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2243 /* if send set is not empty the assign */
2247 for (sic = setFirstItem(_G.sendSet) ; sic ;
2248 sic = setNextItem(_G.sendSet)) {
2249 int size, offset = 0;
2250 aopOp(IC_LEFT(sic),sic,FALSE);
2251 size = AOP_SIZE(IC_LEFT(sic));
2253 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2255 if (strcmp(l,fReturn[offset]))
2256 pic14_emitcode("mov","%s,%s",
2261 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2266 pic14_emitcode("ret","");
2267 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2270 /* if we need assign a result value */
2271 if ((IS_ITEMP(IC_RESULT(ic)) &&
2272 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2273 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2274 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2277 aopOp(IC_RESULT(ic),ic,FALSE);
2280 assignResultValue(IC_RESULT(ic));
2282 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2285 /* adjust the stack for parameters if
2287 if (ic->parmBytes) {
2289 if (ic->parmBytes > 3) {
2290 pic14_emitcode("mov","a,%s",spname);
2291 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2292 pic14_emitcode("mov","%s,a",spname);
2294 for ( i = 0 ; i < ic->parmBytes ;i++)
2295 pic14_emitcode("dec","%s",spname);
2299 /* if register bank was saved then unsave them */
2301 (SPEC_BANK(currFunc->etype) !=
2303 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2305 /* if we hade saved some registers then
2308 unsaveRegisters (ic);
2312 /*-----------------------------------------------------------------*/
2313 /* resultRemat - result is rematerializable */
2314 /*-----------------------------------------------------------------*/
2315 static int resultRemat (iCode *ic)
2317 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2318 if (SKIP_IC(ic) || ic->op == IFX)
2321 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2322 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2323 if (sym->remat && !POINTER_SET(ic))
2330 #if defined(__BORLANDC__) || defined(_MSC_VER)
2331 #define STRCASECMP stricmp
2333 #define STRCASECMP strcasecmp
2336 /*-----------------------------------------------------------------*/
2337 /* inExcludeList - return 1 if the string is in exclude Reg list */
2338 /*-----------------------------------------------------------------*/
2339 static bool inExcludeList(char *s)
2343 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2344 if (options.excludeRegs[i] &&
2345 STRCASECMP(options.excludeRegs[i],"none") == 0)
2348 for ( i = 0 ; options.excludeRegs[i]; i++) {
2349 if (options.excludeRegs[i] &&
2350 STRCASECMP(s,options.excludeRegs[i]) == 0)
2356 /*-----------------------------------------------------------------*/
2357 /* genFunction - generated code for function entry */
2358 /*-----------------------------------------------------------------*/
2359 static void genFunction (iCode *ic)
2364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2365 labelOffset += FUNCTION_LABEL_INC;
2368 /* create the function header */
2369 pic14_emitcode(";","-----------------------------------------");
2370 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2371 pic14_emitcode(";","-----------------------------------------");
2373 pic14_emitcode("","%s:",sym->rname);
2374 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2376 fetype = getSpec(operandType(IC_LEFT(ic)));
2378 /* if critical function then turn interrupts off */
2379 if (SPEC_CRTCL(fetype))
2380 pic14_emitcode("clr","ea");
2382 /* here we need to generate the equates for the
2383 register bank if required */
2385 if (SPEC_BANK(fetype) != rbank) {
2388 rbank = SPEC_BANK(fetype);
2389 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2390 if (strcmp(regspic14[i].base,"0") == 0)
2391 pic14_emitcode("","%s = 0x%02x",
2393 8*rbank+regspic14[i].offset);
2395 pic14_emitcode ("","%s = %s + 0x%02x",
2398 8*rbank+regspic14[i].offset);
2403 /* if this is an interrupt service routine then
2404 save acc, b, dpl, dph */
2405 if (IS_ISR(sym->etype)) {
2407 if (!inExcludeList("acc"))
2408 pic14_emitcode ("push","acc");
2409 if (!inExcludeList("b"))
2410 pic14_emitcode ("push","b");
2411 if (!inExcludeList("dpl"))
2412 pic14_emitcode ("push","dpl");
2413 if (!inExcludeList("dph"))
2414 pic14_emitcode ("push","dph");
2415 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2417 pic14_emitcode ("push", "dpx");
2418 /* Make sure we're using standard DPTR */
2419 pic14_emitcode ("push", "dps");
2420 pic14_emitcode ("mov", "dps, #0x00");
2421 if (options.stack10bit)
2423 /* This ISR could conceivably use DPTR2. Better save it. */
2424 pic14_emitcode ("push", "dpl1");
2425 pic14_emitcode ("push", "dph1");
2426 pic14_emitcode ("push", "dpx1");
2429 /* if this isr has no bank i.e. is going to
2430 run with bank 0 , then we need to save more
2432 if (!SPEC_BANK(sym->etype)) {
2434 /* if this function does not call any other
2435 function then we can be economical and
2436 save only those registers that are used */
2437 if (! sym->hasFcall) {
2440 /* if any registers used */
2441 if (sym->regsUsed) {
2442 /* save the registers used */
2443 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2444 if (bitVectBitValue(sym->regsUsed,i) ||
2445 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2446 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2451 /* this function has a function call cannot
2452 determines register usage so we will have the
2454 saverbank(0,ic,FALSE);
2458 /* if callee-save to be used for this function
2459 then save the registers being used in this function */
2460 if (sym->calleeSave) {
2463 /* if any registers used */
2464 if (sym->regsUsed) {
2465 /* save the registers used */
2466 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2467 if (bitVectBitValue(sym->regsUsed,i) ||
2468 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2469 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2477 /* set the register bank to the desired value */
2478 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2479 pic14_emitcode("push","psw");
2480 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2483 if (IS_RENT(sym->etype) || options.stackAuto) {
2485 if (options.useXstack) {
2486 pic14_emitcode("mov","r0,%s",spname);
2487 pic14_emitcode("mov","a,_bp");
2488 pic14_emitcode("movx","@r0,a");
2489 pic14_emitcode("inc","%s",spname);
2493 /* set up the stack */
2494 pic14_emitcode ("push","_bp"); /* save the callers stack */
2496 pic14_emitcode ("mov","_bp,%s",spname);
2499 /* adjust the stack for the function */
2504 werror(W_STACK_OVERFLOW,sym->name);
2506 if (i > 3 && sym->recvSize < 4) {
2508 pic14_emitcode ("mov","a,sp");
2509 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2510 pic14_emitcode ("mov","sp,a");
2515 pic14_emitcode("inc","sp");
2520 pic14_emitcode ("mov","a,_spx");
2521 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2522 pic14_emitcode ("mov","_spx,a");
2527 /*-----------------------------------------------------------------*/
2528 /* genEndFunction - generates epilogue for functions */
2529 /*-----------------------------------------------------------------*/
2530 static void genEndFunction (iCode *ic)
2532 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2536 if (IS_RENT(sym->etype) || options.stackAuto)
2538 pic14_emitcode ("mov","%s,_bp",spname);
2541 /* if use external stack but some variables were
2542 added to the local stack then decrement the
2544 if (options.useXstack && sym->stack) {
2545 pic14_emitcode("mov","a,sp");
2546 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2547 pic14_emitcode("mov","sp,a");
2551 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2552 if (options.useXstack) {
2553 pic14_emitcode("mov","r0,%s",spname);
2554 pic14_emitcode("movx","a,@r0");
2555 pic14_emitcode("mov","_bp,a");
2556 pic14_emitcode("dec","%s",spname);
2560 pic14_emitcode ("pop","_bp");
2564 /* restore the register bank */
2565 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2566 pic14_emitcode ("pop","psw");
2568 if (IS_ISR(sym->etype)) {
2570 /* now we need to restore the registers */
2571 /* if this isr has no bank i.e. is going to
2572 run with bank 0 , then we need to save more
2574 if (!SPEC_BANK(sym->etype)) {
2576 /* if this function does not call any other
2577 function then we can be economical and
2578 save only those registers that are used */
2579 if (! sym->hasFcall) {
2582 /* if any registers used */
2583 if (sym->regsUsed) {
2584 /* save the registers used */
2585 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2586 if (bitVectBitValue(sym->regsUsed,i) ||
2587 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2588 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2593 /* this function has a function call cannot
2594 determines register usage so we will have the
2596 unsaverbank(0,ic,FALSE);
2600 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2602 if (options.stack10bit)
2604 pic14_emitcode ("pop", "dpx1");
2605 pic14_emitcode ("pop", "dph1");
2606 pic14_emitcode ("pop", "dpl1");
2608 pic14_emitcode ("pop", "dps");
2609 pic14_emitcode ("pop", "dpx");
2611 if (!inExcludeList("dph"))
2612 pic14_emitcode ("pop","dph");
2613 if (!inExcludeList("dpl"))
2614 pic14_emitcode ("pop","dpl");
2615 if (!inExcludeList("b"))
2616 pic14_emitcode ("pop","b");
2617 if (!inExcludeList("acc"))
2618 pic14_emitcode ("pop","acc");
2620 if (SPEC_CRTCL(sym->etype))
2621 pic14_emitcode("setb","ea");
2623 /* if debug then send end of function */
2624 /* if (options.debug && currFunc) { */
2627 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2628 FileBaseName(ic->filename),currFunc->lastLine,
2629 ic->level,ic->block);
2630 if (IS_STATIC(currFunc->etype))
2631 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2633 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2637 pic14_emitcode ("reti","");
2640 if (SPEC_CRTCL(sym->etype))
2641 pic14_emitcode("setb","ea");
2643 if (sym->calleeSave) {
2646 /* if any registers used */
2647 if (sym->regsUsed) {
2648 /* save the registers used */
2649 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2650 if (bitVectBitValue(sym->regsUsed,i) ||
2651 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2652 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2658 /* if debug then send end of function */
2661 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2662 FileBaseName(ic->filename),currFunc->lastLine,
2663 ic->level,ic->block);
2664 if (IS_STATIC(currFunc->etype))
2665 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2667 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2671 pic14_emitcode ("return","");
2672 emitpcode(POC_RETURN,NULL);
2674 /* Mark the end of a function */
2675 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2680 /*-----------------------------------------------------------------*/
2681 /* genRet - generate code for return statement */
2682 /*-----------------------------------------------------------------*/
2683 static void genRet (iCode *ic)
2685 int size,offset = 0 , pushed = 0;
2687 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2688 /* if we have no return value then
2689 just generate the "ret" */
2693 /* we have something to return then
2694 move the return value into place */
2695 aopOp(IC_LEFT(ic),ic,FALSE);
2696 size = AOP_SIZE(IC_LEFT(ic));
2700 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2702 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2704 pic14_emitcode("push","%s",l);
2707 l = aopGet(AOP(IC_LEFT(ic)),offset,
2709 if (strcmp(fReturn[offset],l)) {
2710 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2711 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2712 pic14_emitcode("movlw","%s",l);
2714 pic14_emitcode("movf","%s,w",l);
2716 pic14_emitcode("movwf","%s",fReturn[offset]);
2725 if (strcmp(fReturn[pushed],"a"))
2726 pic14_emitcode("pop",fReturn[pushed]);
2728 pic14_emitcode("pop","acc");
2731 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2734 /* generate a jump to the return label
2735 if the next is not the return statement */
2736 if (!(ic->next && ic->next->op == LABEL &&
2737 IC_LABEL(ic->next) == returnLabel))
2739 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2743 /*-----------------------------------------------------------------*/
2744 /* genLabel - generates a label */
2745 /*-----------------------------------------------------------------*/
2746 static void genLabel (iCode *ic)
2748 /* special case never generate */
2749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2750 if (IC_LABEL(ic) == entryLabel)
2753 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2754 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2757 /*-----------------------------------------------------------------*/
2758 /* genGoto - generates a goto */
2759 /*-----------------------------------------------------------------*/
2761 static void genGoto (iCode *ic)
2763 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2766 /*-----------------------------------------------------------------*/
2767 /* findLabelBackwards: walks back through the iCode chain looking */
2768 /* for the given label. Returns number of iCode instructions */
2769 /* between that label and given ic. */
2770 /* Returns zero if label not found. */
2771 /*-----------------------------------------------------------------*/
2773 static int findLabelBackwards(iCode *ic, int key)
2777 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2783 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2785 /* printf("findLabelBackwards = %d\n", count); */
2794 /*-----------------------------------------------------------------*/
2795 /* genMultbits :- multiplication of bits */
2796 /*-----------------------------------------------------------------*/
2797 static void genMultbits (operand *left,
2801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2803 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2804 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2805 pic14_outBitC(result);
2809 /*-----------------------------------------------------------------*/
2810 /* genMultOneByte : 8 bit multiplication & division */
2811 /*-----------------------------------------------------------------*/
2812 static void genMultOneByte (operand *left,
2816 sym_link *opetype = operandType(result);
2821 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2822 /* (if two literals, the value is computed before) */
2823 /* if one literal, literal on the right */
2824 if (AOP_TYPE(left) == AOP_LIT){
2830 size = AOP_SIZE(result);
2831 /* signed or unsigned */
2832 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2833 l = aopGet(AOP(left),0,FALSE,FALSE);
2835 pic14_emitcode("mul","ab");
2836 /* if result size = 1, mul signed = mul unsigned */
2837 aopPut(AOP(result),"a",0);
2839 if (SPEC_USIGN(opetype)){
2840 aopPut(AOP(result),"b",1);
2842 /* for filling the MSBs */
2843 pic14_emitcode("clr","a");
2846 pic14_emitcode("mov","a,b");
2848 /* adjust the MSB if left or right neg */
2850 /* if one literal */
2851 if (AOP_TYPE(right) == AOP_LIT){
2852 /* AND literal negative */
2853 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2854 /* adjust MSB (c==0 after mul) */
2855 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2859 lbl = newiTempLabel(NULL);
2860 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2861 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2862 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2863 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2864 lbl = newiTempLabel(NULL);
2865 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2866 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2867 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2870 lbl = newiTempLabel(NULL);
2871 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2872 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2873 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2874 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2875 lbl = newiTempLabel(NULL);
2876 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2877 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2878 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2880 aopPut(AOP(result),"a",1);
2883 pic14_emitcode("rlc","a");
2884 pic14_emitcode("subb","a,acc");
2891 aopPut(AOP(result),"a",offset++);
2895 /*-----------------------------------------------------------------*/
2896 /* genMult - generates code for multiplication */
2897 /*-----------------------------------------------------------------*/
2898 static void genMult (iCode *ic)
2900 operand *left = IC_LEFT(ic);
2901 operand *right = IC_RIGHT(ic);
2902 operand *result= IC_RESULT(ic);
2904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2905 /* assign the amsops */
2906 aopOp (left,ic,FALSE);
2907 aopOp (right,ic,FALSE);
2908 aopOp (result,ic,TRUE);
2910 /* special cases first */
2912 if (AOP_TYPE(left) == AOP_CRY &&
2913 AOP_TYPE(right)== AOP_CRY) {
2914 genMultbits(left,right,result);
2918 /* if both are of size == 1 */
2919 if (AOP_SIZE(left) == 1 &&
2920 AOP_SIZE(right) == 1 ) {
2921 genMultOneByte(left,right,result);
2925 /* should have been converted to function call */
2929 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2930 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2931 freeAsmop(result,NULL,ic,TRUE);
2934 /*-----------------------------------------------------------------*/
2935 /* genDivbits :- division of bits */
2936 /*-----------------------------------------------------------------*/
2937 static void genDivbits (operand *left,
2944 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2945 /* the result must be bit */
2946 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2947 l = aopGet(AOP(left),0,FALSE,FALSE);
2951 pic14_emitcode("div","ab");
2952 pic14_emitcode("rrc","a");
2953 aopPut(AOP(result),"c",0);
2956 /*-----------------------------------------------------------------*/
2957 /* genDivOneByte : 8 bit division */
2958 /*-----------------------------------------------------------------*/
2959 static void genDivOneByte (operand *left,
2963 sym_link *opetype = operandType(result);
2968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2969 size = AOP_SIZE(result) - 1;
2971 /* signed or unsigned */
2972 if (SPEC_USIGN(opetype)) {
2973 /* unsigned is easy */
2974 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2975 l = aopGet(AOP(left),0,FALSE,FALSE);
2977 pic14_emitcode("div","ab");
2978 aopPut(AOP(result),"a",0);
2980 aopPut(AOP(result),zero,offset++);
2984 /* signed is a little bit more difficult */
2986 /* save the signs of the operands */
2987 l = aopGet(AOP(left),0,FALSE,FALSE);
2989 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
2990 pic14_emitcode("push","acc"); /* save it on the stack */
2992 /* now sign adjust for both left & right */
2993 l = aopGet(AOP(right),0,FALSE,FALSE);
2995 lbl = newiTempLabel(NULL);
2996 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
2997 pic14_emitcode("cpl","a");
2998 pic14_emitcode("inc","a");
2999 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3000 pic14_emitcode("mov","b,a");
3002 /* sign adjust left side */
3003 l = aopGet(AOP(left),0,FALSE,FALSE);
3006 lbl = newiTempLabel(NULL);
3007 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3008 pic14_emitcode("cpl","a");
3009 pic14_emitcode("inc","a");
3010 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3012 /* now the division */
3013 pic14_emitcode("div","ab");
3014 /* we are interested in the lower order
3016 pic14_emitcode("mov","b,a");
3017 lbl = newiTempLabel(NULL);
3018 pic14_emitcode("pop","acc");
3019 /* if there was an over flow we don't
3020 adjust the sign of the result */
3021 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3022 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3024 pic14_emitcode("clr","a");
3025 pic14_emitcode("subb","a,b");
3026 pic14_emitcode("mov","b,a");
3027 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3029 /* now we are done */
3030 aopPut(AOP(result),"b",0);
3032 pic14_emitcode("mov","c,b.7");
3033 pic14_emitcode("subb","a,acc");
3036 aopPut(AOP(result),"a",offset++);
3040 /*-----------------------------------------------------------------*/
3041 /* genDiv - generates code for division */
3042 /*-----------------------------------------------------------------*/
3043 static void genDiv (iCode *ic)
3045 operand *left = IC_LEFT(ic);
3046 operand *right = IC_RIGHT(ic);
3047 operand *result= IC_RESULT(ic);
3049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3050 /* assign the amsops */
3051 aopOp (left,ic,FALSE);
3052 aopOp (right,ic,FALSE);
3053 aopOp (result,ic,TRUE);
3055 /* special cases first */
3057 if (AOP_TYPE(left) == AOP_CRY &&
3058 AOP_TYPE(right)== AOP_CRY) {
3059 genDivbits(left,right,result);
3063 /* if both are of size == 1 */
3064 if (AOP_SIZE(left) == 1 &&
3065 AOP_SIZE(right) == 1 ) {
3066 genDivOneByte(left,right,result);
3070 /* should have been converted to function call */
3073 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3074 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3075 freeAsmop(result,NULL,ic,TRUE);
3078 /*-----------------------------------------------------------------*/
3079 /* genModbits :- modulus of bits */
3080 /*-----------------------------------------------------------------*/
3081 static void genModbits (operand *left,
3088 /* the result must be bit */
3089 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3090 l = aopGet(AOP(left),0,FALSE,FALSE);
3094 pic14_emitcode("div","ab");
3095 pic14_emitcode("mov","a,b");
3096 pic14_emitcode("rrc","a");
3097 aopPut(AOP(result),"c",0);
3100 /*-----------------------------------------------------------------*/
3101 /* genModOneByte : 8 bit modulus */
3102 /*-----------------------------------------------------------------*/
3103 static void genModOneByte (operand *left,
3107 sym_link *opetype = operandType(result);
3111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3112 /* signed or unsigned */
3113 if (SPEC_USIGN(opetype)) {
3114 /* unsigned is easy */
3115 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3116 l = aopGet(AOP(left),0,FALSE,FALSE);
3118 pic14_emitcode("div","ab");
3119 aopPut(AOP(result),"b",0);
3123 /* signed is a little bit more difficult */
3125 /* save the signs of the operands */
3126 l = aopGet(AOP(left),0,FALSE,FALSE);
3129 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3130 pic14_emitcode("push","acc"); /* save it on the stack */
3132 /* now sign adjust for both left & right */
3133 l = aopGet(AOP(right),0,FALSE,FALSE);
3136 lbl = newiTempLabel(NULL);
3137 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3138 pic14_emitcode("cpl","a");
3139 pic14_emitcode("inc","a");
3140 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3141 pic14_emitcode("mov","b,a");
3143 /* sign adjust left side */
3144 l = aopGet(AOP(left),0,FALSE,FALSE);
3147 lbl = newiTempLabel(NULL);
3148 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3149 pic14_emitcode("cpl","a");
3150 pic14_emitcode("inc","a");
3151 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3153 /* now the multiplication */
3154 pic14_emitcode("div","ab");
3155 /* we are interested in the lower order
3157 lbl = newiTempLabel(NULL);
3158 pic14_emitcode("pop","acc");
3159 /* if there was an over flow we don't
3160 adjust the sign of the result */
3161 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3162 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3164 pic14_emitcode("clr","a");
3165 pic14_emitcode("subb","a,b");
3166 pic14_emitcode("mov","b,a");
3167 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3169 /* now we are done */
3170 aopPut(AOP(result),"b",0);
3174 /*-----------------------------------------------------------------*/
3175 /* genMod - generates code for division */
3176 /*-----------------------------------------------------------------*/
3177 static void genMod (iCode *ic)
3179 operand *left = IC_LEFT(ic);
3180 operand *right = IC_RIGHT(ic);
3181 operand *result= IC_RESULT(ic);
3183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3184 /* assign the amsops */
3185 aopOp (left,ic,FALSE);
3186 aopOp (right,ic,FALSE);
3187 aopOp (result,ic,TRUE);
3189 /* special cases first */
3191 if (AOP_TYPE(left) == AOP_CRY &&
3192 AOP_TYPE(right)== AOP_CRY) {
3193 genModbits(left,right,result);
3197 /* if both are of size == 1 */
3198 if (AOP_SIZE(left) == 1 &&
3199 AOP_SIZE(right) == 1 ) {
3200 genModOneByte(left,right,result);
3204 /* should have been converted to function call */
3208 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3209 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3210 freeAsmop(result,NULL,ic,TRUE);
3213 /*-----------------------------------------------------------------*/
3214 /* genIfxJump :- will create a jump depending on the ifx */
3215 /*-----------------------------------------------------------------*/
3216 static void genIfxJump (iCode *ic, char *jval)
3219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3220 /* if true label then we jump if condition
3222 if ( IC_TRUE(ic) ) {
3224 if(strcmp(jval,"a") == 0)
3226 else if (strcmp(jval,"c") == 0)
3229 //pCodeOp *p = popGetWithString(jval);
3231 //emitpcode(POC_BTFSC, p);
3232 emitpcode(POC_BTFSC, newpCodeOpBit(jval,0));
3233 //pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval);
3236 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3237 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3241 /* false label is present */
3242 if(strcmp(jval,"a") == 0)
3244 else if (strcmp(jval,"c") == 0)
3247 //pCodeOp *p = popGetWithString(jval);
3249 //emitpcode(POC_BTFSS, p);
3250 emitpcode(POC_BTFSS, newpCodeOpBit(jval,0));
3252 // pic14_emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval);
3255 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3256 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3261 /* mark the icode as generated */
3265 /*-----------------------------------------------------------------*/
3267 /*-----------------------------------------------------------------*/
3268 static void genSkip(iCode *ifx,int status_bit)
3273 if ( IC_TRUE(ifx) ) {
3274 switch(status_bit) {
3289 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3290 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3294 switch(status_bit) {
3308 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3309 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3315 /*-----------------------------------------------------------------*/
3317 /*-----------------------------------------------------------------*/
3318 static void genSkipc(iCode *ifx, int condition)
3329 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3331 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3334 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3336 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3340 /*-----------------------------------------------------------------*/
3342 /*-----------------------------------------------------------------*/
3343 static void genSkipz(iCode *ifx, int condition)
3354 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3356 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3359 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3361 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3364 /*-----------------------------------------------------------------*/
3365 /* genCmp :- greater or less than comparison */
3366 /*-----------------------------------------------------------------*/
3367 static void genCmp (operand *left,operand *right,
3368 operand *result, iCode *ifx, int sign)
3370 int size, offset = 0 ;
3371 unsigned long lit = 0L,i = 0;
3373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3374 /* if left & right are bit variables */
3375 if (AOP_TYPE(left) == AOP_CRY &&
3376 AOP_TYPE(right) == AOP_CRY ) {
3377 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3378 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3380 /* subtract right from left if at the
3381 end the carry flag is set then we know that
3382 left is greater than right */
3383 size = max(AOP_SIZE(left),AOP_SIZE(right));
3385 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3386 if((size == 1) && !sign &&
3387 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3388 symbol *lbl = newiTempLabel(NULL);
3389 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3390 aopGet(AOP(left),offset,FALSE,FALSE),
3391 aopGet(AOP(right),offset,FALSE,FALSE),
3393 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3396 if(AOP_TYPE(right) == AOP_LIT) {
3398 DEBUGpic14_emitcode(";right lit","%d",sign);
3400 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3403 i = (lit >> (size*8)) & 0xff;
3405 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3406 pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3407 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3409 emitpcode(POC_MOVLW, popGetLit(i));
3410 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3412 pic14_emitcode("movlw","0x%x",i);
3413 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3414 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3421 if(AOP_TYPE(left) == AOP_LIT) {
3423 DEBUGpic14_emitcode(";left lit","%d",sign);
3425 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3429 i = (lit >> (size*8)) & 0xff;
3431 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3432 pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3433 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3434 } else if( i == 1 ) {
3435 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3436 pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3437 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3440 emitpcode(POC_MOVLW, popGetLit(i));
3441 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3443 pic14_emitcode("movlw","0x%x",i);
3444 pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3445 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3454 DEBUGpic14_emitcode(";sign","%d",sign);
3456 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3457 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3459 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3460 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3465 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3467 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3468 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3471 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3473 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3474 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3482 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3483 pic14_outBitC(result);
3485 /* if the result is used in the next
3486 ifx conditional branch then generate
3487 code a little differently */
3489 genIfxJump (ifx,"c");
3491 pic14_outBitC(result);
3492 /* leave the result in acc */
3497 /*-----------------------------------------------------------------*/
3498 /* genCmpGt :- greater than comparison */
3499 /*-----------------------------------------------------------------*/
3500 static void genCmpGt (iCode *ic, iCode *ifx)
3502 operand *left, *right, *result;
3503 sym_link *letype , *retype;
3506 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3508 right= IC_RIGHT(ic);
3509 result = IC_RESULT(ic);
3511 letype = getSpec(operandType(left));
3512 retype =getSpec(operandType(right));
3513 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3514 /* assign the amsops */
3515 aopOp (left,ic,FALSE);
3516 aopOp (right,ic,FALSE);
3517 aopOp (result,ic,TRUE);
3519 genCmp(right, left, result, ifx, sign);
3521 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3522 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3523 freeAsmop(result,NULL,ic,TRUE);
3526 /*-----------------------------------------------------------------*/
3527 /* genCmpLt - less than comparisons */
3528 /*-----------------------------------------------------------------*/
3529 static void genCmpLt (iCode *ic, iCode *ifx)
3531 operand *left, *right, *result;
3532 sym_link *letype , *retype;
3535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3537 right= IC_RIGHT(ic);
3538 result = IC_RESULT(ic);
3540 letype = getSpec(operandType(left));
3541 retype =getSpec(operandType(right));
3542 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3544 /* assign the amsops */
3545 aopOp (left,ic,FALSE);
3546 aopOp (right,ic,FALSE);
3547 aopOp (result,ic,TRUE);
3549 genCmp(left, right, result, ifx, sign);
3551 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3552 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3553 freeAsmop(result,NULL,ic,TRUE);
3556 /*-----------------------------------------------------------------*/
3557 /* gencjneshort - compare and jump if not equal */
3558 /*-----------------------------------------------------------------*/
3559 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3561 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3563 unsigned long lit = 0L;
3565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3566 /* if the left side is a literal or
3567 if the right is in a pointer register and left
3569 if ((AOP_TYPE(left) == AOP_LIT) ||
3570 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3575 if(AOP_TYPE(right) == AOP_LIT)
3576 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3578 /* if the right side is a literal then anything goes */
3579 if (AOP_TYPE(right) == AOP_LIT &&
3580 AOP_TYPE(left) != AOP_DIR ) {
3583 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3584 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3586 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3589 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3595 /* if the right side is in a register or in direct space or
3596 if the left is a pointer register & right is not */
3597 else if (AOP_TYPE(right) == AOP_REG ||
3598 AOP_TYPE(right) == AOP_DIR ||
3599 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3600 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3602 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3603 ( (lit & 0xff) != 0)) {
3604 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3605 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3608 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3611 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3614 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
3615 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3616 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
3617 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
3619 pic14_emitcode("cjne","a,%s,%05d_DS_",
3620 aopGet(AOP(right),offset,FALSE,TRUE),
3626 /* right is a pointer reg need both a & b */
3628 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3630 pic14_emitcode("mov","b,%s",l);
3631 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3632 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3638 /*-----------------------------------------------------------------*/
3639 /* gencjne - compare and jump if not equal */
3640 /*-----------------------------------------------------------------*/
3641 static void gencjne(operand *left, operand *right, symbol *lbl)
3643 symbol *tlbl = newiTempLabel(NULL);
3645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3646 gencjneshort(left, right, lbl);
3648 pic14_emitcode("mov","a,%s",one);
3649 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3650 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3651 pic14_emitcode("clr","a");
3652 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3656 /*-----------------------------------------------------------------*/
3657 /* genCmpEq - generates code for equal to */
3658 /*-----------------------------------------------------------------*/
3659 static void genCmpEq (iCode *ic, iCode *ifx)
3661 operand *left, *right, *result;
3662 unsigned long lit = 0L;
3665 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3667 DEBUGpic14_emitcode ("; ifx is non-null","");
3669 DEBUGpic14_emitcode ("; ifx is null","");
3671 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3672 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3673 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3675 size = max(AOP_SIZE(left),AOP_SIZE(right));
3677 /* if literal, literal on the right or
3678 if the right is in a pointer register and left
3680 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3681 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3682 operand *t = IC_RIGHT(ic);
3683 IC_RIGHT(ic) = IC_LEFT(ic);
3687 if(ifx && !AOP_SIZE(result)){
3689 /* if they are both bit variables */
3690 if (AOP_TYPE(left) == AOP_CRY &&
3691 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3692 if(AOP_TYPE(right) == AOP_LIT){
3693 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3695 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3696 pic14_emitcode("cpl","c");
3697 } else if(lit == 1L) {
3698 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3700 pic14_emitcode("clr","c");
3702 /* AOP_TYPE(right) == AOP_CRY */
3704 symbol *lbl = newiTempLabel(NULL);
3705 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3706 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3707 pic14_emitcode("cpl","c");
3708 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3710 /* if true label then we jump if condition
3712 tlbl = newiTempLabel(NULL);
3713 if ( IC_TRUE(ifx) ) {
3714 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3715 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3717 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3718 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3720 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3723 /* They're not both bit variables. Is the right a literal? */
3724 if(AOP_TYPE(right) == AOP_LIT) {
3726 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3731 int h = (lit>>8) & 0xff;
3734 /* Check special cases for integers */
3735 switch(lit & 0xffff) {
3737 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3738 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3739 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3740 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3745 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3746 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3747 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3748 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3753 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3754 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3755 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3756 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3761 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3762 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3763 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3764 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3769 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3770 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3771 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3772 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3778 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3779 emitpcode(POC_XORLW,popGetLit(l));
3780 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3782 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3783 pic14_emitcode("xorlw","0x%x",l);
3784 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3787 } else if (l == 0) {
3788 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3789 emitpcode(POC_XORLW,popGetLit(h));
3790 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3792 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3793 pic14_emitcode("xorlw","0x%x",h);
3794 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3798 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3799 emitpcode(POC_XORLW,popGetLit(l));
3800 emitpcode(POC_MOVLW,popGetLit(h));
3802 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3804 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3805 pic14_emitcode("xorlw","0x%x",l);
3806 pic14_emitcode("movlw","0x%x",h);
3808 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3825 switch(lit & 0xff) {
3827 if ( IC_TRUE(ifx) ) {
3829 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3831 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3833 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3835 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3837 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3838 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3840 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3841 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3845 if ( IC_TRUE(ifx) ) {
3846 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3848 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3850 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3852 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3854 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3855 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3857 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3858 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3862 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3863 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3865 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3866 //pic14_emitcode("xorlw","0x%x",lit & 0xff);
3871 // pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
3872 //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3877 } else if(AOP_TYPE(right) == AOP_CRY ) {
3878 /* we know the left is not a bit, but that the right is */
3879 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3880 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3881 popGet(AOP(right),offset,FALSE,FALSE));
3882 emitpcode(POC_XORLW,popGetLit(1));
3884 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3886 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3887 AOP(right)->aopu.aop_dir,
3888 AOP(right)->aopu.aop_dir);
3890 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3891 AOP(right)->aopu.aop_dir,
3892 AOP(right)->aopu.aop_dir);
3894 pic14_emitcode("xorlw","1");
3896 /* if the two are equal, then W will be 0 and the Z bit is set
3897 * we could test Z now, or go ahead and check the high order bytes if
3898 * the variable we're comparing is larger than a byte. */
3901 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3902 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3904 if ( IC_TRUE(ifx) ) {
3906 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3907 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3910 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3911 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3915 /* They're both variables that are larger than bits */
3918 tlbl = newiTempLabel(NULL);
3921 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3922 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3924 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3925 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3927 if ( IC_TRUE(ifx) ) {
3930 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3931 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3934 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3935 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3939 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3940 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3944 if(s>1 && IC_TRUE(ifx)) {
3945 emitpLabel(tlbl->key+100+labelOffset);
3946 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3950 /* mark the icode as generated */
3955 /* if they are both bit variables */
3956 if (AOP_TYPE(left) == AOP_CRY &&
3957 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3958 if(AOP_TYPE(right) == AOP_LIT){
3959 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3961 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3962 pic14_emitcode("cpl","c");
3963 } else if(lit == 1L) {
3964 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3966 pic14_emitcode("clr","c");
3968 /* AOP_TYPE(right) == AOP_CRY */
3970 symbol *lbl = newiTempLabel(NULL);
3971 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3972 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3973 pic14_emitcode("cpl","c");
3974 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3977 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
3978 pic14_outBitC(result);
3982 genIfxJump (ifx,"c");
3985 /* if the result is used in an arithmetic operation
3986 then put the result in place */
3987 pic14_outBitC(result);
3989 gencjne(left,right,newiTempLabel(NULL));
3990 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3991 aopPut(AOP(result),"a",0);
3995 genIfxJump (ifx,"a");
3998 /* if the result is used in an arithmetic operation
3999 then put the result in place */
4000 if (AOP_TYPE(result) != AOP_CRY)
4001 pic14_outAcc(result);
4002 /* leave the result in acc */
4006 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4007 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4008 freeAsmop(result,NULL,ic,TRUE);
4011 /*-----------------------------------------------------------------*/
4012 /* ifxForOp - returns the icode containing the ifx for operand */
4013 /*-----------------------------------------------------------------*/
4014 static iCode *ifxForOp ( operand *op, iCode *ic )
4016 /* if true symbol then needs to be assigned */
4017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4018 if (IS_TRUE_SYMOP(op))
4021 /* if this has register type condition and
4022 the next instruction is ifx with the same operand
4023 and live to of the operand is upto the ifx only then */
4025 ic->next->op == IFX &&
4026 IC_COND(ic->next)->key == op->key &&
4027 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4032 /*-----------------------------------------------------------------*/
4033 /* genAndOp - for && operation */
4034 /*-----------------------------------------------------------------*/
4035 static void genAndOp (iCode *ic)
4037 operand *left,*right, *result;
4040 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4041 /* note here that && operations that are in an
4042 if statement are taken away by backPatchLabels
4043 only those used in arthmetic operations remain */
4044 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4045 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4046 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4048 /* if both are bit variables */
4049 if (AOP_TYPE(left) == AOP_CRY &&
4050 AOP_TYPE(right) == AOP_CRY ) {
4051 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4052 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4053 pic14_outBitC(result);
4055 tlbl = newiTempLabel(NULL);
4056 pic14_toBoolean(left);
4057 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4058 pic14_toBoolean(right);
4059 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4060 pic14_outBitAcc(result);
4063 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4064 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4065 freeAsmop(result,NULL,ic,TRUE);
4069 /*-----------------------------------------------------------------*/
4070 /* genOrOp - for || operation */
4071 /*-----------------------------------------------------------------*/
4074 modified this code, but it doesn't appear to ever get called
4077 static void genOrOp (iCode *ic)
4079 operand *left,*right, *result;
4082 /* note here that || operations that are in an
4083 if statement are taken away by backPatchLabels
4084 only those used in arthmetic operations remain */
4085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4086 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4087 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4088 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4090 /* if both are bit variables */
4091 if (AOP_TYPE(left) == AOP_CRY &&
4092 AOP_TYPE(right) == AOP_CRY ) {
4093 pic14_emitcode("clrc","");
4094 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4095 AOP(left)->aopu.aop_dir,
4096 AOP(left)->aopu.aop_dir);
4097 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4098 AOP(right)->aopu.aop_dir,
4099 AOP(right)->aopu.aop_dir);
4100 pic14_emitcode("setc","");
4103 tlbl = newiTempLabel(NULL);
4104 pic14_toBoolean(left);
4106 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4107 pic14_toBoolean(right);
4108 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4110 pic14_outBitAcc(result);
4113 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4114 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4115 freeAsmop(result,NULL,ic,TRUE);
4118 /*-----------------------------------------------------------------*/
4119 /* isLiteralBit - test if lit == 2^n */
4120 /*-----------------------------------------------------------------*/
4121 static int isLiteralBit(unsigned long lit)
4123 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4124 0x100L,0x200L,0x400L,0x800L,
4125 0x1000L,0x2000L,0x4000L,0x8000L,
4126 0x10000L,0x20000L,0x40000L,0x80000L,
4127 0x100000L,0x200000L,0x400000L,0x800000L,
4128 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4129 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4133 for(idx = 0; idx < 32; idx++)
4139 /*-----------------------------------------------------------------*/
4140 /* continueIfTrue - */
4141 /*-----------------------------------------------------------------*/
4142 static void continueIfTrue (iCode *ic)
4144 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4146 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4150 /*-----------------------------------------------------------------*/
4152 /*-----------------------------------------------------------------*/
4153 static void jumpIfTrue (iCode *ic)
4155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4157 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4161 /*-----------------------------------------------------------------*/
4162 /* jmpTrueOrFalse - */
4163 /*-----------------------------------------------------------------*/
4164 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4166 // ugly but optimized by peephole
4167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4169 symbol *nlbl = newiTempLabel(NULL);
4170 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4171 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4172 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4173 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4176 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4177 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4182 /*-----------------------------------------------------------------*/
4183 /* genAnd - code for and */
4184 /*-----------------------------------------------------------------*/
4185 static void genAnd (iCode *ic, iCode *ifx)
4187 operand *left, *right, *result;
4189 unsigned long lit = 0L;
4193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4194 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4195 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4196 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4199 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4201 AOP_TYPE(left), AOP_TYPE(right));
4202 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4204 AOP_SIZE(left), AOP_SIZE(right));
4207 /* if left is a literal & right is not then exchange them */
4208 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4209 AOP_NEEDSACC(left)) {
4210 operand *tmp = right ;
4215 /* if result = right then exchange them */
4216 if(pic14_sameRegs(AOP(result),AOP(right))){
4217 operand *tmp = right ;
4222 /* if right is bit then exchange them */
4223 if (AOP_TYPE(right) == AOP_CRY &&
4224 AOP_TYPE(left) != AOP_CRY){
4225 operand *tmp = right ;
4229 if(AOP_TYPE(right) == AOP_LIT)
4230 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4232 size = AOP_SIZE(result);
4235 // result = bit & yy;
4236 if (AOP_TYPE(left) == AOP_CRY){
4237 // c = bit & literal;
4238 if(AOP_TYPE(right) == AOP_LIT){
4240 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4243 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4246 if(size && (AOP_TYPE(result) == AOP_CRY)){
4247 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4250 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4254 pic14_emitcode("clr","c");
4257 if (AOP_TYPE(right) == AOP_CRY){
4259 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4260 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4263 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4265 pic14_emitcode("rrc","a");
4266 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4272 pic14_outBitC(result);
4274 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4275 genIfxJump(ifx, "c");
4279 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4280 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4281 if((AOP_TYPE(right) == AOP_LIT) &&
4282 (AOP_TYPE(result) == AOP_CRY) &&
4283 (AOP_TYPE(left) != AOP_CRY)){
4284 int posbit = isLiteralBit(lit);
4288 MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4291 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4295 sprintf(buffer,"acc.%d",posbit&0x07);
4296 genIfxJump(ifx, buffer);
4301 symbol *tlbl = newiTempLabel(NULL);
4302 int sizel = AOP_SIZE(left);
4304 pic14_emitcode("setb","c");
4306 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4307 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4309 if((posbit = isLiteralBit(bytelit)) != 0)
4310 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4312 if(bytelit != 0x0FFL)
4313 pic14_emitcode("anl","a,%s",
4314 aopGet(AOP(right),offset,FALSE,TRUE));
4315 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4320 // bit = left & literal
4322 pic14_emitcode("clr","c");
4323 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4325 // if(left & literal)
4328 jmpTrueOrFalse(ifx, tlbl);
4332 pic14_outBitC(result);
4336 /* if left is same as result */
4337 if(pic14_sameRegs(AOP(result),AOP(left))){
4338 for(;size--; offset++,lit>>=8) {
4339 if(AOP_TYPE(right) == AOP_LIT){
4340 switch(lit & 0xff) {
4342 /* and'ing with 0 has clears the result */
4343 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4346 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4351 int p = my_powof2( (~lit) & 0xff );
4353 /* only one bit is set in the literal, so use a bcf instruction */
4354 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4356 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4357 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4362 if (AOP_TYPE(left) == AOP_ACC)
4363 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4365 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4366 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4373 // left & result in different registers
4374 if(AOP_TYPE(result) == AOP_CRY){
4376 // if(size), result in bit
4377 // if(!size && ifx), conditional oper: if(left & right)
4378 symbol *tlbl = newiTempLabel(NULL);
4379 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4381 pic14_emitcode("setb","c");
4383 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4384 pic14_emitcode("anl","a,%s",
4385 aopGet(AOP(left),offset,FALSE,FALSE));
4386 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4391 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4392 pic14_outBitC(result);
4394 jmpTrueOrFalse(ifx, tlbl);
4396 for(;(size--);offset++) {
4398 // result = left & right
4399 if(AOP_TYPE(right) == AOP_LIT){
4400 int t = (lit >> (offset*8)) & 0x0FFL;
4403 pic14_emitcode("clrf","%s",
4404 aopGet(AOP(result),offset,FALSE,FALSE));
4407 pic14_emitcode("movf","%s,w",
4408 aopGet(AOP(left),offset,FALSE,FALSE));
4409 pic14_emitcode("movwf","%s",
4410 aopGet(AOP(result),offset,FALSE,FALSE));
4413 pic14_emitcode("movlw","0x%x",t);
4414 pic14_emitcode("andwf","%s,w",
4415 aopGet(AOP(left),offset,FALSE,FALSE));
4416 pic14_emitcode("movwf","%s",
4417 aopGet(AOP(result),offset,FALSE,FALSE));
4423 if (AOP_TYPE(left) == AOP_ACC)
4424 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4426 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4427 pic14_emitcode("andwf","%s,w",
4428 aopGet(AOP(left),offset,FALSE,FALSE));
4430 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4436 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4437 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4438 freeAsmop(result,NULL,ic,TRUE);
4441 /*-----------------------------------------------------------------*/
4442 /* genOr - code for or */
4443 /*-----------------------------------------------------------------*/
4444 static void genOr (iCode *ic, iCode *ifx)
4446 operand *left, *right, *result;
4448 unsigned long lit = 0L;
4450 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4452 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4453 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4454 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4457 /* if left is a literal & right is not then exchange them */
4458 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4459 AOP_NEEDSACC(left)) {
4460 operand *tmp = right ;
4465 /* if result = right then exchange them */
4466 if(pic14_sameRegs(AOP(result),AOP(right))){
4467 operand *tmp = right ;
4472 /* if right is bit then exchange them */
4473 if (AOP_TYPE(right) == AOP_CRY &&
4474 AOP_TYPE(left) != AOP_CRY){
4475 operand *tmp = right ;
4480 if(AOP_TYPE(right) == AOP_LIT)
4481 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4483 size = AOP_SIZE(result);
4487 if (AOP_TYPE(left) == AOP_CRY){
4488 if(AOP_TYPE(right) == AOP_LIT){
4489 // c = bit & literal;
4491 // lit != 0 => result = 1
4492 if(AOP_TYPE(result) == AOP_CRY){
4494 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4495 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4496 // AOP(result)->aopu.aop_dir,
4497 // AOP(result)->aopu.aop_dir);
4499 continueIfTrue(ifx);
4503 // lit == 0 => result = left
4504 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4506 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4509 if (AOP_TYPE(right) == AOP_CRY){
4510 if(pic14_sameRegs(AOP(result),AOP(left))){
4512 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4513 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4514 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4516 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4517 AOP(result)->aopu.aop_dir,
4518 AOP(result)->aopu.aop_dir);
4519 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4520 AOP(right)->aopu.aop_dir,
4521 AOP(right)->aopu.aop_dir);
4522 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4523 AOP(result)->aopu.aop_dir,
4524 AOP(result)->aopu.aop_dir);
4527 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4528 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4529 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4530 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4532 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4533 AOP(result)->aopu.aop_dir,
4534 AOP(result)->aopu.aop_dir);
4535 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4536 AOP(right)->aopu.aop_dir,
4537 AOP(right)->aopu.aop_dir);
4538 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4539 AOP(left)->aopu.aop_dir,
4540 AOP(left)->aopu.aop_dir);
4541 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4542 AOP(result)->aopu.aop_dir,
4543 AOP(result)->aopu.aop_dir);
4548 symbol *tlbl = newiTempLabel(NULL);
4549 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4550 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4551 pic14_emitcode(";XXX setb","c");
4552 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4553 AOP(left)->aopu.aop_dir,tlbl->key+100);
4554 pic14_toBoolean(right);
4555 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4556 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4557 jmpTrueOrFalse(ifx, tlbl);
4561 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4568 pic14_outBitC(result);
4570 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4571 genIfxJump(ifx, "c");
4575 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4576 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4577 if((AOP_TYPE(right) == AOP_LIT) &&
4578 (AOP_TYPE(result) == AOP_CRY) &&
4579 (AOP_TYPE(left) != AOP_CRY)){
4581 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4584 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4586 continueIfTrue(ifx);
4589 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4590 // lit = 0, result = boolean(left)
4592 pic14_emitcode(";XXX setb","c");
4593 pic14_toBoolean(right);
4595 symbol *tlbl = newiTempLabel(NULL);
4596 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4598 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4600 genIfxJump (ifx,"a");
4604 pic14_outBitC(result);
4608 /* if left is same as result */
4609 if(pic14_sameRegs(AOP(result),AOP(left))){
4610 for(;size--; offset++,lit>>=8) {
4611 if(AOP_TYPE(right) == AOP_LIT){
4612 if((lit & 0xff) == 0)
4613 /* or'ing with 0 has no effect */
4616 int p = my_powof2(lit & 0xff);
4618 /* only one bit is set in the literal, so use a bsf instruction */
4619 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4620 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4622 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4623 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4625 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4626 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4631 if (AOP_TYPE(left) == AOP_ACC) {
4632 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4633 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4635 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4636 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4638 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4639 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4645 // left & result in different registers
4646 if(AOP_TYPE(result) == AOP_CRY){
4648 // if(size), result in bit
4649 // if(!size && ifx), conditional oper: if(left | right)
4650 symbol *tlbl = newiTempLabel(NULL);
4651 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4652 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4655 pic14_emitcode(";XXX setb","c");
4657 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4658 pic14_emitcode(";XXX orl","a,%s",
4659 aopGet(AOP(left),offset,FALSE,FALSE));
4660 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4665 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4666 pic14_outBitC(result);
4668 jmpTrueOrFalse(ifx, tlbl);
4669 } else for(;(size--);offset++){
4671 // result = left & right
4672 if(AOP_TYPE(right) == AOP_LIT){
4673 int t = (lit >> (offset*8)) & 0x0FFL;
4676 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4677 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4679 pic14_emitcode("movf","%s,w",
4680 aopGet(AOP(left),offset,FALSE,FALSE));
4681 pic14_emitcode("movwf","%s",
4682 aopGet(AOP(result),offset,FALSE,FALSE));
4685 emitpcode(POC_MOVLW, popGetLit(t));
4686 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4687 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4689 pic14_emitcode("movlw","0x%x",t);
4690 pic14_emitcode("iorwf","%s,w",
4691 aopGet(AOP(left),offset,FALSE,FALSE));
4692 pic14_emitcode("movwf","%s",
4693 aopGet(AOP(result),offset,FALSE,FALSE));
4699 // faster than result <- left, anl result,right
4700 // and better if result is SFR
4701 if (AOP_TYPE(left) == AOP_ACC) {
4702 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4703 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4705 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4706 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4708 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4709 pic14_emitcode("iorwf","%s,w",
4710 aopGet(AOP(left),offset,FALSE,FALSE));
4712 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4713 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4718 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4719 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4720 freeAsmop(result,NULL,ic,TRUE);
4723 /*-----------------------------------------------------------------*/
4724 /* genXor - code for xclusive or */
4725 /*-----------------------------------------------------------------*/
4726 static void genXor (iCode *ic, iCode *ifx)
4728 operand *left, *right, *result;
4730 unsigned long lit = 0L;
4732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4734 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4735 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4736 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4738 /* if left is a literal & right is not ||
4739 if left needs acc & right does not */
4740 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4741 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4742 operand *tmp = right ;
4747 /* if result = right then exchange them */
4748 if(pic14_sameRegs(AOP(result),AOP(right))){
4749 operand *tmp = right ;
4754 /* if right is bit then exchange them */
4755 if (AOP_TYPE(right) == AOP_CRY &&
4756 AOP_TYPE(left) != AOP_CRY){
4757 operand *tmp = right ;
4761 if(AOP_TYPE(right) == AOP_LIT)
4762 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4764 size = AOP_SIZE(result);
4768 if (AOP_TYPE(left) == AOP_CRY){
4769 if(AOP_TYPE(right) == AOP_LIT){
4770 // c = bit & literal;
4772 // lit>>1 != 0 => result = 1
4773 if(AOP_TYPE(result) == AOP_CRY){
4775 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4777 continueIfTrue(ifx);
4780 pic14_emitcode("setb","c");
4784 // lit == 0, result = left
4785 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4787 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789 // lit == 1, result = not(left)
4790 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4791 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4794 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4795 pic14_emitcode("cpl","c");
4802 symbol *tlbl = newiTempLabel(NULL);
4803 if (AOP_TYPE(right) == AOP_CRY){
4805 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4808 int sizer = AOP_SIZE(right);
4810 // if val>>1 != 0, result = 1
4811 pic14_emitcode("setb","c");
4813 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4815 // test the msb of the lsb
4816 pic14_emitcode("anl","a,#0xfe");
4817 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4821 pic14_emitcode("rrc","a");
4823 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4824 pic14_emitcode("cpl","c");
4825 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4830 pic14_outBitC(result);
4832 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4833 genIfxJump(ifx, "c");
4837 if(pic14_sameRegs(AOP(result),AOP(left))){
4838 /* if left is same as result */
4839 for(;size--; offset++) {
4840 if(AOP_TYPE(right) == AOP_LIT){
4841 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
4844 if (IS_AOP_PREG(left)) {
4845 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4846 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4847 aopPut(AOP(result),"a",offset);
4849 pic14_emitcode("xrl","%s,%s",
4850 aopGet(AOP(left),offset,FALSE,TRUE),
4851 aopGet(AOP(right),offset,FALSE,FALSE));
4853 if (AOP_TYPE(left) == AOP_ACC)
4854 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4856 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4857 if (IS_AOP_PREG(left)) {
4858 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4859 aopPut(AOP(result),"a",offset);
4861 pic14_emitcode("xrl","%s,a",
4862 aopGet(AOP(left),offset,FALSE,TRUE));
4867 // left & result in different registers
4868 if(AOP_TYPE(result) == AOP_CRY){
4870 // if(size), result in bit
4871 // if(!size && ifx), conditional oper: if(left ^ right)
4872 symbol *tlbl = newiTempLabel(NULL);
4873 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4875 pic14_emitcode("setb","c");
4877 if((AOP_TYPE(right) == AOP_LIT) &&
4878 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4879 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4881 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4882 pic14_emitcode("xrl","a,%s",
4883 aopGet(AOP(left),offset,FALSE,FALSE));
4885 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4890 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4891 pic14_outBitC(result);
4893 jmpTrueOrFalse(ifx, tlbl);
4894 } else for(;(size--);offset++){
4896 // result = left & right
4897 if(AOP_TYPE(right) == AOP_LIT){
4898 int t = (lit >> (offset*8)) & 0x0FFL;
4901 pic14_emitcode("movf","%s,w",
4902 aopGet(AOP(left),offset,FALSE,FALSE));
4903 pic14_emitcode("movwf","%s",
4904 aopGet(AOP(result),offset,FALSE,FALSE));
4907 pic14_emitcode("comf","%s,w",
4908 aopGet(AOP(left),offset,FALSE,FALSE));
4909 pic14_emitcode("movwf","%s",
4910 aopGet(AOP(result),offset,FALSE,FALSE));
4913 pic14_emitcode("movlw","0x%x",t);
4914 pic14_emitcode("xorwf","%s,w",
4915 aopGet(AOP(left),offset,FALSE,FALSE));
4916 pic14_emitcode("movwf","%s",
4917 aopGet(AOP(result),offset,FALSE,FALSE));
4923 // faster than result <- left, anl result,right
4924 // and better if result is SFR
4925 if (AOP_TYPE(left) == AOP_ACC)
4926 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4928 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4929 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4931 if ( AOP_TYPE(result) != AOP_ACC)
4932 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4937 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4938 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4939 freeAsmop(result,NULL,ic,TRUE);
4942 /*-----------------------------------------------------------------*/
4943 /* genInline - write the inline code out */
4944 /*-----------------------------------------------------------------*/
4945 static void genInline (iCode *ic)
4947 char *buffer, *bp, *bp1;
4949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4951 _G.inLine += (!options.asmpeep);
4953 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
4954 strcpy(buffer,IC_INLINE(ic));
4956 /* emit each line as a code */
4960 pic14_emitcode(bp1,"");
4967 pic14_emitcode(bp1,"");
4974 pic14_emitcode(bp1,"");
4975 /* pic14_emitcode("",buffer); */
4976 _G.inLine -= (!options.asmpeep);
4979 /*-----------------------------------------------------------------*/
4980 /* genRRC - rotate right with carry */
4981 /*-----------------------------------------------------------------*/
4982 static void genRRC (iCode *ic)
4984 operand *left , *result ;
4985 int size, offset = 0;
4988 /* rotate right with carry */
4990 result=IC_RESULT(ic);
4991 aopOp (left,ic,FALSE);
4992 aopOp (result,ic,FALSE);
4994 /* move it to the result */
4995 size = AOP_SIZE(result);
4999 l = aopGet(AOP(left),offset,FALSE,FALSE);
5001 pic14_emitcode("rrc","a");
5002 if (AOP_SIZE(result) > 1)
5003 aopPut(AOP(result),"a",offset--);
5005 /* now we need to put the carry into the
5006 highest order byte of the result */
5007 if (AOP_SIZE(result) > 1) {
5008 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5011 pic14_emitcode("mov","acc.7,c");
5012 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5013 freeAsmop(left,NULL,ic,TRUE);
5014 freeAsmop(result,NULL,ic,TRUE);
5017 /*-----------------------------------------------------------------*/
5018 /* genRLC - generate code for rotate left with carry */
5019 /*-----------------------------------------------------------------*/
5020 static void genRLC (iCode *ic)
5022 operand *left , *result ;
5023 int size, offset = 0;
5026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5027 /* rotate right with carry */
5029 result=IC_RESULT(ic);
5030 aopOp (left,ic,FALSE);
5031 aopOp (result,ic,FALSE);
5033 /* move it to the result */
5034 size = AOP_SIZE(result);
5037 l = aopGet(AOP(left),offset,FALSE,FALSE);
5039 pic14_emitcode("add","a,acc");
5040 if (AOP_SIZE(result) > 1)
5041 aopPut(AOP(result),"a",offset++);
5043 l = aopGet(AOP(left),offset,FALSE,FALSE);
5045 pic14_emitcode("rlc","a");
5046 if (AOP_SIZE(result) > 1)
5047 aopPut(AOP(result),"a",offset++);
5050 /* now we need to put the carry into the
5051 highest order byte of the result */
5052 if (AOP_SIZE(result) > 1) {
5053 l = aopGet(AOP(result),0,FALSE,FALSE);
5056 pic14_emitcode("mov","acc.0,c");
5057 aopPut(AOP(result),"a",0);
5058 freeAsmop(left,NULL,ic,TRUE);
5059 freeAsmop(result,NULL,ic,TRUE);
5062 /*-----------------------------------------------------------------*/
5063 /* genGetHbit - generates code get highest order bit */
5064 /*-----------------------------------------------------------------*/
5065 static void genGetHbit (iCode *ic)
5067 operand *left, *result;
5069 result=IC_RESULT(ic);
5070 aopOp (left,ic,FALSE);
5071 aopOp (result,ic,FALSE);
5073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5074 /* get the highest order byte into a */
5075 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5076 if(AOP_TYPE(result) == AOP_CRY){
5077 pic14_emitcode("rlc","a");
5078 pic14_outBitC(result);
5081 pic14_emitcode("rl","a");
5082 pic14_emitcode("anl","a,#0x01");
5083 pic14_outAcc(result);
5087 freeAsmop(left,NULL,ic,TRUE);
5088 freeAsmop(result,NULL,ic,TRUE);
5091 /*-----------------------------------------------------------------*/
5092 /* AccRol - rotate left accumulator by known count */
5093 /*-----------------------------------------------------------------*/
5094 static void AccRol (int shCount)
5096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5097 shCount &= 0x0007; // shCount : 0..7
5102 pic14_emitcode("rl","a");
5105 pic14_emitcode("rl","a");
5106 pic14_emitcode("rl","a");
5109 pic14_emitcode("swap","a");
5110 pic14_emitcode("rr","a");
5113 pic14_emitcode("swap","a");
5116 pic14_emitcode("swap","a");
5117 pic14_emitcode("rl","a");
5120 pic14_emitcode("rr","a");
5121 pic14_emitcode("rr","a");
5124 pic14_emitcode("rr","a");
5129 /*-----------------------------------------------------------------*/
5130 /* AccLsh - left shift accumulator by known count */
5131 /*-----------------------------------------------------------------*/
5132 static void AccLsh (int shCount)
5134 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5137 pic14_emitcode("add","a,acc");
5140 pic14_emitcode("add","a,acc");
5141 pic14_emitcode("add","a,acc");
5143 /* rotate left accumulator */
5145 /* and kill the lower order bits */
5146 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5151 /*-----------------------------------------------------------------*/
5152 /* AccRsh - right shift accumulator by known count */
5153 /*-----------------------------------------------------------------*/
5154 static void AccRsh (int shCount)
5156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5160 pic14_emitcode("rrc","a");
5162 /* rotate right accumulator */
5163 AccRol(8 - shCount);
5164 /* and kill the higher order bits */
5165 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5170 /*-----------------------------------------------------------------*/
5171 /* AccSRsh - signed right shift accumulator by known count */
5172 /*-----------------------------------------------------------------*/
5173 static void AccSRsh (int shCount)
5176 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5179 pic14_emitcode("mov","c,acc.7");
5180 pic14_emitcode("rrc","a");
5181 } else if(shCount == 2){
5182 pic14_emitcode("mov","c,acc.7");
5183 pic14_emitcode("rrc","a");
5184 pic14_emitcode("mov","c,acc.7");
5185 pic14_emitcode("rrc","a");
5187 tlbl = newiTempLabel(NULL);
5188 /* rotate right accumulator */
5189 AccRol(8 - shCount);
5190 /* and kill the higher order bits */
5191 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5192 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5193 pic14_emitcode("orl","a,#0x%02x",
5194 (unsigned char)~SRMask[shCount]);
5195 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5200 /*-----------------------------------------------------------------*/
5201 /* shiftR1Left2Result - shift right one byte from left to result */
5202 /*-----------------------------------------------------------------*/
5203 static void shiftR1Left2Result (operand *left, int offl,
5204 operand *result, int offr,
5205 int shCount, int sign)
5207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5208 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5209 /* shift right accumulator */
5214 aopPut(AOP(result),"a",offr);
5217 /*-----------------------------------------------------------------*/
5218 /* shiftL1Left2Result - shift left one byte from left to result */
5219 /*-----------------------------------------------------------------*/
5220 static void shiftL1Left2Result (operand *left, int offl,
5221 operand *result, int offr, int shCount)
5224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5225 l = aopGet(AOP(left),offl,FALSE,FALSE);
5227 /* shift left accumulator */
5229 aopPut(AOP(result),"a",offr);
5232 /*-----------------------------------------------------------------*/
5233 /* movLeft2Result - move byte from left to result */
5234 /*-----------------------------------------------------------------*/
5235 static void movLeft2Result (operand *left, int offl,
5236 operand *result, int offr, int sign)
5239 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5240 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5241 l = aopGet(AOP(left),offl,FALSE,FALSE);
5243 if (*l == '@' && (IS_AOP_PREG(result))) {
5244 pic14_emitcode("mov","a,%s",l);
5245 aopPut(AOP(result),"a",offr);
5248 aopPut(AOP(result),l,offr);
5250 /* MSB sign in acc.7 ! */
5251 if(pic14_getDataSize(left) == offl+1){
5252 pic14_emitcode("mov","a,%s",l);
5253 aopPut(AOP(result),"a",offr);
5260 /*-----------------------------------------------------------------*/
5261 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5262 /*-----------------------------------------------------------------*/
5263 static void AccAXRrl1 (char *x)
5265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5266 pic14_emitcode("rrc","a");
5267 pic14_emitcode("xch","a,%s", x);
5268 pic14_emitcode("rrc","a");
5269 pic14_emitcode("xch","a,%s", x);
5272 /*-----------------------------------------------------------------*/
5273 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5274 /*-----------------------------------------------------------------*/
5275 static void AccAXLrl1 (char *x)
5277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5278 pic14_emitcode("xch","a,%s",x);
5279 pic14_emitcode("rlc","a");
5280 pic14_emitcode("xch","a,%s",x);
5281 pic14_emitcode("rlc","a");
5284 /*-----------------------------------------------------------------*/
5285 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5286 /*-----------------------------------------------------------------*/
5287 static void AccAXLsh1 (char *x)
5289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5290 pic14_emitcode("xch","a,%s",x);
5291 pic14_emitcode("add","a,acc");
5292 pic14_emitcode("xch","a,%s",x);
5293 pic14_emitcode("rlc","a");
5296 /*-----------------------------------------------------------------*/
5297 /* AccAXLsh - left shift a:x by known count (0..7) */
5298 /*-----------------------------------------------------------------*/
5299 static void AccAXLsh (char *x, int shCount)
5301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5314 case 5 : // AAAAABBB:CCCCCDDD
5315 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5316 pic14_emitcode("anl","a,#0x%02x",
5317 SLMask[shCount]); // BBB00000:CCCCCDDD
5318 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5319 AccRol(shCount); // DDDCCCCC:BBB00000
5320 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5321 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5322 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5323 pic14_emitcode("anl","a,#0x%02x",
5324 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5325 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5326 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5328 case 6 : // AAAAAABB:CCCCCCDD
5329 pic14_emitcode("anl","a,#0x%02x",
5330 SRMask[shCount]); // 000000BB:CCCCCCDD
5331 pic14_emitcode("mov","c,acc.0"); // c = B
5332 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5333 AccAXRrl1(x); // BCCCCCCD:D000000B
5334 AccAXRrl1(x); // BBCCCCCC:DD000000
5336 case 7 : // a:x <<= 7
5337 pic14_emitcode("anl","a,#0x%02x",
5338 SRMask[shCount]); // 0000000B:CCCCCCCD
5339 pic14_emitcode("mov","c,acc.0"); // c = B
5340 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5341 AccAXRrl1(x); // BCCCCCCC:D0000000
5348 /*-----------------------------------------------------------------*/
5349 /* AccAXRsh - right shift a:x known count (0..7) */
5350 /*-----------------------------------------------------------------*/
5351 static void AccAXRsh (char *x, int shCount)
5353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5359 AccAXRrl1(x); // 0->a:x
5363 AccAXRrl1(x); // 0->a:x
5365 AccAXRrl1(x); // 0->a:x
5369 case 5 : // AAAAABBB:CCCCCDDD = a:x
5370 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5371 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5372 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5373 pic14_emitcode("anl","a,#0x%02x",
5374 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5375 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5376 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5377 pic14_emitcode("anl","a,#0x%02x",
5378 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5379 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5380 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5381 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5383 case 6 : // AABBBBBB:CCDDDDDD
5384 pic14_emitcode("mov","c,acc.7");
5385 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5386 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5387 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5388 pic14_emitcode("anl","a,#0x%02x",
5389 SRMask[shCount]); // 000000AA:BBBBBBCC
5391 case 7 : // ABBBBBBB:CDDDDDDD
5392 pic14_emitcode("mov","c,acc.7"); // c = A
5393 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5394 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5395 pic14_emitcode("anl","a,#0x%02x",
5396 SRMask[shCount]); // 0000000A:BBBBBBBC
5403 /*-----------------------------------------------------------------*/
5404 /* AccAXRshS - right shift signed a:x known count (0..7) */
5405 /*-----------------------------------------------------------------*/
5406 static void AccAXRshS (char *x, int shCount)
5409 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5414 pic14_emitcode("mov","c,acc.7");
5415 AccAXRrl1(x); // s->a:x
5418 pic14_emitcode("mov","c,acc.7");
5419 AccAXRrl1(x); // s->a:x
5420 pic14_emitcode("mov","c,acc.7");
5421 AccAXRrl1(x); // s->a:x
5425 case 5 : // AAAAABBB:CCCCCDDD = a:x
5426 tlbl = newiTempLabel(NULL);
5427 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5428 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5429 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5430 pic14_emitcode("anl","a,#0x%02x",
5431 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5432 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5433 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5434 pic14_emitcode("anl","a,#0x%02x",
5435 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5436 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5437 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5438 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5439 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5440 pic14_emitcode("orl","a,#0x%02x",
5441 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5442 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5443 break; // SSSSAAAA:BBBCCCCC
5444 case 6 : // AABBBBBB:CCDDDDDD
5445 tlbl = newiTempLabel(NULL);
5446 pic14_emitcode("mov","c,acc.7");
5447 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5448 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5449 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5450 pic14_emitcode("anl","a,#0x%02x",
5451 SRMask[shCount]); // 000000AA:BBBBBBCC
5452 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5453 pic14_emitcode("orl","a,#0x%02x",
5454 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5455 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5457 case 7 : // ABBBBBBB:CDDDDDDD
5458 tlbl = newiTempLabel(NULL);
5459 pic14_emitcode("mov","c,acc.7"); // c = A
5460 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5461 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5462 pic14_emitcode("anl","a,#0x%02x",
5463 SRMask[shCount]); // 0000000A:BBBBBBBC
5464 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5465 pic14_emitcode("orl","a,#0x%02x",
5466 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5467 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5474 /*-----------------------------------------------------------------*/
5475 /* shiftL2Left2Result - shift left two bytes from left to result */
5476 /*-----------------------------------------------------------------*/
5477 static void shiftL2Left2Result (operand *left, int offl,
5478 operand *result, int offr, int shCount)
5480 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5481 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5482 ((offl + MSB16) == offr)){
5483 /* don't crash result[offr] */
5484 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5485 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5487 movLeft2Result(left,offl, result, offr, 0);
5488 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5490 /* ax << shCount (x = lsb(result))*/
5491 AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5492 aopPut(AOP(result),"a",offr+MSB16);
5496 /*-----------------------------------------------------------------*/
5497 /* shiftR2Left2Result - shift right two bytes from left to result */
5498 /*-----------------------------------------------------------------*/
5499 static void shiftR2Left2Result (operand *left, int offl,
5500 operand *result, int offr,
5501 int shCount, int sign)
5503 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5504 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5505 ((offl + MSB16) == offr)){
5506 /* don't crash result[offr] */
5507 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5508 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5510 movLeft2Result(left,offl, result, offr, 0);
5511 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5513 /* a:x >> shCount (x = lsb(result))*/
5515 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5517 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5518 if(pic14_getDataSize(result) > 1)
5519 aopPut(AOP(result),"a",offr+MSB16);
5522 /*-----------------------------------------------------------------*/
5523 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5524 /*-----------------------------------------------------------------*/
5525 static void shiftLLeftOrResult (operand *left, int offl,
5526 operand *result, int offr, int shCount)
5528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5529 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5530 /* shift left accumulator */
5532 /* or with result */
5533 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5534 /* back to result */
5535 aopPut(AOP(result),"a",offr);
5538 /*-----------------------------------------------------------------*/
5539 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5540 /*-----------------------------------------------------------------*/
5541 static void shiftRLeftOrResult (operand *left, int offl,
5542 operand *result, int offr, int shCount)
5544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5545 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5546 /* shift right accumulator */
5548 /* or with result */
5549 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5550 /* back to result */
5551 aopPut(AOP(result),"a",offr);
5554 /*-----------------------------------------------------------------*/
5555 /* genlshOne - left shift a one byte quantity by known count */
5556 /*-----------------------------------------------------------------*/
5557 static void genlshOne (operand *result, operand *left, int shCount)
5559 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5560 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5563 /*-----------------------------------------------------------------*/
5564 /* genlshTwo - left shift two bytes by known amount != 0 */
5565 /*-----------------------------------------------------------------*/
5566 static void genlshTwo (operand *result,operand *left, int shCount)
5570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5571 size = pic14_getDataSize(result);
5573 /* if shCount >= 8 */
5579 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5581 movLeft2Result(left, LSB, result, MSB16, 0);
5583 aopPut(AOP(result),zero,LSB);
5586 /* 1 <= shCount <= 7 */
5589 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5591 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5595 /*-----------------------------------------------------------------*/
5596 /* shiftLLong - shift left one long from left to result */
5597 /* offl = LSB or MSB16 */
5598 /*-----------------------------------------------------------------*/
5599 static void shiftLLong (operand *left, operand *result, int offr )
5602 int size = AOP_SIZE(result);
5604 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5605 if(size >= LSB+offr){
5606 l = aopGet(AOP(left),LSB,FALSE,FALSE);
5608 pic14_emitcode("add","a,acc");
5609 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5610 size >= MSB16+offr && offr != LSB )
5611 pic14_emitcode("xch","a,%s",
5612 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
5614 aopPut(AOP(result),"a",LSB+offr);
5617 if(size >= MSB16+offr){
5618 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
5619 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
5622 pic14_emitcode("rlc","a");
5623 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5624 size >= MSB24+offr && offr != LSB)
5625 pic14_emitcode("xch","a,%s",
5626 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
5628 aopPut(AOP(result),"a",MSB16+offr);
5631 if(size >= MSB24+offr){
5632 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
5633 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
5636 pic14_emitcode("rlc","a");
5637 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5638 size >= MSB32+offr && offr != LSB )
5639 pic14_emitcode("xch","a,%s",
5640 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
5642 aopPut(AOP(result),"a",MSB24+offr);
5645 if(size > MSB32+offr){
5646 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
5647 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
5650 pic14_emitcode("rlc","a");
5651 aopPut(AOP(result),"a",MSB32+offr);
5654 aopPut(AOP(result),zero,LSB);
5657 /*-----------------------------------------------------------------*/
5658 /* genlshFour - shift four byte by a known amount != 0 */
5659 /*-----------------------------------------------------------------*/
5660 static void genlshFour (operand *result, operand *left, int shCount)
5664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5665 size = AOP_SIZE(result);
5667 /* if shifting more that 3 bytes */
5668 if (shCount >= 24 ) {
5671 /* lowest order of left goes to the highest
5672 order of the destination */
5673 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
5675 movLeft2Result(left, LSB, result, MSB32, 0);
5676 aopPut(AOP(result),zero,LSB);
5677 aopPut(AOP(result),zero,MSB16);
5678 aopPut(AOP(result),zero,MSB32);
5682 /* more than two bytes */
5683 else if ( shCount >= 16 ) {
5684 /* lower order two bytes goes to higher order two bytes */
5686 /* if some more remaining */
5688 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
5690 movLeft2Result(left, MSB16, result, MSB32, 0);
5691 movLeft2Result(left, LSB, result, MSB24, 0);
5693 aopPut(AOP(result),zero,MSB16);
5694 aopPut(AOP(result),zero,LSB);
5698 /* if more than 1 byte */
5699 else if ( shCount >= 8 ) {
5700 /* lower order three bytes goes to higher order three bytes */
5704 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5706 movLeft2Result(left, LSB, result, MSB16, 0);
5708 else{ /* size = 4 */
5710 movLeft2Result(left, MSB24, result, MSB32, 0);
5711 movLeft2Result(left, MSB16, result, MSB24, 0);
5712 movLeft2Result(left, LSB, result, MSB16, 0);
5713 aopPut(AOP(result),zero,LSB);
5715 else if(shCount == 1)
5716 shiftLLong(left, result, MSB16);
5718 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
5719 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5720 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
5721 aopPut(AOP(result),zero,LSB);
5726 /* 1 <= shCount <= 7 */
5727 else if(shCount <= 2){
5728 shiftLLong(left, result, LSB);
5730 shiftLLong(result, result, LSB);
5732 /* 3 <= shCount <= 7, optimize */
5734 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
5735 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
5736 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5740 /*-----------------------------------------------------------------*/
5741 /* genLeftShiftLiteral - left shifting by known count */
5742 /*-----------------------------------------------------------------*/
5743 static void genLeftShiftLiteral (operand *left,
5748 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
5751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5752 freeAsmop(right,NULL,ic,TRUE);
5754 aopOp(left,ic,FALSE);
5755 aopOp(result,ic,FALSE);
5757 size = getSize(operandType(result));
5760 pic14_emitcode("; shift left ","result %d, left %d",size,
5764 /* I suppose that the left size >= result size */
5767 movLeft2Result(left, size, result, size, 0);
5771 else if(shCount >= (size * 8))
5773 aopPut(AOP(result),zero,size);
5777 genlshOne (result,left,shCount);
5782 genlshTwo (result,left,shCount);
5786 genlshFour (result,left,shCount);
5790 freeAsmop(left,NULL,ic,TRUE);
5791 freeAsmop(result,NULL,ic,TRUE);
5794 /*-----------------------------------------------------------------*/
5795 /* genLeftShift - generates code for left shifting */
5796 /*-----------------------------------------------------------------*/
5797 static void genLeftShift (iCode *ic)
5799 operand *left,*right, *result;
5802 symbol *tlbl , *tlbl1;
5804 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5806 right = IC_RIGHT(ic);
5808 result = IC_RESULT(ic);
5810 aopOp(right,ic,FALSE);
5812 /* if the shift count is known then do it
5813 as efficiently as possible */
5814 if (AOP_TYPE(right) == AOP_LIT) {
5815 genLeftShiftLiteral (left,right,result,ic);
5819 /* shift count is unknown then we have to form
5820 a loop get the loop count in B : Note: we take
5821 only the lower order byte since shifting
5822 more that 32 bits make no sense anyway, ( the
5823 largest size of an object can be only 32 bits ) */
5825 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
5826 pic14_emitcode("inc","b");
5827 freeAsmop (right,NULL,ic,TRUE);
5828 aopOp(left,ic,FALSE);
5829 aopOp(result,ic,FALSE);
5831 /* now move the left to the result if they are not the
5833 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
5834 AOP_SIZE(result) > 1) {
5836 size = AOP_SIZE(result);
5839 l = aopGet(AOP(left),offset,FALSE,TRUE);
5840 if (*l == '@' && (IS_AOP_PREG(result))) {
5842 pic14_emitcode("mov","a,%s",l);
5843 aopPut(AOP(result),"a",offset);
5845 aopPut(AOP(result),l,offset);
5850 tlbl = newiTempLabel(NULL);
5851 size = AOP_SIZE(result);
5853 tlbl1 = newiTempLabel(NULL);
5855 /* if it is only one byte then */
5857 symbol *tlbl1 = newiTempLabel(NULL);
5859 l = aopGet(AOP(left),0,FALSE,FALSE);
5861 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
5862 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5863 pic14_emitcode("add","a,acc");
5864 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
5865 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
5866 aopPut(AOP(result),"a",0);
5870 reAdjustPreg(AOP(result));
5872 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
5873 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5874 l = aopGet(AOP(result),offset,FALSE,FALSE);
5876 pic14_emitcode("add","a,acc");
5877 aopPut(AOP(result),"a",offset++);
5879 l = aopGet(AOP(result),offset,FALSE,FALSE);
5881 pic14_emitcode("rlc","a");
5882 aopPut(AOP(result),"a",offset++);
5884 reAdjustPreg(AOP(result));
5886 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
5887 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
5889 freeAsmop(left,NULL,ic,TRUE);
5890 freeAsmop(result,NULL,ic,TRUE);
5893 /*-----------------------------------------------------------------*/
5894 /* genrshOne - right shift a one byte quantity by known count */
5895 /*-----------------------------------------------------------------*/
5896 static void genrshOne (operand *result, operand *left,
5897 int shCount, int sign)
5899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5900 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
5903 /*-----------------------------------------------------------------*/
5904 /* genrshTwo - right shift two bytes by known amount != 0 */
5905 /*-----------------------------------------------------------------*/
5906 static void genrshTwo (operand *result,operand *left,
5907 int shCount, int sign)
5909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5910 /* if shCount >= 8 */
5914 shiftR1Left2Result(left, MSB16, result, LSB,
5917 movLeft2Result(left, MSB16, result, LSB, sign);
5918 addSign(result, MSB16, sign);
5921 /* 1 <= shCount <= 7 */
5923 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
5926 /*-----------------------------------------------------------------*/
5927 /* shiftRLong - shift right one long from left to result */
5928 /* offl = LSB or MSB16 */
5929 /*-----------------------------------------------------------------*/
5930 static void shiftRLong (operand *left, int offl,
5931 operand *result, int sign)
5933 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5935 pic14_emitcode("clr","c");
5936 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
5938 pic14_emitcode("mov","c,acc.7");
5939 pic14_emitcode("rrc","a");
5940 aopPut(AOP(result),"a",MSB32-offl);
5942 /* add sign of "a" */
5943 addSign(result, MSB32, sign);
5945 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
5946 pic14_emitcode("rrc","a");
5947 aopPut(AOP(result),"a",MSB24-offl);
5949 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
5950 pic14_emitcode("rrc","a");
5951 aopPut(AOP(result),"a",MSB16-offl);
5954 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
5955 pic14_emitcode("rrc","a");
5956 aopPut(AOP(result),"a",LSB);
5960 /*-----------------------------------------------------------------*/
5961 /* genrshFour - shift four byte by a known amount != 0 */
5962 /*-----------------------------------------------------------------*/
5963 static void genrshFour (operand *result, operand *left,
5964 int shCount, int sign)
5966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5967 /* if shifting more that 3 bytes */
5968 if(shCount >= 24 ) {
5971 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
5973 movLeft2Result(left, MSB32, result, LSB, sign);
5974 addSign(result, MSB16, sign);
5976 else if(shCount >= 16){
5979 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
5981 movLeft2Result(left, MSB24, result, LSB, 0);
5982 movLeft2Result(left, MSB32, result, MSB16, sign);
5984 addSign(result, MSB24, sign);
5986 else if(shCount >= 8){
5989 shiftRLong(left, MSB16, result, sign);
5990 else if(shCount == 0){
5991 movLeft2Result(left, MSB16, result, LSB, 0);
5992 movLeft2Result(left, MSB24, result, MSB16, 0);
5993 movLeft2Result(left, MSB32, result, MSB24, sign);
5994 addSign(result, MSB32, sign);
5997 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
5998 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
5999 /* the last shift is signed */
6000 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6001 addSign(result, MSB32, sign);
6004 else{ /* 1 <= shCount <= 7 */
6006 shiftRLong(left, LSB, result, sign);
6008 shiftRLong(result, LSB, result, sign);
6011 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6012 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6013 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6018 /*-----------------------------------------------------------------*/
6019 /* genRightShiftLiteral - right shifting by known count */
6020 /*-----------------------------------------------------------------*/
6021 static void genRightShiftLiteral (operand *left,
6027 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6031 freeAsmop(right,NULL,ic,TRUE);
6033 aopOp(left,ic,FALSE);
6034 aopOp(result,ic,FALSE);
6037 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6041 size = pic14_getDataSize(left);
6042 /* test the LEFT size !!! */
6044 /* I suppose that the left size >= result size */
6046 size = pic14_getDataSize(result);
6048 movLeft2Result(left, size, result, size, 0);
6051 else if(shCount >= (size * 8)){
6053 /* get sign in acc.7 */
6054 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6055 addSign(result, LSB, sign);
6059 genrshOne (result,left,shCount,sign);
6063 genrshTwo (result,left,shCount,sign);
6067 genrshFour (result,left,shCount,sign);
6073 freeAsmop(left,NULL,ic,TRUE);
6074 freeAsmop(result,NULL,ic,TRUE);
6078 /*-----------------------------------------------------------------*/
6079 /* genSignedRightShift - right shift of signed number */
6080 /*-----------------------------------------------------------------*/
6081 static void genSignedRightShift (iCode *ic)
6083 operand *right, *left, *result;
6086 symbol *tlbl, *tlbl1 ;
6088 /* we do it the hard way put the shift count in b
6089 and loop thru preserving the sign */
6090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6092 right = IC_RIGHT(ic);
6094 result = IC_RESULT(ic);
6096 aopOp(right,ic,FALSE);
6099 if ( AOP_TYPE(right) == AOP_LIT) {
6100 genRightShiftLiteral (left,right,result,ic,1);
6103 /* shift count is unknown then we have to form
6104 a loop get the loop count in B : Note: we take
6105 only the lower order byte since shifting
6106 more that 32 bits make no sense anyway, ( the
6107 largest size of an object can be only 32 bits ) */
6109 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6110 pic14_emitcode("inc","b");
6111 freeAsmop (right,NULL,ic,TRUE);
6112 aopOp(left,ic,FALSE);
6113 aopOp(result,ic,FALSE);
6115 /* now move the left to the result if they are not the
6117 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6118 AOP_SIZE(result) > 1) {
6120 size = AOP_SIZE(result);
6123 l = aopGet(AOP(left),offset,FALSE,TRUE);
6124 if (*l == '@' && IS_AOP_PREG(result)) {
6126 pic14_emitcode("mov","a,%s",l);
6127 aopPut(AOP(result),"a",offset);
6129 aopPut(AOP(result),l,offset);
6134 /* mov the highest order bit to OVR */
6135 tlbl = newiTempLabel(NULL);
6136 tlbl1= newiTempLabel(NULL);
6138 size = AOP_SIZE(result);
6140 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6141 pic14_emitcode("rlc","a");
6142 pic14_emitcode("mov","ov,c");
6143 /* if it is only one byte then */
6145 l = aopGet(AOP(left),0,FALSE,FALSE);
6147 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6148 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6149 pic14_emitcode("mov","c,ov");
6150 pic14_emitcode("rrc","a");
6151 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6152 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6153 aopPut(AOP(result),"a",0);
6157 reAdjustPreg(AOP(result));
6158 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6159 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6160 pic14_emitcode("mov","c,ov");
6162 l = aopGet(AOP(result),offset,FALSE,FALSE);
6164 pic14_emitcode("rrc","a");
6165 aopPut(AOP(result),"a",offset--);
6167 reAdjustPreg(AOP(result));
6168 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6169 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6172 freeAsmop(left,NULL,ic,TRUE);
6173 freeAsmop(result,NULL,ic,TRUE);
6176 /*-----------------------------------------------------------------*/
6177 /* genRightShift - generate code for right shifting */
6178 /*-----------------------------------------------------------------*/
6179 static void genRightShift (iCode *ic)
6181 operand *right, *left, *result;
6185 symbol *tlbl, *tlbl1 ;
6187 /* if signed then we do it the hard way preserve the
6188 sign bit moving it inwards */
6189 retype = getSpec(operandType(IC_RESULT(ic)));
6190 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6192 if (!SPEC_USIGN(retype)) {
6193 genSignedRightShift (ic);
6197 /* signed & unsigned types are treated the same : i.e. the
6198 signed is NOT propagated inwards : quoting from the
6199 ANSI - standard : "for E1 >> E2, is equivalent to division
6200 by 2**E2 if unsigned or if it has a non-negative value,
6201 otherwise the result is implementation defined ", MY definition
6202 is that the sign does not get propagated */
6204 right = IC_RIGHT(ic);
6206 result = IC_RESULT(ic);
6208 aopOp(right,ic,FALSE);
6210 /* if the shift count is known then do it
6211 as efficiently as possible */
6212 if (AOP_TYPE(right) == AOP_LIT) {
6213 genRightShiftLiteral (left,right,result,ic, 0);
6217 /* shift count is unknown then we have to form
6218 a loop get the loop count in B : Note: we take
6219 only the lower order byte since shifting
6220 more that 32 bits make no sense anyway, ( the
6221 largest size of an object can be only 32 bits ) */
6223 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6224 pic14_emitcode("inc","b");
6225 freeAsmop (right,NULL,ic,TRUE);
6226 aopOp(left,ic,FALSE);
6227 aopOp(result,ic,FALSE);
6229 /* now move the left to the result if they are not the
6231 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6232 AOP_SIZE(result) > 1) {
6234 size = AOP_SIZE(result);
6237 l = aopGet(AOP(left),offset,FALSE,TRUE);
6238 if (*l == '@' && IS_AOP_PREG(result)) {
6240 pic14_emitcode("mov","a,%s",l);
6241 aopPut(AOP(result),"a",offset);
6243 aopPut(AOP(result),l,offset);
6248 tlbl = newiTempLabel(NULL);
6249 tlbl1= newiTempLabel(NULL);
6250 size = AOP_SIZE(result);
6253 /* if it is only one byte then */
6255 l = aopGet(AOP(left),0,FALSE,FALSE);
6257 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6258 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6260 pic14_emitcode("rrc","a");
6261 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6262 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6263 aopPut(AOP(result),"a",0);
6267 reAdjustPreg(AOP(result));
6268 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6269 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6272 l = aopGet(AOP(result),offset,FALSE,FALSE);
6274 pic14_emitcode("rrc","a");
6275 aopPut(AOP(result),"a",offset--);
6277 reAdjustPreg(AOP(result));
6279 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6280 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6283 freeAsmop(left,NULL,ic,TRUE);
6284 freeAsmop(result,NULL,ic,TRUE);
6287 /*-----------------------------------------------------------------*/
6288 /* genUnpackBits - generates code for unpacking bits */
6289 /*-----------------------------------------------------------------*/
6290 static void genUnpackBits (operand *result, char *rname, int ptype)
6297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6298 etype = getSpec(operandType(result));
6300 /* read the first byte */
6305 pic14_emitcode("mov","a,@%s",rname);
6309 pic14_emitcode("movx","a,@%s",rname);
6313 pic14_emitcode("movx","a,@dptr");
6317 pic14_emitcode("clr","a");
6318 pic14_emitcode("movc","a","@a+dptr");
6322 pic14_emitcode("lcall","__gptrget");
6326 /* if we have bitdisplacement then it fits */
6327 /* into this byte completely or if length is */
6328 /* less than a byte */
6329 if ((shCnt = SPEC_BSTR(etype)) ||
6330 (SPEC_BLEN(etype) <= 8)) {
6332 /* shift right acc */
6335 pic14_emitcode("anl","a,#0x%02x",
6336 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6337 aopPut(AOP(result),"a",offset);
6341 /* bit field did not fit in a byte */
6342 rlen = SPEC_BLEN(etype) - 8;
6343 aopPut(AOP(result),"a",offset++);
6350 pic14_emitcode("inc","%s",rname);
6351 pic14_emitcode("mov","a,@%s",rname);
6355 pic14_emitcode("inc","%s",rname);
6356 pic14_emitcode("movx","a,@%s",rname);
6360 pic14_emitcode("inc","dptr");
6361 pic14_emitcode("movx","a,@dptr");
6365 pic14_emitcode("clr","a");
6366 pic14_emitcode("inc","dptr");
6367 pic14_emitcode("movc","a","@a+dptr");
6371 pic14_emitcode("inc","dptr");
6372 pic14_emitcode("lcall","__gptrget");
6377 /* if we are done */
6381 aopPut(AOP(result),"a",offset++);
6386 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6387 aopPut(AOP(result),"a",offset);
6394 /*-----------------------------------------------------------------*/
6395 /* genDataPointerGet - generates code when ptr offset is known */
6396 /*-----------------------------------------------------------------*/
6397 static void genDataPointerGet (operand *left,
6401 int size , offset = 0;
6404 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6407 /* optimization - most of the time, left and result are the same
6408 * address, but different types. for the pic code, we could omit
6412 aopOp(result,ic,TRUE);
6414 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6416 size = AOP_SIZE(result);
6419 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6423 freeAsmop(left,NULL,ic,TRUE);
6424 freeAsmop(result,NULL,ic,TRUE);
6427 /*-----------------------------------------------------------------*/
6428 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6429 /*-----------------------------------------------------------------*/
6430 static void genNearPointerGet (operand *left,
6437 sym_link *rtype, *retype;
6438 sym_link *ltype = operandType(left);
6441 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6443 rtype = operandType(result);
6444 retype= getSpec(rtype);
6446 aopOp(left,ic,FALSE);
6448 /* if left is rematerialisable and
6449 result is not bit variable type and
6450 the left is pointer to data space i.e
6451 lower 128 bytes of space */
6452 if (AOP_TYPE(left) == AOP_IMMD &&
6453 !IS_BITVAR(retype) &&
6454 DCL_TYPE(ltype) == POINTER) {
6455 genDataPointerGet (left,result,ic);
6459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6461 /* if the value is already in a pointer register
6462 then don't need anything more */
6463 if (!AOP_INPREG(AOP(left))) {
6464 /* otherwise get a free pointer register */
6465 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6467 preg = getFreePtr(ic,&aop,FALSE);
6468 pic14_emitcode("mov","%s,%s",
6470 aopGet(AOP(left),0,FALSE,TRUE));
6471 rname = preg->name ;
6473 rname = aopGet(AOP(left),0,FALSE,FALSE);
6475 freeAsmop(left,NULL,ic,TRUE);
6476 aopOp (result,ic,FALSE);
6478 /* if bitfield then unpack the bits */
6479 if (IS_BITVAR(retype))
6480 genUnpackBits (result,rname,POINTER);
6482 /* we have can just get the values */
6483 int size = AOP_SIZE(result);
6486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6488 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6490 pic14_emitcode("mov","a,@%s",rname);
6491 aopPut(AOP(result),"a",offset);
6493 sprintf(buffer,"@%s",rname);
6494 aopPut(AOP(result),buffer,offset);
6498 pic14_emitcode("inc","%s",rname);
6502 /* now some housekeeping stuff */
6504 /* we had to allocate for this iCode */
6505 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6506 freeAsmop(NULL,aop,ic,TRUE);
6508 /* we did not allocate which means left
6509 already in a pointer register, then
6510 if size > 0 && this could be used again
6511 we have to point it back to where it
6513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6514 if (AOP_SIZE(result) > 1 &&
6515 !OP_SYMBOL(left)->remat &&
6516 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6518 int size = AOP_SIZE(result) - 1;
6520 pic14_emitcode("dec","%s",rname);
6525 freeAsmop(result,NULL,ic,TRUE);
6529 /*-----------------------------------------------------------------*/
6530 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
6531 /*-----------------------------------------------------------------*/
6532 static void genPagedPointerGet (operand *left,
6539 sym_link *rtype, *retype;
6541 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6543 rtype = operandType(result);
6544 retype= getSpec(rtype);
6546 aopOp(left,ic,FALSE);
6548 /* if the value is already in a pointer register
6549 then don't need anything more */
6550 if (!AOP_INPREG(AOP(left))) {
6551 /* otherwise get a free pointer register */
6553 preg = getFreePtr(ic,&aop,FALSE);
6554 pic14_emitcode("mov","%s,%s",
6556 aopGet(AOP(left),0,FALSE,TRUE));
6557 rname = preg->name ;
6559 rname = aopGet(AOP(left),0,FALSE,FALSE);
6561 freeAsmop(left,NULL,ic,TRUE);
6562 aopOp (result,ic,FALSE);
6564 /* if bitfield then unpack the bits */
6565 if (IS_BITVAR(retype))
6566 genUnpackBits (result,rname,PPOINTER);
6568 /* we have can just get the values */
6569 int size = AOP_SIZE(result);
6574 pic14_emitcode("movx","a,@%s",rname);
6575 aopPut(AOP(result),"a",offset);
6580 pic14_emitcode("inc","%s",rname);
6584 /* now some housekeeping stuff */
6586 /* we had to allocate for this iCode */
6587 freeAsmop(NULL,aop,ic,TRUE);
6589 /* we did not allocate which means left
6590 already in a pointer register, then
6591 if size > 0 && this could be used again
6592 we have to point it back to where it
6594 if (AOP_SIZE(result) > 1 &&
6595 !OP_SYMBOL(left)->remat &&
6596 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6598 int size = AOP_SIZE(result) - 1;
6600 pic14_emitcode("dec","%s",rname);
6605 freeAsmop(result,NULL,ic,TRUE);
6610 /*-----------------------------------------------------------------*/
6611 /* genFarPointerGet - gget value from far space */
6612 /*-----------------------------------------------------------------*/
6613 static void genFarPointerGet (operand *left,
6614 operand *result, iCode *ic)
6617 sym_link *retype = getSpec(operandType(result));
6619 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6621 aopOp(left,ic,FALSE);
6623 /* if the operand is already in dptr
6624 then we do nothing else we move the value to dptr */
6625 if (AOP_TYPE(left) != AOP_STR) {
6626 /* if this is remateriazable */
6627 if (AOP_TYPE(left) == AOP_IMMD)
6628 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6629 else { /* we need to get it byte by byte */
6630 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6631 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6632 if (options.model == MODEL_FLAT24)
6634 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6638 /* so dptr know contains the address */
6639 freeAsmop(left,NULL,ic,TRUE);
6640 aopOp(result,ic,FALSE);
6642 /* if bit then unpack */
6643 if (IS_BITVAR(retype))
6644 genUnpackBits(result,"dptr",FPOINTER);
6646 size = AOP_SIZE(result);
6650 pic14_emitcode("movx","a,@dptr");
6651 aopPut(AOP(result),"a",offset++);
6653 pic14_emitcode("inc","dptr");
6657 freeAsmop(result,NULL,ic,TRUE);
6660 /*-----------------------------------------------------------------*/
6661 /* pic14_emitcodePointerGet - gget value from code space */
6662 /*-----------------------------------------------------------------*/
6663 static void pic14_emitcodePointerGet (operand *left,
6664 operand *result, iCode *ic)
6667 sym_link *retype = getSpec(operandType(result));
6669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6671 aopOp(left,ic,FALSE);
6673 /* if the operand is already in dptr
6674 then we do nothing else we move the value to dptr */
6675 if (AOP_TYPE(left) != AOP_STR) {
6676 /* if this is remateriazable */
6677 if (AOP_TYPE(left) == AOP_IMMD)
6678 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6679 else { /* we need to get it byte by byte */
6680 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6681 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6682 if (options.model == MODEL_FLAT24)
6684 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6688 /* so dptr know contains the address */
6689 freeAsmop(left,NULL,ic,TRUE);
6690 aopOp(result,ic,FALSE);
6692 /* if bit then unpack */
6693 if (IS_BITVAR(retype))
6694 genUnpackBits(result,"dptr",CPOINTER);
6696 size = AOP_SIZE(result);
6700 pic14_emitcode("clr","a");
6701 pic14_emitcode("movc","a,@a+dptr");
6702 aopPut(AOP(result),"a",offset++);
6704 pic14_emitcode("inc","dptr");
6708 freeAsmop(result,NULL,ic,TRUE);
6711 /*-----------------------------------------------------------------*/
6712 /* genGenPointerGet - gget value from generic pointer space */
6713 /*-----------------------------------------------------------------*/
6714 static void genGenPointerGet (operand *left,
6715 operand *result, iCode *ic)
6718 sym_link *retype = getSpec(operandType(result));
6720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6721 aopOp(left,ic,FALSE);
6723 /* if the operand is already in dptr
6724 then we do nothing else we move the value to dptr */
6725 if (AOP_TYPE(left) != AOP_STR) {
6726 /* if this is remateriazable */
6727 if (AOP_TYPE(left) == AOP_IMMD) {
6728 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6729 pic14_emitcode("mov","b,#%d",pointerCode(retype));
6731 else { /* we need to get it byte by byte */
6732 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
6733 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
6734 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
6735 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
6736 pic14_emitcode("movwf","FSR");
6738 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6739 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6740 if (options.model == MODEL_FLAT24)
6742 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6743 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
6747 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
6752 /* so dptr know contains the address */
6753 freeAsmop(left,NULL,ic,TRUE);
6754 aopOp(result,ic,FALSE);
6756 /* if bit then unpack */
6757 if (IS_BITVAR(retype))
6758 genUnpackBits(result,"dptr",GPOINTER);
6760 size = AOP_SIZE(result);
6764 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
6766 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
6768 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
6770 pic14_emitcode("movf","indf,w");
6771 pic14_emitcode("movwf","%s",
6772 aopGet(AOP(result),offset++,FALSE,FALSE));
6774 pic14_emitcode("incf","fsr,f");
6779 freeAsmop(result,NULL,ic,TRUE);
6782 /*-----------------------------------------------------------------*/
6783 /* genPointerGet - generate code for pointer get */
6784 /*-----------------------------------------------------------------*/
6785 static void genPointerGet (iCode *ic)
6787 operand *left, *result ;
6788 sym_link *type, *etype;
6791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6794 result = IC_RESULT(ic) ;
6796 /* depending on the type of pointer we need to
6797 move it to the correct pointer register */
6798 type = operandType(left);
6799 etype = getSpec(type);
6800 /* if left is of type of pointer then it is simple */
6801 if (IS_PTR(type) && !IS_FUNC(type->next))
6802 p_type = DCL_TYPE(type);
6804 /* we have to go by the storage class */
6805 p_type = PTR_TYPE(SPEC_OCLS(etype));
6807 /* if (SPEC_OCLS(etype)->codesp ) { */
6808 /* p_type = CPOINTER ; */
6811 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
6812 /* p_type = FPOINTER ; */
6814 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
6815 /* p_type = PPOINTER; */
6817 /* if (SPEC_OCLS(etype) == idata ) */
6818 /* p_type = IPOINTER; */
6820 /* p_type = POINTER ; */
6823 /* now that we have the pointer type we assign
6824 the pointer values */
6829 genNearPointerGet (left,result,ic);
6833 genPagedPointerGet(left,result,ic);
6837 genFarPointerGet (left,result,ic);
6841 pic14_emitcodePointerGet (left,result,ic);
6845 genGenPointerGet (left,result,ic);
6851 /*-----------------------------------------------------------------*/
6852 /* genPackBits - generates code for packed bit storage */
6853 /*-----------------------------------------------------------------*/
6854 static void genPackBits (sym_link *etype ,
6856 char *rname, int p_type)
6864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6865 blen = SPEC_BLEN(etype);
6866 bstr = SPEC_BSTR(etype);
6868 l = aopGet(AOP(right),offset++,FALSE,FALSE);
6871 /* if the bit lenth is less than or */
6872 /* it exactly fits a byte then */
6873 if (SPEC_BLEN(etype) <= 8 ) {
6874 shCount = SPEC_BSTR(etype) ;
6876 /* shift left acc */
6879 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
6884 pic14_emitcode ("mov","b,a");
6885 pic14_emitcode("mov","a,@%s",rname);
6889 pic14_emitcode ("mov","b,a");
6890 pic14_emitcode("movx","a,@dptr");
6894 pic14_emitcode ("push","b");
6895 pic14_emitcode ("push","acc");
6896 pic14_emitcode ("lcall","__gptrget");
6897 pic14_emitcode ("pop","b");
6901 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
6902 ((unsigned char)(0xFF << (blen+bstr)) |
6903 (unsigned char)(0xFF >> (8-bstr)) ) );
6904 pic14_emitcode ("orl","a,b");
6905 if (p_type == GPOINTER)
6906 pic14_emitcode("pop","b");
6912 pic14_emitcode("mov","@%s,a",rname);
6916 pic14_emitcode("movx","@dptr,a");
6920 DEBUGpic14_emitcode(";lcall","__gptrput");
6925 if ( SPEC_BLEN(etype) <= 8 )
6928 pic14_emitcode("inc","%s",rname);
6929 rLen = SPEC_BLEN(etype) ;
6931 /* now generate for lengths greater than one byte */
6934 l = aopGet(AOP(right),offset++,FALSE,TRUE);
6944 pic14_emitcode("mov","@%s,a",rname);
6946 pic14_emitcode("mov","@%s,%s",rname,l);
6951 pic14_emitcode("movx","@dptr,a");
6956 DEBUGpic14_emitcode(";lcall","__gptrput");
6959 pic14_emitcode ("inc","%s",rname);
6964 /* last last was not complete */
6966 /* save the byte & read byte */
6969 pic14_emitcode ("mov","b,a");
6970 pic14_emitcode("mov","a,@%s",rname);
6974 pic14_emitcode ("mov","b,a");
6975 pic14_emitcode("movx","a,@dptr");
6979 pic14_emitcode ("push","b");
6980 pic14_emitcode ("push","acc");
6981 pic14_emitcode ("lcall","__gptrget");
6982 pic14_emitcode ("pop","b");
6986 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
6987 pic14_emitcode ("orl","a,b");
6990 if (p_type == GPOINTER)
6991 pic14_emitcode("pop","b");
6996 pic14_emitcode("mov","@%s,a",rname);
7000 pic14_emitcode("movx","@dptr,a");
7004 DEBUGpic14_emitcode(";lcall","__gptrput");
7008 /*-----------------------------------------------------------------*/
7009 /* genDataPointerSet - remat pointer to data space */
7010 /*-----------------------------------------------------------------*/
7011 static void genDataPointerSet(operand *right,
7015 int size, offset = 0 ;
7016 char *l, buffer[256];
7018 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7019 aopOp(right,ic,FALSE);
7021 l = aopGet(AOP(result),0,FALSE,TRUE);
7022 size = AOP_SIZE(right);
7023 // tsd, was l+1 - the underline `_' prefix was being stripped
7026 sprintf(buffer,"(%s + %d)",l,offset);
7028 sprintf(buffer,"%s",l);
7030 if (AOP_TYPE(right) == AOP_LIT) {
7031 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7032 lit = lit >> (8*offset);
7034 pic14_emitcode("movlw","%d",lit);
7035 pic14_emitcode("movwf","%s",buffer);
7037 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7038 emitpcode(POC_MOVWF, popRegFromString(buffer));
7041 pic14_emitcode("clrf","%s",buffer);
7042 emitpcode(POC_CLRF, popRegFromString(buffer));
7045 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7046 pic14_emitcode("movwf","%s",buffer);
7048 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7049 emitpcode(POC_MOVWF, popRegFromString(buffer));
7056 freeAsmop(right,NULL,ic,TRUE);
7057 freeAsmop(result,NULL,ic,TRUE);
7060 /*-----------------------------------------------------------------*/
7061 /* genNearPointerSet - pic14_emitcode for near pointer put */
7062 /*-----------------------------------------------------------------*/
7063 static void genNearPointerSet (operand *right,
7070 sym_link *ptype = operandType(result);
7073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7074 retype= getSpec(operandType(right));
7076 aopOp(result,ic,FALSE);
7078 /* if the result is rematerializable &
7079 in data space & not a bit variable */
7080 if (AOP_TYPE(result) == AOP_IMMD &&
7081 DCL_TYPE(ptype) == POINTER &&
7082 !IS_BITVAR(retype)) {
7083 genDataPointerSet (right,result,ic);
7087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7089 /* if the value is already in a pointer register
7090 then don't need anything more */
7091 if (!AOP_INPREG(AOP(result))) {
7092 /* otherwise get a free pointer register */
7093 //aop = newAsmop(0);
7094 //preg = getFreePtr(ic,&aop,FALSE);
7095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7096 //pic14_emitcode("mov","%s,%s",
7098 // aopGet(AOP(result),0,FALSE,TRUE));
7099 //rname = preg->name ;
7100 pic14_emitcode("movwf","fsr");
7102 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7104 freeAsmop(result,NULL,ic,TRUE);
7105 aopOp (right,ic,FALSE);
7106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7108 /* if bitfield then unpack the bits */
7109 if (IS_BITVAR(retype)) {
7110 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7111 "The programmer is obviously confused");
7112 //genPackBits (retype,right,rname,POINTER);
7116 /* we have can just get the values */
7117 int size = AOP_SIZE(right);
7120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7122 l = aopGet(AOP(right),offset,FALSE,TRUE);
7125 //pic14_emitcode("mov","@%s,a",rname);
7126 pic14_emitcode("movf","indf,w ;1");
7129 if (AOP_TYPE(right) == AOP_LIT) {
7130 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7132 pic14_emitcode("movlw","%s",l);
7133 pic14_emitcode("movwf","indf ;2");
7135 pic14_emitcode("clrf","indf");
7137 pic14_emitcode("movf","%s,w",l);
7138 pic14_emitcode("movwf","indf ;2");
7140 //pic14_emitcode("mov","@%s,%s",rname,l);
7143 pic14_emitcode("incf","fsr,f ;3");
7144 //pic14_emitcode("inc","%s",rname);
7149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7150 /* now some housekeeping stuff */
7152 /* we had to allocate for this iCode */
7153 freeAsmop(NULL,aop,ic,TRUE);
7155 /* we did not allocate which means left
7156 already in a pointer register, then
7157 if size > 0 && this could be used again
7158 we have to point it back to where it
7160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7161 if (AOP_SIZE(right) > 1 &&
7162 !OP_SYMBOL(result)->remat &&
7163 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7165 int size = AOP_SIZE(right) - 1;
7167 pic14_emitcode("decf","fsr,f");
7168 //pic14_emitcode("dec","%s",rname);
7172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7174 freeAsmop(right,NULL,ic,TRUE);
7179 /*-----------------------------------------------------------------*/
7180 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7181 /*-----------------------------------------------------------------*/
7182 static void genPagedPointerSet (operand *right,
7191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7193 retype= getSpec(operandType(right));
7195 aopOp(result,ic,FALSE);
7197 /* if the value is already in a pointer register
7198 then don't need anything more */
7199 if (!AOP_INPREG(AOP(result))) {
7200 /* otherwise get a free pointer register */
7202 preg = getFreePtr(ic,&aop,FALSE);
7203 pic14_emitcode("mov","%s,%s",
7205 aopGet(AOP(result),0,FALSE,TRUE));
7206 rname = preg->name ;
7208 rname = aopGet(AOP(result),0,FALSE,FALSE);
7210 freeAsmop(result,NULL,ic,TRUE);
7211 aopOp (right,ic,FALSE);
7213 /* if bitfield then unpack the bits */
7214 if (IS_BITVAR(retype))
7215 genPackBits (retype,right,rname,PPOINTER);
7217 /* we have can just get the values */
7218 int size = AOP_SIZE(right);
7222 l = aopGet(AOP(right),offset,FALSE,TRUE);
7225 pic14_emitcode("movx","@%s,a",rname);
7228 pic14_emitcode("inc","%s",rname);
7234 /* now some housekeeping stuff */
7236 /* we had to allocate for this iCode */
7237 freeAsmop(NULL,aop,ic,TRUE);
7239 /* we did not allocate which means left
7240 already in a pointer register, then
7241 if size > 0 && this could be used again
7242 we have to point it back to where it
7244 if (AOP_SIZE(right) > 1 &&
7245 !OP_SYMBOL(result)->remat &&
7246 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7248 int size = AOP_SIZE(right) - 1;
7250 pic14_emitcode("dec","%s",rname);
7255 freeAsmop(right,NULL,ic,TRUE);
7260 /*-----------------------------------------------------------------*/
7261 /* genFarPointerSet - set value from far space */
7262 /*-----------------------------------------------------------------*/
7263 static void genFarPointerSet (operand *right,
7264 operand *result, iCode *ic)
7267 sym_link *retype = getSpec(operandType(right));
7269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7270 aopOp(result,ic,FALSE);
7272 /* if the operand is already in dptr
7273 then we do nothing else we move the value to dptr */
7274 if (AOP_TYPE(result) != AOP_STR) {
7275 /* if this is remateriazable */
7276 if (AOP_TYPE(result) == AOP_IMMD)
7277 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7278 else { /* we need to get it byte by byte */
7279 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7280 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7281 if (options.model == MODEL_FLAT24)
7283 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7287 /* so dptr know contains the address */
7288 freeAsmop(result,NULL,ic,TRUE);
7289 aopOp(right,ic,FALSE);
7291 /* if bit then unpack */
7292 if (IS_BITVAR(retype))
7293 genPackBits(retype,right,"dptr",FPOINTER);
7295 size = AOP_SIZE(right);
7299 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7301 pic14_emitcode("movx","@dptr,a");
7303 pic14_emitcode("inc","dptr");
7307 freeAsmop(right,NULL,ic,TRUE);
7310 /*-----------------------------------------------------------------*/
7311 /* genGenPointerSet - set value from generic pointer space */
7312 /*-----------------------------------------------------------------*/
7313 static void genGenPointerSet (operand *right,
7314 operand *result, iCode *ic)
7317 sym_link *retype = getSpec(operandType(right));
7319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7321 aopOp(result,ic,FALSE);
7323 /* if the operand is already in dptr
7324 then we do nothing else we move the value to dptr */
7325 if (AOP_TYPE(result) != AOP_STR) {
7326 /* if this is remateriazable */
7327 if (AOP_TYPE(result) == AOP_IMMD) {
7328 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7329 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7331 else { /* we need to get it byte by byte */
7332 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7335 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7336 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7339 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7341 pic14_emitcode("movwf","INDF");
7344 /* so dptr know contains the address */
7345 freeAsmop(result,NULL,ic,TRUE);
7346 aopOp(right,ic,FALSE);
7348 /* if bit then unpack */
7349 if (IS_BITVAR(retype))
7350 genPackBits(retype,right,"dptr",GPOINTER);
7352 size = AOP_SIZE(right);
7356 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7358 pic14_emitcode("incf","fsr,f");
7359 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7360 pic14_emitcode("movwf","indf");
7362 //DEBUGpic14_emitcode(";lcall","__gptrput");
7364 // pic14_emitcode("inc","dptr");
7368 freeAsmop(right,NULL,ic,TRUE);
7371 /*-----------------------------------------------------------------*/
7372 /* genPointerSet - stores the value into a pointer location */
7373 /*-----------------------------------------------------------------*/
7374 static void genPointerSet (iCode *ic)
7376 operand *right, *result ;
7377 sym_link *type, *etype;
7380 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7382 right = IC_RIGHT(ic);
7383 result = IC_RESULT(ic) ;
7385 /* depending on the type of pointer we need to
7386 move it to the correct pointer register */
7387 type = operandType(result);
7388 etype = getSpec(type);
7389 /* if left is of type of pointer then it is simple */
7390 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7391 p_type = DCL_TYPE(type);
7394 /* we have to go by the storage class */
7395 p_type = PTR_TYPE(SPEC_OCLS(etype));
7397 /* if (SPEC_OCLS(etype)->codesp ) { */
7398 /* p_type = CPOINTER ; */
7401 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7402 /* p_type = FPOINTER ; */
7404 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7405 /* p_type = PPOINTER ; */
7407 /* if (SPEC_OCLS(etype) == idata ) */
7408 /* p_type = IPOINTER ; */
7410 /* p_type = POINTER ; */
7413 /* now that we have the pointer type we assign
7414 the pointer values */
7419 genNearPointerSet (right,result,ic);
7423 genPagedPointerSet (right,result,ic);
7427 genFarPointerSet (right,result,ic);
7431 genGenPointerSet (right,result,ic);
7437 /*-----------------------------------------------------------------*/
7438 /* genIfx - generate code for Ifx statement */
7439 /*-----------------------------------------------------------------*/
7440 static void genIfx (iCode *ic, iCode *popIc)
7442 operand *cond = IC_COND(ic);
7445 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7446 aopOp(cond,ic,FALSE);
7448 /* get the value into acc */
7449 if (AOP_TYPE(cond) != AOP_CRY)
7450 pic14_toBoolean(cond);
7453 /* the result is now in the accumulator */
7454 freeAsmop(cond,NULL,ic,TRUE);
7456 /* if there was something to be popped then do it */
7460 /* if the condition is a bit variable */
7461 if (isbit && IS_ITEMP(cond) &&
7463 genIfxJump(ic,SPIL_LOC(cond)->rname);
7464 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7468 if (isbit && !IS_ITEMP(cond))
7469 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7471 DEBUGpic14_emitcode ("; isbit","a");
7474 if (isbit && !IS_ITEMP(cond))
7475 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7482 /*-----------------------------------------------------------------*/
7483 /* genAddrOf - generates code for address of */
7484 /*-----------------------------------------------------------------*/
7485 static void genAddrOf (iCode *ic)
7487 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7492 aopOp(IC_RESULT(ic),ic,FALSE);
7494 /* if the operand is on the stack then we
7495 need to get the stack offset of this
7498 /* if it has an offset then we need to compute
7501 pic14_emitcode("mov","a,_bp");
7502 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7503 aopPut(AOP(IC_RESULT(ic)),"a",0);
7505 /* we can just move _bp */
7506 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7508 /* fill the result with zero */
7509 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7512 if (options.stack10bit && size < (FPTRSIZE - 1))
7515 "*** warning: pointer to stack var truncated.\n");
7522 if (options.stack10bit && offset == 2)
7524 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
7528 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
7535 /* object not on stack then we need the name */
7536 size = AOP_SIZE(IC_RESULT(ic));
7540 char s[SDCC_NAME_MAX];
7542 sprintf(s,"#(%s >> %d)",
7546 sprintf(s,"#%s",sym->rname);
7547 aopPut(AOP(IC_RESULT(ic)),s,offset++);
7551 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
7556 /*-----------------------------------------------------------------*/
7557 /* genFarFarAssign - assignment when both are in far space */
7558 /*-----------------------------------------------------------------*/
7559 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
7561 int size = AOP_SIZE(right);
7564 /* first push the right side on to the stack */
7566 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7568 pic14_emitcode ("push","acc");
7571 freeAsmop(right,NULL,ic,FALSE);
7572 /* now assign DPTR to result */
7573 aopOp(result,ic,FALSE);
7574 size = AOP_SIZE(result);
7576 pic14_emitcode ("pop","acc");
7577 aopPut(AOP(result),"a",--offset);
7579 freeAsmop(result,NULL,ic,FALSE);
7584 /*-----------------------------------------------------------------*/
7585 /* genAssign - generate code for assignment */
7586 /*-----------------------------------------------------------------*/
7587 static void genAssign (iCode *ic)
7589 operand *result, *right;
7591 unsigned long lit = 0L;
7593 result = IC_RESULT(ic);
7594 right = IC_RIGHT(ic) ;
7596 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7598 /* if they are the same */
7599 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
7602 aopOp(right,ic,FALSE);
7603 aopOp(result,ic,TRUE);
7605 /* if they are the same registers */
7606 if (pic14_sameRegs(AOP(right),AOP(result)))
7609 /* if the result is a bit */
7610 if (AOP_TYPE(result) == AOP_CRY) {
7612 /* if the right size is a literal then
7613 we know what the value is */
7614 if (AOP_TYPE(right) == AOP_LIT) {
7616 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
7617 popGet(AOP(result),0,FALSE,FALSE));
7619 if (((int) operandLitValue(right)))
7620 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
7621 AOP(result)->aopu.aop_dir,
7622 AOP(result)->aopu.aop_dir);
7624 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
7625 AOP(result)->aopu.aop_dir,
7626 AOP(result)->aopu.aop_dir);
7630 /* the right is also a bit variable */
7631 if (AOP_TYPE(right) == AOP_CRY) {
7632 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
7633 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
7634 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
7636 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
7637 AOP(result)->aopu.aop_dir,
7638 AOP(result)->aopu.aop_dir);
7639 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
7640 AOP(right)->aopu.aop_dir,
7641 AOP(right)->aopu.aop_dir);
7642 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
7643 AOP(result)->aopu.aop_dir,
7644 AOP(result)->aopu.aop_dir);
7649 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
7650 pic14_toBoolean(right);
7652 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
7653 //aopPut(AOP(result),"a",0);
7657 /* bit variables done */
7659 size = AOP_SIZE(result);
7661 if(AOP_TYPE(right) == AOP_LIT)
7662 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
7663 if((AOP_TYPE(result) != AOP_REG) &&
7664 (AOP_TYPE(right) == AOP_LIT) &&
7665 !IS_FLOAT(operandType(right)) &&
7669 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
7670 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
7671 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
7673 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
7674 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
7675 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
7676 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
7681 if(AOP_TYPE(right) == AOP_LIT) {
7682 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
7683 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
7685 } else if (AOP_TYPE(right) == AOP_CRY) {
7686 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
7688 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
7689 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
7692 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7693 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
7696 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
7702 freeAsmop (right,NULL,ic,FALSE);
7703 freeAsmop (result,NULL,ic,TRUE);
7706 /*-----------------------------------------------------------------*/
7707 /* genJumpTab - genrates code for jump table */
7708 /*-----------------------------------------------------------------*/
7709 static void genJumpTab (iCode *ic)
7714 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7716 aopOp(IC_JTCOND(ic),ic,FALSE);
7717 /* get the condition into accumulator */
7718 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
7720 /* multiply by three */
7721 pic14_emitcode("add","a,acc");
7722 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
7723 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
7725 jtab = newiTempLabel(NULL);
7726 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
7727 pic14_emitcode("jmp","@a+dptr");
7728 pic14_emitcode("","%05d_DS_:",jtab->key+100);
7729 /* now generate the jump labels */
7730 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
7731 jtab = setNextItem(IC_JTLABELS(ic)))
7732 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
7736 /*-----------------------------------------------------------------*/
7737 /* genMixedOperation - gen code for operators between mixed types */
7738 /*-----------------------------------------------------------------*/
7740 TSD - Written for the PIC port - but this unfortunately is buggy.
7741 This routine is good in that it is able to efficiently promote
7742 types to different (larger) sizes. Unfortunately, the temporary
7743 variables that are optimized out by this routine are sometimes
7744 used in other places. So until I know how to really parse the
7745 iCode tree, I'm going to not be using this routine :(.
7747 static int genMixedOperation (iCode *ic)
7750 operand *result = IC_RESULT(ic);
7751 sym_link *ctype = operandType(IC_LEFT(ic));
7752 operand *right = IC_RIGHT(ic);
7758 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
7760 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
7766 nextright = IC_RIGHT(nextic);
7767 nextleft = IC_LEFT(nextic);
7768 nextresult = IC_RESULT(nextic);
7770 aopOp(right,ic,FALSE);
7771 aopOp(result,ic,FALSE);
7772 aopOp(nextright, nextic, FALSE);
7773 aopOp(nextleft, nextic, FALSE);
7774 aopOp(nextresult, nextic, FALSE);
7776 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
7782 pic14_emitcode(";remove right +","");
7784 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
7790 pic14_emitcode(";remove left +","");
7794 big = AOP_SIZE(nextleft);
7795 small = AOP_SIZE(nextright);
7797 switch(nextic->op) {
7800 pic14_emitcode(";optimize a +","");
7801 /* if unsigned or not an integral type */
7802 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
7803 pic14_emitcode(";add a bit to something","");
7806 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
7808 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
7809 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
7810 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
7812 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
7820 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
7821 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7822 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7825 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7827 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
7828 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
7829 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
7830 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7831 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
7834 pic14_emitcode("rlf","known_zero,w");
7841 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
7842 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7843 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7845 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7855 freeAsmop(right,NULL,ic,TRUE);
7856 freeAsmop(result,NULL,ic,TRUE);
7857 freeAsmop(nextright,NULL,ic,TRUE);
7858 freeAsmop(nextleft,NULL,ic,TRUE);
7860 nextic->generated = 1;
7867 /*-----------------------------------------------------------------*/
7868 /* genCast - gen code for casting */
7869 /*-----------------------------------------------------------------*/
7870 static void genCast (iCode *ic)
7872 operand *result = IC_RESULT(ic);
7873 sym_link *ctype = operandType(IC_LEFT(ic));
7874 operand *right = IC_RIGHT(ic);
7877 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
7878 /* if they are equivalent then do nothing */
7879 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
7882 aopOp(right,ic,FALSE) ;
7883 aopOp(result,ic,FALSE);
7885 /* if the result is a bit */
7886 if (AOP_TYPE(result) == AOP_CRY) {
7887 /* if the right size is a literal then
7888 we know what the value is */
7889 if (AOP_TYPE(right) == AOP_LIT) {
7891 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
7892 popGet(AOP(result),0,FALSE,FALSE));
7894 if (((int) operandLitValue(right)))
7895 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
7896 AOP(result)->aopu.aop_dir,
7897 AOP(result)->aopu.aop_dir);
7899 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
7900 AOP(result)->aopu.aop_dir,
7901 AOP(result)->aopu.aop_dir);
7906 /* the right is also a bit variable */
7907 if (AOP_TYPE(right) == AOP_CRY) {
7910 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
7912 pic14_emitcode("clrc","");
7913 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
7914 AOP(right)->aopu.aop_dir,
7915 AOP(right)->aopu.aop_dir);
7916 aopPut(AOP(result),"c",0);
7921 pic14_toBoolean(right);
7922 aopPut(AOP(result),"a",0);
7926 /* if they are the same size : or less */
7927 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
7929 /* if they are in the same place */
7930 if (pic14_sameRegs(AOP(right),AOP(result)))
7933 /* if they in different places then copy */
7934 size = AOP_SIZE(result);
7938 aopGet(AOP(right),offset,FALSE,FALSE),
7946 /* if the result is of type pointer */
7947 if (IS_PTR(ctype)) {
7950 sym_link *type = operandType(right);
7951 sym_link *etype = getSpec(type);
7953 /* pointer to generic pointer */
7954 if (IS_GENPTR(ctype)) {
7958 p_type = DCL_TYPE(type);
7960 /* we have to go by the storage class */
7961 p_type = PTR_TYPE(SPEC_OCLS(etype));
7963 /* if (SPEC_OCLS(etype)->codesp ) */
7964 /* p_type = CPOINTER ; */
7966 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7967 /* p_type = FPOINTER ; */
7969 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7970 /* p_type = PPOINTER; */
7972 /* if (SPEC_OCLS(etype) == idata ) */
7973 /* p_type = IPOINTER ; */
7975 /* p_type = POINTER ; */
7978 /* the first two bytes are known */
7979 size = GPTRSIZE - 1;
7983 aopGet(AOP(right),offset,FALSE,FALSE),
7987 /* the last byte depending on type */
8004 /* this should never happen */
8005 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8006 "got unknown pointer type");
8009 aopPut(AOP(result),l, GPTRSIZE - 1);
8013 /* just copy the pointers */
8014 size = AOP_SIZE(result);
8018 aopGet(AOP(right),offset,FALSE,FALSE),
8026 if (AOP_TYPE(right) == AOP_CRY) {
8028 size = AOP_SIZE(right);
8030 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8031 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8032 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8034 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8035 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8036 AOP(right)->aopu.aop_dir,
8037 AOP(right)->aopu.aop_dir);
8038 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8040 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8041 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8046 /* so we now know that the size of destination is greater
8047 than the size of the source.
8048 Now, if the next iCode is an operator then we might be
8049 able to optimize the operation without performing a cast.
8051 if(genMixedOperation(ic))
8055 /* we move to result for the size of source */
8056 size = AOP_SIZE(right);
8059 pic14_emitcode(";","%d",__LINE__);
8061 aopGet(AOP(right),offset,FALSE,FALSE),
8066 /* now depending on the sign of the destination */
8067 size = AOP_SIZE(result) - AOP_SIZE(right);
8068 /* if unsigned or not an integral type */
8069 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8071 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8072 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8076 /* we need to extend the sign :{ */
8077 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8080 emitpcode(POC_CLRW, NULL);
8081 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8082 emitpcode(POC_MOVLW, popGetLit(0xff));
8084 pic14_emitcode("clrw","");
8085 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8086 AOP(right)->aopu.aop_dir,
8087 AOP(right)->aopu.aop_dir);
8088 pic14_emitcode("movlw","0xff");
8090 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8091 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8093 // aopPut(AOP(result),"a",offset++);
8098 /* we are done hurray !!!! */
8101 freeAsmop(right,NULL,ic,TRUE);
8102 freeAsmop(result,NULL,ic,TRUE);
8106 /*-----------------------------------------------------------------*/
8107 /* genDjnz - generate decrement & jump if not zero instrucion */
8108 /*-----------------------------------------------------------------*/
8109 static int genDjnz (iCode *ic, iCode *ifx)
8112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8117 /* if the if condition has a false label
8118 then we cannot save */
8122 /* if the minus is not of the form
8124 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8125 !IS_OP_LITERAL(IC_RIGHT(ic)))
8128 if (operandLitValue(IC_RIGHT(ic)) != 1)
8131 /* if the size of this greater than one then no
8133 if (getSize(operandType(IC_RESULT(ic))) > 1)
8136 /* otherwise we can save BIG */
8137 lbl = newiTempLabel(NULL);
8138 lbl1= newiTempLabel(NULL);
8140 aopOp(IC_RESULT(ic),ic,FALSE);
8142 if (IS_AOP_PREG(IC_RESULT(ic))) {
8143 pic14_emitcode("dec","%s",
8144 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8145 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8146 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8150 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8151 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8153 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8154 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8157 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8158 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8159 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8160 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8163 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8168 /*-----------------------------------------------------------------*/
8169 /* genReceive - generate code for a receive iCode */
8170 /*-----------------------------------------------------------------*/
8171 static void genReceive (iCode *ic)
8173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8175 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8176 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8177 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8179 int size = getSize(operandType(IC_RESULT(ic)));
8180 int offset = fReturnSizePic - size;
8182 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8183 fReturn[fReturnSizePic - offset - 1] : "acc"));
8186 aopOp(IC_RESULT(ic),ic,FALSE);
8187 size = AOP_SIZE(IC_RESULT(ic));
8190 pic14_emitcode ("pop","acc");
8191 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8196 aopOp(IC_RESULT(ic),ic,FALSE);
8198 assignResultValue(IC_RESULT(ic));
8201 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8204 /*-----------------------------------------------------------------*/
8205 /* genpic14Code - generate code for pic14 based controllers */
8206 /*-----------------------------------------------------------------*/
8208 * At this point, ralloc.c has gone through the iCode and attempted
8209 * to optimize in a way suitable for a PIC. Now we've got to generate
8210 * PIC instructions that correspond to the iCode.
8212 * Once the instructions are generated, we'll pass through both the
8213 * peep hole optimizer and the pCode optimizer.
8214 *-----------------------------------------------------------------*/
8216 void genpic14Code (iCode *lic)
8221 lineHead = lineCurr = NULL;
8223 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8226 /* if debug information required */
8227 /* if (options.debug && currFunc) { */
8229 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8231 if (IS_STATIC(currFunc->etype)) {
8232 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8233 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8235 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8236 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8242 for (ic = lic ; ic ; ic = ic->next ) {
8244 DEBUGpic14_emitcode(";ic","");
8245 if ( cln != ic->lineno ) {
8246 if ( options.debug ) {
8248 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8249 FileBaseName(ic->filename),ic->lineno,
8250 ic->level,ic->block);
8253 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8256 /* if the result is marked as
8257 spilt and rematerializable or code for
8258 this has already been generated then
8260 if (resultRemat(ic) || ic->generated )
8263 /* depending on the operation */
8282 /* IPOP happens only when trying to restore a
8283 spilt live range, if there is an ifx statement
8284 following this pop then the if statement might
8285 be using some of the registers being popped which
8286 would destory the contents of the register so
8287 we need to check for this condition and handle it */
8289 ic->next->op == IFX &&
8290 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8291 genIfx (ic->next,ic);
8309 genEndFunction (ic);
8329 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8346 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8350 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8357 /* note these two are xlated by algebraic equivalence
8358 during parsing SDCC.y */
8359 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8360 "got '>=' or '<=' shouldn't have come here");
8364 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8376 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8380 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8384 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8411 case GET_VALUE_AT_ADDRESS:
8416 if (POINTER_SET(ic))
8443 addSet(&_G.sendSet,ic);
8452 /* now we are ready to call the
8453 peep hole optimizer */
8454 if (!options.nopeep) {
8455 printf("peep hole optimizing\n");
8456 peepHole (&lineHead);
8458 /* now do the actual printing */
8459 printLine (lineHead,codeOutFile);
8461 printf("printing pBlock\n\n");
8462 printpBlock(stdout,pb);