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"
40 #define __FUNCTION__ __FILE__
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
49 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
50 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
51 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
62 //char *aopLiteral (value *val, int offset);
63 unsigned int pic14aopLiteral (value *val, int offset);
65 /* this is the down and dirty file with all kinds of
66 kludgy & hacky stuff. This is what it is all about
67 CODE GENERATION for a specific MCU . some of the
68 routines may be reusable, will have to see */
70 static char *zero = "#0x00";
71 static char *one = "#0x01";
72 static char *spname = "sp";
74 char *fReturnpic14[] = {"FSR","dph","b","a" };
75 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
76 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
77 static char **fReturn = fReturnpic14;
79 static char *accUse[] = {"a","b"};
81 //static short rbank = -1;
93 char *Safe_strdup(char *str); // in pcode.c
95 extern int pic14_ptrRegReq ;
96 extern int pic14_nRegs;
97 extern FILE *codeOutFile;
98 static void saverbank (int, iCode *,bool);
99 #define RESULTONSTACK(x) \
100 (IC_RESULT(x) && IC_RESULT(x)->aop && \
101 IC_RESULT(x)->aop->type == AOP_STK )
103 #define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode(";XXX mov","a,%s %s,%d",x,__FILE__,__LINE__);
104 #define CLRC emitcode(";XXX clr","c %s,%d",__FILE__,__LINE__);
106 #define BIT_NUMBER(x) (x & 7)
107 #define BIT_REGISTER(x) (x>>3)
109 static lineNode *lineHead = NULL;
110 static lineNode *lineCurr = NULL;
112 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
113 0xE0, 0xC0, 0x80, 0x00};
114 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
115 0x07, 0x03, 0x01, 0x00};
123 #define FUNCTION_LABEL_INC 20
124 static int labelOffset=0;
125 static int debug_verbose=1;
129 /*-----------------------------------------------------------------*/
130 /* Macros for emitting instructions */
131 /*-----------------------------------------------------------------*/
133 #define emitSKPC emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_C_BIT))
134 #define emitSKPNC emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_C_BIT))
135 #define emitSKPZ emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
136 #define emitSKPNZ emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
137 #define emitCLRZ emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
138 #define emitCLRC emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_C_BIT))
139 #define emitSETZ emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
140 #define emitSETC emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_C_BIT))
142 //#define emitSKPC emitcode("btfss","status,c")
143 //#define emitSKPNC emitcode("btfsc","status,c")
144 //#define emitSKPZ emitcode("btfss","status,z")
145 //#define emitSKPNZ emitcode("btfsc","status,z")
147 /*-----------------------------------------------------------------*/
148 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
149 /* exponent of 2 is returned, otherwise -1 is */
151 /* note that this is similar to the function `powof2' in SDCCsymt */
155 /*-----------------------------------------------------------------*/
156 static int my_powof2 (unsigned long num)
159 if( (num & (num-1)) == 0) {
172 static void emitpLabel(int key)
174 addpCode2pBlock(pb,newpCodeLabel(key));
177 static void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
180 addpCode2pBlock(pb,newpCode(poc,pcop));
183 /*-----------------------------------------------------------------*/
184 /* emitcode - writes the code into a file : for now it is simple */
185 /*-----------------------------------------------------------------*/
186 static void emitcode (char *inst,char *fmt, ...)
189 char lb[MAX_INLINEASM];
196 sprintf(lb,"%s\t",inst);
198 sprintf(lb,"%s",inst);
199 vsprintf(lb+(strlen(lb)),fmt,ap);
203 while (isspace(*lbp)) lbp++;
206 lineCurr = (lineCurr ?
207 connectLine(lineCurr,newLineNode(lb)) :
208 (lineHead = newLineNode(lb)));
209 lineCurr->isInline = _G.inLine;
210 lineCurr->isDebug = _G.debugLine;
213 addpCode2pBlock(pb,newpCodeCharP(lb));
218 static void DEBUGemitcode (char *inst,char *fmt, ...)
221 char lb[MAX_INLINEASM];
231 sprintf(lb,"%s\t",inst);
233 sprintf(lb,"%s",inst);
234 vsprintf(lb+(strlen(lb)),fmt,ap);
238 while (isspace(*lbp)) lbp++;
241 lineCurr = (lineCurr ?
242 connectLine(lineCurr,newLineNode(lb)) :
243 (lineHead = newLineNode(lb)));
244 lineCurr->isInline = _G.inLine;
245 lineCurr->isDebug = _G.debugLine;
247 addpCode2pBlock(pb,newpCodeCharP(lb));
253 /*-----------------------------------------------------------------*/
254 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
255 /*-----------------------------------------------------------------*/
256 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
258 bool r0iu = FALSE , r1iu = FALSE;
259 bool r0ou = FALSE , r1ou = FALSE;
261 /* the logic: if r0 & r1 used in the instruction
262 then we are in trouble otherwise */
264 /* first check if r0 & r1 are used by this
265 instruction, in which case we are in trouble */
266 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
267 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
272 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
273 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
275 /* if no usage of r0 then return it */
276 if (!r0iu && !r0ou) {
277 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
278 (*aopp)->type = AOP_R0;
280 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
283 /* if no usage of r1 then return it */
284 if (!r1iu && !r1ou) {
285 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
286 (*aopp)->type = AOP_R1;
288 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
291 /* now we know they both have usage */
292 /* if r0 not used in this instruction */
294 /* push it if not already pushed */
296 emitcode ("push","%s",
297 pic14_regWithIdx(R0_IDX)->dname);
301 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
302 (*aopp)->type = AOP_R0;
304 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
307 /* if r1 not used then */
310 /* push it if not already pushed */
312 emitcode ("push","%s",
313 pic14_regWithIdx(R1_IDX)->dname);
317 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
318 (*aopp)->type = AOP_R1;
319 return pic14_regWithIdx(R1_IDX);
323 /* I said end of world but not quite end of world yet */
324 /* if this is a result then we can push it on the stack*/
326 (*aopp)->type = AOP_STK;
331 /* other wise this is true end of the world */
332 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
333 "getFreePtr should never reach here");
337 /*-----------------------------------------------------------------*/
338 /* newAsmop - creates a new asmOp */
339 /*-----------------------------------------------------------------*/
340 static asmop *newAsmop (short type)
344 aop = Safe_calloc(1,sizeof(asmop));
349 static void genSetDPTR(int n)
353 emitcode(";", "Select standard DPTR");
354 emitcode("mov", "dps, #0x00");
358 emitcode(";", "Select alternate DPTR");
359 emitcode("mov", "dps, #0x01");
363 /*-----------------------------------------------------------------*/
364 /* pointerCode - returns the code for a pointer type */
365 /*-----------------------------------------------------------------*/
366 static int pointerCode (sym_link *etype)
369 return PTR_TYPE(SPEC_OCLS(etype));
373 /*-----------------------------------------------------------------*/
374 /* aopForSym - for a true symbol */
375 /*-----------------------------------------------------------------*/
376 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
379 memmap *space= SPEC_OCLS(sym->etype);
381 DEBUGemitcode("; ***","%s %d",__FUNCTION__,__LINE__);
382 /* if already has one */
386 /* assign depending on the storage class */
387 /* if it is on the stack or indirectly addressable */
388 /* space we need to assign either r0 or r1 to it */
389 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
390 sym->aop = aop = newAsmop(0);
391 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
392 aop->size = getSize(sym->type);
394 /* now assign the address of the variable to
395 the pointer register */
396 if (aop->type != AOP_STK) {
400 emitcode("push","acc");
402 emitcode("mov","a,_bp");
403 emitcode("add","a,#0x%02x",
405 ((char)(sym->stack - _G.nRegsSaved )) :
406 ((char)sym->stack)) & 0xff);
407 emitcode("mov","%s,a",
408 aop->aopu.aop_ptr->name);
411 emitcode("pop","acc");
413 emitcode("mov","%s,#%s",
414 aop->aopu.aop_ptr->name,
416 aop->paged = space->paged;
418 aop->aopu.aop_stk = sym->stack;
422 if (sym->onStack && options.stack10bit)
424 /* It's on the 10 bit stack, which is located in
428 //DEBUGemitcode(";","%d",__LINE__);
431 emitcode("push","acc");
433 emitcode("mov","a,_bp");
434 emitcode("add","a,#0x%02x",
436 ((char)(sym->stack - _G.nRegsSaved )) :
437 ((char)sym->stack)) & 0xff);
440 emitcode ("mov","dpx1,#0x40");
441 emitcode ("mov","dph1,#0x00");
442 emitcode ("mov","dpl1, a");
446 emitcode("pop","acc");
448 sym->aop = aop = newAsmop(AOP_DPTR2);
449 aop->size = getSize(sym->type);
453 //DEBUGemitcode(";","%d",__LINE__);
454 /* if in bit space */
455 if (IN_BITSPACE(space)) {
456 sym->aop = aop = newAsmop (AOP_CRY);
457 aop->aopu.aop_dir = sym->rname ;
458 aop->size = getSize(sym->type);
459 DEBUGemitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
462 /* if it is in direct space */
463 if (IN_DIRSPACE(space)) {
464 sym->aop = aop = newAsmop (AOP_DIR);
465 aop->aopu.aop_dir = sym->rname ;
466 aop->size = getSize(sym->type);
467 DEBUGemitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
471 /* special case for a function */
472 if (IS_FUNC(sym->type)) {
473 sym->aop = aop = newAsmop(AOP_IMMD);
474 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
475 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
476 strcpy(aop->aopu.aop_immd,sym->rname);
477 aop->size = FPTRSIZE;
482 /* only remaining is far space */
483 /* in which case DPTR gets the address */
484 sym->aop = aop = newAsmop(AOP_DPTR);
485 emitcode ("mov","dptr,#%s", sym->rname);
486 aop->size = getSize(sym->type);
488 DEBUGemitcode(";","%d size = %d",__LINE__,aop->size);
489 /* if it is in code space */
490 if (IN_CODESPACE(space))
496 /*-----------------------------------------------------------------*/
497 /* aopForRemat - rematerialzes an object */
498 /*-----------------------------------------------------------------*/
499 static asmop *aopForRemat (symbol *sym)
501 iCode *ic = sym->rematiCode;
502 asmop *aop = newAsmop(AOP_IMMD);
504 DEBUGemitcode(";","%s %d",__FUNCTION__,__LINE__);
507 val += operandLitValue(IC_RIGHT(ic));
508 else if (ic->op == '-')
509 val -= operandLitValue(IC_RIGHT(ic));
513 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
517 sprintf(buffer,"(%s %c 0x%04x)",
518 OP_SYMBOL(IC_LEFT(ic))->rname,
519 val >= 0 ? '+' : '-',
522 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
524 //DEBUGemitcode(";","%s",buffer);
525 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
526 strcpy(aop->aopu.aop_immd,buffer);
530 /*-----------------------------------------------------------------*/
531 /* regsInCommon - two operands have some registers in common */
532 /*-----------------------------------------------------------------*/
533 static bool regsInCommon (operand *op1, operand *op2)
538 /* if they have registers in common */
539 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
542 sym1 = OP_SYMBOL(op1);
543 sym2 = OP_SYMBOL(op2);
545 if (sym1->nRegs == 0 || sym2->nRegs == 0)
548 for (i = 0 ; i < sym1->nRegs ; i++) {
553 for (j = 0 ; j < sym2->nRegs ;j++ ) {
557 if (sym2->regs[j] == sym1->regs[i])
565 /*-----------------------------------------------------------------*/
566 /* operandsEqu - equivalent */
567 /*-----------------------------------------------------------------*/
568 static bool operandsEqu ( operand *op1, operand *op2)
572 /* if they not symbols */
573 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
576 sym1 = OP_SYMBOL(op1);
577 sym2 = OP_SYMBOL(op2);
579 /* if both are itemps & one is spilt
580 and the other is not then false */
581 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
582 sym1->isspilt != sym2->isspilt )
585 /* if they are the same */
589 if (strcmp(sym1->rname,sym2->rname) == 0)
593 /* if left is a tmp & right is not */
597 (sym1->usl.spillLoc == sym2))
604 (sym2->usl.spillLoc == sym1))
610 /*-----------------------------------------------------------------*/
611 /* sameRegs - two asmops have the same registers */
612 /*-----------------------------------------------------------------*/
613 static bool sameRegs (asmop *aop1, asmop *aop2 )
620 if (aop1->type != AOP_REG ||
621 aop2->type != AOP_REG )
624 if (aop1->size != aop2->size )
627 for (i = 0 ; i < aop1->size ; i++ )
628 if (aop1->aopu.aop_reg[i] !=
629 aop2->aopu.aop_reg[i] )
635 /*-----------------------------------------------------------------*/
636 /* aopOp - allocates an asmop for an operand : */
637 /*-----------------------------------------------------------------*/
638 static void aopOp (operand *op, iCode *ic, bool result)
647 DEBUGemitcode(";","%d",__LINE__);
648 /* if this a literal */
649 if (IS_OP_LITERAL(op)) {
650 DEBUGemitcode(";","%d",__LINE__);
651 op->aop = aop = newAsmop(AOP_LIT);
652 aop->aopu.aop_lit = op->operand.valOperand;
653 aop->size = getSize(operandType(op));
657 /* if already has a asmop then continue */
661 /* if the underlying symbol has a aop */
662 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
663 DEBUGemitcode(";","%d",__LINE__);
664 op->aop = OP_SYMBOL(op)->aop;
668 /* if this is a true symbol */
669 if (IS_TRUE_SYMOP(op)) {
670 DEBUGemitcode(";","%d",__LINE__);
671 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
675 /* this is a temporary : this has
681 e) can be a return use only */
686 /* if the type is a conditional */
687 if (sym->regType == REG_CND) {
688 DEBUGemitcode(";","%d",__LINE__);
689 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
694 /* if it is spilt then two situations
696 b) has a spill location */
697 if (sym->isspilt || sym->nRegs == 0) {
699 DEBUGemitcode(";","%d",__LINE__);
700 /* rematerialize it NOW */
702 sym->aop = op->aop = aop =
704 aop->size = getSize(sym->type);
705 DEBUGemitcode(";","%d",__LINE__);
711 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
712 aop->size = getSize(sym->type);
713 for ( i = 0 ; i < 2 ; i++ )
714 aop->aopu.aop_str[i] = accUse[i];
715 DEBUGemitcode(";","%d",__LINE__);
721 aop = op->aop = sym->aop = newAsmop(AOP_STR);
722 aop->size = getSize(sym->type);
723 for ( i = 0 ; i < fReturnSizePic ; i++ )
724 aop->aopu.aop_str[i] = fReturn[i];
725 DEBUGemitcode(";","%d",__LINE__);
729 /* else spill location */
730 DEBUGemitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
731 sym->aop = op->aop = aop =
732 aopForSym(ic,sym->usl.spillLoc,result);
733 aop->size = getSize(sym->type);
737 /* must be in a register */
738 sym->aop = op->aop = aop = newAsmop(AOP_REG);
739 aop->size = sym->nRegs;
740 for ( i = 0 ; i < sym->nRegs ;i++)
741 aop->aopu.aop_reg[i] = sym->regs[i];
744 /*-----------------------------------------------------------------*/
745 /* freeAsmop - free up the asmop given to an operand */
746 /*----------------------------------------------------------------*/
747 static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
764 /* depending on the asmop type only three cases need work AOP_RO
765 , AOP_R1 && AOP_STK */
770 emitcode ("pop","ar0");
774 bitVectUnSetBit(ic->rUsed,R0_IDX);
780 emitcode ("pop","ar1");
784 bitVectUnSetBit(ic->rUsed,R1_IDX);
790 int stk = aop->aopu.aop_stk + aop->size;
791 bitVectUnSetBit(ic->rUsed,R0_IDX);
792 bitVectUnSetBit(ic->rUsed,R1_IDX);
794 getFreePtr(ic,&aop,FALSE);
796 if (options.stack10bit)
798 /* I'm not sure what to do here yet... */
801 "*** Warning: probably generating bad code for "
802 "10 bit stack mode.\n");
806 emitcode ("mov","a,_bp");
807 emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
808 emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
810 emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
814 emitcode("pop","acc");
815 emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
817 emitcode("dec","%s",aop->aopu.aop_ptr->name);
820 freeAsmop(op,NULL,ic,TRUE);
822 emitcode("pop","ar0");
827 emitcode("pop","ar1");
834 /* all other cases just dealloc */
838 OP_SYMBOL(op)->aop = NULL;
839 /* if the symbol has a spill */
841 SPIL_LOC(op)->aop = NULL;
846 /*-----------------------------------------------------------------*/
847 /* aopGet - for fetching value of the aop */
848 /*-----------------------------------------------------------------*/
849 static char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
854 //DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
855 /* offset is greater than
857 if (offset > (aop->size - 1) &&
858 aop->type != AOP_LIT)
861 /* depending on type */
866 DEBUGemitcode(";","%d",__LINE__);
867 /* if we need to increment it */
868 while (offset > aop->coff) {
869 emitcode ("inc","%s",aop->aopu.aop_ptr->name);
873 while (offset < aop->coff) {
874 emitcode("dec","%s",aop->aopu.aop_ptr->name);
880 emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
881 return (dname ? "acc" : "a");
883 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
884 rs = Safe_calloc(1,strlen(s)+1);
890 DEBUGemitcode(";","%d",__LINE__);
891 if (aop->type == AOP_DPTR2)
896 while (offset > aop->coff) {
897 emitcode ("inc","dptr");
901 while (offset < aop->coff) {
902 emitcode("lcall","__decdptr");
909 emitcode("movc","a,@a+dptr");
912 emitcode("movx","a,@dptr");
915 if (aop->type == AOP_DPTR2)
920 return (dname ? "acc" : "a");
924 DEBUGemitcode(";","%d",__LINE__);
926 sprintf (s,"%s",aop->aopu.aop_immd);
929 sprintf(s,"(%s >> %d)",
935 rs = Safe_calloc(1,strlen(s)+1);
941 sprintf(s,"(%s + %d)",
945 sprintf(s,"%s",aop->aopu.aop_dir);
946 rs = Safe_calloc(1,strlen(s)+1);
951 DEBUGemitcode(";","%d",__LINE__);
953 return aop->aopu.aop_reg[offset]->dname;
955 return aop->aopu.aop_reg[offset]->name;
958 emitcode(";","%d",__LINE__);
959 //emitcode("clr","a");
960 //emitcode("mov","c,%s",aop->aopu.aop_dir);
961 //emitcode("rlc","a") ;
962 //return (dname ? "acc" : "a");
963 return aop->aopu.aop_dir;
966 DEBUGemitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
967 //if (!offset && dname)
969 //return aop->aopu.aop_str[offset];
970 return "AOP_accumulator_bug";
973 DEBUGemitcode(";","%d",__LINE__);
974 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
975 rs = Safe_calloc(1,strlen(s)+1);
980 DEBUGemitcode(";","%d",__LINE__);
982 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
986 return aop->aopu.aop_str[offset];
990 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
991 "aopget got unsupported aop->type");
995 /*-----------------------------------------------------------------*/
996 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
997 /*-----------------------------------------------------------------*/
998 static pCodeOp *popGetLabel(unsigned int key)
1000 return newpCodeOpLabel(key+100+labelOffset);
1003 /*-----------------------------------------------------------------*/
1004 /* popCopy - copy a pcode operator */
1005 /*-----------------------------------------------------------------*/
1006 static pCodeOp *popCopy(pCodeOp *pc)
1010 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1011 pcop->type = pc->type;
1012 if(!(pcop->name = strdup(pc->name)))
1013 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1018 /*-----------------------------------------------------------------*/
1019 /* popCopy - copy a pcode operator */
1020 /*-----------------------------------------------------------------*/
1021 static pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1025 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1026 pcop->type = PO_BIT;
1027 if(!(pcop->name = strdup(pc->name)))
1028 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1029 ((pCodeOpBit *)pcop)->bit = bitval;
1031 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1036 /*-----------------------------------------------------------------*/
1037 /* popGet - asm operator to pcode operator conversion */
1038 /*-----------------------------------------------------------------*/
1039 static pCodeOp *popGetLit(unsigned int lit)
1042 return newpCodeOpLit(lit);
1046 /*-----------------------------------------------------------------*/
1047 /* popGet - asm operator to pcode operator conversion */
1048 /*-----------------------------------------------------------------*/
1049 static pCodeOp *popGetWithString(char *str)
1055 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1059 pcop = newpCodeOp(str,PO_STR);
1063 /*-----------------------------------------------------------------*/
1064 /* popGet - asm operator to pcode operator conversion */
1065 /*-----------------------------------------------------------------*/
1066 static pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1073 //DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1074 /* offset is greater than
1077 if (offset > (aop->size - 1) &&
1078 aop->type != AOP_LIT)
1079 return NULL; //zero;
1081 /* depending on type */
1082 switch (aop->type) {
1089 DEBUGemitcode(";8051 legacy","%d",__LINE__);
1090 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1091 pcop->type = PO_SFR_REGISTER;
1093 PCOR(pcop)->rIdx = -1;
1094 PCOR(pcop)->r = NULL;
1095 // Really nasty hack to check for temporary registers
1097 pcop->name = Safe_strdup("BAD_REGISTER");
1102 DEBUGemitcode(";","%d",__LINE__);
1103 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1104 pcop->type = PO_IMMEDIATE;
1106 sprintf (s,"%s",aop->aopu.aop_immd);
1109 sprintf(s,"(%s >> %d)",
1114 aop->aopu.aop_immd);
1115 pcop->name = Safe_calloc(1,strlen(s)+1);
1116 strcpy(pcop->name,s);
1120 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1121 pcop->type = PO_DIR;
1123 sprintf(s,"(%s + %d)",
1127 sprintf(s,"%s",aop->aopu.aop_dir);
1128 pcop->name = Safe_calloc(1,strlen(s)+1);
1129 strcpy(pcop->name,s);
1136 DEBUGemitcode(";","%d",__LINE__);
1137 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1138 pcop->type = PO_GPR_REGISTER;
1140 rs = aop->aopu.aop_reg[offset]->dname;
1142 rs = aop->aopu.aop_reg[offset]->name;
1144 PCOR(pcop)->rIdx = aop->aopu.aop_reg[offset]->rIdx;
1145 PCOR(pcop)->r = pic14_regWithIdx(aop->aopu.aop_reg[offset]->rIdx);
1146 // Really nasty hack to check for temporary registers
1148 if(len >=3 && rs[0]=='r' && rs[1]=='0' && rs[2]=='x')
1149 pcop->type = PO_GPR_TEMP;
1151 fprintf(stderr,"popGet - AOP_REG is not a temp: %s\n",rs);
1153 DEBUGemitcode(";","%d %s",__LINE__,rs);
1154 pcop->name = NULL;// Safe_calloc(1,(strlen(rs)+1));
1155 //strcpy(pcop->name,rs);
1160 pcop = newpCodeOpBit(aop->aopu.aop_dir,0);
1164 DEBUGemitcode(";","%d",__LINE__);
1165 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1168 DEBUGemitcode(";","%d",__LINE__);
1170 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1171 pcop->type = PO_STR;
1173 //aop->coff = offset ;
1174 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1175 sprintf(s,"%s","acc");
1177 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1178 pcop->name = Safe_calloc(1,strlen(s)+1);
1179 strcpy(pcop->name,s);
1184 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1185 "popGet got unsupported aop->type");
1188 /*-----------------------------------------------------------------*/
1189 /* aopPut - puts a string for a aop */
1190 /*-----------------------------------------------------------------*/
1191 static void aopPut (asmop *aop, char *s, int offset)
1196 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1198 if (aop->size && offset > ( aop->size - 1)) {
1199 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1200 "aopPut got offset > aop->size");
1204 /* will assign value to value */
1205 /* depending on where it is ofcourse */
1206 switch (aop->type) {
1209 sprintf(d,"(%s + %d)",
1210 aop->aopu.aop_dir,offset);
1212 sprintf(d,"%s",aop->aopu.aop_dir);
1215 DEBUGemitcode(";","%d",__LINE__);
1217 emitcode("movf","%s,w",s);
1218 emitcode("movwf","%s",d);
1221 emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1222 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1229 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1230 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1233 strcmp(s,"r0") == 0 ||
1234 strcmp(s,"r1") == 0 ||
1235 strcmp(s,"r2") == 0 ||
1236 strcmp(s,"r3") == 0 ||
1237 strcmp(s,"r4") == 0 ||
1238 strcmp(s,"r5") == 0 ||
1239 strcmp(s,"r6") == 0 ||
1240 strcmp(s,"r7") == 0 )
1241 emitcode("mov","%s,%s ; %d",
1242 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1247 emitcode("movf","%s,w ; %d",s,__LINE__);
1249 emitcode("movwf","%s",
1250 aop->aopu.aop_reg[offset]->name);
1253 emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1254 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1262 if (aop->type == AOP_DPTR2)
1268 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1269 "aopPut writting to code space");
1273 while (offset > aop->coff) {
1275 emitcode ("inc","dptr");
1278 while (offset < aop->coff) {
1280 emitcode("lcall","__decdptr");
1285 /* if not in accumulater */
1288 emitcode ("movx","@dptr,a");
1290 if (aop->type == AOP_DPTR2)
1298 while (offset > aop->coff) {
1300 emitcode("inc","%s",aop->aopu.aop_ptr->name);
1302 while (offset < aop->coff) {
1304 emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1310 emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1315 emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1317 if (strcmp(s,"r0") == 0 ||
1318 strcmp(s,"r1") == 0 ||
1319 strcmp(s,"r2") == 0 ||
1320 strcmp(s,"r3") == 0 ||
1321 strcmp(s,"r4") == 0 ||
1322 strcmp(s,"r5") == 0 ||
1323 strcmp(s,"r6") == 0 ||
1324 strcmp(s,"r7") == 0 ) {
1326 sprintf(buffer,"a%s",s);
1327 emitcode("mov","@%s,%s",
1328 aop->aopu.aop_ptr->name,buffer);
1330 emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1335 if (strcmp(s,"a") == 0)
1336 emitcode("push","acc");
1338 emitcode("push","%s",s);
1343 /* if bit variable */
1344 if (!aop->aopu.aop_dir) {
1345 emitcode("clr","a");
1346 emitcode("rlc","a");
1349 emitcode("clr","%s",aop->aopu.aop_dir);
1352 emitcode("setb","%s",aop->aopu.aop_dir);
1355 emitcode("mov","%s,c",aop->aopu.aop_dir);
1357 lbl = newiTempLabel(NULL);
1359 if (strcmp(s,"a")) {
1362 emitcode("clr","c");
1363 emitcode("jz","%05d_DS_",lbl->key+100);
1364 emitcode("cpl","c");
1365 emitcode("","%05d_DS_:",lbl->key+100);
1366 emitcode("mov","%s,c",aop->aopu.aop_dir);
1373 if (strcmp(aop->aopu.aop_str[offset],s))
1374 emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1379 if (!offset && (strcmp(s,"acc") == 0))
1382 if (strcmp(aop->aopu.aop_str[offset],s))
1383 emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1387 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1388 "aopPut got unsupported aop->type");
1394 /*-----------------------------------------------------------------*/
1395 /* reAdjustPreg - points a register back to where it should */
1396 /*-----------------------------------------------------------------*/
1397 static void reAdjustPreg (asmop *aop)
1401 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1403 if ((size = aop->size) <= 1)
1406 switch (aop->type) {
1410 emitcode("dec","%s",aop->aopu.aop_ptr->name);
1414 if (aop->type == AOP_DPTR2)
1420 emitcode("lcall","__decdptr");
1423 if (aop->type == AOP_DPTR2)
1433 #define AOP(op) op->aop
1434 #define AOP_TYPE(op) AOP(op)->type
1435 #define AOP_SIZE(op) AOP(op)->size
1436 #define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
1437 AOP_TYPE(x) == AOP_R0))
1439 #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
1440 AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
1443 #define AOP_INPREG(x) (x && (x->type == AOP_REG && \
1444 (x->aopu.aop_reg[0] == pic14_regWithIdx(R0_IDX) || \
1445 x->aopu.aop_reg[0] == pic14_regWithIdx(R1_IDX) )))
1447 /*-----------------------------------------------------------------*/
1448 /* genNotFloat - generates not for float operations */
1449 /*-----------------------------------------------------------------*/
1450 static void genNotFloat (operand *op, operand *res)
1456 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1457 /* we will put 127 in the first byte of
1459 aopPut(AOP(res),"#127",0);
1460 size = AOP_SIZE(op) - 1;
1463 l = aopGet(op->aop,offset++,FALSE,FALSE);
1467 emitcode("orl","a,%s",
1469 offset++,FALSE,FALSE));
1471 tlbl = newiTempLabel(NULL);
1473 tlbl = newiTempLabel(NULL);
1474 aopPut(res->aop,one,1);
1475 emitcode("jz","%05d_DS_",(tlbl->key+100));
1476 aopPut(res->aop,zero,1);
1477 emitcode("","%05d_DS_:",(tlbl->key+100));
1479 size = res->aop->size - 2;
1481 /* put zeros in the rest */
1483 aopPut(res->aop,zero,offset++);
1487 /*-----------------------------------------------------------------*/
1488 /* opIsGptr: returns non-zero if the passed operand is */
1489 /* a generic pointer type. */
1490 /*-----------------------------------------------------------------*/
1491 static int opIsGptr(operand *op)
1493 sym_link *type = operandType(op);
1495 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1496 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1504 /*-----------------------------------------------------------------*/
1505 /* getDataSize - get the operand data size */
1506 /*-----------------------------------------------------------------*/
1507 static int getDataSize(operand *op)
1509 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1512 return AOP_SIZE(op);
1514 // tsd- in the pic port, the genptr size is 1, so this code here
1515 // fails. ( in the 8051 port, the size was 4).
1518 size = AOP_SIZE(op);
1519 if (size == GPTRSIZE)
1521 sym_link *type = operandType(op);
1522 if (IS_GENPTR(type))
1524 /* generic pointer; arithmetic operations
1525 * should ignore the high byte (pointer type).
1528 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1535 /*-----------------------------------------------------------------*/
1536 /* outAcc - output Acc */
1537 /*-----------------------------------------------------------------*/
1538 static void outAcc(operand *result)
1541 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1542 size = getDataSize(result);
1544 aopPut(AOP(result),"a",0);
1547 /* unsigned or positive */
1549 aopPut(AOP(result),zero,offset++);
1554 /*-----------------------------------------------------------------*/
1555 /* outBitC - output a bit C */
1556 /*-----------------------------------------------------------------*/
1557 static void outBitC(operand *result)
1560 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1561 /* if the result is bit */
1562 if (AOP_TYPE(result) == AOP_CRY)
1563 aopPut(AOP(result),"c",0);
1565 emitcode("clr","a ; %d", __LINE__);
1566 emitcode("rlc","a");
1571 /*-----------------------------------------------------------------*/
1572 /* toBoolean - emit code for orl a,operator(sizeop) */
1573 /*-----------------------------------------------------------------*/
1574 static void toBoolean(operand *oper)
1576 int size = AOP_SIZE(oper) - 1;
1579 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1581 if ( AOP_TYPE(oper) != AOP_ACC) {
1582 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1583 emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1586 emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1587 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1592 /*-----------------------------------------------------------------*/
1593 /* genNot - generate code for ! operation */
1594 /*-----------------------------------------------------------------*/
1595 static void genNot (iCode *ic)
1598 sym_link *optype = operandType(IC_LEFT(ic));
1600 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1601 /* assign asmOps to operand & result */
1602 aopOp (IC_LEFT(ic),ic,FALSE);
1603 aopOp (IC_RESULT(ic),ic,TRUE);
1605 /* if in bit space then a special case */
1606 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1607 emitcode("movlw","1<<%s");
1608 //emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1609 //emitcode("cpl","c");
1610 //outBitC(IC_RESULT(ic));
1614 /* if type float then do float */
1615 if (IS_FLOAT(optype)) {
1616 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1620 toBoolean(IC_LEFT(ic));
1622 tlbl = newiTempLabel(NULL);
1623 emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1624 emitcode("","%05d_DS_:",tlbl->key+100);
1625 outBitC(IC_RESULT(ic));
1628 /* release the aops */
1629 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1630 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1634 /*-----------------------------------------------------------------*/
1635 /* genCpl - generate code for complement */
1636 /*-----------------------------------------------------------------*/
1637 static void genCpl (iCode *ic)
1643 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1644 /* assign asmOps to operand & result */
1645 aopOp (IC_LEFT(ic),ic,FALSE);
1646 aopOp (IC_RESULT(ic),ic,TRUE);
1648 /* if both are in bit space then
1650 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1651 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1653 emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1654 emitcode("cpl","c");
1655 emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1659 size = AOP_SIZE(IC_RESULT(ic));
1661 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1663 emitcode("cpl","a");
1664 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1669 /* release the aops */
1670 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1671 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1674 /*-----------------------------------------------------------------*/
1675 /* genUminusFloat - unary minus for floating points */
1676 /*-----------------------------------------------------------------*/
1677 static void genUminusFloat(operand *op,operand *result)
1679 int size ,offset =0 ;
1682 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1683 /* for this we just need to flip the
1684 first it then copy the rest in place */
1685 size = AOP_SIZE(op) - 1;
1686 l = aopGet(AOP(op),3,FALSE,FALSE);
1690 emitcode("cpl","acc.7");
1691 aopPut(AOP(result),"a",3);
1695 aopGet(AOP(op),offset,FALSE,FALSE),
1701 /*-----------------------------------------------------------------*/
1702 /* genUminus - unary minus code generation */
1703 /*-----------------------------------------------------------------*/
1704 static void genUminus (iCode *ic)
1707 sym_link *optype, *rtype;
1710 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1712 aopOp(IC_LEFT(ic),ic,FALSE);
1713 aopOp(IC_RESULT(ic),ic,TRUE);
1715 /* if both in bit space then special
1717 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1718 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1720 emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1721 emitcode("cpl","c");
1722 emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1726 optype = operandType(IC_LEFT(ic));
1727 rtype = operandType(IC_RESULT(ic));
1729 /* if float then do float stuff */
1730 if (IS_FLOAT(optype)) {
1731 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1735 /* otherwise subtract from zero */
1736 size = AOP_SIZE(IC_LEFT(ic));
1740 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1741 if (!strcmp(l,"a")) {
1742 emitcode("cpl","a");
1743 emitcode("inc","a");
1745 emitcode("clr","a");
1746 emitcode("subb","a,%s",l);
1748 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1751 /* if any remaining bytes in the result */
1752 /* we just need to propagate the sign */
1753 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1754 emitcode("rlc","a");
1755 emitcode("subb","a,acc");
1757 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1761 /* release the aops */
1762 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1763 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1766 /*-----------------------------------------------------------------*/
1767 /* saveRegisters - will look for a call and save the registers */
1768 /*-----------------------------------------------------------------*/
1769 static void saveRegisters(iCode *lic)
1776 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1778 for (ic = lic ; ic ; ic = ic->next)
1779 if (ic->op == CALL || ic->op == PCALL)
1783 fprintf(stderr,"found parameter push with no function call\n");
1787 /* if the registers have been saved already then
1789 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1792 /* find the registers in use at this time
1793 and push them away to safety */
1794 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1798 if (options.useXstack) {
1799 if (bitVectBitValue(rsave,R0_IDX))
1800 emitcode("mov","b,r0");
1801 emitcode("mov","r0,%s",spname);
1802 for (i = 0 ; i < pic14_nRegs ; i++) {
1803 if (bitVectBitValue(rsave,i)) {
1805 emitcode("mov","a,b");
1807 emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1808 emitcode("movx","@r0,a");
1809 emitcode("inc","r0");
1812 emitcode("mov","%s,r0",spname);
1813 if (bitVectBitValue(rsave,R0_IDX))
1814 emitcode("mov","r0,b");
1816 for (i = 0 ; i < pic14_nRegs ; i++) {
1817 if (bitVectBitValue(rsave,i))
1818 emitcode("push","%s",pic14_regWithIdx(i)->dname);
1821 detype = getSpec(operandType(IC_LEFT(ic)));
1823 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1824 IS_ISR(currFunc->etype) &&
1827 saverbank(SPEC_BANK(detype),ic,TRUE);
1830 /*-----------------------------------------------------------------*/
1831 /* unsaveRegisters - pop the pushed registers */
1832 /*-----------------------------------------------------------------*/
1833 static void unsaveRegisters (iCode *ic)
1838 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1839 /* find the registers in use at this time
1840 and push them away to safety */
1841 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1844 if (options.useXstack) {
1845 emitcode("mov","r0,%s",spname);
1846 for (i = pic14_nRegs ; i >= 0 ; i--) {
1847 if (bitVectBitValue(rsave,i)) {
1848 emitcode("dec","r0");
1849 emitcode("movx","a,@r0");
1851 emitcode("mov","b,a");
1853 emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1857 emitcode("mov","%s,r0",spname);
1858 if (bitVectBitValue(rsave,R0_IDX))
1859 emitcode("mov","r0,b");
1861 for (i = pic14_nRegs ; i >= 0 ; i--) {
1862 if (bitVectBitValue(rsave,i))
1863 emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1869 /*-----------------------------------------------------------------*/
1871 /*-----------------------------------------------------------------*/
1872 static void pushSide(operand * oper, int size)
1875 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1877 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1878 if (AOP_TYPE(oper) != AOP_REG &&
1879 AOP_TYPE(oper) != AOP_DIR &&
1881 emitcode("mov","a,%s",l);
1882 emitcode("push","acc");
1884 emitcode("push","%s",l);
1888 /*-----------------------------------------------------------------*/
1889 /* assignResultValue - */
1890 /*-----------------------------------------------------------------*/
1891 static void assignResultValue(operand * oper)
1894 int size = AOP_SIZE(oper);
1896 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1898 // The last byte in the assignment is in W
1899 aopPut(AOP(oper),"W",size-1);
1903 aopPut(AOP(oper),fReturn[offset],offset);
1911 /*-----------------------------------------------------------------*/
1912 /* genXpush - pushes onto the external stack */
1913 /*-----------------------------------------------------------------*/
1914 static void genXpush (iCode *ic)
1916 asmop *aop = newAsmop(0);
1918 int size,offset = 0;
1920 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1921 aopOp(IC_LEFT(ic),ic,FALSE);
1922 r = getFreePtr(ic,&aop,FALSE);
1925 emitcode("mov","%s,_spx",r->name);
1927 size = AOP_SIZE(IC_LEFT(ic));
1930 char *l = aopGet(AOP(IC_LEFT(ic)),
1931 offset++,FALSE,FALSE);
1933 emitcode("movx","@%s,a",r->name);
1934 emitcode("inc","%s",r->name);
1939 emitcode("mov","_spx,%s",r->name);
1941 freeAsmop(NULL,aop,ic,TRUE);
1942 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1945 /*-----------------------------------------------------------------*/
1946 /* genIpush - genrate code for pushing this gets a little complex */
1947 /*-----------------------------------------------------------------*/
1948 static void genIpush (iCode *ic)
1950 int size, offset = 0 ;
1954 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1955 /* if this is not a parm push : ie. it is spill push
1956 and spill push is always done on the local stack */
1957 if (!ic->parmPush) {
1959 /* and the item is spilt then do nothing */
1960 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1963 aopOp(IC_LEFT(ic),ic,FALSE);
1964 size = AOP_SIZE(IC_LEFT(ic));
1965 /* push it on the stack */
1967 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1972 emitcode("push","%s",l);
1977 /* this is a paramter push: in this case we call
1978 the routine to find the call and save those
1979 registers that need to be saved */
1982 /* if use external stack then call the external
1983 stack pushing routine */
1984 if (options.useXstack) {
1989 /* then do the push */
1990 aopOp(IC_LEFT(ic),ic,FALSE);
1993 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1994 size = AOP_SIZE(IC_LEFT(ic));
1997 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1998 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1999 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2001 emitcode("mov","a,%s",l);
2002 emitcode("push","acc");
2004 emitcode("push","%s",l);
2007 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2010 /*-----------------------------------------------------------------*/
2011 /* genIpop - recover the registers: can happen only for spilling */
2012 /*-----------------------------------------------------------------*/
2013 static void genIpop (iCode *ic)
2018 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2019 /* if the temp was not pushed then */
2020 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2023 aopOp(IC_LEFT(ic),ic,FALSE);
2024 size = AOP_SIZE(IC_LEFT(ic));
2027 emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2030 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2033 /*-----------------------------------------------------------------*/
2034 /* unsaverbank - restores the resgister bank from stack */
2035 /*-----------------------------------------------------------------*/
2036 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2042 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2044 if (options.useXstack) {
2046 r = getFreePtr(ic,&aop,FALSE);
2049 emitcode("mov","%s,_spx",r->name);
2050 emitcode("movx","a,@%s",r->name);
2051 emitcode("mov","psw,a");
2052 emitcode("dec","%s",r->name);
2055 emitcode ("pop","psw");
2058 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2059 if (options.useXstack) {
2060 emitcode("movx","a,@%s",r->name);
2061 //emitcode("mov","(%s+%d),a",
2062 // regspic14[i].base,8*bank+regspic14[i].offset);
2063 emitcode("dec","%s",r->name);
2066 emitcode("pop",""); //"(%s+%d)",
2067 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2070 if (options.useXstack) {
2072 emitcode("mov","_spx,%s",r->name);
2073 freeAsmop(NULL,aop,ic,TRUE);
2078 /*-----------------------------------------------------------------*/
2079 /* saverbank - saves an entire register bank on the stack */
2080 /*-----------------------------------------------------------------*/
2081 static void saverbank (int bank, iCode *ic, bool pushPsw)
2087 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2088 if (options.useXstack) {
2091 r = getFreePtr(ic,&aop,FALSE);
2092 emitcode("mov","%s,_spx",r->name);
2096 for (i = 0 ; i < pic14_nRegs ;i++) {
2097 if (options.useXstack) {
2098 emitcode("inc","%s",r->name);
2099 //emitcode("mov","a,(%s+%d)",
2100 // regspic14[i].base,8*bank+regspic14[i].offset);
2101 emitcode("movx","@%s,a",r->name);
2103 emitcode("push","");// "(%s+%d)",
2104 //regspic14[i].base,8*bank+regspic14[i].offset);
2108 if (options.useXstack) {
2109 emitcode("mov","a,psw");
2110 emitcode("movx","@%s,a",r->name);
2111 emitcode("inc","%s",r->name);
2112 emitcode("mov","_spx,%s",r->name);
2113 freeAsmop (NULL,aop,ic,TRUE);
2116 emitcode("push","psw");
2118 emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2124 /*-----------------------------------------------------------------*/
2125 /* genCall - generates a call statement */
2126 /*-----------------------------------------------------------------*/
2127 static void genCall (iCode *ic)
2131 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2133 /* if caller saves & we have not saved then */
2137 /* if we are calling a function that is not using
2138 the same register bank then we need to save the
2139 destination registers on the stack */
2140 detype = getSpec(operandType(IC_LEFT(ic)));
2142 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2143 IS_ISR(currFunc->etype) &&
2146 saverbank(SPEC_BANK(detype),ic,TRUE);
2148 /* if send set is not empty the assign */
2152 for (sic = setFirstItem(_G.sendSet) ; sic ;
2153 sic = setNextItem(_G.sendSet)) {
2154 int size, offset = 0;
2156 aopOp(IC_LEFT(sic),sic,FALSE);
2157 size = AOP_SIZE(IC_LEFT(sic));
2159 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2161 DEBUGemitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2163 if (strcmp(l,fReturn[offset])) {
2165 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2166 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2167 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2168 //emitcode("movlw","%s",l);
2170 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2171 //emitcode("movf","%s,w",l);
2173 // The last one is passed in W
2175 emitcode("movwf","%s",fReturn[offset]);
2179 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2184 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2185 OP_SYMBOL(IC_LEFT(ic))->rname :
2186 OP_SYMBOL(IC_LEFT(ic))->name));
2188 emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2189 OP_SYMBOL(IC_LEFT(ic))->rname :
2190 OP_SYMBOL(IC_LEFT(ic))->name));
2192 /* if we need assign a result value */
2193 if ((IS_ITEMP(IC_RESULT(ic)) &&
2194 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2195 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2196 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2199 aopOp(IC_RESULT(ic),ic,FALSE);
2202 assignResultValue(IC_RESULT(ic));
2204 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2207 /* adjust the stack for parameters if
2209 if (ic->parmBytes) {
2211 if (ic->parmBytes > 3) {
2212 emitcode("mov","a,%s",spname);
2213 emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2214 emitcode("mov","%s,a",spname);
2216 for ( i = 0 ; i < ic->parmBytes ;i++)
2217 emitcode("dec","%s",spname);
2221 /* if register bank was saved then pop them */
2223 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2225 /* if we hade saved some registers then unsave them */
2226 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2227 unsaveRegisters (ic);
2232 /*-----------------------------------------------------------------*/
2233 /* genPcall - generates a call by pointer statement */
2234 /*-----------------------------------------------------------------*/
2235 static void genPcall (iCode *ic)
2238 symbol *rlbl = newiTempLabel(NULL);
2241 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2242 /* if caller saves & we have not saved then */
2246 /* if we are calling a function that is not using
2247 the same register bank then we need to save the
2248 destination registers on the stack */
2249 detype = getSpec(operandType(IC_LEFT(ic)));
2251 IS_ISR(currFunc->etype) &&
2252 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2253 saverbank(SPEC_BANK(detype),ic,TRUE);
2256 /* push the return address on to the stack */
2257 emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2258 emitcode("push","acc");
2259 emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2260 emitcode("push","acc");
2262 if (options.model == MODEL_FLAT24)
2264 emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2265 emitcode("push","acc");
2268 /* now push the calling address */
2269 aopOp(IC_LEFT(ic),ic,FALSE);
2271 pushSide(IC_LEFT(ic), FPTRSIZE);
2273 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2275 /* if send set is not empty the assign */
2279 for (sic = setFirstItem(_G.sendSet) ; sic ;
2280 sic = setNextItem(_G.sendSet)) {
2281 int size, offset = 0;
2282 aopOp(IC_LEFT(sic),sic,FALSE);
2283 size = AOP_SIZE(IC_LEFT(sic));
2285 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2287 if (strcmp(l,fReturn[offset]))
2288 emitcode("mov","%s,%s",
2293 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2299 emitcode("","%05d_DS_:",(rlbl->key+100));
2302 /* if we need assign a result value */
2303 if ((IS_ITEMP(IC_RESULT(ic)) &&
2304 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2305 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2306 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2309 aopOp(IC_RESULT(ic),ic,FALSE);
2312 assignResultValue(IC_RESULT(ic));
2314 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2317 /* adjust the stack for parameters if
2319 if (ic->parmBytes) {
2321 if (ic->parmBytes > 3) {
2322 emitcode("mov","a,%s",spname);
2323 emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2324 emitcode("mov","%s,a",spname);
2326 for ( i = 0 ; i < ic->parmBytes ;i++)
2327 emitcode("dec","%s",spname);
2331 /* if register bank was saved then unsave them */
2333 (SPEC_BANK(currFunc->etype) !=
2335 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2337 /* if we hade saved some registers then
2340 unsaveRegisters (ic);
2344 /*-----------------------------------------------------------------*/
2345 /* resultRemat - result is rematerializable */
2346 /*-----------------------------------------------------------------*/
2347 static int resultRemat (iCode *ic)
2349 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2350 if (SKIP_IC(ic) || ic->op == IFX)
2353 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2354 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2355 if (sym->remat && !POINTER_SET(ic))
2362 #if defined(__BORLANDC__) || defined(_MSC_VER)
2363 #define STRCASECMP stricmp
2365 #define STRCASECMP strcasecmp
2368 /*-----------------------------------------------------------------*/
2369 /* inExcludeList - return 1 if the string is in exclude Reg list */
2370 /*-----------------------------------------------------------------*/
2371 static bool inExcludeList(char *s)
2375 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2376 if (options.excludeRegs[i] &&
2377 STRCASECMP(options.excludeRegs[i],"none") == 0)
2380 for ( i = 0 ; options.excludeRegs[i]; i++) {
2381 if (options.excludeRegs[i] &&
2382 STRCASECMP(s,options.excludeRegs[i]) == 0)
2388 /*-----------------------------------------------------------------*/
2389 /* genFunction - generated code for function entry */
2390 /*-----------------------------------------------------------------*/
2391 static void genFunction (iCode *ic)
2396 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2397 labelOffset += FUNCTION_LABEL_INC;
2400 /* create the function header */
2401 emitcode(";","-----------------------------------------");
2402 emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2403 emitcode(";","-----------------------------------------");
2405 emitcode("","%s:",sym->rname);
2406 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2408 fetype = getSpec(operandType(IC_LEFT(ic)));
2410 /* if critical function then turn interrupts off */
2411 if (SPEC_CRTCL(fetype))
2412 emitcode("clr","ea");
2414 /* here we need to generate the equates for the
2415 register bank if required */
2417 if (SPEC_BANK(fetype) != rbank) {
2420 rbank = SPEC_BANK(fetype);
2421 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2422 if (strcmp(regspic14[i].base,"0") == 0)
2423 emitcode("","%s = 0x%02x",
2425 8*rbank+regspic14[i].offset);
2427 emitcode ("","%s = %s + 0x%02x",
2430 8*rbank+regspic14[i].offset);
2435 /* if this is an interrupt service routine then
2436 save acc, b, dpl, dph */
2437 if (IS_ISR(sym->etype)) {
2439 if (!inExcludeList("acc"))
2440 emitcode ("push","acc");
2441 if (!inExcludeList("b"))
2442 emitcode ("push","b");
2443 if (!inExcludeList("dpl"))
2444 emitcode ("push","dpl");
2445 if (!inExcludeList("dph"))
2446 emitcode ("push","dph");
2447 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2449 emitcode ("push", "dpx");
2450 /* Make sure we're using standard DPTR */
2451 emitcode ("push", "dps");
2452 emitcode ("mov", "dps, #0x00");
2453 if (options.stack10bit)
2455 /* This ISR could conceivably use DPTR2. Better save it. */
2456 emitcode ("push", "dpl1");
2457 emitcode ("push", "dph1");
2458 emitcode ("push", "dpx1");
2461 /* if this isr has no bank i.e. is going to
2462 run with bank 0 , then we need to save more
2464 if (!SPEC_BANK(sym->etype)) {
2466 /* if this function does not call any other
2467 function then we can be economical and
2468 save only those registers that are used */
2469 if (! sym->hasFcall) {
2472 /* if any registers used */
2473 if (sym->regsUsed) {
2474 /* save the registers used */
2475 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2476 if (bitVectBitValue(sym->regsUsed,i) ||
2477 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2478 emitcode("push","%s",pic14_regWithIdx(i)->dname);
2483 /* this function has a function call cannot
2484 determines register usage so we will have the
2486 saverbank(0,ic,FALSE);
2490 /* if callee-save to be used for this function
2491 then save the registers being used in this function */
2492 if (sym->calleeSave) {
2495 /* if any registers used */
2496 if (sym->regsUsed) {
2497 /* save the registers used */
2498 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2499 if (bitVectBitValue(sym->regsUsed,i) ||
2500 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2501 emitcode("push","%s",pic14_regWithIdx(i)->dname);
2509 /* set the register bank to the desired value */
2510 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2511 emitcode("push","psw");
2512 emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2515 if (IS_RENT(sym->etype) || options.stackAuto) {
2517 if (options.useXstack) {
2518 emitcode("mov","r0,%s",spname);
2519 emitcode("mov","a,_bp");
2520 emitcode("movx","@r0,a");
2521 emitcode("inc","%s",spname);
2525 /* set up the stack */
2526 emitcode ("push","_bp"); /* save the callers stack */
2528 emitcode ("mov","_bp,%s",spname);
2531 /* adjust the stack for the function */
2536 werror(W_STACK_OVERFLOW,sym->name);
2538 if (i > 3 && sym->recvSize < 4) {
2540 emitcode ("mov","a,sp");
2541 emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2542 emitcode ("mov","sp,a");
2547 emitcode("inc","sp");
2552 emitcode ("mov","a,_spx");
2553 emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2554 emitcode ("mov","_spx,a");
2559 /*-----------------------------------------------------------------*/
2560 /* genEndFunction - generates epilogue for functions */
2561 /*-----------------------------------------------------------------*/
2562 static void genEndFunction (iCode *ic)
2564 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2566 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2568 if (IS_RENT(sym->etype) || options.stackAuto)
2570 emitcode ("mov","%s,_bp",spname);
2573 /* if use external stack but some variables were
2574 added to the local stack then decrement the
2576 if (options.useXstack && sym->stack) {
2577 emitcode("mov","a,sp");
2578 emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2579 emitcode("mov","sp,a");
2583 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2584 if (options.useXstack) {
2585 emitcode("mov","r0,%s",spname);
2586 emitcode("movx","a,@r0");
2587 emitcode("mov","_bp,a");
2588 emitcode("dec","%s",spname);
2592 emitcode ("pop","_bp");
2596 /* restore the register bank */
2597 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2598 emitcode ("pop","psw");
2600 if (IS_ISR(sym->etype)) {
2602 /* now we need to restore the registers */
2603 /* if this isr has no bank i.e. is going to
2604 run with bank 0 , then we need to save more
2606 if (!SPEC_BANK(sym->etype)) {
2608 /* if this function does not call any other
2609 function then we can be economical and
2610 save only those registers that are used */
2611 if (! sym->hasFcall) {
2614 /* if any registers used */
2615 if (sym->regsUsed) {
2616 /* save the registers used */
2617 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2618 if (bitVectBitValue(sym->regsUsed,i) ||
2619 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2620 emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2625 /* this function has a function call cannot
2626 determines register usage so we will have the
2628 unsaverbank(0,ic,FALSE);
2632 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2634 if (options.stack10bit)
2636 emitcode ("pop", "dpx1");
2637 emitcode ("pop", "dph1");
2638 emitcode ("pop", "dpl1");
2640 emitcode ("pop", "dps");
2641 emitcode ("pop", "dpx");
2643 if (!inExcludeList("dph"))
2644 emitcode ("pop","dph");
2645 if (!inExcludeList("dpl"))
2646 emitcode ("pop","dpl");
2647 if (!inExcludeList("b"))
2648 emitcode ("pop","b");
2649 if (!inExcludeList("acc"))
2650 emitcode ("pop","acc");
2652 if (SPEC_CRTCL(sym->etype))
2653 emitcode("setb","ea");
2655 /* if debug then send end of function */
2656 /* if (options.debug && currFunc) { */
2659 emitcode(";","C$%s$%d$%d$%d ==.",
2660 FileBaseName(ic->filename),currFunc->lastLine,
2661 ic->level,ic->block);
2662 if (IS_STATIC(currFunc->etype))
2663 emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2665 emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2669 emitcode ("reti","");
2672 if (SPEC_CRTCL(sym->etype))
2673 emitcode("setb","ea");
2675 if (sym->calleeSave) {
2678 /* if any registers used */
2679 if (sym->regsUsed) {
2680 /* save the registers used */
2681 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2682 if (bitVectBitValue(sym->regsUsed,i) ||
2683 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2684 emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2690 /* if debug then send end of function */
2693 emitcode(";","C$%s$%d$%d$%d ==.",
2694 FileBaseName(ic->filename),currFunc->lastLine,
2695 ic->level,ic->block);
2696 if (IS_STATIC(currFunc->etype))
2697 emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2699 emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2703 emitcode ("return","");
2704 emitpcode(POC_RETURN,NULL);
2706 /* Mark the end of a function */
2707 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2712 /*-----------------------------------------------------------------*/
2713 /* genRet - generate code for return statement */
2714 /*-----------------------------------------------------------------*/
2715 static void genRet (iCode *ic)
2717 int size,offset = 0 , pushed = 0;
2719 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2720 /* if we have no return value then
2721 just generate the "ret" */
2725 /* we have something to return then
2726 move the return value into place */
2727 aopOp(IC_LEFT(ic),ic,FALSE);
2728 size = AOP_SIZE(IC_LEFT(ic));
2732 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2734 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2736 emitcode("push","%s",l);
2739 l = aopGet(AOP(IC_LEFT(ic)),offset,
2741 if (strcmp(fReturn[offset],l)) {
2742 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2743 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2744 emitcode("movlw","%s",l);
2746 emitcode("movf","%s,w",l);
2748 emitcode("movwf","%s",fReturn[offset]);
2757 if (strcmp(fReturn[pushed],"a"))
2758 emitcode("pop",fReturn[pushed]);
2760 emitcode("pop","acc");
2763 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2766 /* generate a jump to the return label
2767 if the next is not the return statement */
2768 if (!(ic->next && ic->next->op == LABEL &&
2769 IC_LABEL(ic->next) == returnLabel))
2771 emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2775 /*-----------------------------------------------------------------*/
2776 /* genLabel - generates a label */
2777 /*-----------------------------------------------------------------*/
2778 static void genLabel (iCode *ic)
2780 /* special case never generate */
2781 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2782 if (IC_LABEL(ic) == entryLabel)
2785 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2786 emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2789 /*-----------------------------------------------------------------*/
2790 /* genGoto - generates a goto */
2791 /*-----------------------------------------------------------------*/
2793 static void genGoto (iCode *ic)
2795 emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2798 /*-----------------------------------------------------------------*/
2799 /* findLabelBackwards: walks back through the iCode chain looking */
2800 /* for the given label. Returns number of iCode instructions */
2801 /* between that label and given ic. */
2802 /* Returns zero if label not found. */
2803 /*-----------------------------------------------------------------*/
2805 static int findLabelBackwards(iCode *ic, int key)
2809 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2815 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2817 /* printf("findLabelBackwards = %d\n", count); */
2825 /*-----------------------------------------------------------------*/
2826 /* genPlusIncr :- does addition with increment if possible */
2827 /*-----------------------------------------------------------------*/
2828 static bool genPlusIncr (iCode *ic)
2830 unsigned int icount ;
2831 unsigned int size = getDataSize(IC_RESULT(ic));
2833 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2834 DEBUGemitcode ("; ","result %d, left %d, right %d",
2835 AOP_TYPE(IC_RESULT(ic)),
2836 AOP_TYPE(IC_LEFT(ic)),
2837 AOP_TYPE(IC_RIGHT(ic)));
2839 /* will try to generate an increment */
2840 /* if the right side is not a literal
2842 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
2845 DEBUGemitcode ("; ","%s %d",__FUNCTION__,__LINE__);
2846 /* if the literal value of the right hand side
2847 is greater than 1 then it is faster to add */
2848 if ((icount = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
2851 /* if increment 16 bits in register */
2852 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
2857 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
2858 //emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
2862 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
2863 //emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
2869 DEBUGemitcode ("; ","%s %d",__FUNCTION__,__LINE__);
2870 /* if left is in accumulator - probably a bit operation*/
2871 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
2872 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
2874 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2875 emitcode("bcf","(%s >> 3), (%s & 7)",
2876 AOP(IC_RESULT(ic))->aopu.aop_dir,
2877 AOP(IC_RESULT(ic))->aopu.aop_dir);
2879 emitpcode(POC_XORLW,popGetLit(1));
2880 //emitcode("xorlw","1");
2882 emitpcode(POC_ANDLW,popGetLit(1));
2883 //emitcode("andlw","1");
2886 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2887 emitcode("bsf","(%s >> 3), (%s & 7)",
2888 AOP(IC_RESULT(ic))->aopu.aop_dir,
2889 AOP(IC_RESULT(ic))->aopu.aop_dir);
2896 /* if the sizes are greater than 1 then we cannot */
2897 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
2898 AOP_SIZE(IC_LEFT(ic)) > 1 )
2901 /* If we are incrementing the same register by two: */
2903 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2906 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2907 //emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2912 DEBUGemitcode ("; ","couldn't increment result-%s left-%s",
2913 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
2914 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
2918 /*-----------------------------------------------------------------*/
2919 /* outBitAcc - output a bit in acc */
2920 /*-----------------------------------------------------------------*/
2921 static void outBitAcc(operand *result)
2923 symbol *tlbl = newiTempLabel(NULL);
2924 /* if the result is a bit */
2925 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2927 if (AOP_TYPE(result) == AOP_CRY){
2928 aopPut(AOP(result),"a",0);
2931 emitcode("jz","%05d_DS_",tlbl->key+100);
2932 emitcode("mov","a,%s",one);
2933 emitcode("","%05d_DS_:",tlbl->key+100);
2938 /*-----------------------------------------------------------------*/
2939 /* genPlusBits - generates code for addition of two bits */
2940 /*-----------------------------------------------------------------*/
2941 static void genPlusBits (iCode *ic)
2944 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2946 The following block of code will add two bits.
2947 Note that it'll even work if the destination is
2948 the carry (C in the status register).
2949 It won't work if the 'Z' bit is a source or destination.
2952 /* If the result is stored in the accumulator (w) */
2953 if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
2954 //emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
2955 // popGet(AOP(result),0,FALSE,FALSE));
2957 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2958 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2959 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
2960 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2961 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
2962 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
2964 emitcode("movlw","(1 << (%s & 7))",
2965 AOP(IC_RESULT(ic))->aopu.aop_dir,
2966 AOP(IC_RESULT(ic))->aopu.aop_dir);
2967 emitcode("bcf","(%s >> 3), (%s & 7)",
2968 AOP(IC_RESULT(ic))->aopu.aop_dir,
2969 AOP(IC_RESULT(ic))->aopu.aop_dir);
2970 emitcode("btfsc","(%s >> 3), (%s & 7)",
2971 AOP(IC_RIGHT(ic))->aopu.aop_dir,
2972 AOP(IC_RIGHT(ic))->aopu.aop_dir);
2973 emitcode("xorwf","(%s >>3),f",
2974 AOP(IC_RESULT(ic))->aopu.aop_dir);
2975 emitcode("btfsc","(%s >> 3), (%s & 7)",
2976 AOP(IC_LEFT(ic))->aopu.aop_dir,
2977 AOP(IC_LEFT(ic))->aopu.aop_dir);
2978 emitcode("xorwf","(%s>>3),f",
2979 AOP(IC_RESULT(ic))->aopu.aop_dir);
2982 emitpcode(POC_CLRW, NULL);
2983 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
2984 emitpcode(POC_XORLW, popGetLit(1));
2985 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
2986 emitpcode(POC_XORLW, popGetLit(1));
2988 emitcode("clrw","");
2989 emitcode("btfsc","(%s >> 3), (%s & 7)",
2990 AOP(IC_RIGHT(ic))->aopu.aop_dir,
2991 AOP(IC_RIGHT(ic))->aopu.aop_dir);
2992 emitcode("xorlw","1");
2993 emitcode("btfsc","(%s >> 3), (%s & 7)",
2994 AOP(IC_LEFT(ic))->aopu.aop_dir,
2995 AOP(IC_LEFT(ic))->aopu.aop_dir);
2996 emitcode("xorlw","1");
3002 /* This is the original version of this code.
3004 * This is being kept around for reference,
3005 * because I am not entirely sure I got it right...
3007 static void adjustArithmeticResult(iCode *ic)
3009 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
3010 AOP_SIZE(IC_LEFT(ic)) == 3 &&
3011 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
3012 aopPut(AOP(IC_RESULT(ic)),
3013 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
3016 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
3017 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
3018 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
3019 aopPut(AOP(IC_RESULT(ic)),
3020 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
3023 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
3024 AOP_SIZE(IC_LEFT(ic)) < 3 &&
3025 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
3026 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
3027 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
3029 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
3030 aopPut(AOP(IC_RESULT(ic)),buffer,2);
3034 /* This is the pure and virtuous version of this code.
3035 * I'm pretty certain it's right, but not enough to toss the old
3038 static void adjustArithmeticResult(iCode *ic)
3040 if (opIsGptr(IC_RESULT(ic)) &&
3041 opIsGptr(IC_LEFT(ic)) &&
3042 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
3044 aopPut(AOP(IC_RESULT(ic)),
3045 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
3049 if (opIsGptr(IC_RESULT(ic)) &&
3050 opIsGptr(IC_RIGHT(ic)) &&
3051 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
3053 aopPut(AOP(IC_RESULT(ic)),
3054 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
3058 if (opIsGptr(IC_RESULT(ic)) &&
3059 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
3060 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
3061 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
3062 !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
3064 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
3065 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
3070 /*-----------------------------------------------------------------*/
3071 /* genPlus - generates code for addition */
3072 /*-----------------------------------------------------------------*/
3073 static void genPlus (iCode *ic)
3075 int size, offset = 0;
3077 /* special cases :- */
3078 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3080 aopOp (IC_LEFT(ic),ic,FALSE);
3081 aopOp (IC_RIGHT(ic),ic,FALSE);
3082 aopOp (IC_RESULT(ic),ic,TRUE);
3084 /* if literal, literal on the right or
3085 if left requires ACC or right is already
3088 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
3089 operand *t = IC_RIGHT(ic);
3090 IC_RIGHT(ic) = IC_LEFT(ic);
3094 /* if both left & right are in bit space */
3095 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
3096 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
3101 /* if left in bit space & right literal */
3102 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
3103 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
3104 /* if result in bit space */
3105 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
3106 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
3107 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3108 if (!sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
3109 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3110 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3113 size = getDataSize(IC_RESULT(ic));
3115 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3116 emitcode("addc","a,#00 ;%d",__LINE__);
3117 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
3123 /* if I can do an increment instead
3124 of add then GOOD for ME */
3125 if (genPlusIncr (ic) == TRUE)
3128 size = getDataSize(IC_RESULT(ic));
3130 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
3131 /* Add a literal to something else */
3133 unsigned lit = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3137 DEBUGemitcode(";","adding lit to something. size %d",size);
3140 DEBUGemitcode(";","size %d",size);
3142 switch (lit & 0xff) {
3146 if(sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
3147 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3150 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3151 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
3152 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3156 if(sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
3157 emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3160 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3161 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
3162 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3166 if( !know_W || ( (lit&0xff) != l1) ) {
3168 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
3170 if(sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
3171 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3174 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3175 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3178 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE));
3188 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
3190 emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3191 emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3192 emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3194 /* here we are adding a bit to a char or int */
3196 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
3198 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3199 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3201 emitcode("btfsc","(%s >> 3), (%s & 7)",
3202 AOP(IC_RIGHT(ic))->aopu.aop_dir,
3203 AOP(IC_RIGHT(ic))->aopu.aop_dir);
3204 emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3207 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
3208 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3209 emitpcode(POC_XORLW , popGetLit(1));
3211 emitcode("btfsc","(%s >> 3), (%s & 7)",
3212 AOP(IC_RIGHT(ic))->aopu.aop_dir,
3213 AOP(IC_RIGHT(ic))->aopu.aop_dir);
3214 emitcode(" xorlw","1");
3216 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3217 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3218 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3220 emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3221 emitcode("btfsc","(%s >> 3), (%s & 7)",
3222 AOP(IC_RIGHT(ic))->aopu.aop_dir,
3223 AOP(IC_RIGHT(ic))->aopu.aop_dir);
3224 emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3227 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
3229 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
3230 emitpcode(POC_ANDLW , popGetLit(1));
3231 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3233 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3235 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3236 emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3244 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
3246 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3247 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3249 emitcode("clrz","");
3251 emitcode("btfsc","(%s >> 3), (%s & 7)",
3252 AOP(IC_RIGHT(ic))->aopu.aop_dir,
3253 AOP(IC_RIGHT(ic))->aopu.aop_dir);
3254 emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3258 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3259 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3260 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3261 emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3264 emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3265 emitcode("btfsc","(%s >> 3), (%s & 7)",
3266 AOP(IC_RIGHT(ic))->aopu.aop_dir,
3267 AOP(IC_RIGHT(ic))->aopu.aop_dir);
3268 emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3269 emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3275 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
3276 //emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
3283 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
3284 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3285 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3288 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
3289 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3290 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
3291 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3294 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3296 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
3297 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3299 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
3300 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
3301 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3303 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3304 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
3305 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3315 if (!sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
3316 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3317 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3319 emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3320 emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3323 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3325 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3326 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3329 emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3331 emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3332 emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3340 //adjustArithmeticResult(ic);
3343 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3344 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3345 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3348 /*-----------------------------------------------------------------*/
3349 /* genMinusDec :- does subtraction with decrement if possible */
3350 /*-----------------------------------------------------------------*/
3351 static bool genMinusDec (iCode *ic)
3353 unsigned int icount ;
3354 unsigned int size = getDataSize(IC_RESULT(ic));
3356 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3357 /* will try to generate an increment */
3358 /* if the right side is not a literal
3360 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
3361 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
3362 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
3365 DEBUGemitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
3367 /* if the literal value of the right hand side
3368 is greater than 4 then it is not worth it */
3369 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
3372 /* if decrement 16 bits in register */
3373 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
3378 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
3379 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
3380 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
3382 emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
3383 emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
3384 emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
3386 /* size is 3 or 4 */
3387 emitpcode(POC_MOVLW, popGetLit(0xff));
3388 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
3390 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
3392 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
3394 emitcode("movlw","0xff");
3395 emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
3398 emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
3400 emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
3404 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
3406 emitcode("skpnc","");
3408 emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
3417 /* if the sizes are greater than 1 then we cannot */
3418 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
3419 AOP_SIZE(IC_LEFT(ic)) > 1 )
3422 /* we can if the aops of the left & result match or
3423 if they are in registers and the registers are the
3425 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
3428 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3430 //emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3435 DEBUGemitcode ("; returning"," result=%s, left=%s",
3436 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
3437 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3440 emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3441 emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3443 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3444 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3452 /*-----------------------------------------------------------------*/
3453 /* addSign - complete with sign */
3454 /*-----------------------------------------------------------------*/
3455 static void addSign(operand *result, int offset, int sign)
3457 int size = (getDataSize(result) - offset);
3458 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3461 emitcode("rlc","a");
3462 emitcode("subb","a,acc");
3464 aopPut(AOP(result),"a",offset++);
3467 aopPut(AOP(result),zero,offset++);
3471 /*-----------------------------------------------------------------*/
3472 /* genMinusBits - generates code for subtraction of two bits */
3473 /*-----------------------------------------------------------------*/
3474 static void genMinusBits (iCode *ic)
3476 symbol *lbl = newiTempLabel(NULL);
3477 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3478 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
3479 emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
3480 emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
3481 emitcode("cpl","c");
3482 emitcode("","%05d_DS_:",(lbl->key+100));
3483 outBitC(IC_RESULT(ic));
3486 emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
3487 emitcode("subb","a,acc");
3488 emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
3489 emitcode("inc","a");
3490 emitcode("","%05d_DS_:",(lbl->key+100));
3491 aopPut(AOP(IC_RESULT(ic)),"a",0);
3492 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
3496 /*-----------------------------------------------------------------*/
3497 /* genMinus - generates code for subtraction */
3498 /*-----------------------------------------------------------------*/
3499 static void genMinus (iCode *ic)
3501 int size, offset = 0;
3502 unsigned long lit = 0L;
3504 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3505 aopOp (IC_LEFT(ic),ic,FALSE);
3506 aopOp (IC_RIGHT(ic),ic,FALSE);
3507 aopOp (IC_RESULT(ic),ic,TRUE);
3509 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
3510 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
3511 operand *t = IC_RIGHT(ic);
3512 IC_RIGHT(ic) = IC_LEFT(ic);
3516 /* special cases :- */
3517 /* if both left & right are in bit space */
3518 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
3519 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
3524 /* if I can do an decrement instead
3525 of subtract then GOOD for ME */
3526 if (genMinusDec (ic) == TRUE)
3529 size = getDataSize(IC_RESULT(ic));
3531 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
3532 /* Add a literal to something else */
3534 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3537 /* add the first byte: */
3538 emitcode("movlw","0x%x", lit & 0xff);
3539 emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3540 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
3541 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3553 if((lit & 0xff) == 0xff) {
3554 emitpcode(POC_MOVLW, popGetLit(0xff));
3556 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3558 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
3560 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3561 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3565 /* do the rlf known zero trick here */
3566 emitpcode(POC_MOVLW, popGetLit(1));
3568 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
3573 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
3576 emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3577 emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3578 emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3580 /* here we are subtracting a bit from a char or int */
3582 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
3584 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3585 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3587 emitcode("btfsc","(%s >> 3), (%s & 7)",
3588 AOP(IC_RIGHT(ic))->aopu.aop_dir,
3589 AOP(IC_RIGHT(ic))->aopu.aop_dir);
3590 emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3593 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
3594 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3595 emitpcode(POC_XORLW , popGetLit(1));
3596 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
3597 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
3599 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
3601 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
3602 if (sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
3604 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3605 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3608 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3610 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3612 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3613 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3617 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
3618 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3619 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
3620 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3625 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3626 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3627 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3630 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
3632 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3635 emitpcode(POC_ANDLW , popGetLit(1));
3637 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3639 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3648 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
3649 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3650 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3651 emitpcode(POC_SUBLW, popGetLit(0));
3652 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3655 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
3656 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3657 emitpcode(POC_SUBLW, popGetLit(0));
3658 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
3659 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3662 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3663 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
3664 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3666 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
3667 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3669 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
3670 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
3671 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3673 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3675 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
3676 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
3677 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3679 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3681 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3688 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
3690 if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
3691 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3693 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3694 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3701 if (!sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
3702 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
3703 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
3705 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3707 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
3708 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
3716 // adjustArithmeticResult(ic);
3719 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3720 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3721 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3725 /*-----------------------------------------------------------------*/
3726 /* genMultbits :- multiplication of bits */
3727 /*-----------------------------------------------------------------*/
3728 static void genMultbits (operand *left,
3732 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3734 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3735 emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
3740 /*-----------------------------------------------------------------*/
3741 /* genMultOneByte : 8 bit multiplication & division */
3742 /*-----------------------------------------------------------------*/
3743 static void genMultOneByte (operand *left,
3747 sym_link *opetype = operandType(result);
3752 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3753 /* (if two literals, the value is computed before) */
3754 /* if one literal, literal on the right */
3755 if (AOP_TYPE(left) == AOP_LIT){
3761 size = AOP_SIZE(result);
3762 /* signed or unsigned */
3763 emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3764 l = aopGet(AOP(left),0,FALSE,FALSE);
3766 emitcode("mul","ab");
3767 /* if result size = 1, mul signed = mul unsigned */
3768 aopPut(AOP(result),"a",0);
3770 if (SPEC_USIGN(opetype)){
3771 aopPut(AOP(result),"b",1);
3773 /* for filling the MSBs */
3774 emitcode("clr","a");
3777 emitcode("mov","a,b");
3779 /* adjust the MSB if left or right neg */
3781 /* if one literal */
3782 if (AOP_TYPE(right) == AOP_LIT){
3783 /* AND literal negative */
3784 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3785 /* adjust MSB (c==0 after mul) */
3786 emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3790 lbl = newiTempLabel(NULL);
3791 emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3792 emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
3793 emitcode("","%05d_DS_:",(lbl->key+100));
3794 emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3795 lbl = newiTempLabel(NULL);
3796 emitcode("jc","%05d_DS_",(lbl->key+100));
3797 emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3798 emitcode("","%05d_DS_:",(lbl->key+100));
3801 lbl = newiTempLabel(NULL);
3802 emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
3803 emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
3804 emitcode("","%05d_DS_:",(lbl->key+100));
3805 emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
3806 lbl = newiTempLabel(NULL);
3807 emitcode("jc","%05d_DS_",(lbl->key+100));
3808 emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
3809 emitcode("","%05d_DS_:",(lbl->key+100));
3811 aopPut(AOP(result),"a",1);
3814 emitcode("rlc","a");
3815 emitcode("subb","a,acc");
3822 aopPut(AOP(result),"a",offset++);
3826 /*-----------------------------------------------------------------*/
3827 /* genMult - generates code for multiplication */
3828 /*-----------------------------------------------------------------*/
3829 static void genMult (iCode *ic)
3831 operand *left = IC_LEFT(ic);
3832 operand *right = IC_RIGHT(ic);
3833 operand *result= IC_RESULT(ic);
3835 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3836 /* assign the amsops */
3837 aopOp (left,ic,FALSE);
3838 aopOp (right,ic,FALSE);
3839 aopOp (result,ic,TRUE);
3841 /* special cases first */
3843 if (AOP_TYPE(left) == AOP_CRY &&
3844 AOP_TYPE(right)== AOP_CRY) {
3845 genMultbits(left,right,result);
3849 /* if both are of size == 1 */
3850 if (AOP_SIZE(left) == 1 &&
3851 AOP_SIZE(right) == 1 ) {
3852 genMultOneByte(left,right,result);
3856 /* should have been converted to function call */
3860 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3861 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3862 freeAsmop(result,NULL,ic,TRUE);
3865 /*-----------------------------------------------------------------*/
3866 /* genDivbits :- division of bits */
3867 /*-----------------------------------------------------------------*/
3868 static void genDivbits (operand *left,
3875 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3876 /* the result must be bit */
3877 emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3878 l = aopGet(AOP(left),0,FALSE,FALSE);
3882 emitcode("div","ab");
3883 emitcode("rrc","a");
3884 aopPut(AOP(result),"c",0);
3887 /*-----------------------------------------------------------------*/
3888 /* genDivOneByte : 8 bit division */
3889 /*-----------------------------------------------------------------*/
3890 static void genDivOneByte (operand *left,
3894 sym_link *opetype = operandType(result);
3899 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3900 size = AOP_SIZE(result) - 1;
3902 /* signed or unsigned */
3903 if (SPEC_USIGN(opetype)) {
3904 /* unsigned is easy */
3905 emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3906 l = aopGet(AOP(left),0,FALSE,FALSE);
3908 emitcode("div","ab");
3909 aopPut(AOP(result),"a",0);
3911 aopPut(AOP(result),zero,offset++);
3915 /* signed is a little bit more difficult */
3917 /* save the signs of the operands */
3918 l = aopGet(AOP(left),0,FALSE,FALSE);
3920 emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3921 emitcode("push","acc"); /* save it on the stack */
3923 /* now sign adjust for both left & right */
3924 l = aopGet(AOP(right),0,FALSE,FALSE);
3926 lbl = newiTempLabel(NULL);
3927 emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3928 emitcode("cpl","a");
3929 emitcode("inc","a");
3930 emitcode("","%05d_DS_:",(lbl->key+100));
3931 emitcode("mov","b,a");
3933 /* sign adjust left side */
3934 l = aopGet(AOP(left),0,FALSE,FALSE);
3937 lbl = newiTempLabel(NULL);
3938 emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3939 emitcode("cpl","a");
3940 emitcode("inc","a");
3941 emitcode("","%05d_DS_:",(lbl->key+100));
3943 /* now the division */
3944 emitcode("div","ab");
3945 /* we are interested in the lower order
3947 emitcode("mov","b,a");
3948 lbl = newiTempLabel(NULL);
3949 emitcode("pop","acc");
3950 /* if there was an over flow we don't
3951 adjust the sign of the result */
3952 emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3953 emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3955 emitcode("clr","a");
3956 emitcode("subb","a,b");
3957 emitcode("mov","b,a");
3958 emitcode("","%05d_DS_:",(lbl->key+100));
3960 /* now we are done */
3961 aopPut(AOP(result),"b",0);
3963 emitcode("mov","c,b.7");
3964 emitcode("subb","a,acc");
3967 aopPut(AOP(result),"a",offset++);
3971 /*-----------------------------------------------------------------*/
3972 /* genDiv - generates code for division */
3973 /*-----------------------------------------------------------------*/
3974 static void genDiv (iCode *ic)
3976 operand *left = IC_LEFT(ic);
3977 operand *right = IC_RIGHT(ic);
3978 operand *result= IC_RESULT(ic);
3980 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3981 /* assign the amsops */
3982 aopOp (left,ic,FALSE);
3983 aopOp (right,ic,FALSE);
3984 aopOp (result,ic,TRUE);
3986 /* special cases first */
3988 if (AOP_TYPE(left) == AOP_CRY &&
3989 AOP_TYPE(right)== AOP_CRY) {
3990 genDivbits(left,right,result);
3994 /* if both are of size == 1 */
3995 if (AOP_SIZE(left) == 1 &&
3996 AOP_SIZE(right) == 1 ) {
3997 genDivOneByte(left,right,result);
4001 /* should have been converted to function call */
4004 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4005 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4006 freeAsmop(result,NULL,ic,TRUE);
4009 /*-----------------------------------------------------------------*/
4010 /* genModbits :- modulus of bits */
4011 /*-----------------------------------------------------------------*/
4012 static void genModbits (operand *left,
4019 /* the result must be bit */
4020 emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
4021 l = aopGet(AOP(left),0,FALSE,FALSE);
4025 emitcode("div","ab");
4026 emitcode("mov","a,b");
4027 emitcode("rrc","a");
4028 aopPut(AOP(result),"c",0);
4031 /*-----------------------------------------------------------------*/
4032 /* genModOneByte : 8 bit modulus */
4033 /*-----------------------------------------------------------------*/
4034 static void genModOneByte (operand *left,
4038 sym_link *opetype = operandType(result);
4042 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4043 /* signed or unsigned */
4044 if (SPEC_USIGN(opetype)) {
4045 /* unsigned is easy */
4046 emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
4047 l = aopGet(AOP(left),0,FALSE,FALSE);
4049 emitcode("div","ab");
4050 aopPut(AOP(result),"b",0);
4054 /* signed is a little bit more difficult */
4056 /* save the signs of the operands */
4057 l = aopGet(AOP(left),0,FALSE,FALSE);
4060 emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
4061 emitcode("push","acc"); /* save it on the stack */
4063 /* now sign adjust for both left & right */
4064 l = aopGet(AOP(right),0,FALSE,FALSE);
4067 lbl = newiTempLabel(NULL);
4068 emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4069 emitcode("cpl","a");
4070 emitcode("inc","a");
4071 emitcode("","%05d_DS_:",(lbl->key+100));
4072 emitcode("mov","b,a");
4074 /* sign adjust left side */
4075 l = aopGet(AOP(left),0,FALSE,FALSE);
4078 lbl = newiTempLabel(NULL);
4079 emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4080 emitcode("cpl","a");
4081 emitcode("inc","a");
4082 emitcode("","%05d_DS_:",(lbl->key+100));
4084 /* now the multiplication */
4085 emitcode("div","ab");
4086 /* we are interested in the lower order
4088 lbl = newiTempLabel(NULL);
4089 emitcode("pop","acc");
4090 /* if there was an over flow we don't
4091 adjust the sign of the result */
4092 emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4093 emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4095 emitcode("clr","a");
4096 emitcode("subb","a,b");
4097 emitcode("mov","b,a");
4098 emitcode("","%05d_DS_:",(lbl->key+100));
4100 /* now we are done */
4101 aopPut(AOP(result),"b",0);
4105 /*-----------------------------------------------------------------*/
4106 /* genMod - generates code for division */
4107 /*-----------------------------------------------------------------*/
4108 static void genMod (iCode *ic)
4110 operand *left = IC_LEFT(ic);
4111 operand *right = IC_RIGHT(ic);
4112 operand *result= IC_RESULT(ic);
4114 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4115 /* assign the amsops */
4116 aopOp (left,ic,FALSE);
4117 aopOp (right,ic,FALSE);
4118 aopOp (result,ic,TRUE);
4120 /* special cases first */
4122 if (AOP_TYPE(left) == AOP_CRY &&
4123 AOP_TYPE(right)== AOP_CRY) {
4124 genModbits(left,right,result);
4128 /* if both are of size == 1 */
4129 if (AOP_SIZE(left) == 1 &&
4130 AOP_SIZE(right) == 1 ) {
4131 genModOneByte(left,right,result);
4135 /* should have been converted to function call */
4139 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4140 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4141 freeAsmop(result,NULL,ic,TRUE);
4144 /*-----------------------------------------------------------------*/
4145 /* genIfxJump :- will create a jump depending on the ifx */
4146 /*-----------------------------------------------------------------*/
4147 static void genIfxJump (iCode *ic, char *jval)
4150 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4151 /* if true label then we jump if condition
4153 if ( IC_TRUE(ic) ) {
4155 if(strcmp(jval,"a") == 0)
4157 else if (strcmp(jval,"c") == 0)
4160 //pCodeOp *p = popGetWithString(jval);
4162 //emitpcode(POC_BTFSC, p);
4163 emitpcode(POC_BTFSC, newpCodeOpBit(jval,0));
4164 //emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval);
4167 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4168 emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
4172 /* false label is present */
4173 if(strcmp(jval,"a") == 0)
4175 else if (strcmp(jval,"c") == 0)
4178 //pCodeOp *p = popGetWithString(jval);
4180 //emitpcode(POC_BTFSS, p);
4181 emitpcode(POC_BTFSS, newpCodeOpBit(jval,0));
4183 // emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval);
4186 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4187 emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
4192 /* mark the icode as generated */
4196 /*-----------------------------------------------------------------*/
4198 /*-----------------------------------------------------------------*/
4199 static void genSkip(iCode *ifx,int status_bit)
4204 if ( IC_TRUE(ifx) ) {
4205 switch(status_bit) {
4215 emitcode("skpndc","");
4220 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4221 emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4225 switch(status_bit) {
4236 emitcode("skpdc","");
4239 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4240 emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4246 /*-----------------------------------------------------------------*/
4248 /*-----------------------------------------------------------------*/
4249 static void genSkipc(iCode *ifx, int condition)
4260 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4262 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4265 emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4267 emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4271 /*-----------------------------------------------------------------*/
4273 /*-----------------------------------------------------------------*/
4274 static void genSkipz(iCode *ifx, int condition)
4285 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4287 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4290 emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4292 emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4295 /*-----------------------------------------------------------------*/
4296 /* genCmp :- greater or less than comparison */
4297 /*-----------------------------------------------------------------*/
4298 static void genCmp (operand *left,operand *right,
4299 operand *result, iCode *ifx, int sign)
4301 int size, offset = 0 ;
4302 unsigned long lit = 0L,i = 0;
4304 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4305 /* if left & right are bit variables */
4306 if (AOP_TYPE(left) == AOP_CRY &&
4307 AOP_TYPE(right) == AOP_CRY ) {
4308 emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4309 emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4311 /* subtract right from left if at the
4312 end the carry flag is set then we know that
4313 left is greater than right */
4314 size = max(AOP_SIZE(left),AOP_SIZE(right));
4316 /* if unsigned char cmp with lit, do cjne left,#right,zz */
4317 if((size == 1) && !sign &&
4318 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
4319 symbol *lbl = newiTempLabel(NULL);
4320 emitcode("cjne","%s,%s,%05d_DS_",
4321 aopGet(AOP(left),offset,FALSE,FALSE),
4322 aopGet(AOP(right),offset,FALSE,FALSE),
4324 emitcode("","%05d_DS_:",lbl->key+100);
4327 if(AOP_TYPE(right) == AOP_LIT) {
4329 DEBUGemitcode(";right lit","%d",sign);
4331 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4334 i = (lit >> (size*8)) & 0xff;
4336 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
4337 emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
4338 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4340 emitpcode(POC_MOVLW, popGetLit(i));
4341 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
4343 emitcode("movlw","0x%x",i);
4344 emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
4345 genSkipc(ifx,IC_TRUE(ifx) == NULL);
4352 if(AOP_TYPE(left) == AOP_LIT) {
4354 DEBUGemitcode(";left lit","%d",sign);
4356 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
4360 i = (lit >> (size*8)) & 0xff;
4362 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
4363 emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
4364 genSkipz(ifx,IC_TRUE(ifx) != NULL);
4365 } else if( i == 1 ) {
4366 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
4367 emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
4368 genSkipz(ifx,IC_TRUE(ifx) != NULL);
4371 emitpcode(POC_MOVLW, popGetLit(i));
4372 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
4374 emitcode("movlw","0x%x",i);
4375 emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
4376 genSkipc(ifx,IC_TRUE(ifx) != NULL);
4385 DEBUGemitcode(";sign","%d",sign);
4387 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4388 emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
4390 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4391 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
4396 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4398 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
4399 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
4402 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4404 emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4405 emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4413 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4416 /* if the result is used in the next
4417 ifx conditional branch then generate
4418 code a little differently */
4420 genIfxJump (ifx,"c");
4423 /* leave the result in acc */
4428 /*-----------------------------------------------------------------*/
4429 /* genCmpGt :- greater than comparison */
4430 /*-----------------------------------------------------------------*/
4431 static void genCmpGt (iCode *ic, iCode *ifx)
4433 operand *left, *right, *result;
4434 sym_link *letype , *retype;
4437 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4439 right= IC_RIGHT(ic);
4440 result = IC_RESULT(ic);
4442 letype = getSpec(operandType(left));
4443 retype =getSpec(operandType(right));
4444 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4445 /* assign the amsops */
4446 aopOp (left,ic,FALSE);
4447 aopOp (right,ic,FALSE);
4448 aopOp (result,ic,TRUE);
4450 genCmp(right, left, result, ifx, sign);
4452 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4453 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4454 freeAsmop(result,NULL,ic,TRUE);
4457 /*-----------------------------------------------------------------*/
4458 /* genCmpLt - less than comparisons */
4459 /*-----------------------------------------------------------------*/
4460 static void genCmpLt (iCode *ic, iCode *ifx)
4462 operand *left, *right, *result;
4463 sym_link *letype , *retype;
4466 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4468 right= IC_RIGHT(ic);
4469 result = IC_RESULT(ic);
4471 letype = getSpec(operandType(left));
4472 retype =getSpec(operandType(right));
4473 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4475 /* assign the amsops */
4476 aopOp (left,ic,FALSE);
4477 aopOp (right,ic,FALSE);
4478 aopOp (result,ic,TRUE);
4480 genCmp(left, right, result, ifx, sign);
4482 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4483 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4484 freeAsmop(result,NULL,ic,TRUE);
4487 /*-----------------------------------------------------------------*/
4488 /* gencjneshort - compare and jump if not equal */
4489 /*-----------------------------------------------------------------*/
4490 static void gencjneshort(operand *left, operand *right, symbol *lbl)
4492 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4494 unsigned long lit = 0L;
4496 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4497 /* if the left side is a literal or
4498 if the right is in a pointer register and left
4500 if ((AOP_TYPE(left) == AOP_LIT) ||
4501 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4506 if(AOP_TYPE(right) == AOP_LIT)
4507 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4509 /* if the right side is a literal then anything goes */
4510 if (AOP_TYPE(right) == AOP_LIT &&
4511 AOP_TYPE(left) != AOP_DIR ) {
4514 emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4515 emitcode("xorlw","0x%x",lit & 0xff);
4517 emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4520 emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
4526 /* if the right side is in a register or in direct space or
4527 if the left is a pointer register & right is not */
4528 else if (AOP_TYPE(right) == AOP_REG ||
4529 AOP_TYPE(right) == AOP_DIR ||
4530 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4531 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4533 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
4534 ( (lit & 0xff) != 0)) {
4535 emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4536 emitcode("xorlw","0x%x",lit & 0xff);
4539 emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4542 emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
4545 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4546 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
4547 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
4548 emitcode("jnz","%05d_DS_",lbl->key+100);
4550 emitcode("cjne","a,%s,%05d_DS_",
4551 aopGet(AOP(right),offset,FALSE,TRUE),
4557 /* right is a pointer reg need both a & b */
4559 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4561 emitcode("mov","b,%s",l);
4562 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4563 emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4569 /*-----------------------------------------------------------------*/
4570 /* gencjne - compare and jump if not equal */
4571 /*-----------------------------------------------------------------*/
4572 static void gencjne(operand *left, operand *right, symbol *lbl)
4574 symbol *tlbl = newiTempLabel(NULL);
4576 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4577 gencjneshort(left, right, lbl);
4579 emitcode("mov","a,%s",one);
4580 emitcode("sjmp","%05d_DS_",tlbl->key+100);
4581 emitcode("","%05d_DS_:",lbl->key+100);
4582 emitcode("clr","a");
4583 emitcode("","%05d_DS_:",tlbl->key+100);
4587 /*-----------------------------------------------------------------*/
4588 /* genCmpEq - generates code for equal to */
4589 /*-----------------------------------------------------------------*/
4590 static void genCmpEq (iCode *ic, iCode *ifx)
4592 operand *left, *right, *result;
4593 unsigned long lit = 0L;
4596 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4598 DEBUGemitcode ("; ifx is non-null","");
4600 DEBUGemitcode ("; ifx is null","");
4602 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4603 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4604 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4606 size = max(AOP_SIZE(left),AOP_SIZE(right));
4608 /* if literal, literal on the right or
4609 if the right is in a pointer register and left
4611 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4612 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4613 operand *t = IC_RIGHT(ic);
4614 IC_RIGHT(ic) = IC_LEFT(ic);
4618 if(ifx && !AOP_SIZE(result)){
4620 /* if they are both bit variables */
4621 if (AOP_TYPE(left) == AOP_CRY &&
4622 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4623 if(AOP_TYPE(right) == AOP_LIT){
4624 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4626 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4627 emitcode("cpl","c");
4628 } else if(lit == 1L) {
4629 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4631 emitcode("clr","c");
4633 /* AOP_TYPE(right) == AOP_CRY */
4635 symbol *lbl = newiTempLabel(NULL);
4636 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4637 emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4638 emitcode("cpl","c");
4639 emitcode("","%05d_DS_:",(lbl->key+100));
4641 /* if true label then we jump if condition
4643 tlbl = newiTempLabel(NULL);
4644 if ( IC_TRUE(ifx) ) {
4645 emitcode("jnc","%05d_DS_",tlbl->key+100);
4646 emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4648 emitcode("jc","%05d_DS_",tlbl->key+100);
4649 emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4651 emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4654 /* They're not both bit variables. Is the right a literal? */
4655 if(AOP_TYPE(right) == AOP_LIT) {
4657 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4662 int h = (lit>>8) & 0xff;
4665 /* Check special cases for integers */
4666 switch(lit & 0xffff) {
4668 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4669 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4670 //emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4671 //emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4676 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4677 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4678 emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4679 emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4684 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4685 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4686 emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4687 emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4692 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4693 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4694 emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4695 emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4700 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4701 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4702 emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4703 emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4709 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4710 emitpcode(POC_XORLW,popGetLit(l));
4711 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4713 emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4714 emitcode("xorlw","0x%x",l);
4715 emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4718 } else if (l == 0) {
4719 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4720 emitpcode(POC_XORLW,popGetLit(h));
4721 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4723 emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4724 emitcode("xorlw","0x%x",h);
4725 emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4729 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4730 emitpcode(POC_XORLW,popGetLit(l));
4731 emitpcode(POC_MOVLW,popGetLit(h));
4733 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
4735 emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4736 emitcode("xorlw","0x%x",l);
4737 emitcode("movlw","0x%x",h);
4739 emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
4756 switch(lit & 0xff) {
4758 if ( IC_TRUE(ifx) ) {
4760 emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4762 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4764 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4766 emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4768 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4769 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4771 emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4772 emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4776 if ( IC_TRUE(ifx) ) {
4777 emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4779 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4781 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4783 emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4785 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4786 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4788 emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4789 emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4793 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4794 //emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4796 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4797 //emitcode("xorlw","0x%x",lit & 0xff);
4802 // emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
4803 //emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4808 } else if(AOP_TYPE(right) == AOP_CRY ) {
4809 /* we know the left is not a bit, but that the right is */
4810 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4811 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4812 popGet(AOP(right),offset,FALSE,FALSE));
4813 emitpcode(POC_XORLW,popGetLit(1));
4815 emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4817 emitcode("btfsc","(%s >> 3), (%s & 7)",
4818 AOP(right)->aopu.aop_dir,
4819 AOP(right)->aopu.aop_dir);
4821 emitcode("btfss","(%s >> 3), (%s & 7)",
4822 AOP(right)->aopu.aop_dir,
4823 AOP(right)->aopu.aop_dir);
4825 emitcode("xorlw","1");
4827 /* if the two are equal, then W will be 0 and the Z bit is set
4828 * we could test Z now, or go ahead and check the high order bytes if
4829 * the variable we're comparing is larger than a byte. */
4832 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4833 //emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4835 if ( IC_TRUE(ifx) ) {
4837 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4838 emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4841 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4842 emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4846 /* They're both variables that are larger than bits */
4849 tlbl = newiTempLabel(NULL);
4852 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4853 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4855 emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4856 emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4858 if ( IC_TRUE(ifx) ) {
4861 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4862 emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4865 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4866 emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4870 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4871 emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4875 if(s>1 && IC_TRUE(ifx)) {
4876 emitpLabel(tlbl->key+100+labelOffset);
4877 emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4881 /* mark the icode as generated */
4886 /* if they are both bit variables */
4887 if (AOP_TYPE(left) == AOP_CRY &&
4888 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4889 if(AOP_TYPE(right) == AOP_LIT){
4890 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4892 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4893 emitcode("cpl","c");
4894 } else if(lit == 1L) {
4895 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4897 emitcode("clr","c");
4899 /* AOP_TYPE(right) == AOP_CRY */
4901 symbol *lbl = newiTempLabel(NULL);
4902 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4903 emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4904 emitcode("cpl","c");
4905 emitcode("","%05d_DS_:",(lbl->key+100));
4908 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4913 genIfxJump (ifx,"c");
4916 /* if the result is used in an arithmetic operation
4917 then put the result in place */
4920 gencjne(left,right,newiTempLabel(NULL));
4921 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4922 aopPut(AOP(result),"a",0);
4926 genIfxJump (ifx,"a");
4929 /* if the result is used in an arithmetic operation
4930 then put the result in place */
4931 if (AOP_TYPE(result) != AOP_CRY)
4933 /* leave the result in acc */
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 /* ifxForOp - returns the icode containing the ifx for operand */
4944 /*-----------------------------------------------------------------*/
4945 static iCode *ifxForOp ( operand *op, iCode *ic )
4947 /* if true symbol then needs to be assigned */
4948 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4949 if (IS_TRUE_SYMOP(op))
4952 /* if this has register type condition and
4953 the next instruction is ifx with the same operand
4954 and live to of the operand is upto the ifx only then */
4956 ic->next->op == IFX &&
4957 IC_COND(ic->next)->key == op->key &&
4958 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4963 /*-----------------------------------------------------------------*/
4964 /* genAndOp - for && operation */
4965 /*-----------------------------------------------------------------*/
4966 static void genAndOp (iCode *ic)
4968 operand *left,*right, *result;
4971 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4972 /* note here that && operations that are in an
4973 if statement are taken away by backPatchLabels
4974 only those used in arthmetic operations remain */
4975 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4976 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4977 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4979 /* if both are bit variables */
4980 if (AOP_TYPE(left) == AOP_CRY &&
4981 AOP_TYPE(right) == AOP_CRY ) {
4982 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4983 emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4986 tlbl = newiTempLabel(NULL);
4988 emitcode("jz","%05d_DS_",tlbl->key+100);
4990 emitcode("","%05d_DS_:",tlbl->key+100);
4994 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4995 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4996 freeAsmop(result,NULL,ic,TRUE);
5000 /*-----------------------------------------------------------------*/
5001 /* genOrOp - for || operation */
5002 /*-----------------------------------------------------------------*/
5005 modified this code, but it doesn't appear to ever get called
5008 static void genOrOp (iCode *ic)
5010 operand *left,*right, *result;
5013 /* note here that || operations that are in an
5014 if statement are taken away by backPatchLabels
5015 only those used in arthmetic operations remain */
5016 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5017 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5018 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5019 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5021 /* if both are bit variables */
5022 if (AOP_TYPE(left) == AOP_CRY &&
5023 AOP_TYPE(right) == AOP_CRY ) {
5024 emitcode("clrc","");
5025 emitcode("btfss","(%s >> 3), (%s & 7)",
5026 AOP(left)->aopu.aop_dir,
5027 AOP(left)->aopu.aop_dir);
5028 emitcode("btfsc","(%s >> 3), (%s & 7)",
5029 AOP(right)->aopu.aop_dir,
5030 AOP(right)->aopu.aop_dir);
5031 emitcode("setc","");
5034 tlbl = newiTempLabel(NULL);
5037 emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5039 emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5044 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5045 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5046 freeAsmop(result,NULL,ic,TRUE);
5049 /*-----------------------------------------------------------------*/
5050 /* isLiteralBit - test if lit == 2^n */
5051 /*-----------------------------------------------------------------*/
5052 static int isLiteralBit(unsigned long lit)
5054 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5055 0x100L,0x200L,0x400L,0x800L,
5056 0x1000L,0x2000L,0x4000L,0x8000L,
5057 0x10000L,0x20000L,0x40000L,0x80000L,
5058 0x100000L,0x200000L,0x400000L,0x800000L,
5059 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5060 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5063 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5064 for(idx = 0; idx < 32; idx++)
5070 /*-----------------------------------------------------------------*/
5071 /* continueIfTrue - */
5072 /*-----------------------------------------------------------------*/
5073 static void continueIfTrue (iCode *ic)
5075 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5077 emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5081 /*-----------------------------------------------------------------*/
5083 /*-----------------------------------------------------------------*/
5084 static void jumpIfTrue (iCode *ic)
5086 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5088 emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5092 /*-----------------------------------------------------------------*/
5093 /* jmpTrueOrFalse - */
5094 /*-----------------------------------------------------------------*/
5095 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5097 // ugly but optimized by peephole
5098 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5100 symbol *nlbl = newiTempLabel(NULL);
5101 emitcode("sjmp","%05d_DS_",nlbl->key+100);
5102 emitcode("","%05d_DS_:",tlbl->key+100);
5103 emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5104 emitcode("","%05d_DS_:",nlbl->key+100);
5107 emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5108 emitcode("","%05d_DS_:",tlbl->key+100);
5113 /*-----------------------------------------------------------------*/
5114 /* genAnd - code for and */
5115 /*-----------------------------------------------------------------*/
5116 static void genAnd (iCode *ic, iCode *ifx)
5118 operand *left, *right, *result;
5120 unsigned long lit = 0L;
5124 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5125 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5126 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5127 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5130 emitcode("","; Type res[%d] = l[%d]&r[%d]",
5132 AOP_TYPE(left), AOP_TYPE(right));
5133 emitcode("","; Size res[%d] = l[%d]&r[%d]",
5135 AOP_SIZE(left), AOP_SIZE(right));
5138 /* if left is a literal & right is not then exchange them */
5139 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5140 AOP_NEEDSACC(left)) {
5141 operand *tmp = right ;
5146 /* if result = right then exchange them */
5147 if(sameRegs(AOP(result),AOP(right))){
5148 operand *tmp = right ;
5153 /* if right is bit then exchange them */
5154 if (AOP_TYPE(right) == AOP_CRY &&
5155 AOP_TYPE(left) != AOP_CRY){
5156 operand *tmp = right ;
5160 if(AOP_TYPE(right) == AOP_LIT)
5161 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5163 size = AOP_SIZE(result);
5166 // result = bit & yy;
5167 if (AOP_TYPE(left) == AOP_CRY){
5168 // c = bit & literal;
5169 if(AOP_TYPE(right) == AOP_LIT){
5171 if(size && sameRegs(AOP(result),AOP(left)))
5174 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5177 if(size && (AOP_TYPE(result) == AOP_CRY)){
5178 emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5181 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5185 emitcode("clr","c");
5188 if (AOP_TYPE(right) == AOP_CRY){
5190 emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5191 emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5194 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5196 emitcode("rrc","a");
5197 emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5205 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5206 genIfxJump(ifx, "c");
5210 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5211 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5212 if((AOP_TYPE(right) == AOP_LIT) &&
5213 (AOP_TYPE(result) == AOP_CRY) &&
5214 (AOP_TYPE(left) != AOP_CRY)){
5215 int posbit = isLiteralBit(lit);
5219 MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5222 emitcode("mov","c,acc.%d",posbit&0x07);
5226 sprintf(buffer,"acc.%d",posbit&0x07);
5227 genIfxJump(ifx, buffer);
5232 symbol *tlbl = newiTempLabel(NULL);
5233 int sizel = AOP_SIZE(left);
5235 emitcode("setb","c");
5237 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5238 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5240 if((posbit = isLiteralBit(bytelit)) != 0)
5241 emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5243 if(bytelit != 0x0FFL)
5244 emitcode("anl","a,%s",
5245 aopGet(AOP(right),offset,FALSE,TRUE));
5246 emitcode("jnz","%05d_DS_",tlbl->key+100);
5251 // bit = left & literal
5253 emitcode("clr","c");
5254 emitcode("","%05d_DS_:",tlbl->key+100);
5256 // if(left & literal)
5259 jmpTrueOrFalse(ifx, tlbl);
5267 /* if left is same as result */
5268 if(sameRegs(AOP(result),AOP(left))){
5269 for(;size--; offset++,lit>>=8) {
5270 if(AOP_TYPE(right) == AOP_LIT){
5271 switch(lit & 0xff) {
5273 /* and'ing with 0 has clears the result */
5274 emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5277 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5282 int p = my_powof2( (~lit) & 0xff );
5284 /* only one bit is set in the literal, so use a bcf instruction */
5285 emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5287 emitcode("movlw","0x%x", (lit & 0xff));
5288 emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
5293 if (AOP_TYPE(left) == AOP_ACC)
5294 emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5296 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5297 emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5304 // left & result in different registers
5305 if(AOP_TYPE(result) == AOP_CRY){
5307 // if(size), result in bit
5308 // if(!size && ifx), conditional oper: if(left & right)
5309 symbol *tlbl = newiTempLabel(NULL);
5310 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5312 emitcode("setb","c");
5314 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5315 emitcode("anl","a,%s",
5316 aopGet(AOP(left),offset,FALSE,FALSE));
5317 emitcode("jnz","%05d_DS_",tlbl->key+100);
5322 emitcode("","%05d_DS_:",tlbl->key+100);
5325 jmpTrueOrFalse(ifx, tlbl);
5327 for(;(size--);offset++) {
5329 // result = left & right
5330 if(AOP_TYPE(right) == AOP_LIT){
5331 int t = (lit >> (offset*8)) & 0x0FFL;
5334 emitcode("clrf","%s",
5335 aopGet(AOP(result),offset,FALSE,FALSE));
5338 emitcode("movf","%s,w",
5339 aopGet(AOP(left),offset,FALSE,FALSE));
5340 emitcode("movwf","%s",
5341 aopGet(AOP(result),offset,FALSE,FALSE));
5344 emitcode("movlw","0x%x",t);
5345 emitcode("andwf","%s,w",
5346 aopGet(AOP(left),offset,FALSE,FALSE));
5347 emitcode("movwf","%s",
5348 aopGet(AOP(result),offset,FALSE,FALSE));
5354 if (AOP_TYPE(left) == AOP_ACC)
5355 emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5357 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5358 emitcode("andwf","%s,w",
5359 aopGet(AOP(left),offset,FALSE,FALSE));
5361 emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5367 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5368 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5369 freeAsmop(result,NULL,ic,TRUE);
5372 /*-----------------------------------------------------------------*/
5373 /* genOr - code for or */
5374 /*-----------------------------------------------------------------*/
5375 static void genOr (iCode *ic, iCode *ifx)
5377 operand *left, *right, *result;
5379 unsigned long lit = 0L;
5381 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5383 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5384 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5385 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5388 /* if left is a literal & right is not then exchange them */
5389 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5390 AOP_NEEDSACC(left)) {
5391 operand *tmp = right ;
5396 /* if result = right then exchange them */
5397 if(sameRegs(AOP(result),AOP(right))){
5398 operand *tmp = right ;
5403 /* if right is bit then exchange them */
5404 if (AOP_TYPE(right) == AOP_CRY &&
5405 AOP_TYPE(left) != AOP_CRY){
5406 operand *tmp = right ;
5411 if(AOP_TYPE(right) == AOP_LIT)
5412 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5414 size = AOP_SIZE(result);
5418 if (AOP_TYPE(left) == AOP_CRY){
5419 if(AOP_TYPE(right) == AOP_LIT){
5420 // c = bit & literal;
5422 // lit != 0 => result = 1
5423 if(AOP_TYPE(result) == AOP_CRY){
5425 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
5426 //emitcode("bsf","(%s >> 3), (%s & 7)",
5427 // AOP(result)->aopu.aop_dir,
5428 // AOP(result)->aopu.aop_dir);
5430 continueIfTrue(ifx);
5434 // lit == 0 => result = left
5435 if(size && sameRegs(AOP(result),AOP(left)))
5437 emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5440 if (AOP_TYPE(right) == AOP_CRY){
5441 if(sameRegs(AOP(result),AOP(left))){
5443 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
5444 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
5445 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
5447 emitcode("bcf","(%s >> 3), (%s & 7)",
5448 AOP(result)->aopu.aop_dir,
5449 AOP(result)->aopu.aop_dir);
5450 emitcode("btfsc","(%s >> 3), (%s & 7)",
5451 AOP(right)->aopu.aop_dir,
5452 AOP(right)->aopu.aop_dir);
5453 emitcode("bsf","(%s >> 3), (%s & 7)",
5454 AOP(result)->aopu.aop_dir,
5455 AOP(result)->aopu.aop_dir);
5458 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
5459 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
5460 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
5461 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
5463 emitcode("bcf","(%s >> 3), (%s & 7)",
5464 AOP(result)->aopu.aop_dir,
5465 AOP(result)->aopu.aop_dir);
5466 emitcode("btfss","(%s >> 3), (%s & 7)",
5467 AOP(right)->aopu.aop_dir,
5468 AOP(right)->aopu.aop_dir);
5469 emitcode("btfsc","(%s >> 3), (%s & 7)",
5470 AOP(left)->aopu.aop_dir,
5471 AOP(left)->aopu.aop_dir);
5472 emitcode("bsf","(%s >> 3), (%s & 7)",
5473 AOP(result)->aopu.aop_dir,
5474 AOP(result)->aopu.aop_dir);
5479 symbol *tlbl = newiTempLabel(NULL);
5480 emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5481 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5482 emitcode(";XXX setb","c");
5483 emitcode(";XXX jb","%s,%05d_DS_",
5484 AOP(left)->aopu.aop_dir,tlbl->key+100);
5486 emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5487 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5488 jmpTrueOrFalse(ifx, tlbl);
5492 emitcode("","%05d_DS_:",tlbl->key+100);
5501 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5502 genIfxJump(ifx, "c");
5506 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5507 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5508 if((AOP_TYPE(right) == AOP_LIT) &&
5509 (AOP_TYPE(result) == AOP_CRY) &&
5510 (AOP_TYPE(left) != AOP_CRY)){
5512 emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5515 emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5517 continueIfTrue(ifx);
5520 emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5521 // lit = 0, result = boolean(left)
5523 emitcode(";XXX setb","c");
5526 symbol *tlbl = newiTempLabel(NULL);
5527 emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5529 emitcode("","%05d_DS_:",tlbl->key+100);
5531 genIfxJump (ifx,"a");
5539 /* if left is same as result */
5540 if(sameRegs(AOP(result),AOP(left))){
5541 for(;size--; offset++,lit>>=8) {
5542 if(AOP_TYPE(right) == AOP_LIT){
5543 if((lit & 0xff) == 0)
5544 /* or'ing with 0 has no effect */
5547 int p = my_powof2(lit & 0xff);
5549 /* only one bit is set in the literal, so use a bsf instruction */
5550 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
5551 emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5553 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5554 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
5556 emitcode("movlw","0x%x", (lit & 0xff));
5557 emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
5562 if (AOP_TYPE(left) == AOP_ACC) {
5563 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
5564 emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5566 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
5567 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
5569 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5570 emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5576 // left & result in different registers
5577 if(AOP_TYPE(result) == AOP_CRY){
5579 // if(size), result in bit
5580 // if(!size && ifx), conditional oper: if(left | right)
5581 symbol *tlbl = newiTempLabel(NULL);
5582 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5583 emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5586 emitcode(";XXX setb","c");
5588 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5589 emitcode(";XXX orl","a,%s",
5590 aopGet(AOP(left),offset,FALSE,FALSE));
5591 emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5596 emitcode("","%05d_DS_:",tlbl->key+100);
5599 jmpTrueOrFalse(ifx, tlbl);
5600 } else for(;(size--);offset++){
5602 // result = left & right
5603 if(AOP_TYPE(right) == AOP_LIT){
5604 int t = (lit >> (offset*8)) & 0x0FFL;
5607 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
5608 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5610 emitcode("movf","%s,w",
5611 aopGet(AOP(left),offset,FALSE,FALSE));
5612 emitcode("movwf","%s",
5613 aopGet(AOP(result),offset,FALSE,FALSE));
5616 emitpcode(POC_MOVLW, popGetLit(t));
5617 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5618 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5620 emitcode("movlw","0x%x",t);
5621 emitcode("iorwf","%s,w",
5622 aopGet(AOP(left),offset,FALSE,FALSE));
5623 emitcode("movwf","%s",
5624 aopGet(AOP(result),offset,FALSE,FALSE));
5630 // faster than result <- left, anl result,right
5631 // and better if result is SFR
5632 if (AOP_TYPE(left) == AOP_ACC) {
5633 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
5634 emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5636 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
5637 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5639 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5640 emitcode("iorwf","%s,w",
5641 aopGet(AOP(left),offset,FALSE,FALSE));
5643 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5644 emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5649 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5650 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5651 freeAsmop(result,NULL,ic,TRUE);
5654 /*-----------------------------------------------------------------*/
5655 /* genXor - code for xclusive or */
5656 /*-----------------------------------------------------------------*/
5657 static void genXor (iCode *ic, iCode *ifx)
5659 operand *left, *right, *result;
5661 unsigned long lit = 0L;
5663 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5665 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5666 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5667 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5669 /* if left is a literal & right is not ||
5670 if left needs acc & right does not */
5671 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5672 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5673 operand *tmp = right ;
5678 /* if result = right then exchange them */
5679 if(sameRegs(AOP(result),AOP(right))){
5680 operand *tmp = right ;
5685 /* if right is bit then exchange them */
5686 if (AOP_TYPE(right) == AOP_CRY &&
5687 AOP_TYPE(left) != AOP_CRY){
5688 operand *tmp = right ;
5692 if(AOP_TYPE(right) == AOP_LIT)
5693 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5695 size = AOP_SIZE(result);
5699 if (AOP_TYPE(left) == AOP_CRY){
5700 if(AOP_TYPE(right) == AOP_LIT){
5701 // c = bit & literal;
5703 // lit>>1 != 0 => result = 1
5704 if(AOP_TYPE(result) == AOP_CRY){
5706 emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5708 continueIfTrue(ifx);
5711 emitcode("setb","c");
5715 // lit == 0, result = left
5716 if(size && sameRegs(AOP(result),AOP(left)))
5718 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5720 // lit == 1, result = not(left)
5721 if(size && sameRegs(AOP(result),AOP(left))){
5722 emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5725 emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5726 emitcode("cpl","c");
5733 symbol *tlbl = newiTempLabel(NULL);
5734 if (AOP_TYPE(right) == AOP_CRY){
5736 emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5739 int sizer = AOP_SIZE(right);
5741 // if val>>1 != 0, result = 1
5742 emitcode("setb","c");
5744 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5746 // test the msb of the lsb
5747 emitcode("anl","a,#0xfe");
5748 emitcode("jnz","%05d_DS_",tlbl->key+100);
5752 emitcode("rrc","a");
5754 emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5755 emitcode("cpl","c");
5756 emitcode("","%05d_DS_:",(tlbl->key+100));
5763 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5764 genIfxJump(ifx, "c");
5768 if(sameRegs(AOP(result),AOP(left))){
5769 /* if left is same as result */
5770 for(;size--; offset++) {
5771 if(AOP_TYPE(right) == AOP_LIT){
5772 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
5775 if (IS_AOP_PREG(left)) {
5776 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5777 emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5778 aopPut(AOP(result),"a",offset);
5780 emitcode("xrl","%s,%s",
5781 aopGet(AOP(left),offset,FALSE,TRUE),
5782 aopGet(AOP(right),offset,FALSE,FALSE));
5784 if (AOP_TYPE(left) == AOP_ACC)
5785 emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5787 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5788 if (IS_AOP_PREG(left)) {
5789 emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5790 aopPut(AOP(result),"a",offset);
5792 emitcode("xrl","%s,a",
5793 aopGet(AOP(left),offset,FALSE,TRUE));
5798 // left & result in different registers
5799 if(AOP_TYPE(result) == AOP_CRY){
5801 // if(size), result in bit
5802 // if(!size && ifx), conditional oper: if(left ^ right)
5803 symbol *tlbl = newiTempLabel(NULL);
5804 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5806 emitcode("setb","c");
5808 if((AOP_TYPE(right) == AOP_LIT) &&
5809 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5810 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5812 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5813 emitcode("xrl","a,%s",
5814 aopGet(AOP(left),offset,FALSE,FALSE));
5816 emitcode("jnz","%05d_DS_",tlbl->key+100);
5821 emitcode("","%05d_DS_:",tlbl->key+100);
5824 jmpTrueOrFalse(ifx, tlbl);
5825 } else for(;(size--);offset++){
5827 // result = left & right
5828 if(AOP_TYPE(right) == AOP_LIT){
5829 int t = (lit >> (offset*8)) & 0x0FFL;
5832 emitcode("movf","%s,w",
5833 aopGet(AOP(left),offset,FALSE,FALSE));
5834 emitcode("movwf","%s",
5835 aopGet(AOP(result),offset,FALSE,FALSE));
5838 emitcode("comf","%s,w",
5839 aopGet(AOP(left),offset,FALSE,FALSE));
5840 emitcode("movwf","%s",
5841 aopGet(AOP(result),offset,FALSE,FALSE));
5844 emitcode("movlw","0x%x",t);
5845 emitcode("xorwf","%s,w",
5846 aopGet(AOP(left),offset,FALSE,FALSE));
5847 emitcode("movwf","%s",
5848 aopGet(AOP(result),offset,FALSE,FALSE));
5854 // faster than result <- left, anl result,right
5855 // and better if result is SFR
5856 if (AOP_TYPE(left) == AOP_ACC)
5857 emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5859 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5860 emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5862 if ( AOP_TYPE(result) != AOP_ACC)
5863 emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5868 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5869 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5870 freeAsmop(result,NULL,ic,TRUE);
5873 /*-----------------------------------------------------------------*/
5874 /* genInline - write the inline code out */
5875 /*-----------------------------------------------------------------*/
5876 static void genInline (iCode *ic)
5878 char buffer[MAX_INLINEASM];
5882 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5884 _G.inLine += (!options.asmpeep);
5885 strcpy(buffer,IC_INLINE(ic));
5887 /* emit each line as a code */
5906 /* emitcode("",buffer); */
5907 _G.inLine -= (!options.asmpeep);
5910 /*-----------------------------------------------------------------*/
5911 /* genRRC - rotate right with carry */
5912 /*-----------------------------------------------------------------*/
5913 static void genRRC (iCode *ic)
5915 operand *left , *result ;
5916 int size, offset = 0;
5919 /* rotate right with carry */
5921 result=IC_RESULT(ic);
5922 aopOp (left,ic,FALSE);
5923 aopOp (result,ic,FALSE);
5925 /* move it to the result */
5926 size = AOP_SIZE(result);
5930 l = aopGet(AOP(left),offset,FALSE,FALSE);
5932 emitcode("rrc","a");
5933 if (AOP_SIZE(result) > 1)
5934 aopPut(AOP(result),"a",offset--);
5936 /* now we need to put the carry into the
5937 highest order byte of the result */
5938 if (AOP_SIZE(result) > 1) {
5939 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5942 emitcode("mov","acc.7,c");
5943 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5944 freeAsmop(left,NULL,ic,TRUE);
5945 freeAsmop(result,NULL,ic,TRUE);
5948 /*-----------------------------------------------------------------*/
5949 /* genRLC - generate code for rotate left with carry */
5950 /*-----------------------------------------------------------------*/
5951 static void genRLC (iCode *ic)
5953 operand *left , *result ;
5954 int size, offset = 0;
5957 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5958 /* rotate right with carry */
5960 result=IC_RESULT(ic);
5961 aopOp (left,ic,FALSE);
5962 aopOp (result,ic,FALSE);
5964 /* move it to the result */
5965 size = AOP_SIZE(result);
5968 l = aopGet(AOP(left),offset,FALSE,FALSE);
5970 emitcode("add","a,acc");
5971 if (AOP_SIZE(result) > 1)
5972 aopPut(AOP(result),"a",offset++);
5974 l = aopGet(AOP(left),offset,FALSE,FALSE);
5976 emitcode("rlc","a");
5977 if (AOP_SIZE(result) > 1)
5978 aopPut(AOP(result),"a",offset++);
5981 /* now we need to put the carry into the
5982 highest order byte of the result */
5983 if (AOP_SIZE(result) > 1) {
5984 l = aopGet(AOP(result),0,FALSE,FALSE);
5987 emitcode("mov","acc.0,c");
5988 aopPut(AOP(result),"a",0);
5989 freeAsmop(left,NULL,ic,TRUE);
5990 freeAsmop(result,NULL,ic,TRUE);
5993 /*-----------------------------------------------------------------*/
5994 /* genGetHbit - generates code get highest order bit */
5995 /*-----------------------------------------------------------------*/
5996 static void genGetHbit (iCode *ic)
5998 operand *left, *result;
6000 result=IC_RESULT(ic);
6001 aopOp (left,ic,FALSE);
6002 aopOp (result,ic,FALSE);
6004 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6005 /* get the highest order byte into a */
6006 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6007 if(AOP_TYPE(result) == AOP_CRY){
6008 emitcode("rlc","a");
6013 emitcode("anl","a,#0x01");
6018 freeAsmop(left,NULL,ic,TRUE);
6019 freeAsmop(result,NULL,ic,TRUE);
6022 /*-----------------------------------------------------------------*/
6023 /* AccRol - rotate left accumulator by known count */
6024 /*-----------------------------------------------------------------*/
6025 static void AccRol (int shCount)
6027 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6028 shCount &= 0x0007; // shCount : 0..7
6040 emitcode("swap","a");
6044 emitcode("swap","a");
6047 emitcode("swap","a");
6060 /*-----------------------------------------------------------------*/
6061 /* AccLsh - left shift accumulator by known count */
6062 /*-----------------------------------------------------------------*/
6063 static void AccLsh (int shCount)
6065 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6068 emitcode("add","a,acc");
6071 emitcode("add","a,acc");
6072 emitcode("add","a,acc");
6074 /* rotate left accumulator */
6076 /* and kill the lower order bits */
6077 emitcode("anl","a,#0x%02x", SLMask[shCount]);
6082 /*-----------------------------------------------------------------*/
6083 /* AccRsh - right shift accumulator by known count */
6084 /*-----------------------------------------------------------------*/
6085 static void AccRsh (int shCount)
6087 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6091 emitcode("rrc","a");
6093 /* rotate right accumulator */
6094 AccRol(8 - shCount);
6095 /* and kill the higher order bits */
6096 emitcode("anl","a,#0x%02x", SRMask[shCount]);
6101 /*-----------------------------------------------------------------*/
6102 /* AccSRsh - signed right shift accumulator by known count */
6103 /*-----------------------------------------------------------------*/
6104 static void AccSRsh (int shCount)
6107 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6110 emitcode("mov","c,acc.7");
6111 emitcode("rrc","a");
6112 } else if(shCount == 2){
6113 emitcode("mov","c,acc.7");
6114 emitcode("rrc","a");
6115 emitcode("mov","c,acc.7");
6116 emitcode("rrc","a");
6118 tlbl = newiTempLabel(NULL);
6119 /* rotate right accumulator */
6120 AccRol(8 - shCount);
6121 /* and kill the higher order bits */
6122 emitcode("anl","a,#0x%02x", SRMask[shCount]);
6123 emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6124 emitcode("orl","a,#0x%02x",
6125 (unsigned char)~SRMask[shCount]);
6126 emitcode("","%05d_DS_:",tlbl->key+100);
6131 /*-----------------------------------------------------------------*/
6132 /* shiftR1Left2Result - shift right one byte from left to result */
6133 /*-----------------------------------------------------------------*/
6134 static void shiftR1Left2Result (operand *left, int offl,
6135 operand *result, int offr,
6136 int shCount, int sign)
6138 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6139 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6140 /* shift right accumulator */
6145 aopPut(AOP(result),"a",offr);
6148 /*-----------------------------------------------------------------*/
6149 /* shiftL1Left2Result - shift left one byte from left to result */
6150 /*-----------------------------------------------------------------*/
6151 static void shiftL1Left2Result (operand *left, int offl,
6152 operand *result, int offr, int shCount)
6155 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6156 l = aopGet(AOP(left),offl,FALSE,FALSE);
6158 /* shift left accumulator */
6160 aopPut(AOP(result),"a",offr);
6163 /*-----------------------------------------------------------------*/
6164 /* movLeft2Result - move byte from left to result */
6165 /*-----------------------------------------------------------------*/
6166 static void movLeft2Result (operand *left, int offl,
6167 operand *result, int offr, int sign)
6170 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6171 if(!sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6172 l = aopGet(AOP(left),offl,FALSE,FALSE);
6174 if (*l == '@' && (IS_AOP_PREG(result))) {
6175 emitcode("mov","a,%s",l);
6176 aopPut(AOP(result),"a",offr);
6179 aopPut(AOP(result),l,offr);
6181 /* MSB sign in acc.7 ! */
6182 if(getDataSize(left) == offl+1){
6183 emitcode("mov","a,%s",l);
6184 aopPut(AOP(result),"a",offr);
6191 /*-----------------------------------------------------------------*/
6192 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
6193 /*-----------------------------------------------------------------*/
6194 static void AccAXRrl1 (char *x)
6196 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 emitcode("rrc","a");
6198 emitcode("xch","a,%s", x);
6199 emitcode("rrc","a");
6200 emitcode("xch","a,%s", x);
6203 /*-----------------------------------------------------------------*/
6204 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
6205 /*-----------------------------------------------------------------*/
6206 static void AccAXLrl1 (char *x)
6208 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6209 emitcode("xch","a,%s",x);
6210 emitcode("rlc","a");
6211 emitcode("xch","a,%s",x);
6212 emitcode("rlc","a");
6215 /*-----------------------------------------------------------------*/
6216 /* AccAXLsh1 - left shift a:x<-0 by 1 */
6217 /*-----------------------------------------------------------------*/
6218 static void AccAXLsh1 (char *x)
6220 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6221 emitcode("xch","a,%s",x);
6222 emitcode("add","a,acc");
6223 emitcode("xch","a,%s",x);
6224 emitcode("rlc","a");
6227 /*-----------------------------------------------------------------*/
6228 /* AccAXLsh - left shift a:x by known count (0..7) */
6229 /*-----------------------------------------------------------------*/
6230 static void AccAXLsh (char *x, int shCount)
6232 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6245 case 5 : // AAAAABBB:CCCCCDDD
6246 AccRol(shCount); // BBBAAAAA:CCCCCDDD
6247 emitcode("anl","a,#0x%02x",
6248 SLMask[shCount]); // BBB00000:CCCCCDDD
6249 emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
6250 AccRol(shCount); // DDDCCCCC:BBB00000
6251 emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
6252 emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
6253 emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
6254 emitcode("anl","a,#0x%02x",
6255 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
6256 emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
6257 emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
6259 case 6 : // AAAAAABB:CCCCCCDD
6260 emitcode("anl","a,#0x%02x",
6261 SRMask[shCount]); // 000000BB:CCCCCCDD
6262 emitcode("mov","c,acc.0"); // c = B
6263 emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
6264 AccAXRrl1(x); // BCCCCCCD:D000000B
6265 AccAXRrl1(x); // BBCCCCCC:DD000000
6267 case 7 : // a:x <<= 7
6268 emitcode("anl","a,#0x%02x",
6269 SRMask[shCount]); // 0000000B:CCCCCCCD
6270 emitcode("mov","c,acc.0"); // c = B
6271 emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
6272 AccAXRrl1(x); // BCCCCCCC:D0000000
6279 /*-----------------------------------------------------------------*/
6280 /* AccAXRsh - right shift a:x known count (0..7) */
6281 /*-----------------------------------------------------------------*/
6282 static void AccAXRsh (char *x, int shCount)
6284 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6290 AccAXRrl1(x); // 0->a:x
6294 AccAXRrl1(x); // 0->a:x
6296 AccAXRrl1(x); // 0->a:x
6300 case 5 : // AAAAABBB:CCCCCDDD = a:x
6301 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
6302 emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
6303 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
6304 emitcode("anl","a,#0x%02x",
6305 SRMask[shCount]); // 000CCCCC:BBBAAAAA
6306 emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
6307 emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
6308 emitcode("anl","a,#0x%02x",
6309 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
6310 emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
6311 emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
6312 emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
6314 case 6 : // AABBBBBB:CCDDDDDD
6315 emitcode("mov","c,acc.7");
6316 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
6317 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
6318 emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
6319 emitcode("anl","a,#0x%02x",
6320 SRMask[shCount]); // 000000AA:BBBBBBCC
6322 case 7 : // ABBBBBBB:CDDDDDDD
6323 emitcode("mov","c,acc.7"); // c = A
6324 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
6325 emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
6326 emitcode("anl","a,#0x%02x",
6327 SRMask[shCount]); // 0000000A:BBBBBBBC
6334 /*-----------------------------------------------------------------*/
6335 /* AccAXRshS - right shift signed a:x known count (0..7) */
6336 /*-----------------------------------------------------------------*/
6337 static void AccAXRshS (char *x, int shCount)
6340 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6345 emitcode("mov","c,acc.7");
6346 AccAXRrl1(x); // s->a:x
6349 emitcode("mov","c,acc.7");
6350 AccAXRrl1(x); // s->a:x
6351 emitcode("mov","c,acc.7");
6352 AccAXRrl1(x); // s->a:x
6356 case 5 : // AAAAABBB:CCCCCDDD = a:x
6357 tlbl = newiTempLabel(NULL);
6358 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
6359 emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
6360 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
6361 emitcode("anl","a,#0x%02x",
6362 SRMask[shCount]); // 000CCCCC:BBBAAAAA
6363 emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
6364 emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
6365 emitcode("anl","a,#0x%02x",
6366 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
6367 emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
6368 emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
6369 emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
6370 emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6371 emitcode("orl","a,#0x%02x",
6372 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
6373 emitcode("","%05d_DS_:",tlbl->key+100);
6374 break; // SSSSAAAA:BBBCCCCC
6375 case 6 : // AABBBBBB:CCDDDDDD
6376 tlbl = newiTempLabel(NULL);
6377 emitcode("mov","c,acc.7");
6378 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
6379 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
6380 emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
6381 emitcode("anl","a,#0x%02x",
6382 SRMask[shCount]); // 000000AA:BBBBBBCC
6383 emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6384 emitcode("orl","a,#0x%02x",
6385 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
6386 emitcode("","%05d_DS_:",tlbl->key+100);
6388 case 7 : // ABBBBBBB:CDDDDDDD
6389 tlbl = newiTempLabel(NULL);
6390 emitcode("mov","c,acc.7"); // c = A
6391 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
6392 emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
6393 emitcode("anl","a,#0x%02x",
6394 SRMask[shCount]); // 0000000A:BBBBBBBC
6395 emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6396 emitcode("orl","a,#0x%02x",
6397 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
6398 emitcode("","%05d_DS_:",tlbl->key+100);
6405 /*-----------------------------------------------------------------*/
6406 /* shiftL2Left2Result - shift left two bytes from left to result */
6407 /*-----------------------------------------------------------------*/
6408 static void shiftL2Left2Result (operand *left, int offl,
6409 operand *result, int offr, int shCount)
6411 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6412 if(sameRegs(AOP(result), AOP(left)) &&
6413 ((offl + MSB16) == offr)){
6414 /* don't crash result[offr] */
6415 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6416 emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6418 movLeft2Result(left,offl, result, offr, 0);
6419 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6421 /* ax << shCount (x = lsb(result))*/
6422 AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6423 aopPut(AOP(result),"a",offr+MSB16);
6427 /*-----------------------------------------------------------------*/
6428 /* shiftR2Left2Result - shift right two bytes from left to result */
6429 /*-----------------------------------------------------------------*/
6430 static void shiftR2Left2Result (operand *left, int offl,
6431 operand *result, int offr,
6432 int shCount, int sign)
6434 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6435 if(sameRegs(AOP(result), AOP(left)) &&
6436 ((offl + MSB16) == offr)){
6437 /* don't crash result[offr] */
6438 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6439 emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6441 movLeft2Result(left,offl, result, offr, 0);
6442 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6444 /* a:x >> shCount (x = lsb(result))*/
6446 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6448 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6449 if(getDataSize(result) > 1)
6450 aopPut(AOP(result),"a",offr+MSB16);
6453 /*-----------------------------------------------------------------*/
6454 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6455 /*-----------------------------------------------------------------*/
6456 static void shiftLLeftOrResult (operand *left, int offl,
6457 operand *result, int offr, int shCount)
6459 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6460 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6461 /* shift left accumulator */
6463 /* or with result */
6464 emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6465 /* back to result */
6466 aopPut(AOP(result),"a",offr);
6469 /*-----------------------------------------------------------------*/
6470 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6471 /*-----------------------------------------------------------------*/
6472 static void shiftRLeftOrResult (operand *left, int offl,
6473 operand *result, int offr, int shCount)
6475 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6476 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6477 /* shift right accumulator */
6479 /* or with result */
6480 emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6481 /* back to result */
6482 aopPut(AOP(result),"a",offr);
6485 /*-----------------------------------------------------------------*/
6486 /* genlshOne - left shift a one byte quantity by known count */
6487 /*-----------------------------------------------------------------*/
6488 static void genlshOne (operand *result, operand *left, int shCount)
6490 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6491 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6494 /*-----------------------------------------------------------------*/
6495 /* genlshTwo - left shift two bytes by known amount != 0 */
6496 /*-----------------------------------------------------------------*/
6497 static void genlshTwo (operand *result,operand *left, int shCount)
6501 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6502 size = getDataSize(result);
6504 /* if shCount >= 8 */
6510 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6512 movLeft2Result(left, LSB, result, MSB16, 0);
6514 aopPut(AOP(result),zero,LSB);
6517 /* 1 <= shCount <= 7 */
6520 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6522 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6526 /*-----------------------------------------------------------------*/
6527 /* shiftLLong - shift left one long from left to result */
6528 /* offl = LSB or MSB16 */
6529 /*-----------------------------------------------------------------*/
6530 static void shiftLLong (operand *left, operand *result, int offr )
6533 int size = AOP_SIZE(result);
6535 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6536 if(size >= LSB+offr){
6537 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6539 emitcode("add","a,acc");
6540 if (sameRegs(AOP(left),AOP(result)) &&
6541 size >= MSB16+offr && offr != LSB )
6542 emitcode("xch","a,%s",
6543 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6545 aopPut(AOP(result),"a",LSB+offr);
6548 if(size >= MSB16+offr){
6549 if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6550 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6553 emitcode("rlc","a");
6554 if (sameRegs(AOP(left),AOP(result)) &&
6555 size >= MSB24+offr && offr != LSB)
6556 emitcode("xch","a,%s",
6557 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6559 aopPut(AOP(result),"a",MSB16+offr);
6562 if(size >= MSB24+offr){
6563 if (!(sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6564 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6567 emitcode("rlc","a");
6568 if (sameRegs(AOP(left),AOP(result)) &&
6569 size >= MSB32+offr && offr != LSB )
6570 emitcode("xch","a,%s",
6571 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6573 aopPut(AOP(result),"a",MSB24+offr);
6576 if(size > MSB32+offr){
6577 if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6578 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6581 emitcode("rlc","a");
6582 aopPut(AOP(result),"a",MSB32+offr);
6585 aopPut(AOP(result),zero,LSB);
6588 /*-----------------------------------------------------------------*/
6589 /* genlshFour - shift four byte by a known amount != 0 */
6590 /*-----------------------------------------------------------------*/
6591 static void genlshFour (operand *result, operand *left, int shCount)
6595 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6596 size = AOP_SIZE(result);
6598 /* if shifting more that 3 bytes */
6599 if (shCount >= 24 ) {
6602 /* lowest order of left goes to the highest
6603 order of the destination */
6604 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6606 movLeft2Result(left, LSB, result, MSB32, 0);
6607 aopPut(AOP(result),zero,LSB);
6608 aopPut(AOP(result),zero,MSB16);
6609 aopPut(AOP(result),zero,MSB32);
6613 /* more than two bytes */
6614 else if ( shCount >= 16 ) {
6615 /* lower order two bytes goes to higher order two bytes */
6617 /* if some more remaining */
6619 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6621 movLeft2Result(left, MSB16, result, MSB32, 0);
6622 movLeft2Result(left, LSB, result, MSB24, 0);
6624 aopPut(AOP(result),zero,MSB16);
6625 aopPut(AOP(result),zero,LSB);
6629 /* if more than 1 byte */
6630 else if ( shCount >= 8 ) {
6631 /* lower order three bytes goes to higher order three bytes */
6635 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6637 movLeft2Result(left, LSB, result, MSB16, 0);
6639 else{ /* size = 4 */
6641 movLeft2Result(left, MSB24, result, MSB32, 0);
6642 movLeft2Result(left, MSB16, result, MSB24, 0);
6643 movLeft2Result(left, LSB, result, MSB16, 0);
6644 aopPut(AOP(result),zero,LSB);
6646 else if(shCount == 1)
6647 shiftLLong(left, result, MSB16);
6649 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6650 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6651 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6652 aopPut(AOP(result),zero,LSB);
6657 /* 1 <= shCount <= 7 */
6658 else if(shCount <= 2){
6659 shiftLLong(left, result, LSB);
6661 shiftLLong(result, result, LSB);
6663 /* 3 <= shCount <= 7, optimize */
6665 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6666 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6667 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6671 /*-----------------------------------------------------------------*/
6672 /* genLeftShiftLiteral - left shifting by known count */
6673 /*-----------------------------------------------------------------*/
6674 static void genLeftShiftLiteral (operand *left,
6679 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6682 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6683 freeAsmop(right,NULL,ic,TRUE);
6685 aopOp(left,ic,FALSE);
6686 aopOp(result,ic,FALSE);
6688 size = getSize(operandType(result));
6691 emitcode("; shift left ","result %d, left %d",size,
6695 /* I suppose that the left size >= result size */
6698 movLeft2Result(left, size, result, size, 0);
6702 else if(shCount >= (size * 8))
6704 aopPut(AOP(result),zero,size);
6708 genlshOne (result,left,shCount);
6713 genlshTwo (result,left,shCount);
6717 genlshFour (result,left,shCount);
6721 freeAsmop(left,NULL,ic,TRUE);
6722 freeAsmop(result,NULL,ic,TRUE);
6725 /*-----------------------------------------------------------------*/
6726 /* genLeftShift - generates code for left shifting */
6727 /*-----------------------------------------------------------------*/
6728 static void genLeftShift (iCode *ic)
6730 operand *left,*right, *result;
6733 symbol *tlbl , *tlbl1;
6735 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6737 right = IC_RIGHT(ic);
6739 result = IC_RESULT(ic);
6741 aopOp(right,ic,FALSE);
6743 /* if the shift count is known then do it
6744 as efficiently as possible */
6745 if (AOP_TYPE(right) == AOP_LIT) {
6746 genLeftShiftLiteral (left,right,result,ic);
6750 /* shift count is unknown then we have to form
6751 a loop get the loop count in B : Note: we take
6752 only the lower order byte since shifting
6753 more that 32 bits make no sense anyway, ( the
6754 largest size of an object can be only 32 bits ) */
6756 emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6757 emitcode("inc","b");
6758 freeAsmop (right,NULL,ic,TRUE);
6759 aopOp(left,ic,FALSE);
6760 aopOp(result,ic,FALSE);
6762 /* now move the left to the result if they are not the
6764 if (!sameRegs(AOP(left),AOP(result)) &&
6765 AOP_SIZE(result) > 1) {
6767 size = AOP_SIZE(result);
6770 l = aopGet(AOP(left),offset,FALSE,TRUE);
6771 if (*l == '@' && (IS_AOP_PREG(result))) {
6773 emitcode("mov","a,%s",l);
6774 aopPut(AOP(result),"a",offset);
6776 aopPut(AOP(result),l,offset);
6781 tlbl = newiTempLabel(NULL);
6782 size = AOP_SIZE(result);
6784 tlbl1 = newiTempLabel(NULL);
6786 /* if it is only one byte then */
6788 symbol *tlbl1 = newiTempLabel(NULL);
6790 l = aopGet(AOP(left),0,FALSE,FALSE);
6792 emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6793 emitcode("","%05d_DS_:",tlbl->key+100);
6794 emitcode("add","a,acc");
6795 emitcode("","%05d_DS_:",tlbl1->key+100);
6796 emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6797 aopPut(AOP(result),"a",0);
6801 reAdjustPreg(AOP(result));
6803 emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6804 emitcode("","%05d_DS_:",tlbl->key+100);
6805 l = aopGet(AOP(result),offset,FALSE,FALSE);
6807 emitcode("add","a,acc");
6808 aopPut(AOP(result),"a",offset++);
6810 l = aopGet(AOP(result),offset,FALSE,FALSE);
6812 emitcode("rlc","a");
6813 aopPut(AOP(result),"a",offset++);
6815 reAdjustPreg(AOP(result));
6817 emitcode("","%05d_DS_:",tlbl1->key+100);
6818 emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6820 freeAsmop(left,NULL,ic,TRUE);
6821 freeAsmop(result,NULL,ic,TRUE);
6824 /*-----------------------------------------------------------------*/
6825 /* genrshOne - right shift a one byte quantity by known count */
6826 /*-----------------------------------------------------------------*/
6827 static void genrshOne (operand *result, operand *left,
6828 int shCount, int sign)
6830 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6831 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6834 /*-----------------------------------------------------------------*/
6835 /* genrshTwo - right shift two bytes by known amount != 0 */
6836 /*-----------------------------------------------------------------*/
6837 static void genrshTwo (operand *result,operand *left,
6838 int shCount, int sign)
6840 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6841 /* if shCount >= 8 */
6845 shiftR1Left2Result(left, MSB16, result, LSB,
6848 movLeft2Result(left, MSB16, result, LSB, sign);
6849 addSign(result, MSB16, sign);
6852 /* 1 <= shCount <= 7 */
6854 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6857 /*-----------------------------------------------------------------*/
6858 /* shiftRLong - shift right one long from left to result */
6859 /* offl = LSB or MSB16 */
6860 /*-----------------------------------------------------------------*/
6861 static void shiftRLong (operand *left, int offl,
6862 operand *result, int sign)
6864 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6866 emitcode("clr","c");
6867 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6869 emitcode("mov","c,acc.7");
6870 emitcode("rrc","a");
6871 aopPut(AOP(result),"a",MSB32-offl);
6873 /* add sign of "a" */
6874 addSign(result, MSB32, sign);
6876 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6877 emitcode("rrc","a");
6878 aopPut(AOP(result),"a",MSB24-offl);
6880 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6881 emitcode("rrc","a");
6882 aopPut(AOP(result),"a",MSB16-offl);
6885 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6886 emitcode("rrc","a");
6887 aopPut(AOP(result),"a",LSB);
6891 /*-----------------------------------------------------------------*/
6892 /* genrshFour - shift four byte by a known amount != 0 */
6893 /*-----------------------------------------------------------------*/
6894 static void genrshFour (operand *result, operand *left,
6895 int shCount, int sign)
6897 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6898 /* if shifting more that 3 bytes */
6899 if(shCount >= 24 ) {
6902 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6904 movLeft2Result(left, MSB32, result, LSB, sign);
6905 addSign(result, MSB16, sign);
6907 else if(shCount >= 16){
6910 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6912 movLeft2Result(left, MSB24, result, LSB, 0);
6913 movLeft2Result(left, MSB32, result, MSB16, sign);
6915 addSign(result, MSB24, sign);
6917 else if(shCount >= 8){
6920 shiftRLong(left, MSB16, result, sign);
6921 else if(shCount == 0){
6922 movLeft2Result(left, MSB16, result, LSB, 0);
6923 movLeft2Result(left, MSB24, result, MSB16, 0);
6924 movLeft2Result(left, MSB32, result, MSB24, sign);
6925 addSign(result, MSB32, sign);
6928 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6929 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6930 /* the last shift is signed */
6931 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6932 addSign(result, MSB32, sign);
6935 else{ /* 1 <= shCount <= 7 */
6937 shiftRLong(left, LSB, result, sign);
6939 shiftRLong(result, LSB, result, sign);
6942 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6943 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6944 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6949 /*-----------------------------------------------------------------*/
6950 /* genRightShiftLiteral - right shifting by known count */
6951 /*-----------------------------------------------------------------*/
6952 static void genRightShiftLiteral (operand *left,
6958 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6961 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6962 freeAsmop(right,NULL,ic,TRUE);
6964 aopOp(left,ic,FALSE);
6965 aopOp(result,ic,FALSE);
6968 emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6972 size = getDataSize(left);
6973 /* test the LEFT size !!! */
6975 /* I suppose that the left size >= result size */
6977 size = getDataSize(result);
6979 movLeft2Result(left, size, result, size, 0);
6982 else if(shCount >= (size * 8)){
6984 /* get sign in acc.7 */
6985 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6986 addSign(result, LSB, sign);
6990 genrshOne (result,left,shCount,sign);
6994 genrshTwo (result,left,shCount,sign);
6998 genrshFour (result,left,shCount,sign);
7004 freeAsmop(left,NULL,ic,TRUE);
7005 freeAsmop(result,NULL,ic,TRUE);
7009 /*-----------------------------------------------------------------*/
7010 /* genSignedRightShift - right shift of signed number */
7011 /*-----------------------------------------------------------------*/
7012 static void genSignedRightShift (iCode *ic)
7014 operand *right, *left, *result;
7017 symbol *tlbl, *tlbl1 ;
7019 /* we do it the hard way put the shift count in b
7020 and loop thru preserving the sign */
7021 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7023 right = IC_RIGHT(ic);
7025 result = IC_RESULT(ic);
7027 aopOp(right,ic,FALSE);
7030 if ( AOP_TYPE(right) == AOP_LIT) {
7031 genRightShiftLiteral (left,right,result,ic,1);
7034 /* shift count is unknown then we have to form
7035 a loop get the loop count in B : Note: we take
7036 only the lower order byte since shifting
7037 more that 32 bits make no sense anyway, ( the
7038 largest size of an object can be only 32 bits ) */
7040 emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7041 emitcode("inc","b");
7042 freeAsmop (right,NULL,ic,TRUE);
7043 aopOp(left,ic,FALSE);
7044 aopOp(result,ic,FALSE);
7046 /* now move the left to the result if they are not the
7048 if (!sameRegs(AOP(left),AOP(result)) &&
7049 AOP_SIZE(result) > 1) {
7051 size = AOP_SIZE(result);
7054 l = aopGet(AOP(left),offset,FALSE,TRUE);
7055 if (*l == '@' && IS_AOP_PREG(result)) {
7057 emitcode("mov","a,%s",l);
7058 aopPut(AOP(result),"a",offset);
7060 aopPut(AOP(result),l,offset);
7065 /* mov the highest order bit to OVR */
7066 tlbl = newiTempLabel(NULL);
7067 tlbl1= newiTempLabel(NULL);
7069 size = AOP_SIZE(result);
7071 emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7072 emitcode("rlc","a");
7073 emitcode("mov","ov,c");
7074 /* if it is only one byte then */
7076 l = aopGet(AOP(left),0,FALSE,FALSE);
7078 emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7079 emitcode("","%05d_DS_:",tlbl->key+100);
7080 emitcode("mov","c,ov");
7081 emitcode("rrc","a");
7082 emitcode("","%05d_DS_:",tlbl1->key+100);
7083 emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7084 aopPut(AOP(result),"a",0);
7088 reAdjustPreg(AOP(result));
7089 emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7090 emitcode("","%05d_DS_:",tlbl->key+100);
7091 emitcode("mov","c,ov");
7093 l = aopGet(AOP(result),offset,FALSE,FALSE);
7095 emitcode("rrc","a");
7096 aopPut(AOP(result),"a",offset--);
7098 reAdjustPreg(AOP(result));
7099 emitcode("","%05d_DS_:",tlbl1->key+100);
7100 emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7103 freeAsmop(left,NULL,ic,TRUE);
7104 freeAsmop(result,NULL,ic,TRUE);
7107 /*-----------------------------------------------------------------*/
7108 /* genRightShift - generate code for right shifting */
7109 /*-----------------------------------------------------------------*/
7110 static void genRightShift (iCode *ic)
7112 operand *right, *left, *result;
7116 symbol *tlbl, *tlbl1 ;
7118 /* if signed then we do it the hard way preserve the
7119 sign bit moving it inwards */
7120 retype = getSpec(operandType(IC_RESULT(ic)));
7121 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7123 if (!SPEC_USIGN(retype)) {
7124 genSignedRightShift (ic);
7128 /* signed & unsigned types are treated the same : i.e. the
7129 signed is NOT propagated inwards : quoting from the
7130 ANSI - standard : "for E1 >> E2, is equivalent to division
7131 by 2**E2 if unsigned or if it has a non-negative value,
7132 otherwise the result is implementation defined ", MY definition
7133 is that the sign does not get propagated */
7135 right = IC_RIGHT(ic);
7137 result = IC_RESULT(ic);
7139 aopOp(right,ic,FALSE);
7141 /* if the shift count is known then do it
7142 as efficiently as possible */
7143 if (AOP_TYPE(right) == AOP_LIT) {
7144 genRightShiftLiteral (left,right,result,ic, 0);
7148 /* shift count is unknown then we have to form
7149 a loop get the loop count in B : Note: we take
7150 only the lower order byte since shifting
7151 more that 32 bits make no sense anyway, ( the
7152 largest size of an object can be only 32 bits ) */
7154 emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7155 emitcode("inc","b");
7156 freeAsmop (right,NULL,ic,TRUE);
7157 aopOp(left,ic,FALSE);
7158 aopOp(result,ic,FALSE);
7160 /* now move the left to the result if they are not the
7162 if (!sameRegs(AOP(left),AOP(result)) &&
7163 AOP_SIZE(result) > 1) {
7165 size = AOP_SIZE(result);
7168 l = aopGet(AOP(left),offset,FALSE,TRUE);
7169 if (*l == '@' && IS_AOP_PREG(result)) {
7171 emitcode("mov","a,%s",l);
7172 aopPut(AOP(result),"a",offset);
7174 aopPut(AOP(result),l,offset);
7179 tlbl = newiTempLabel(NULL);
7180 tlbl1= newiTempLabel(NULL);
7181 size = AOP_SIZE(result);
7184 /* if it is only one byte then */
7186 l = aopGet(AOP(left),0,FALSE,FALSE);
7188 emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7189 emitcode("","%05d_DS_:",tlbl->key+100);
7191 emitcode("rrc","a");
7192 emitcode("","%05d_DS_:",tlbl1->key+100);
7193 emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7194 aopPut(AOP(result),"a",0);
7198 reAdjustPreg(AOP(result));
7199 emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7200 emitcode("","%05d_DS_:",tlbl->key+100);
7203 l = aopGet(AOP(result),offset,FALSE,FALSE);
7205 emitcode("rrc","a");
7206 aopPut(AOP(result),"a",offset--);
7208 reAdjustPreg(AOP(result));
7210 emitcode("","%05d_DS_:",tlbl1->key+100);
7211 emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7214 freeAsmop(left,NULL,ic,TRUE);
7215 freeAsmop(result,NULL,ic,TRUE);
7218 /*-----------------------------------------------------------------*/
7219 /* genUnpackBits - generates code for unpacking bits */
7220 /*-----------------------------------------------------------------*/
7221 static void genUnpackBits (operand *result, char *rname, int ptype)
7228 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7229 etype = getSpec(operandType(result));
7231 /* read the first byte */
7236 emitcode("mov","a,@%s",rname);
7240 emitcode("movx","a,@%s",rname);
7244 emitcode("movx","a,@dptr");
7248 emitcode("clr","a");
7249 emitcode("movc","a","@a+dptr");
7253 emitcode("lcall","__gptrget");
7257 /* if we have bitdisplacement then it fits */
7258 /* into this byte completely or if length is */
7259 /* less than a byte */
7260 if ((shCnt = SPEC_BSTR(etype)) ||
7261 (SPEC_BLEN(etype) <= 8)) {
7263 /* shift right acc */
7266 emitcode("anl","a,#0x%02x",
7267 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7268 aopPut(AOP(result),"a",offset);
7272 /* bit field did not fit in a byte */
7273 rlen = SPEC_BLEN(etype) - 8;
7274 aopPut(AOP(result),"a",offset++);
7281 emitcode("inc","%s",rname);
7282 emitcode("mov","a,@%s",rname);
7286 emitcode("inc","%s",rname);
7287 emitcode("movx","a,@%s",rname);
7291 emitcode("inc","dptr");
7292 emitcode("movx","a,@dptr");
7296 emitcode("clr","a");
7297 emitcode("inc","dptr");
7298 emitcode("movc","a","@a+dptr");
7302 emitcode("inc","dptr");
7303 emitcode("lcall","__gptrget");
7308 /* if we are done */
7312 aopPut(AOP(result),"a",offset++);
7317 emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7318 aopPut(AOP(result),"a",offset);
7325 /*-----------------------------------------------------------------*/
7326 /* genDataPointerGet - generates code when ptr offset is known */
7327 /*-----------------------------------------------------------------*/
7328 static void genDataPointerGet (operand *left,
7334 int size , offset = 0;
7335 aopOp(result,ic,TRUE);
7337 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7339 /* get the string representation of the name */
7340 l = aopGet(AOP(left),0,FALSE,TRUE);
7341 size = AOP_SIZE(result);
7342 // tsd, was l+1 - the underline `_' prefix was being stripped
7345 sprintf(buffer,"(%s + %d)",l,offset);
7347 sprintf(buffer,"%s",l);
7348 aopPut(AOP(result),buffer,offset++);
7351 freeAsmop(left,NULL,ic,TRUE);
7352 freeAsmop(result,NULL,ic,TRUE);
7355 /*-----------------------------------------------------------------*/
7356 /* genNearPointerGet - emitcode for near pointer fetch */
7357 /*-----------------------------------------------------------------*/
7358 static void genNearPointerGet (operand *left,
7365 sym_link *rtype, *retype;
7366 sym_link *ltype = operandType(left);
7369 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7371 rtype = operandType(result);
7372 retype= getSpec(rtype);
7374 aopOp(left,ic,FALSE);
7376 /* if left is rematerialisable and
7377 result is not bit variable type and
7378 the left is pointer to data space i.e
7379 lower 128 bytes of space */
7380 if (AOP_TYPE(left) == AOP_IMMD &&
7381 !IS_BITVAR(retype) &&
7382 DCL_TYPE(ltype) == POINTER) {
7383 genDataPointerGet (left,result,ic);
7387 /* if the value is already in a pointer register
7388 then don't need anything more */
7389 if (!AOP_INPREG(AOP(left))) {
7390 /* otherwise get a free pointer register */
7392 preg = getFreePtr(ic,&aop,FALSE);
7393 emitcode("mov","%s,%s",
7395 aopGet(AOP(left),0,FALSE,TRUE));
7396 rname = preg->name ;
7398 rname = aopGet(AOP(left),0,FALSE,FALSE);
7400 freeAsmop(left,NULL,ic,TRUE);
7401 aopOp (result,ic,FALSE);
7403 /* if bitfield then unpack the bits */
7404 if (IS_BITVAR(retype))
7405 genUnpackBits (result,rname,POINTER);
7407 /* we have can just get the values */
7408 int size = AOP_SIZE(result);
7412 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7414 emitcode("mov","a,@%s",rname);
7415 aopPut(AOP(result),"a",offset);
7417 sprintf(buffer,"@%s",rname);
7418 aopPut(AOP(result),buffer,offset);
7422 emitcode("inc","%s",rname);
7426 /* now some housekeeping stuff */
7428 /* we had to allocate for this iCode */
7429 freeAsmop(NULL,aop,ic,TRUE);
7431 /* we did not allocate which means left
7432 already in a pointer register, then
7433 if size > 0 && this could be used again
7434 we have to point it back to where it
7436 if (AOP_SIZE(result) > 1 &&
7437 !OP_SYMBOL(left)->remat &&
7438 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7440 int size = AOP_SIZE(result) - 1;
7442 emitcode("dec","%s",rname);
7447 freeAsmop(result,NULL,ic,TRUE);
7451 /*-----------------------------------------------------------------*/
7452 /* genPagedPointerGet - emitcode for paged pointer fetch */
7453 /*-----------------------------------------------------------------*/
7454 static void genPagedPointerGet (operand *left,
7461 sym_link *rtype, *retype;
7463 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7465 rtype = operandType(result);
7466 retype= getSpec(rtype);
7468 aopOp(left,ic,FALSE);
7470 /* if the value is already in a pointer register
7471 then don't need anything more */
7472 if (!AOP_INPREG(AOP(left))) {
7473 /* otherwise get a free pointer register */
7475 preg = getFreePtr(ic,&aop,FALSE);
7476 emitcode("mov","%s,%s",
7478 aopGet(AOP(left),0,FALSE,TRUE));
7479 rname = preg->name ;
7481 rname = aopGet(AOP(left),0,FALSE,FALSE);
7483 freeAsmop(left,NULL,ic,TRUE);
7484 aopOp (result,ic,FALSE);
7486 /* if bitfield then unpack the bits */
7487 if (IS_BITVAR(retype))
7488 genUnpackBits (result,rname,PPOINTER);
7490 /* we have can just get the values */
7491 int size = AOP_SIZE(result);
7496 emitcode("movx","a,@%s",rname);
7497 aopPut(AOP(result),"a",offset);
7502 emitcode("inc","%s",rname);
7506 /* now some housekeeping stuff */
7508 /* we had to allocate for this iCode */
7509 freeAsmop(NULL,aop,ic,TRUE);
7511 /* we did not allocate which means left
7512 already in a pointer register, then
7513 if size > 0 && this could be used again
7514 we have to point it back to where it
7516 if (AOP_SIZE(result) > 1 &&
7517 !OP_SYMBOL(left)->remat &&
7518 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7520 int size = AOP_SIZE(result) - 1;
7522 emitcode("dec","%s",rname);
7527 freeAsmop(result,NULL,ic,TRUE);
7532 /*-----------------------------------------------------------------*/
7533 /* genFarPointerGet - gget value from far space */
7534 /*-----------------------------------------------------------------*/
7535 static void genFarPointerGet (operand *left,
7536 operand *result, iCode *ic)
7539 sym_link *retype = getSpec(operandType(result));
7541 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7543 aopOp(left,ic,FALSE);
7545 /* if the operand is already in dptr
7546 then we do nothing else we move the value to dptr */
7547 if (AOP_TYPE(left) != AOP_STR) {
7548 /* if this is remateriazable */
7549 if (AOP_TYPE(left) == AOP_IMMD)
7550 emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7551 else { /* we need to get it byte by byte */
7552 emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7553 emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7554 if (options.model == MODEL_FLAT24)
7556 emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7560 /* so dptr know contains the address */
7561 freeAsmop(left,NULL,ic,TRUE);
7562 aopOp(result,ic,FALSE);
7564 /* if bit then unpack */
7565 if (IS_BITVAR(retype))
7566 genUnpackBits(result,"dptr",FPOINTER);
7568 size = AOP_SIZE(result);
7572 emitcode("movx","a,@dptr");
7573 aopPut(AOP(result),"a",offset++);
7575 emitcode("inc","dptr");
7579 freeAsmop(result,NULL,ic,TRUE);
7582 /*-----------------------------------------------------------------*/
7583 /* emitcodePointerGet - gget value from code space */
7584 /*-----------------------------------------------------------------*/
7585 static void emitcodePointerGet (operand *left,
7586 operand *result, iCode *ic)
7589 sym_link *retype = getSpec(operandType(result));
7591 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7593 aopOp(left,ic,FALSE);
7595 /* if the operand is already in dptr
7596 then we do nothing else we move the value to dptr */
7597 if (AOP_TYPE(left) != AOP_STR) {
7598 /* if this is remateriazable */
7599 if (AOP_TYPE(left) == AOP_IMMD)
7600 emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7601 else { /* we need to get it byte by byte */
7602 emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7603 emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7604 if (options.model == MODEL_FLAT24)
7606 emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7610 /* so dptr know contains the address */
7611 freeAsmop(left,NULL,ic,TRUE);
7612 aopOp(result,ic,FALSE);
7614 /* if bit then unpack */
7615 if (IS_BITVAR(retype))
7616 genUnpackBits(result,"dptr",CPOINTER);
7618 size = AOP_SIZE(result);
7622 emitcode("clr","a");
7623 emitcode("movc","a,@a+dptr");
7624 aopPut(AOP(result),"a",offset++);
7626 emitcode("inc","dptr");
7630 freeAsmop(result,NULL,ic,TRUE);
7633 /*-----------------------------------------------------------------*/
7634 /* genGenPointerGet - gget value from generic pointer space */
7635 /*-----------------------------------------------------------------*/
7636 static void genGenPointerGet (operand *left,
7637 operand *result, iCode *ic)
7640 sym_link *retype = getSpec(operandType(result));
7642 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7643 aopOp(left,ic,FALSE);
7645 /* if the operand is already in dptr
7646 then we do nothing else we move the value to dptr */
7647 if (AOP_TYPE(left) != AOP_STR) {
7648 /* if this is remateriazable */
7649 if (AOP_TYPE(left) == AOP_IMMD) {
7650 emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7651 emitcode("mov","b,#%d",pointerCode(retype));
7653 else { /* we need to get it byte by byte */
7655 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7656 emitpcode(POC_MOVWF,popCopy(&pc_fsr));
7657 emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7658 emitcode("movwf","FSR");
7660 emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7661 emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7662 if (options.model == MODEL_FLAT24)
7664 emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7665 emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7669 emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7674 /* so dptr know contains the address */
7675 freeAsmop(left,NULL,ic,TRUE);
7676 aopOp(result,ic,FALSE);
7678 /* if bit then unpack */
7679 if (IS_BITVAR(retype))
7680 genUnpackBits(result,"dptr",GPOINTER);
7682 size = AOP_SIZE(result);
7686 emitpcode(POC_MOVFW,popCopy(&pc_fsr));
7687 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7689 emitpcode(POC_INCF,popCopy(&pc_fsr));
7691 emitcode("movf","indf,w");
7692 emitcode("movwf","%s",
7693 aopGet(AOP(result),offset++,FALSE,FALSE));
7695 emitcode("incf","fsr,f");
7700 freeAsmop(result,NULL,ic,TRUE);
7703 /*-----------------------------------------------------------------*/
7704 /* genPointerGet - generate code for pointer get */
7705 /*-----------------------------------------------------------------*/
7706 static void genPointerGet (iCode *ic)
7708 operand *left, *result ;
7709 sym_link *type, *etype;
7712 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7715 result = IC_RESULT(ic) ;
7717 /* depending on the type of pointer we need to
7718 move it to the correct pointer register */
7719 type = operandType(left);
7720 etype = getSpec(type);
7721 /* if left is of type of pointer then it is simple */
7722 if (IS_PTR(type) && !IS_FUNC(type->next))
7723 p_type = DCL_TYPE(type);
7725 /* we have to go by the storage class */
7726 p_type = PTR_TYPE(SPEC_OCLS(etype));
7728 /* if (SPEC_OCLS(etype)->codesp ) { */
7729 /* p_type = CPOINTER ; */
7732 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7733 /* p_type = FPOINTER ; */
7735 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7736 /* p_type = PPOINTER; */
7738 /* if (SPEC_OCLS(etype) == idata ) */
7739 /* p_type = IPOINTER; */
7741 /* p_type = POINTER ; */
7744 /* now that we have the pointer type we assign
7745 the pointer values */
7750 genNearPointerGet (left,result,ic);
7754 genPagedPointerGet(left,result,ic);
7758 genFarPointerGet (left,result,ic);
7762 emitcodePointerGet (left,result,ic);
7766 genGenPointerGet (left,result,ic);
7772 /*-----------------------------------------------------------------*/
7773 /* genPackBits - generates code for packed bit storage */
7774 /*-----------------------------------------------------------------*/
7775 static void genPackBits (sym_link *etype ,
7777 char *rname, int p_type)
7785 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7786 blen = SPEC_BLEN(etype);
7787 bstr = SPEC_BSTR(etype);
7789 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7792 /* if the bit lenth is less than or */
7793 /* it exactly fits a byte then */
7794 if (SPEC_BLEN(etype) <= 8 ) {
7795 shCount = SPEC_BSTR(etype) ;
7797 /* shift left acc */
7800 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7805 emitcode ("mov","b,a");
7806 emitcode("mov","a,@%s",rname);
7810 emitcode ("mov","b,a");
7811 emitcode("movx","a,@dptr");
7815 emitcode ("push","b");
7816 emitcode ("push","acc");
7817 emitcode ("lcall","__gptrget");
7818 emitcode ("pop","b");
7822 emitcode ("anl","a,#0x%02x",(unsigned char)
7823 ((unsigned char)(0xFF << (blen+bstr)) |
7824 (unsigned char)(0xFF >> (8-bstr)) ) );
7825 emitcode ("orl","a,b");
7826 if (p_type == GPOINTER)
7827 emitcode("pop","b");
7833 emitcode("mov","@%s,a",rname);
7837 emitcode("movx","@dptr,a");
7841 DEBUGemitcode(";lcall","__gptrput");
7846 if ( SPEC_BLEN(etype) <= 8 )
7849 emitcode("inc","%s",rname);
7850 rLen = SPEC_BLEN(etype) ;
7852 /* now generate for lengths greater than one byte */
7855 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7865 emitcode("mov","@%s,a",rname);
7867 emitcode("mov","@%s,%s",rname,l);
7872 emitcode("movx","@dptr,a");
7877 DEBUGemitcode(";lcall","__gptrput");
7880 emitcode ("inc","%s",rname);
7885 /* last last was not complete */
7887 /* save the byte & read byte */
7890 emitcode ("mov","b,a");
7891 emitcode("mov","a,@%s",rname);
7895 emitcode ("mov","b,a");
7896 emitcode("movx","a,@dptr");
7900 emitcode ("push","b");
7901 emitcode ("push","acc");
7902 emitcode ("lcall","__gptrget");
7903 emitcode ("pop","b");
7907 emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7908 emitcode ("orl","a,b");
7911 if (p_type == GPOINTER)
7912 emitcode("pop","b");
7917 emitcode("mov","@%s,a",rname);
7921 emitcode("movx","@dptr,a");
7925 DEBUGemitcode(";lcall","__gptrput");
7929 /*-----------------------------------------------------------------*/
7930 /* genDataPointerSet - remat pointer to data space */
7931 /*-----------------------------------------------------------------*/
7932 static void genDataPointerSet(operand *right,
7936 int size, offset = 0 ;
7937 char *l, buffer[256];
7939 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7940 aopOp(right,ic,FALSE);
7942 l = aopGet(AOP(result),0,FALSE,TRUE);
7943 size = AOP_SIZE(right);
7944 // tsd, was l+1 - the underline `_' prefix was being stripped
7947 sprintf(buffer,"(%s + %d)",l,offset);
7949 sprintf(buffer,"%s",l);
7951 if (AOP_TYPE(right) == AOP_LIT) {
7952 unsigned int lit = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7953 lit = lit >> (8*offset);
7955 emitcode("movlw","%s",lit);
7956 emitcode("movwf","%s",buffer);
7958 emitcode("clrf","%s",buffer);
7960 emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7961 emitcode("movwf","%s",buffer);
7967 freeAsmop(right,NULL,ic,TRUE);
7968 freeAsmop(result,NULL,ic,TRUE);
7971 /*-----------------------------------------------------------------*/
7972 /* genNearPointerSet - emitcode for near pointer put */
7973 /*-----------------------------------------------------------------*/
7974 static void genNearPointerSet (operand *right,
7981 sym_link *ptype = operandType(result);
7984 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7985 retype= getSpec(operandType(right));
7987 aopOp(result,ic,FALSE);
7989 /* if the result is rematerializable &
7990 in data space & not a bit variable */
7991 if (AOP_TYPE(result) == AOP_IMMD &&
7992 DCL_TYPE(ptype) == POINTER &&
7993 !IS_BITVAR(retype)) {
7994 genDataPointerSet (right,result,ic);
7998 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8000 /* if the value is already in a pointer register
8001 then don't need anything more */
8002 if (!AOP_INPREG(AOP(result))) {
8003 /* otherwise get a free pointer register */
8004 //aop = newAsmop(0);
8005 //preg = getFreePtr(ic,&aop,FALSE);
8006 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8007 //emitcode("mov","%s,%s",
8009 // aopGet(AOP(result),0,FALSE,TRUE));
8010 //rname = preg->name ;
8011 emitcode("movwf","fsr");
8013 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8015 freeAsmop(result,NULL,ic,TRUE);
8016 aopOp (right,ic,FALSE);
8017 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 /* if bitfield then unpack the bits */
8020 if (IS_BITVAR(retype)) {
8021 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8022 "The programmer is obviously confused");
8023 //genPackBits (retype,right,rname,POINTER);
8027 /* we have can just get the values */
8028 int size = AOP_SIZE(right);
8031 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8033 l = aopGet(AOP(right),offset,FALSE,TRUE);
8036 //emitcode("mov","@%s,a",rname);
8037 emitcode("movf","indf,w ;1");
8040 if (AOP_TYPE(right) == AOP_LIT) {
8041 unsigned int lit = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8043 emitcode("movlw","%s",l);
8044 emitcode("movwf","indf ;2");
8046 emitcode("clrf","indf");
8048 emitcode("movf","%s,w",l);
8049 emitcode("movwf","indf ;2");
8051 //emitcode("mov","@%s,%s",rname,l);
8054 emitcode("incf","fsr,f ;3");
8055 //emitcode("inc","%s",rname);
8060 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8061 /* now some housekeeping stuff */
8063 /* we had to allocate for this iCode */
8064 freeAsmop(NULL,aop,ic,TRUE);
8066 /* we did not allocate which means left
8067 already in a pointer register, then
8068 if size > 0 && this could be used again
8069 we have to point it back to where it
8071 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8072 if (AOP_SIZE(right) > 1 &&
8073 !OP_SYMBOL(result)->remat &&
8074 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8076 int size = AOP_SIZE(right) - 1;
8078 emitcode("decf","fsr,f");
8079 //emitcode("dec","%s",rname);
8083 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8085 freeAsmop(right,NULL,ic,TRUE);
8090 /*-----------------------------------------------------------------*/
8091 /* genPagedPointerSet - emitcode for Paged pointer put */
8092 /*-----------------------------------------------------------------*/
8093 static void genPagedPointerSet (operand *right,
8102 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8104 retype= getSpec(operandType(right));
8106 aopOp(result,ic,FALSE);
8108 /* if the value is already in a pointer register
8109 then don't need anything more */
8110 if (!AOP_INPREG(AOP(result))) {
8111 /* otherwise get a free pointer register */
8113 preg = getFreePtr(ic,&aop,FALSE);
8114 emitcode("mov","%s,%s",
8116 aopGet(AOP(result),0,FALSE,TRUE));
8117 rname = preg->name ;
8119 rname = aopGet(AOP(result),0,FALSE,FALSE);
8121 freeAsmop(result,NULL,ic,TRUE);
8122 aopOp (right,ic,FALSE);
8124 /* if bitfield then unpack the bits */
8125 if (IS_BITVAR(retype))
8126 genPackBits (retype,right,rname,PPOINTER);
8128 /* we have can just get the values */
8129 int size = AOP_SIZE(right);
8133 l = aopGet(AOP(right),offset,FALSE,TRUE);
8136 emitcode("movx","@%s,a",rname);
8139 emitcode("inc","%s",rname);
8145 /* now some housekeeping stuff */
8147 /* we had to allocate for this iCode */
8148 freeAsmop(NULL,aop,ic,TRUE);
8150 /* we did not allocate which means left
8151 already in a pointer register, then
8152 if size > 0 && this could be used again
8153 we have to point it back to where it
8155 if (AOP_SIZE(right) > 1 &&
8156 !OP_SYMBOL(result)->remat &&
8157 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8159 int size = AOP_SIZE(right) - 1;
8161 emitcode("dec","%s",rname);
8166 freeAsmop(right,NULL,ic,TRUE);
8171 /*-----------------------------------------------------------------*/
8172 /* genFarPointerSet - set value from far space */
8173 /*-----------------------------------------------------------------*/
8174 static void genFarPointerSet (operand *right,
8175 operand *result, iCode *ic)
8178 sym_link *retype = getSpec(operandType(right));
8180 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8181 aopOp(result,ic,FALSE);
8183 /* if the operand is already in dptr
8184 then we do nothing else we move the value to dptr */
8185 if (AOP_TYPE(result) != AOP_STR) {
8186 /* if this is remateriazable */
8187 if (AOP_TYPE(result) == AOP_IMMD)
8188 emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8189 else { /* we need to get it byte by byte */
8190 emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8191 emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8192 if (options.model == MODEL_FLAT24)
8194 emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8198 /* so dptr know contains the address */
8199 freeAsmop(result,NULL,ic,TRUE);
8200 aopOp(right,ic,FALSE);
8202 /* if bit then unpack */
8203 if (IS_BITVAR(retype))
8204 genPackBits(retype,right,"dptr",FPOINTER);
8206 size = AOP_SIZE(right);
8210 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8212 emitcode("movx","@dptr,a");
8214 emitcode("inc","dptr");
8218 freeAsmop(right,NULL,ic,TRUE);
8221 /*-----------------------------------------------------------------*/
8222 /* genGenPointerSet - set value from generic pointer space */
8223 /*-----------------------------------------------------------------*/
8224 static void genGenPointerSet (operand *right,
8225 operand *result, iCode *ic)
8228 sym_link *retype = getSpec(operandType(right));
8230 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8232 aopOp(result,ic,FALSE);
8234 /* if the operand is already in dptr
8235 then we do nothing else we move the value to dptr */
8236 if (AOP_TYPE(result) != AOP_STR) {
8237 /* if this is remateriazable */
8238 if (AOP_TYPE(result) == AOP_IMMD) {
8239 emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8240 emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8242 else { /* we need to get it byte by byte */
8243 char *l = aopGet(AOP(result),0,FALSE,FALSE);
8246 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
8247 emitpcode(POC_MOVWF,popCopy(&pc_indf));
8250 emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
8252 emitcode("movwf","INDF");
8255 /* so dptr know contains the address */
8256 freeAsmop(result,NULL,ic,TRUE);
8257 aopOp(right,ic,FALSE);
8259 /* if bit then unpack */
8260 if (IS_BITVAR(retype))
8261 genPackBits(retype,right,"dptr",GPOINTER);
8263 size = AOP_SIZE(right);
8267 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8269 emitcode("incf","fsr,f");
8270 emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8271 emitcode("movwf","indf");
8273 //DEBUGemitcode(";lcall","__gptrput");
8275 // emitcode("inc","dptr");
8279 freeAsmop(right,NULL,ic,TRUE);
8282 /*-----------------------------------------------------------------*/
8283 /* genPointerSet - stores the value into a pointer location */
8284 /*-----------------------------------------------------------------*/
8285 static void genPointerSet (iCode *ic)
8287 operand *right, *result ;
8288 sym_link *type, *etype;
8291 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8293 right = IC_RIGHT(ic);
8294 result = IC_RESULT(ic) ;
8296 /* depending on the type of pointer we need to
8297 move it to the correct pointer register */
8298 type = operandType(result);
8299 etype = getSpec(type);
8300 /* if left is of type of pointer then it is simple */
8301 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8302 p_type = DCL_TYPE(type);
8305 /* we have to go by the storage class */
8306 p_type = PTR_TYPE(SPEC_OCLS(etype));
8308 /* if (SPEC_OCLS(etype)->codesp ) { */
8309 /* p_type = CPOINTER ; */
8312 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8313 /* p_type = FPOINTER ; */
8315 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8316 /* p_type = PPOINTER ; */
8318 /* if (SPEC_OCLS(etype) == idata ) */
8319 /* p_type = IPOINTER ; */
8321 /* p_type = POINTER ; */
8324 /* now that we have the pointer type we assign
8325 the pointer values */
8330 genNearPointerSet (right,result,ic);
8334 genPagedPointerSet (right,result,ic);
8338 genFarPointerSet (right,result,ic);
8342 genGenPointerSet (right,result,ic);
8348 /*-----------------------------------------------------------------*/
8349 /* genIfx - generate code for Ifx statement */
8350 /*-----------------------------------------------------------------*/
8351 static void genIfx (iCode *ic, iCode *popIc)
8353 operand *cond = IC_COND(ic);
8356 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8357 aopOp(cond,ic,FALSE);
8359 /* get the value into acc */
8360 if (AOP_TYPE(cond) != AOP_CRY)
8364 /* the result is now in the accumulator */
8365 freeAsmop(cond,NULL,ic,TRUE);
8367 /* if there was something to be popped then do it */
8371 /* if the condition is a bit variable */
8372 if (isbit && IS_ITEMP(cond) &&
8374 genIfxJump(ic,SPIL_LOC(cond)->rname);
8375 DEBUGemitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8379 if (isbit && !IS_ITEMP(cond))
8380 DEBUGemitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
8382 DEBUGemitcode ("; isbit","a");
8385 if (isbit && !IS_ITEMP(cond))
8386 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8393 /*-----------------------------------------------------------------*/
8394 /* genAddrOf - generates code for address of */
8395 /*-----------------------------------------------------------------*/
8396 static void genAddrOf (iCode *ic)
8398 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8401 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8403 aopOp(IC_RESULT(ic),ic,FALSE);
8405 /* if the operand is on the stack then we
8406 need to get the stack offset of this
8409 /* if it has an offset then we need to compute
8412 emitcode("mov","a,_bp");
8413 emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
8414 aopPut(AOP(IC_RESULT(ic)),"a",0);
8416 /* we can just move _bp */
8417 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
8419 /* fill the result with zero */
8420 size = AOP_SIZE(IC_RESULT(ic)) - 1;
8423 if (options.stack10bit && size < (FPTRSIZE - 1))
8426 "*** warning: pointer to stack var truncated.\n");
8433 if (options.stack10bit && offset == 2)
8435 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8439 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8446 /* object not on stack then we need the name */
8447 size = AOP_SIZE(IC_RESULT(ic));
8451 char s[SDCC_NAME_MAX];
8453 sprintf(s,"#(%s >> %d)",
8457 sprintf(s,"#%s",sym->rname);
8458 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8462 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8467 /*-----------------------------------------------------------------*/
8468 /* genFarFarAssign - assignment when both are in far space */
8469 /*-----------------------------------------------------------------*/
8470 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8472 int size = AOP_SIZE(right);
8475 /* first push the right side on to the stack */
8477 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8479 emitcode ("push","acc");
8482 freeAsmop(right,NULL,ic,FALSE);
8483 /* now assign DPTR to result */
8484 aopOp(result,ic,FALSE);
8485 size = AOP_SIZE(result);
8487 emitcode ("pop","acc");
8488 aopPut(AOP(result),"a",--offset);
8490 freeAsmop(result,NULL,ic,FALSE);
8495 /*-----------------------------------------------------------------*/
8496 /* genAssign - generate code for assignment */
8497 /*-----------------------------------------------------------------*/
8498 static void genAssign (iCode *ic)
8500 operand *result, *right;
8502 unsigned long lit = 0L;
8504 result = IC_RESULT(ic);
8505 right = IC_RIGHT(ic) ;
8507 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8509 /* if they are the same */
8510 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8513 aopOp(right,ic,FALSE);
8514 aopOp(result,ic,TRUE);
8516 /* if they are the same registers */
8517 if (sameRegs(AOP(right),AOP(result)))
8520 /* if the result is a bit */
8521 if (AOP_TYPE(result) == AOP_CRY) {
8523 /* if the right size is a literal then
8524 we know what the value is */
8525 if (AOP_TYPE(right) == AOP_LIT) {
8527 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8528 popGet(AOP(result),0,FALSE,FALSE));
8530 if (((int) operandLitValue(right)))
8531 emitcode("bsf","(%s >> 3),(%s & 7)",
8532 AOP(result)->aopu.aop_dir,
8533 AOP(result)->aopu.aop_dir);
8535 emitcode("bcf","(%s >> 3),(%s & 7)",
8536 AOP(result)->aopu.aop_dir,
8537 AOP(result)->aopu.aop_dir);
8541 /* the right is also a bit variable */
8542 if (AOP_TYPE(right) == AOP_CRY) {
8543 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8544 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8545 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8547 emitcode("bcf","(%s >> 3),(%s & 7)",
8548 AOP(result)->aopu.aop_dir,
8549 AOP(result)->aopu.aop_dir);
8550 emitcode("btfsc","(%s >> 3),(%s & 7)",
8551 AOP(right)->aopu.aop_dir,
8552 AOP(right)->aopu.aop_dir);
8553 emitcode("bsf","(%s >> 3),(%s & 7)",
8554 AOP(result)->aopu.aop_dir,
8555 AOP(result)->aopu.aop_dir);
8560 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8563 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8564 //aopPut(AOP(result),"a",0);
8568 /* bit variables done */
8570 size = AOP_SIZE(result);
8572 if(AOP_TYPE(right) == AOP_LIT)
8573 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8574 if((AOP_TYPE(result) != AOP_REG) &&
8575 (AOP_TYPE(right) == AOP_LIT) &&
8576 !IS_FLOAT(operandType(right)) &&
8580 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8581 //emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8582 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8584 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8585 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8586 //emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8587 //emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8592 if(AOP_TYPE(right) == AOP_LIT) {
8593 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8594 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8596 } else if (AOP_TYPE(right) == AOP_CRY) {
8597 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8599 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8600 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8603 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8604 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8607 //emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8613 freeAsmop (right,NULL,ic,FALSE);
8614 freeAsmop (result,NULL,ic,TRUE);
8617 /*-----------------------------------------------------------------*/
8618 /* genJumpTab - genrates code for jump table */
8619 /*-----------------------------------------------------------------*/
8620 static void genJumpTab (iCode *ic)
8625 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8627 aopOp(IC_JTCOND(ic),ic,FALSE);
8628 /* get the condition into accumulator */
8629 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8631 /* multiply by three */
8632 emitcode("add","a,acc");
8633 emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8634 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8636 jtab = newiTempLabel(NULL);
8637 emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8638 emitcode("jmp","@a+dptr");
8639 emitcode("","%05d_DS_:",jtab->key+100);
8640 /* now generate the jump labels */
8641 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8642 jtab = setNextItem(IC_JTLABELS(ic)))
8643 emitcode("ljmp","%05d_DS_",jtab->key+100);
8647 /*-----------------------------------------------------------------*/
8648 /* genMixedOperation - gen code for operators between mixed types */
8649 /*-----------------------------------------------------------------*/
8651 TSD - Written for the PIC port - but this unfortunately is buggy.
8652 This routine is good in that it is able to efficiently promote
8653 types to different (larger) sizes. Unfortunately, the temporary
8654 variables that are optimized out by this routine are sometimes
8655 used in other places. So until I know how to really parse the
8656 iCode tree, I'm going to not be using this routine :(.
8658 static int genMixedOperation (iCode *ic)
8661 operand *result = IC_RESULT(ic);
8662 sym_link *ctype = operandType(IC_LEFT(ic));
8663 operand *right = IC_RIGHT(ic);
8669 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8671 emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8677 nextright = IC_RIGHT(nextic);
8678 nextleft = IC_LEFT(nextic);
8679 nextresult = IC_RESULT(nextic);
8681 aopOp(right,ic,FALSE);
8682 aopOp(result,ic,FALSE);
8683 aopOp(nextright, nextic, FALSE);
8684 aopOp(nextleft, nextic, FALSE);
8685 aopOp(nextresult, nextic, FALSE);
8687 if (sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8693 emitcode(";remove right +","");
8695 } else if (sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8701 emitcode(";remove left +","");
8705 big = AOP_SIZE(nextleft);
8706 small = AOP_SIZE(nextright);
8708 switch(nextic->op) {
8711 emitcode(";optimize a +","");
8712 /* if unsigned or not an integral type */
8713 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8714 emitcode(";add a bit to something","");
8717 emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8719 if (!sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8720 emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8721 emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8723 emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8731 if (!sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8732 emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8733 emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8736 emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8738 emitcode("btfsc","(%s >> 3), (%s & 7)",
8739 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8740 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8741 emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8742 emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8745 emitcode("rlf","known_zero,w");
8752 if (!sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8753 emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8754 emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8756 emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8766 freeAsmop(right,NULL,ic,TRUE);
8767 freeAsmop(result,NULL,ic,TRUE);
8768 freeAsmop(nextright,NULL,ic,TRUE);
8769 freeAsmop(nextleft,NULL,ic,TRUE);
8771 nextic->generated = 1;
8778 /*-----------------------------------------------------------------*/
8779 /* genCast - gen code for casting */
8780 /*-----------------------------------------------------------------*/
8781 static void genCast (iCode *ic)
8783 operand *result = IC_RESULT(ic);
8784 sym_link *ctype = operandType(IC_LEFT(ic));
8785 operand *right = IC_RIGHT(ic);
8788 DEBUGemitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8789 /* if they are equivalent then do nothing */
8790 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8793 aopOp(right,ic,FALSE) ;
8794 aopOp(result,ic,FALSE);
8796 /* if the result is a bit */
8797 if (AOP_TYPE(result) == AOP_CRY) {
8798 /* if the right size is a literal then
8799 we know what the value is */
8800 if (AOP_TYPE(right) == AOP_LIT) {
8802 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8803 popGet(AOP(result),0,FALSE,FALSE));
8805 if (((int) operandLitValue(right)))
8806 emitcode("bsf","(%s >> 3), (%s & 7)",
8807 AOP(result)->aopu.aop_dir,
8808 AOP(result)->aopu.aop_dir);
8810 emitcode("bcf","(%s >> 3), (%s & 7)",
8811 AOP(result)->aopu.aop_dir,
8812 AOP(result)->aopu.aop_dir);
8817 /* the right is also a bit variable */
8818 if (AOP_TYPE(right) == AOP_CRY) {
8821 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8823 emitcode("clrc","");
8824 emitcode("btfsc","(%s >> 3), (%s & 7)",
8825 AOP(right)->aopu.aop_dir,
8826 AOP(right)->aopu.aop_dir);
8827 aopPut(AOP(result),"c",0);
8833 aopPut(AOP(result),"a",0);
8837 /* if they are the same size : or less */
8838 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8840 /* if they are in the same place */
8841 if (sameRegs(AOP(right),AOP(result)))
8844 /* if they in different places then copy */
8845 size = AOP_SIZE(result);
8849 aopGet(AOP(right),offset,FALSE,FALSE),
8857 /* if the result is of type pointer */
8858 if (IS_PTR(ctype)) {
8861 sym_link *type = operandType(right);
8862 sym_link *etype = getSpec(type);
8864 /* pointer to generic pointer */
8865 if (IS_GENPTR(ctype)) {
8869 p_type = DCL_TYPE(type);
8871 /* we have to go by the storage class */
8872 p_type = PTR_TYPE(SPEC_OCLS(etype));
8874 /* if (SPEC_OCLS(etype)->codesp ) */
8875 /* p_type = CPOINTER ; */
8877 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8878 /* p_type = FPOINTER ; */
8880 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8881 /* p_type = PPOINTER; */
8883 /* if (SPEC_OCLS(etype) == idata ) */
8884 /* p_type = IPOINTER ; */
8886 /* p_type = POINTER ; */
8889 /* the first two bytes are known */
8890 size = GPTRSIZE - 1;
8894 aopGet(AOP(right),offset,FALSE,FALSE),
8898 /* the last byte depending on type */
8915 /* this should never happen */
8916 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8917 "got unknown pointer type");
8920 aopPut(AOP(result),l, GPTRSIZE - 1);
8924 /* just copy the pointers */
8925 size = AOP_SIZE(result);
8929 aopGet(AOP(right),offset,FALSE,FALSE),
8937 if (AOP_TYPE(right) == AOP_CRY) {
8939 size = AOP_SIZE(right);
8941 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8942 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8943 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8945 emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8946 emitcode("btfsc","(%s >> 3), (%s & 7)",
8947 AOP(right)->aopu.aop_dir,
8948 AOP(right)->aopu.aop_dir);
8949 emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8951 emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8952 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8957 /* so we now know that the size of destination is greater
8958 than the size of the source.
8959 Now, if the next iCode is an operator then we might be
8960 able to optimize the operation without performing a cast.
8962 if(genMixedOperation(ic))
8966 /* we move to result for the size of source */
8967 size = AOP_SIZE(right);
8970 emitcode(";","%d",__LINE__);
8972 aopGet(AOP(right),offset,FALSE,FALSE),
8977 /* now depending on the sign of the destination */
8978 size = AOP_SIZE(result) - AOP_SIZE(right);
8979 /* if unsigned or not an integral type */
8980 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8982 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8983 emitcode("clrf","%s ;%d",aopGet(AOP(result),offset++,FALSE,FALSE),__LINE__);
8986 /* we need to extend the sign :{ */
8987 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8990 emitpcode(POC_CLRW, NULL);
8991 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8992 emitpcode(POC_MOVLW, popGetLit(0xff));
8994 emitcode("clrw","");
8995 emitcode("btfsc","(%s >> 3), (%s & 7)",
8996 AOP(right)->aopu.aop_dir,
8997 AOP(right)->aopu.aop_dir);
8998 emitcode("movlw","0xff");
9000 emitpcode(POC_MOVWF, popGet(AOP(result),offset++,FALSE,FALSE));
9001 emitcode("movwf","%s",aopGet(AOP(result),offset++,FALSE,FALSE));
9002 // aopPut(AOP(result),"a",offset++);
9007 /* we are done hurray !!!! */
9010 freeAsmop(right,NULL,ic,TRUE);
9011 freeAsmop(result,NULL,ic,TRUE);
9015 /*-----------------------------------------------------------------*/
9016 /* genDjnz - generate decrement & jump if not zero instrucion */
9017 /*-----------------------------------------------------------------*/
9018 static int genDjnz (iCode *ic, iCode *ifx)
9021 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9026 /* if the if condition has a false label
9027 then we cannot save */
9031 /* if the minus is not of the form
9033 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9034 !IS_OP_LITERAL(IC_RIGHT(ic)))
9037 if (operandLitValue(IC_RIGHT(ic)) != 1)
9040 /* if the size of this greater than one then no
9042 if (getSize(operandType(IC_RESULT(ic))) > 1)
9045 /* otherwise we can save BIG */
9046 lbl = newiTempLabel(NULL);
9047 lbl1= newiTempLabel(NULL);
9049 aopOp(IC_RESULT(ic),ic,FALSE);
9051 if (IS_AOP_PREG(IC_RESULT(ic))) {
9052 emitcode("dec","%s",
9053 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9054 emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9055 emitcode("jnz","%05d_DS_",lbl->key+100);
9059 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9060 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9062 emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9063 emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9066 /* emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9067 /* emitcode ("","%05d_DS_:",lbl->key+100); */
9068 /* emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9069 /* emitcode ("","%05d_DS_:",lbl1->key+100); */
9072 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9077 /*-----------------------------------------------------------------*/
9078 /* genReceive - generate code for a receive iCode */
9079 /*-----------------------------------------------------------------*/
9080 static void genReceive (iCode *ic)
9082 DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9084 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9085 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9086 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9088 int size = getSize(operandType(IC_RESULT(ic)));
9089 int offset = fReturnSizePic - size;
9091 emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9092 fReturn[fReturnSizePic - offset - 1] : "acc"));
9095 aopOp(IC_RESULT(ic),ic,FALSE);
9096 size = AOP_SIZE(IC_RESULT(ic));
9099 emitcode ("pop","acc");
9100 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9105 aopOp(IC_RESULT(ic),ic,FALSE);
9107 assignResultValue(IC_RESULT(ic));
9110 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9113 /*-----------------------------------------------------------------*/
9114 /* genpic14Code - generate code for pic14 based controllers */
9115 /*-----------------------------------------------------------------*/
9117 * At this point, ralloc.c has gone through the iCode and attempted
9118 * to optimize in a way suitable for a PIC. Now we've got to generate
9119 * PIC instructions that correspond to the iCode.
9121 * Once the instructions are generated, we'll pass through both the
9122 * peep hole optimizer and the pCode optimizer.
9123 *-----------------------------------------------------------------*/
9125 void genpic14Code (iCode *lic)
9130 lineHead = lineCurr = NULL;
9132 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9135 /* if debug information required */
9136 /* if (options.debug && currFunc) { */
9138 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9140 if (IS_STATIC(currFunc->etype)) {
9141 emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9142 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9144 emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9145 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9151 for (ic = lic ; ic ; ic = ic->next ) {
9153 DEBUGemitcode(";ic","");
9154 if ( cln != ic->lineno ) {
9155 if ( options.debug ) {
9157 emitcode("",";C$%s$%d$%d$%d ==.",
9158 FileBaseName(ic->filename),ic->lineno,
9159 ic->level,ic->block);
9162 emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
9165 /* if the result is marked as
9166 spilt and rematerializable or code for
9167 this has already been generated then
9169 if (resultRemat(ic) || ic->generated )
9172 /* depending on the operation */
9191 /* IPOP happens only when trying to restore a
9192 spilt live range, if there is an ifx statement
9193 following this pop then the if statement might
9194 be using some of the registers being popped which
9195 would destory the contents of the register so
9196 we need to check for this condition and handle it */
9198 ic->next->op == IFX &&
9199 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9200 genIfx (ic->next,ic);
9218 genEndFunction (ic);
9238 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9255 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9259 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9266 /* note these two are xlated by algebraic equivalence
9267 during parsing SDCC.y */
9268 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9269 "got '>=' or '<=' shouldn't have come here");
9273 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9285 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9289 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9293 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9320 case GET_VALUE_AT_ADDRESS:
9325 if (POINTER_SET(ic))
9352 addSet(&_G.sendSet,ic);
9357 /* piCode(ic,stdout); */
9363 /* now we are ready to call the
9364 peep hole optimizer */
9365 if (!options.nopeep) {
9366 printf("peep hole optimizing\n");
9367 peepHole (&lineHead);
9369 /* now do the actual printing */
9370 printLine (lineHead,codeOutFile);
9372 printf("printing pBlock\n\n");
9373 printpBlock(stdout,pb);