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"
61 //char *aopLiteral (value *val, int offset);
62 char *pic14aopLiteral (value * val, int offset);
64 /* this is the down and dirty file with all kinds of
65 kludgy & hacky stuff. This is what it is all about
66 CODE GENERATION for a specific MCU . some of the
67 routines may be reusable, will have to see */
69 static char *zero = "#0x00";
70 static char *one = "#0x01";
71 static char *spname = "sp";
73 char *fReturnpic14[] =
74 {"fsr", "dph", "b", "a"};
75 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
76 static unsigned fReturnSize = 4; /* shared with ralloc.c */
77 static char **fReturn = fReturnpic14;
79 static char *accUse[] =
82 //static short rbank = -1;
96 extern int pic14_ptrRegReq;
97 extern int pic14_nRegs;
98 extern FILE *codeOutFile;
99 static void saverbank (int, iCode *, bool);
100 #define RESULTONSTACK(x) \
101 (IC_RESULT(x) && IC_RESULT(x)->aop && \
102 IC_RESULT(x)->aop->type == AOP_STK )
104 #define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode(";XXX mov","a,%s %s,%d",x,__FILE__,__LINE__);
105 #define CLRC emitcode(";XXX clr","c %s,%d",__FILE__,__LINE__);
107 #define BIT_NUMBER(x) (x & 7)
108 #define BIT_REGISTER(x) (x>>3)
110 static lineNode *lineHead = NULL;
111 static lineNode *lineCurr = NULL;
113 static unsigned char SLMask[] =
114 {0xFF, 0xFE, 0xFC, 0xF8, 0xF0,
115 0xE0, 0xC0, 0x80, 0x00};
116 static unsigned char SRMask[] =
117 {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
118 0x07, 0x03, 0x01, 0x00};
126 #define FUNCTION_LABEL_INC 20
127 static int labelOffset = 0;
128 static int debug_verbose = 0;
131 /*-----------------------------------------------------------------*/
132 /* Macros for emitting instructions */
133 /*-----------------------------------------------------------------*/
134 #define emitSKPC emitcode("btfss","status,c")
135 #define emitSKPNC emitcode("btfsc","status,c")
136 #define emitSKPZ emitcode("btfss","status,z")
137 #define emitSKPNZ emitcode("btfsc","status,z")
139 /*-----------------------------------------------------------------*/
140 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
141 /* exponent of 2 is returned, otherwise -1 is */
143 /* note that this is similar to the function `powof2' in SDCCsymt */
147 /*-----------------------------------------------------------------*/
149 my_powof2 (unsigned long num)
153 if ((num & (num - 1)) == 0)
169 /*-----------------------------------------------------------------*/
170 /* emitcode - writes the code into a file : for now it is simple */
171 /*-----------------------------------------------------------------*/
173 emitcode (char *inst, char *fmt,...)
176 char lb[MAX_INLINEASM];
184 sprintf (lb, "%s\t", inst);
186 sprintf (lb, "%s", inst);
187 vsprintf (lb + (strlen (lb)), fmt, ap);
190 vsprintf (lb, fmt, ap);
192 while (isspace (*lbp))
196 lineCurr = (lineCurr ?
197 connectLine (lineCurr, newLineNode (lb)) :
198 (lineHead = newLineNode (lb)));
199 lineCurr->isInline = _G.inLine;
200 lineCurr->isDebug = _G.debugLine;
205 DEBUGemitcode (char *inst, char *fmt,...)
208 char lb[MAX_INLINEASM];
219 sprintf (lb, "%s\t", inst);
221 sprintf (lb, "%s", inst);
222 vsprintf (lb + (strlen (lb)), fmt, ap);
225 vsprintf (lb, fmt, ap);
227 while (isspace (*lbp))
231 lineCurr = (lineCurr ?
232 connectLine (lineCurr, newLineNode (lb)) :
233 (lineHead = newLineNode (lb)));
234 lineCurr->isInline = _G.inLine;
235 lineCurr->isDebug = _G.debugLine;
240 /*-----------------------------------------------------------------*/
241 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed */
242 /*-----------------------------------------------------------------*/
244 getFreePtr (iCode * ic, asmop ** aopp, bool result)
246 bool r0iu = FALSE, r1iu = FALSE;
247 bool r0ou = FALSE, r1ou = FALSE;
249 /* the logic: if r0 & r1 used in the instruction
250 then we are in trouble otherwise */
252 /* first check if r0 & r1 are used by this
253 instruction, in which case we are in trouble */
254 if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
255 (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
260 r0ou = bitVectBitValue (ic->rMask, R0_IDX);
261 r1ou = bitVectBitValue (ic->rMask, R1_IDX);
263 /* if no usage of r0 then return it */
266 ic->rUsed = bitVectSetBit (ic->rUsed, R0_IDX);
267 (*aopp)->type = AOP_R0;
269 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx (R0_IDX);
272 /* if no usage of r1 then return it */
275 ic->rUsed = bitVectSetBit (ic->rUsed, R1_IDX);
276 (*aopp)->type = AOP_R1;
278 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx (R1_IDX);
281 /* now we know they both have usage */
282 /* if r0 not used in this instruction */
285 /* push it if not already pushed */
288 emitcode ("push", "%s",
289 pic14_regWithIdx (R0_IDX)->dname);
293 ic->rUsed = bitVectSetBit (ic->rUsed, R0_IDX);
294 (*aopp)->type = AOP_R0;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx (R0_IDX);
299 /* if r1 not used then */
303 /* push it if not already pushed */
306 emitcode ("push", "%s",
307 pic14_regWithIdx (R1_IDX)->dname);
311 ic->rUsed = bitVectSetBit (ic->rUsed, R1_IDX);
312 (*aopp)->type = AOP_R1;
313 return pic14_regWithIdx (R1_IDX);
317 /* I said end of world but not quite end of world yet */
318 /* if this is a result then we can push it on the stack */
321 (*aopp)->type = AOP_STK;
326 /* other wise this is true end of the world */
327 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
328 "getFreePtr should never reach here");
332 /*-----------------------------------------------------------------*/
333 /* newAsmop - creates a new asmOp */
334 /*-----------------------------------------------------------------*/
336 newAsmop (short type)
340 aop = Safe_calloc (1, sizeof (asmop));
350 emitcode (";", "Select standard DPTR");
351 emitcode ("mov", "dps, #0x00");
355 emitcode (";", "Select alternate DPTR");
356 emitcode ("mov", "dps, #0x01");
360 /*-----------------------------------------------------------------*/
361 /* pointerCode - returns the code for a pointer type */
362 /*-----------------------------------------------------------------*/
364 pointerCode (sym_link * etype)
367 return PTR_TYPE (SPEC_OCLS (etype));
371 /*-----------------------------------------------------------------*/
372 /* aopForSym - for a true symbol */
373 /*-----------------------------------------------------------------*/
375 aopForSym (iCode * ic, symbol * sym, bool result)
378 memmap *space = SPEC_OCLS (sym->etype);
380 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
381 /* if already has one */
385 /* assign depending on the storage class */
386 /* if it is on the stack or indirectly addressable */
387 /* space we need to assign either r0 or r1 to it */
388 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)
402 emitcode ("push", "acc");
404 emitcode ("mov", "a,_bp");
405 emitcode ("add", "a,#0x%02x",
407 ((char) (sym->stack - _G.nRegsSaved)) :
408 ((char) sym->stack)) & 0xff);
409 emitcode ("mov", "%s,a",
410 aop->aopu.aop_ptr->name);
413 emitcode ("pop", "acc");
416 emitcode ("mov", "%s,#%s",
417 aop->aopu.aop_ptr->name,
419 aop->paged = space->paged;
422 aop->aopu.aop_stk = sym->stack;
426 if (sym->onStack && options.stack10bit)
428 /* It's on the 10 bit stack, which is located in
432 //DEBUGemitcode(";","%d",__LINE__);
435 emitcode ("push", "acc");
437 emitcode ("mov", "a,_bp");
438 emitcode ("add", "a,#0x%02x",
440 ((char) (sym->stack - _G.nRegsSaved)) :
441 ((char) sym->stack)) & 0xff);
444 emitcode ("mov", "dpx1,#0x40");
445 emitcode ("mov", "dph1,#0x00");
446 emitcode ("mov", "dpl1, a");
450 emitcode ("pop", "acc");
452 sym->aop = aop = newAsmop (AOP_DPTR2);
453 aop->size = getSize (sym->type);
457 //DEBUGemitcode(";","%d",__LINE__);
458 /* if in bit space */
459 if (IN_BITSPACE (space))
461 sym->aop = aop = newAsmop (AOP_CRY);
462 aop->aopu.aop_dir = sym->rname;
463 aop->size = getSize (sym->type);
464 DEBUGemitcode (";", "%d sym->rname = %s, size = %d", __LINE__, sym->rname, aop->size);
467 /* if it is in direct space */
468 if (IN_DIRSPACE (space))
470 sym->aop = aop = newAsmop (AOP_DIR);
471 aop->aopu.aop_dir = sym->rname;
472 aop->size = getSize (sym->type);
473 DEBUGemitcode (";", "%d sym->rname = %s, size = %d", __LINE__, sym->rname, aop->size);
477 /* special case for a function */
478 if (IS_FUNC (sym->type))
480 sym->aop = aop = newAsmop (AOP_IMMD);
481 aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
482 strcpy (aop->aopu.aop_immd, sym->rname);
483 aop->size = FPTRSIZE;
488 /* only remaining is far space */
489 /* in which case DPTR gets the address */
490 sym->aop = aop = newAsmop (AOP_DPTR);
491 emitcode ("mov", "dptr,#%s", sym->rname);
492 aop->size = getSize (sym->type);
494 DEBUGemitcode (";", "%d size = %d", __LINE__, aop->size);
495 /* if it is in code space */
496 if (IN_CODESPACE (space))
502 /*-----------------------------------------------------------------*/
503 /* aopForRemat - rematerialzes an object */
504 /*-----------------------------------------------------------------*/
506 aopForRemat (symbol * sym)
508 iCode *ic = sym->rematiCode;
509 asmop *aop = newAsmop (AOP_IMMD);
511 DEBUGemitcode (";", "%s %d", __FUNCTION__, __LINE__);
515 val += operandLitValue (IC_RIGHT (ic));
516 else if (ic->op == '-')
517 val -= operandLitValue (IC_RIGHT (ic));
521 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
525 sprintf (buffer, "(%s %c 0x%04x)",
526 OP_SYMBOL (IC_LEFT (ic))->rname,
527 val >= 0 ? '+' : '-',
530 strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
532 //DEBUGemitcode(";","%s",buffer);
533 aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
534 strcpy (aop->aopu.aop_immd, buffer);
538 /*-----------------------------------------------------------------*/
539 /* regsInCommon - two operands have some registers in common */
540 /*-----------------------------------------------------------------*/
542 regsInCommon (operand * op1, operand * op2)
547 /* if they have registers in common */
548 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
551 sym1 = OP_SYMBOL (op1);
552 sym2 = OP_SYMBOL (op2);
554 if (sym1->nRegs == 0 || sym2->nRegs == 0)
557 for (i = 0; i < sym1->nRegs; i++)
563 for (j = 0; j < sym2->nRegs; j++)
568 if (sym2->regs[j] == sym1->regs[i])
576 /*-----------------------------------------------------------------*/
577 /* operandsEqu - equivalent */
578 /*-----------------------------------------------------------------*/
580 operandsEqu (operand * op1, operand * op2)
584 /* if they not symbols */
585 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
588 sym1 = OP_SYMBOL (op1);
589 sym2 = OP_SYMBOL (op2);
591 /* if both are itemps & one is spilt
592 and the other is not then false */
593 if (IS_ITEMP (op1) && IS_ITEMP (op2) &&
594 sym1->isspilt != sym2->isspilt)
597 /* if they are the same */
601 if (strcmp (sym1->rname, sym2->rname) == 0)
605 /* if left is a tmp & right is not */
606 if (IS_ITEMP (op1) &&
609 (sym1->usl.spillLoc == sym2))
612 if (IS_ITEMP (op2) &&
616 (sym2->usl.spillLoc == sym1))
622 /*-----------------------------------------------------------------*/
623 /* sameRegs - two asmops have the same registers */
624 /*-----------------------------------------------------------------*/
626 sameRegs (asmop * aop1, asmop * aop2)
633 if (aop1->type != AOP_REG ||
634 aop2->type != AOP_REG)
637 if (aop1->size != aop2->size)
640 for (i = 0; i < aop1->size; i++)
641 if (aop1->aopu.aop_reg[i] !=
642 aop2->aopu.aop_reg[i])
648 /*-----------------------------------------------------------------*/
649 /* aopOp - allocates an asmop for an operand : */
650 /*-----------------------------------------------------------------*/
652 aopOp (operand * op, iCode * ic, bool result)
661 DEBUGemitcode (";", "%d", __LINE__);
662 /* if this a literal */
663 if (IS_OP_LITERAL (op))
665 DEBUGemitcode (";", "%d", __LINE__);
666 op->aop = aop = newAsmop (AOP_LIT);
667 aop->aopu.aop_lit = op->operand.valOperand;
668 aop->size = getSize (operandType (op));
672 /* if already has a asmop then continue */
676 /* if the underlying symbol has a aop */
677 if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
679 DEBUGemitcode (";", "%d", __LINE__);
680 op->aop = OP_SYMBOL (op)->aop;
684 /* if this is a true symbol */
685 if (IS_TRUE_SYMOP (op))
687 DEBUGemitcode (";", "%d", __LINE__);
688 op->aop = aopForSym (ic, OP_SYMBOL (op), result);
692 /* this is a temporary : this has
698 e) can be a return use only */
700 sym = OP_SYMBOL (op);
703 /* if the type is a conditional */
704 if (sym->regType == REG_CND)
706 DEBUGemitcode (";", "%d", __LINE__);
707 aop = op->aop = sym->aop = newAsmop (AOP_CRY);
712 /* if it is spilt then two situations
714 b) has a spill location */
715 if (sym->isspilt || sym->nRegs == 0)
718 DEBUGemitcode (";", "%d", __LINE__);
719 /* rematerialize it NOW */
722 sym->aop = op->aop = aop =
724 aop->size = getSize (sym->type);
725 DEBUGemitcode (";", "%d", __LINE__);
732 aop = op->aop = sym->aop = newAsmop (AOP_ACC);
733 aop->size = getSize (sym->type);
734 for (i = 0; i < 2; i++)
735 aop->aopu.aop_str[i] = accUse[i];
736 DEBUGemitcode (";", "%d", __LINE__);
743 aop = op->aop = sym->aop = newAsmop (AOP_STR);
744 aop->size = getSize (sym->type);
745 for (i = 0; i < fReturnSize; i++)
746 aop->aopu.aop_str[i] = fReturn[i];
747 DEBUGemitcode (";", "%d", __LINE__);
751 /* else spill location */
752 DEBUGemitcode (";", "%s %d %s", __FUNCTION__, __LINE__, sym->usl.spillLoc->rname);
753 sym->aop = op->aop = aop =
754 aopForSym (ic, sym->usl.spillLoc, result);
755 aop->size = getSize (sym->type);
759 /* must be in a register */
760 sym->aop = op->aop = aop = newAsmop (AOP_REG);
761 aop->size = sym->nRegs;
762 for (i = 0; i < sym->nRegs; i++)
763 aop->aopu.aop_reg[i] = sym->regs[i];
766 /*-----------------------------------------------------------------*/
767 /* freeAsmop - free up the asmop given to an operand */
768 /*----------------------------------------------------------------*/
770 freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
787 /* depending on the asmop type only three cases need work AOP_RO
788 , AOP_R1 && AOP_STK */
796 emitcode ("pop", "ar0");
800 bitVectUnSetBit (ic->rUsed, R0_IDX);
808 emitcode ("pop", "ar1");
812 bitVectUnSetBit (ic->rUsed, R1_IDX);
818 int stk = aop->aopu.aop_stk + aop->size;
819 bitVectUnSetBit (ic->rUsed, R0_IDX);
820 bitVectUnSetBit (ic->rUsed, R1_IDX);
822 getFreePtr (ic, &aop, FALSE);
824 if (options.stack10bit)
826 /* I'm not sure what to do here yet... */
829 "*** Warning: probably generating bad code for "
830 "10 bit stack mode.\n");
835 emitcode ("mov", "a,_bp");
836 emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff);
837 emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name);
841 emitcode ("mov", "%s,_bp", aop->aopu.aop_ptr->name);
846 emitcode ("pop", "acc");
847 emitcode ("mov", "@%s,a", aop->aopu.aop_ptr->name);
850 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
853 freeAsmop (op, NULL, ic, TRUE);
856 emitcode ("pop", "ar0");
862 emitcode ("pop", "ar1");
869 /* all other cases just dealloc */
875 OP_SYMBOL (op)->aop = NULL;
876 /* if the symbol has a spill */
878 SPIL_LOC (op)->aop = NULL;
883 /*-----------------------------------------------------------------*/
884 /* aopGet - for fetching value of the aop */
885 /*-----------------------------------------------------------------*/
887 aopGet (asmop * aop, int offset, bool bit16, bool dname)
892 //DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
893 /* offset is greater than
895 if (offset > (aop->size - 1) &&
896 aop->type != AOP_LIT)
899 /* depending on type */
905 DEBUGemitcode (";", "%d", __LINE__);
906 /* if we need to increment it */
907 while (offset > aop->coff)
909 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
913 while (offset < aop->coff)
915 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
922 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
923 return (dname ? "acc" : "a");
925 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
926 rs = Safe_calloc (1, strlen (s) + 1);
932 DEBUGemitcode (";", "%d", __LINE__);
933 if (aop->type == AOP_DPTR2)
938 while (offset > aop->coff)
940 emitcode ("inc", "dptr");
944 while (offset < aop->coff)
946 emitcode ("lcall", "__decdptr");
953 emitcode ("clr", "a");
954 emitcode ("movc", "a,@a+dptr");
958 emitcode ("movx", "a,@dptr");
961 if (aop->type == AOP_DPTR2)
966 return (dname ? "acc" : "a");
970 DEBUGemitcode (";", "%d", __LINE__);
972 sprintf (s, "%s", aop->aopu.aop_immd);
974 sprintf (s, "(%s >> %d)",
980 rs = Safe_calloc (1, strlen (s) + 1);
986 sprintf (s, "(%s + %d)",
990 sprintf (s, "%s", aop->aopu.aop_dir);
991 rs = Safe_calloc (1, strlen (s) + 1);
996 DEBUGemitcode (";", "%d", __LINE__);
998 return aop->aopu.aop_reg[offset]->dname;
1000 return aop->aopu.aop_reg[offset]->name;
1003 emitcode (";", "%d", __LINE__);
1004 //emitcode("clr","a");
1005 //emitcode("mov","c,%s",aop->aopu.aop_dir);
1006 //emitcode("rlc","a") ;
1007 //return (dname ? "acc" : "a");
1008 return aop->aopu.aop_dir;
1011 DEBUGemitcode (";Warning -pic port ignoring get(AOP_ACC)", "%d", __LINE__);
1012 //if (!offset && dname)
1014 //return aop->aopu.aop_str[offset];
1015 return "AOP_accumulator_bug";
1018 DEBUGemitcode (";", "%d", __LINE__);
1019 return pic14aopLiteral (aop->aopu.aop_lit, offset);
1022 DEBUGemitcode (";", "%d", __LINE__);
1024 if (strcmp (aop->aopu.aop_str[offset], "a") == 0 &&
1028 return aop->aopu.aop_str[offset];
1032 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1033 "aopget got unsupported aop->type");
1036 /*-----------------------------------------------------------------*/
1037 /* aopPut - puts a string for a aop */
1038 /*-----------------------------------------------------------------*/
1040 aopPut (asmop * aop, char *s, int offset)
1045 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1047 if (aop->size && offset > (aop->size - 1))
1049 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1050 "aopPut got offset > aop->size");
1054 /* will assign value to value */
1055 /* depending on where it is ofcourse */
1060 sprintf (d, "(%s + %d)",
1061 aop->aopu.aop_dir, offset);
1063 sprintf (d, "%s", aop->aopu.aop_dir);
1067 DEBUGemitcode (";", "%d", __LINE__);
1068 if (strcmp (s, "W"))
1069 emitcode ("movf", "%s,w", s);
1070 emitcode ("movwf", "%s", d);
1075 if (strcmp (aop->aopu.aop_reg[offset]->name, s) != 0 &&
1076 strcmp (aop->aopu.aop_reg[offset]->dname, s) != 0)
1080 strcmp(s,"r0") == 0 ||
1081 strcmp(s,"r1") == 0 ||
1082 strcmp(s,"r2") == 0 ||
1083 strcmp(s,"r3") == 0 ||
1084 strcmp(s,"r4") == 0 ||
1085 strcmp(s,"r5") == 0 ||
1086 strcmp(s,"r6") == 0 ||
1087 strcmp(s,"r7") == 0 )
1088 emitcode("mov","%s,%s ; %d",
1089 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1093 if (strcmp (s, "W"))
1094 emitcode ("movf", "%s,w ; %d", s, __LINE__);
1096 emitcode ("movwf", "%s",
1097 aop->aopu.aop_reg[offset]->name);
1105 if (aop->type == AOP_DPTR2)
1112 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1113 "aopPut writting to code space");
1117 while (offset > aop->coff)
1120 emitcode ("inc", "dptr");
1123 while (offset < aop->coff)
1126 emitcode ("lcall", "__decdptr");
1131 /* if not in accumulater */
1134 emitcode ("movx", "@dptr,a");
1136 if (aop->type == AOP_DPTR2)
1144 while (offset > aop->coff)
1147 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1149 while (offset < aop->coff)
1152 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1159 emitcode ("movx", "@%s,a", aop->aopu.aop_ptr->name);
1165 emitcode ("mov", "@%s,a ; %d", aop->aopu.aop_ptr->name, __LINE__);
1167 else if (strcmp (s, "r0") == 0 ||
1168 strcmp (s, "r1") == 0 ||
1169 strcmp (s, "r2") == 0 ||
1170 strcmp (s, "r3") == 0 ||
1171 strcmp (s, "r4") == 0 ||
1172 strcmp (s, "r5") == 0 ||
1173 strcmp (s, "r6") == 0 ||
1174 strcmp (s, "r7") == 0)
1177 sprintf (buffer, "a%s", s);
1178 emitcode ("mov", "@%s,%s",
1179 aop->aopu.aop_ptr->name, buffer);
1182 emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
1187 if (strcmp (s, "a") == 0)
1188 emitcode ("push", "acc");
1190 emitcode ("push", "%s", s);
1195 /* if bit variable */
1196 if (!aop->aopu.aop_dir)
1198 emitcode ("clr", "a");
1199 emitcode ("rlc", "a");
1204 emitcode ("clr", "%s", aop->aopu.aop_dir);
1206 emitcode ("setb", "%s", aop->aopu.aop_dir);
1207 else if (!strcmp (s, "c"))
1208 emitcode ("mov", "%s,c", aop->aopu.aop_dir);
1211 lbl = newiTempLabel (NULL);
1213 if (strcmp (s, "a"))
1217 emitcode ("clr", "c");
1218 emitcode ("jz", "%05d_DS_", lbl->key + 100);
1219 emitcode ("cpl", "c");
1220 emitcode ("", "%05d_DS_:", lbl->key + 100);
1221 emitcode ("mov", "%s,c", aop->aopu.aop_dir);
1228 if (strcmp (aop->aopu.aop_str[offset], s))
1229 emitcode ("mov", "%s,%s ; %d", aop->aopu.aop_str[offset], s, __LINE__);
1234 if (!offset && (strcmp (s, "acc") == 0))
1237 if (strcmp (aop->aopu.aop_str[offset], s))
1238 emitcode ("mov", "%s,%s ; %d", aop->aopu.aop_str[offset], s, __LINE__);
1242 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1243 "aopPut got unsupported aop->type");
1249 /*-----------------------------------------------------------------*/
1250 /* reAdjustPreg - points a register back to where it should */
1251 /*-----------------------------------------------------------------*/
1253 reAdjustPreg (asmop * aop)
1257 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1259 if ((size = aop->size) <= 1)
1267 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1271 if (aop->type == AOP_DPTR2)
1277 emitcode ("lcall", "__decdptr");
1280 if (aop->type == AOP_DPTR2)
1290 #define AOP(op) op->aop
1291 #define AOP_TYPE(op) AOP(op)->type
1292 #define AOP_SIZE(op) AOP(op)->size
1293 #define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
1294 AOP_TYPE(x) == AOP_R0))
1296 #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
1297 AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
1300 #define AOP_INPREG(x) (x && (x->type == AOP_REG && \
1301 (x->aopu.aop_reg[0] == pic14_regWithIdx(R0_IDX) || \
1302 x->aopu.aop_reg[0] == pic14_regWithIdx(R1_IDX) )))
1304 /*-----------------------------------------------------------------*/
1305 /* genNotFloat - generates not for float operations */
1306 /*-----------------------------------------------------------------*/
1308 genNotFloat (operand * op, operand * res)
1314 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1315 /* we will put 127 in the first byte of
1317 aopPut (AOP (res), "#127", 0);
1318 size = AOP_SIZE (op) - 1;
1321 l = aopGet (op->aop, offset++, FALSE, FALSE);
1326 emitcode ("orl", "a,%s",
1328 offset++, FALSE, FALSE));
1330 tlbl = newiTempLabel (NULL);
1332 tlbl = newiTempLabel (NULL);
1333 aopPut (res->aop, one, 1);
1334 emitcode ("jz", "%05d_DS_", (tlbl->key + 100));
1335 aopPut (res->aop, zero, 1);
1336 emitcode ("", "%05d_DS_:", (tlbl->key + 100));
1338 size = res->aop->size - 2;
1340 /* put zeros in the rest */
1342 aopPut (res->aop, zero, offset++);
1346 /*-----------------------------------------------------------------*/
1347 /* opIsGptr: returns non-zero if the passed operand is */
1348 /* a generic pointer type. */
1349 /*-----------------------------------------------------------------*/
1351 opIsGptr (operand * op)
1353 sym_link *type = operandType (op);
1355 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1356 if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type))
1364 /*-----------------------------------------------------------------*/
1365 /* getDataSize - get the operand data size */
1366 /*-----------------------------------------------------------------*/
1368 getDataSize (operand * op)
1370 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1373 return AOP_SIZE (op);
1375 // tsd- in the pic port, the genptr size is 1, so this code here
1376 // fails. ( in the 8051 port, the size was 4).
1379 size = AOP_SIZE (op);
1380 if (size == GPTRSIZE)
1382 sym_link *type = operandType (op);
1383 if (IS_GENPTR (type))
1385 /* generic pointer; arithmetic operations
1386 * should ignore the high byte (pointer type).
1389 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1396 /*-----------------------------------------------------------------*/
1397 /* outAcc - output Acc */
1398 /*-----------------------------------------------------------------*/
1400 outAcc (operand * result)
1403 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1404 size = getDataSize (result);
1407 aopPut (AOP (result), "a", 0);
1410 /* unsigned or positive */
1413 aopPut (AOP (result), zero, offset++);
1418 /*-----------------------------------------------------------------*/
1419 /* outBitC - output a bit C */
1420 /*-----------------------------------------------------------------*/
1422 outBitC (operand * result)
1425 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1426 /* if the result is bit */
1427 if (AOP_TYPE (result) == AOP_CRY)
1428 aopPut (AOP (result), "c", 0);
1431 emitcode ("clr", "a ; %d", __LINE__);
1432 emitcode ("rlc", "a");
1437 /*-----------------------------------------------------------------*/
1438 /* toBoolean - emit code for orl a,operator(sizeop) */
1439 /*-----------------------------------------------------------------*/
1441 toBoolean (operand * oper)
1443 int size = AOP_SIZE (oper) - 1;
1446 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1448 if (AOP_TYPE (oper) != AOP_ACC)
1449 emitcode ("movf", "%s,w", aopGet (AOP (oper), 0, FALSE, FALSE));
1452 emitcode ("iorwf", "%s,w", aopGet (AOP (oper), offset++, FALSE, FALSE));
1456 /*-----------------------------------------------------------------*/
1457 /* genNot - generate code for ! operation */
1458 /*-----------------------------------------------------------------*/
1463 sym_link *optype = operandType (IC_LEFT (ic));
1465 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1466 /* assign asmOps to operand & result */
1467 aopOp (IC_LEFT (ic), ic, FALSE);
1468 aopOp (IC_RESULT (ic), ic, TRUE);
1470 /* if in bit space then a special case */
1471 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
1473 emitcode ("movlw", "1<<%s");
1474 //emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1475 //emitcode("cpl","c");
1476 //outBitC(IC_RESULT(ic));
1480 /* if type float then do float */
1481 if (IS_FLOAT (optype))
1483 genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
1487 toBoolean (IC_LEFT (ic));
1489 tlbl = newiTempLabel (NULL);
1490 emitcode ("cjne", "a,#0x01,%05d_DS_", tlbl->key + 100);
1491 emitcode ("", "%05d_DS_:", tlbl->key + 100);
1492 outBitC (IC_RESULT (ic));
1495 /* release the aops */
1496 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
1497 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1501 /*-----------------------------------------------------------------*/
1502 /* genCpl - generate code for complement */
1503 /*-----------------------------------------------------------------*/
1511 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1512 /* assign asmOps to operand & result */
1513 aopOp (IC_LEFT (ic), ic, FALSE);
1514 aopOp (IC_RESULT (ic), ic, TRUE);
1516 /* if both are in bit space then
1518 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
1519 AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
1522 emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
1523 emitcode ("cpl", "c");
1524 emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
1528 size = AOP_SIZE (IC_RESULT (ic));
1531 char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE);
1533 emitcode ("cpl", "a");
1534 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
1539 /* release the aops */
1540 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
1541 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1544 /*-----------------------------------------------------------------*/
1545 /* genUminusFloat - unary minus for floating points */
1546 /*-----------------------------------------------------------------*/
1548 genUminusFloat (operand * op, operand * result)
1550 int size, offset = 0;
1553 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1554 /* for this we just need to flip the
1555 first it then copy the rest in place */
1556 size = AOP_SIZE (op) - 1;
1557 l = aopGet (AOP (op), 3, FALSE, FALSE);
1561 emitcode ("cpl", "acc.7");
1562 aopPut (AOP (result), "a", 3);
1566 aopPut (AOP (result),
1567 aopGet (AOP (op), offset, FALSE, FALSE),
1573 /*-----------------------------------------------------------------*/
1574 /* genUminus - unary minus code generation */
1575 /*-----------------------------------------------------------------*/
1577 genUminus (iCode * ic)
1580 sym_link *optype, *rtype;
1583 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1585 aopOp (IC_LEFT (ic), ic, FALSE);
1586 aopOp (IC_RESULT (ic), ic, TRUE);
1588 /* if both in bit space then special
1590 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
1591 AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
1594 emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
1595 emitcode ("cpl", "c");
1596 emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
1600 optype = operandType (IC_LEFT (ic));
1601 rtype = operandType (IC_RESULT (ic));
1603 /* if float then do float stuff */
1604 if (IS_FLOAT (optype))
1606 genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
1610 /* otherwise subtract from zero */
1611 size = AOP_SIZE (IC_LEFT (ic));
1616 char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE);
1617 if (!strcmp (l, "a"))
1619 emitcode ("cpl", "a");
1620 emitcode ("inc", "a");
1624 emitcode ("clr", "a");
1625 emitcode ("subb", "a,%s", l);
1627 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
1630 /* if any remaining bytes in the result */
1631 /* we just need to propagate the sign */
1632 if ((size = (AOP_SIZE (IC_RESULT (ic)) - AOP_SIZE (IC_LEFT (ic)))))
1634 emitcode ("rlc", "a");
1635 emitcode ("subb", "a,acc");
1637 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
1641 /* release the aops */
1642 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
1643 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1646 /*-----------------------------------------------------------------*/
1647 /* saveRegisters - will look for a call and save the registers */
1648 /*-----------------------------------------------------------------*/
1650 saveRegisters (iCode * lic)
1657 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1659 for (ic = lic; ic; ic = ic->next)
1660 if (ic->op == CALL || ic->op == PCALL)
1665 fprintf (stderr, "found parameter push with no function call\n");
1669 /* if the registers have been saved already then
1671 if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave))
1674 /* find the registers in use at this time
1675 and push them away to safety */
1676 rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
1680 if (options.useXstack)
1682 if (bitVectBitValue (rsave, R0_IDX))
1683 emitcode ("mov", "b,r0");
1684 emitcode ("mov", "r0,%s", spname);
1685 for (i = 0; i < pic14_nRegs; i++)
1687 if (bitVectBitValue (rsave, i))
1690 emitcode ("mov", "a,b");
1692 emitcode ("mov", "a,%s", pic14_regWithIdx (i)->name);
1693 emitcode ("movx", "@r0,a");
1694 emitcode ("inc", "r0");
1697 emitcode ("mov", "%s,r0", spname);
1698 if (bitVectBitValue (rsave, R0_IDX))
1699 emitcode ("mov", "r0,b");
1702 for (i = 0; i < pic14_nRegs; i++)
1704 if (bitVectBitValue (rsave, i))
1705 emitcode ("push", "%s", pic14_regWithIdx (i)->dname);
1708 detype = getSpec (operandType (IC_LEFT (ic)));
1710 (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
1711 IS_ISR (currFunc->etype) &&
1714 saverbank (SPEC_BANK (detype), ic, TRUE);
1717 /*-----------------------------------------------------------------*/
1718 /* unsaveRegisters - pop the pushed registers */
1719 /*-----------------------------------------------------------------*/
1721 unsaveRegisters (iCode * ic)
1726 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1727 /* find the registers in use at this time
1728 and push them away to safety */
1729 rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
1732 if (options.useXstack)
1734 emitcode ("mov", "r0,%s", spname);
1735 for (i = pic14_nRegs; i >= 0; i--)
1737 if (bitVectBitValue (rsave, i))
1739 emitcode ("dec", "r0");
1740 emitcode ("movx", "a,@r0");
1742 emitcode ("mov", "b,a");
1744 emitcode ("mov", "%s,a", pic14_regWithIdx (i)->name);
1748 emitcode ("mov", "%s,r0", spname);
1749 if (bitVectBitValue (rsave, R0_IDX))
1750 emitcode ("mov", "r0,b");
1753 for (i = pic14_nRegs; i >= 0; i--)
1755 if (bitVectBitValue (rsave, i))
1756 emitcode ("pop", "%s", pic14_regWithIdx (i)->dname);
1762 /*-----------------------------------------------------------------*/
1764 /*-----------------------------------------------------------------*/
1766 pushSide (operand * oper, int size)
1769 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1772 char *l = aopGet (AOP (oper), offset++, FALSE, TRUE);
1773 if (AOP_TYPE (oper) != AOP_REG &&
1774 AOP_TYPE (oper) != AOP_DIR &&
1777 emitcode ("mov", "a,%s", l);
1778 emitcode ("push", "acc");
1781 emitcode ("push", "%s", l);
1785 /*-----------------------------------------------------------------*/
1786 /* assignResultValue - */
1787 /*-----------------------------------------------------------------*/
1789 assignResultValue (operand * oper)
1792 int size = AOP_SIZE (oper);
1794 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1796 // The last byte in the assignment is in W
1797 aopPut (AOP (oper), "W", size - 1);
1803 aopPut (AOP (oper), fReturn[offset], offset);
1811 /*-----------------------------------------------------------------*/
1812 /* genXpush - pushes onto the external stack */
1813 /*-----------------------------------------------------------------*/
1815 genXpush (iCode * ic)
1817 asmop *aop = newAsmop (0);
1819 int size, offset = 0;
1821 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1822 aopOp (IC_LEFT (ic), ic, FALSE);
1823 r = getFreePtr (ic, &aop, FALSE);
1826 emitcode ("mov", "%s,_spx", r->name);
1828 size = AOP_SIZE (IC_LEFT (ic));
1832 char *l = aopGet (AOP (IC_LEFT (ic)),
1833 offset++, FALSE, FALSE);
1835 emitcode ("movx", "@%s,a", r->name);
1836 emitcode ("inc", "%s", r->name);
1841 emitcode ("mov", "_spx,%s", r->name);
1843 freeAsmop (NULL, aop, ic, TRUE);
1844 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1847 /*-----------------------------------------------------------------*/
1848 /* genIpush - genrate code for pushing this gets a little complex */
1849 /*-----------------------------------------------------------------*/
1851 genIpush (iCode * ic)
1853 int size, offset = 0;
1857 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1858 /* if this is not a parm push : ie. it is spill push
1859 and spill push is always done on the local stack */
1863 /* and the item is spilt then do nothing */
1864 if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
1867 aopOp (IC_LEFT (ic), ic, FALSE);
1868 size = AOP_SIZE (IC_LEFT (ic));
1869 /* push it on the stack */
1872 l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE);
1878 emitcode ("push", "%s", l);
1883 /* this is a paramter push: in this case we call
1884 the routine to find the call and save those
1885 registers that need to be saved */
1888 /* if use external stack then call the external
1889 stack pushing routine */
1890 if (options.useXstack)
1896 /* then do the push */
1897 aopOp (IC_LEFT (ic), ic, FALSE);
1900 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1901 size = AOP_SIZE (IC_LEFT (ic));
1905 l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE);
1906 if (AOP_TYPE (IC_LEFT (ic)) != AOP_REG &&
1907 AOP_TYPE (IC_LEFT (ic)) != AOP_DIR &&
1910 emitcode ("mov", "a,%s", l);
1911 emitcode ("push", "acc");
1914 emitcode ("push", "%s", l);
1917 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1920 /*-----------------------------------------------------------------*/
1921 /* genIpop - recover the registers: can happen only for spilling */
1922 /*-----------------------------------------------------------------*/
1924 genIpop (iCode * ic)
1929 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1930 /* if the temp was not pushed then */
1931 if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
1934 aopOp (IC_LEFT (ic), ic, FALSE);
1935 size = AOP_SIZE (IC_LEFT (ic));
1936 offset = (size - 1);
1938 emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
1941 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1944 /*-----------------------------------------------------------------*/
1945 /* unsaverbank - restores the resgister bank from stack */
1946 /*-----------------------------------------------------------------*/
1948 unsaverbank (int bank, iCode * ic, bool popPsw)
1954 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
1957 if (options.useXstack)
1960 r = getFreePtr (ic, &aop, FALSE);
1963 emitcode ("mov", "%s,_spx", r->name);
1964 emitcode ("movx", "a,@%s", r->name);
1965 emitcode ("mov", "psw,a");
1966 emitcode ("dec", "%s", r->name);
1970 emitcode ("pop", "psw");
1973 for (i = (pic14_nRegs - 1); i >= 0; i--)
1975 if (options.useXstack)
1977 emitcode ("movx", "a,@%s", r->name);
1978 //emitcode("mov","(%s+%d),a",
1979 // regspic14[i].base,8*bank+regspic14[i].offset);
1980 emitcode ("dec", "%s", r->name);
1984 emitcode ("pop", ""); //"(%s+%d)",
1985 //regspic14[i].base,8*bank); //+regspic14[i].offset);
1989 if (options.useXstack)
1992 emitcode ("mov", "_spx,%s", r->name);
1993 freeAsmop (NULL, aop, ic, TRUE);
1998 /*-----------------------------------------------------------------*/
1999 /* saverbank - saves an entire register bank on the stack */
2000 /*-----------------------------------------------------------------*/
2002 saverbank (int bank, iCode * ic, bool pushPsw)
2008 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2009 if (options.useXstack)
2013 r = getFreePtr (ic, &aop, FALSE);
2014 emitcode ("mov", "%s,_spx", r->name);
2018 for (i = 0; i < pic14_nRegs; i++)
2020 if (options.useXstack)
2022 emitcode ("inc", "%s", r->name);
2023 //emitcode("mov","a,(%s+%d)",
2024 // regspic14[i].base,8*bank+regspic14[i].offset);
2025 emitcode ("movx", "@%s,a", r->name);
2028 emitcode ("push", ""); // "(%s+%d)",
2029 //regspic14[i].base,8*bank+regspic14[i].offset);
2035 if (options.useXstack)
2037 emitcode ("mov", "a,psw");
2038 emitcode ("movx", "@%s,a", r->name);
2039 emitcode ("inc", "%s", r->name);
2040 emitcode ("mov", "_spx,%s", r->name);
2041 freeAsmop (NULL, aop, ic, TRUE);
2045 emitcode ("push", "psw");
2047 emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
2053 /*-----------------------------------------------------------------*/
2054 /* genCall - generates a call statement */
2055 /*-----------------------------------------------------------------*/
2057 genCall (iCode * ic)
2061 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2063 /* if caller saves & we have not saved then */
2067 /* if we are calling a function that is not using
2068 the same register bank then we need to save the
2069 destination registers on the stack */
2070 detype = getSpec (operandType (IC_LEFT (ic)));
2072 (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
2073 IS_ISR (currFunc->etype) &&
2076 saverbank (SPEC_BANK (detype), ic, TRUE);
2078 /* if send set is not empty the assign */
2083 for (sic = setFirstItem (_G.sendSet); sic;
2084 sic = setNextItem (_G.sendSet))
2086 int size, offset = 0;
2088 aopOp (IC_LEFT (sic), sic, FALSE);
2089 size = AOP_SIZE (IC_LEFT (sic));
2092 char *l = aopGet (AOP (IC_LEFT (sic)), offset,
2094 DEBUGemitcode (";", "%d - left type %d", __LINE__, AOP (IC_LEFT (sic))->type);
2096 if (strcmp (l, fReturn[offset]))
2099 if (((AOP (IC_LEFT (sic))->type) == AOP_IMMD) ||
2100 ((AOP (IC_LEFT (sic))->type) == AOP_LIT))
2101 emitcode ("movlw", "%s", l);
2103 emitcode ("movf", "%s,w", l);
2104 // The last one is past in W
2106 emitcode ("movwf", "%s", fReturn[offset]);
2110 freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
2115 emitcode ("call", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
2116 OP_SYMBOL (IC_LEFT (ic))->rname :
2117 OP_SYMBOL (IC_LEFT (ic))->name));
2119 /* if we need assign a result value */
2120 if ((IS_ITEMP (IC_RESULT (ic)) &&
2121 (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
2122 OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
2123 IS_TRUE_SYMOP (IC_RESULT (ic)))
2127 aopOp (IC_RESULT (ic), ic, FALSE);
2130 assignResultValue (IC_RESULT (ic));
2132 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
2135 /* adjust the stack for parameters if
2137 if (IC_LEFT (ic)->parmBytes)
2140 if (IC_LEFT (ic)->parmBytes > 3)
2142 emitcode ("mov", "a,%s", spname);
2143 emitcode ("add", "a,#0x%02x", (-IC_LEFT (ic)->parmBytes) & 0xff);
2144 emitcode ("mov", "%s,a", spname);
2147 for (i = 0; i < IC_LEFT (ic)->parmBytes; i++)
2148 emitcode ("dec", "%s", spname);
2152 /* if register bank was saved then pop them */
2154 unsaverbank (SPEC_BANK (detype), ic, TRUE);
2156 /* if we hade saved some registers then unsave them */
2157 if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
2158 unsaveRegisters (ic);
2163 /*-----------------------------------------------------------------*/
2164 /* genPcall - generates a call by pointer statement */
2165 /*-----------------------------------------------------------------*/
2167 genPcall (iCode * ic)
2170 symbol *rlbl = newiTempLabel (NULL);
2173 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2174 /* if caller saves & we have not saved then */
2178 /* if we are calling a function that is not using
2179 the same register bank then we need to save the
2180 destination registers on the stack */
2181 detype = getSpec (operandType (IC_LEFT (ic)));
2183 IS_ISR (currFunc->etype) &&
2184 (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
2185 saverbank (SPEC_BANK (detype), ic, TRUE);
2188 /* push the return address on to the stack */
2189 emitcode ("mov", "a,#%05d_DS_", (rlbl->key + 100));
2190 emitcode ("push", "acc");
2191 emitcode ("mov", "a,#(%05d_DS_ >> 8)", (rlbl->key + 100));
2192 emitcode ("push", "acc");
2194 if (options.model == MODEL_FLAT24)
2196 emitcode ("mov", "a,#(%05d_DS_ >> 16)", (rlbl->key + 100));
2197 emitcode ("push", "acc");
2200 /* now push the calling address */
2201 aopOp (IC_LEFT (ic), ic, FALSE);
2203 pushSide (IC_LEFT (ic), FPTRSIZE);
2205 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
2207 /* if send set is not empty the assign */
2212 for (sic = setFirstItem (_G.sendSet); sic;
2213 sic = setNextItem (_G.sendSet))
2215 int size, offset = 0;
2216 aopOp (IC_LEFT (sic), sic, FALSE);
2217 size = AOP_SIZE (IC_LEFT (sic));
2220 char *l = aopGet (AOP (IC_LEFT (sic)), offset,
2222 if (strcmp (l, fReturn[offset]))
2223 emitcode ("mov", "%s,%s",
2228 freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
2233 emitcode ("ret", "");
2234 emitcode ("", "%05d_DS_:", (rlbl->key + 100));
2237 /* if we need assign a result value */
2238 if ((IS_ITEMP (IC_RESULT (ic)) &&
2239 (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
2240 OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
2241 IS_TRUE_SYMOP (IC_RESULT (ic)))
2245 aopOp (IC_RESULT (ic), ic, FALSE);
2248 assignResultValue (IC_RESULT (ic));
2250 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
2253 /* adjust the stack for parameters if
2255 if (IC_LEFT (ic)->parmBytes)
2258 if (IC_LEFT (ic)->parmBytes > 3)
2260 emitcode ("mov", "a,%s", spname);
2261 emitcode ("add", "a,#0x%02x", (-IC_LEFT (ic)->parmBytes) & 0xff);
2262 emitcode ("mov", "%s,a", spname);
2265 for (i = 0; i < IC_LEFT (ic)->parmBytes; i++)
2266 emitcode ("dec", "%s", spname);
2270 /* if register bank was saved then unsave them */
2272 (SPEC_BANK (currFunc->etype) !=
2273 SPEC_BANK (detype)))
2274 unsaverbank (SPEC_BANK (detype), ic, TRUE);
2276 /* if we hade saved some registers then
2279 unsaveRegisters (ic);
2283 /*-----------------------------------------------------------------*/
2284 /* resultRemat - result is rematerializable */
2285 /*-----------------------------------------------------------------*/
2287 resultRemat (iCode * ic)
2289 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2290 if (SKIP_IC (ic) || ic->op == IFX)
2293 if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
2295 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2296 if (sym->remat && !POINTER_SET (ic))
2303 #if defined(__BORLANDC__) || defined(_MSC_VER)
2304 #define STRCASECMP stricmp
2306 #define STRCASECMP strcasecmp
2309 /*-----------------------------------------------------------------*/
2310 /* inExcludeList - return 1 if the string is in exclude Reg list */
2311 /*-----------------------------------------------------------------*/
2313 inExcludeList (char *s)
2317 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2318 if (options.excludeRegs[i] &&
2319 STRCASECMP (options.excludeRegs[i], "none") == 0)
2322 for (i = 0; options.excludeRegs[i]; i++)
2324 if (options.excludeRegs[i] &&
2325 STRCASECMP (s, options.excludeRegs[i]) == 0)
2331 /*-----------------------------------------------------------------*/
2332 /* genFunction - generated code for function entry */
2333 /*-----------------------------------------------------------------*/
2335 genFunction (iCode * ic)
2340 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2341 labelOffset += FUNCTION_LABEL_INC;
2344 /* create the function header */
2345 emitcode (";", "-----------------------------------------");
2346 emitcode (";", " function %s", (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
2347 emitcode (";", "-----------------------------------------");
2349 emitcode ("", "%s:", sym->rname);
2350 fetype = getSpec (operandType (IC_LEFT (ic)));
2352 /* if critical function then turn interrupts off */
2353 if (SPEC_CRTCL (fetype))
2354 emitcode ("clr", "ea");
2356 /* here we need to generate the equates for the
2357 register bank if required */
2359 if (SPEC_BANK (fetype) != rbank)
2363 rbank = SPEC_BANK (fetype);
2364 for (i = 0; i < pic14_nRegs; i++)
2366 if (strcmp (regspic14[i].base, "0") == 0)
2367 emitcode ("", "%s = 0x%02x",
2369 8 * rbank + regspic14[i].offset);
2371 emitcode ("", "%s = %s + 0x%02x",
2374 8 * rbank + regspic14[i].offset);
2379 /* if this is an interrupt service routine then
2380 save acc, b, dpl, dph */
2381 if (IS_ISR (sym->etype))
2384 if (!inExcludeList ("acc"))
2385 emitcode ("push", "acc");
2386 if (!inExcludeList ("b"))
2387 emitcode ("push", "b");
2388 if (!inExcludeList ("dpl"))
2389 emitcode ("push", "dpl");
2390 if (!inExcludeList ("dph"))
2391 emitcode ("push", "dph");
2392 if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
2394 emitcode ("push", "dpx");
2395 /* Make sure we're using standard DPTR */
2396 emitcode ("push", "dps");
2397 emitcode ("mov", "dps, #0x00");
2398 if (options.stack10bit)
2400 /* This ISR could conceivably use DPTR2. Better save it. */
2401 emitcode ("push", "dpl1");
2402 emitcode ("push", "dph1");
2403 emitcode ("push", "dpx1");
2406 /* if this isr has no bank i.e. is going to
2407 run with bank 0 , then we need to save more
2409 if (!SPEC_BANK (sym->etype))
2412 /* if this function does not call any other
2413 function then we can be economical and
2414 save only those registers that are used */
2419 /* if any registers used */
2422 /* save the registers used */
2423 for (i = 0; i < sym->regsUsed->size; i++)
2425 if (bitVectBitValue (sym->regsUsed, i) ||
2426 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2427 emitcode ("push", "%s", pic14_regWithIdx (i)->dname);
2434 /* this function has a function call cannot
2435 determines register usage so we will have the
2437 saverbank (0, ic, FALSE);
2443 /* if callee-save to be used for this function
2444 then save the registers being used in this function */
2445 if (sym->calleeSave)
2449 /* if any registers used */
2452 /* save the registers used */
2453 for (i = 0; i < sym->regsUsed->size; i++)
2455 if (bitVectBitValue (sym->regsUsed, i) ||
2456 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2458 emitcode ("push", "%s", pic14_regWithIdx (i)->dname);
2466 /* set the register bank to the desired value */
2467 if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
2469 emitcode ("push", "psw");
2470 emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
2473 if (IS_RENT (sym->etype) || options.stackAuto)
2476 if (options.useXstack)
2478 emitcode ("mov", "r0,%s", spname);
2479 emitcode ("mov", "a,_bp");
2480 emitcode ("movx", "@r0,a");
2481 emitcode ("inc", "%s", spname);
2485 /* set up the stack */
2486 emitcode ("push", "_bp"); /* save the callers stack */
2488 emitcode ("mov", "_bp,%s", spname);
2491 /* adjust the stack for the function */
2497 werror (W_STACK_OVERFLOW, sym->name);
2499 if (i > 3 && sym->recvSize < 4)
2502 emitcode ("mov", "a,sp");
2503 emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
2504 emitcode ("mov", "sp,a");
2509 emitcode ("inc", "sp");
2515 emitcode ("mov", "a,_spx");
2516 emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff));
2517 emitcode ("mov", "_spx,a");
2522 /*-----------------------------------------------------------------*/
2523 /* genEndFunction - generates epilogue for functions */
2524 /*-----------------------------------------------------------------*/
2526 genEndFunction (iCode * ic)
2528 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
2530 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2532 if (IS_RENT (sym->etype) || options.stackAuto)
2534 emitcode ("mov", "%s,_bp", spname);
2537 /* if use external stack but some variables were
2538 added to the local stack then decrement the
2540 if (options.useXstack && sym->stack)
2542 emitcode ("mov", "a,sp");
2543 emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
2544 emitcode ("mov", "sp,a");
2548 if ((IS_RENT (sym->etype) || options.stackAuto))
2550 if (options.useXstack)
2552 emitcode ("mov", "r0,%s", spname);
2553 emitcode ("movx", "a,@r0");
2554 emitcode ("mov", "_bp,a");
2555 emitcode ("dec", "%s", spname);
2559 emitcode ("pop", "_bp");
2563 /* restore the register bank */
2564 if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
2565 emitcode ("pop", "psw");
2567 if (IS_ISR (sym->etype))
2570 /* now we need to restore the registers */
2571 /* if this isr has no bank i.e. is going to
2572 run with bank 0 , then we need to save more
2574 if (!SPEC_BANK (sym->etype))
2577 /* if this function does not call any other
2578 function then we can be economical and
2579 save only those registers that are used */
2584 /* if any registers used */
2587 /* save the registers used */
2588 for (i = sym->regsUsed->size; i >= 0; i--)
2590 if (bitVectBitValue (sym->regsUsed, i) ||
2591 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2592 emitcode ("pop", "%s", pic14_regWithIdx (i)->dname);
2599 /* this function has a function call cannot
2600 determines register usage so we will have the
2602 unsaverbank (0, ic, FALSE);
2606 if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
2608 if (options.stack10bit)
2610 emitcode ("pop", "dpx1");
2611 emitcode ("pop", "dph1");
2612 emitcode ("pop", "dpl1");
2614 emitcode ("pop", "dps");
2615 emitcode ("pop", "dpx");
2617 if (!inExcludeList ("dph"))
2618 emitcode ("pop", "dph");
2619 if (!inExcludeList ("dpl"))
2620 emitcode ("pop", "dpl");
2621 if (!inExcludeList ("b"))
2622 emitcode ("pop", "b");
2623 if (!inExcludeList ("acc"))
2624 emitcode ("pop", "acc");
2626 if (SPEC_CRTCL (sym->etype))
2627 emitcode ("setb", "ea");
2629 /* if debug then send end of function */
2630 /* if (options.debug && currFunc) { */
2634 emitcode (";", "C$%s$%d$%d$%d ==.",
2635 FileBaseName (ic->filename), currFunc->lastLine,
2636 ic->level, ic->block);
2637 if (IS_STATIC (currFunc->etype))
2638 emitcode (";", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
2640 emitcode (";", "XG$%s$0$0 ==.", currFunc->name);
2644 emitcode ("reti", "");
2648 if (SPEC_CRTCL (sym->etype))
2649 emitcode ("setb", "ea");
2651 if (sym->calleeSave)
2655 /* if any registers used */
2658 /* save the registers used */
2659 for (i = sym->regsUsed->size; i >= 0; i--)
2661 if (bitVectBitValue (sym->regsUsed, i) ||
2662 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2663 emitcode ("pop", "%s", pic14_regWithIdx (i)->dname);
2669 /* if debug then send end of function */
2673 emitcode (";", "C$%s$%d$%d$%d ==.",
2674 FileBaseName (ic->filename), currFunc->lastLine,
2675 ic->level, ic->block);
2676 if (IS_STATIC (currFunc->etype))
2677 emitcode (";", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
2679 emitcode (";", "XG$%s$0$0 ==.", currFunc->name);
2683 emitcode ("return", "");
2688 /*-----------------------------------------------------------------*/
2689 /* genRet - generate code for return statement */
2690 /*-----------------------------------------------------------------*/
2694 int size, offset = 0, pushed = 0;
2696 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2697 /* if we have no return value then
2698 just generate the "ret" */
2702 /* we have something to return then
2703 move the return value into place */
2704 aopOp (IC_LEFT (ic), ic, FALSE);
2705 size = AOP_SIZE (IC_LEFT (ic));
2710 if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
2713 l = aopGet (AOP (IC_LEFT (ic)), offset++,
2715 emitcode ("push", "%s", l);
2720 l = aopGet (AOP (IC_LEFT (ic)), offset,
2722 if (strcmp (fReturn[offset], l))
2724 if (((AOP (IC_LEFT (ic))->type) == AOP_IMMD) ||
2725 ((AOP (IC_LEFT (ic))->type) == AOP_LIT))
2726 emitcode ("movlw", "%s", l);
2728 emitcode ("movf", "%s,w", l);
2730 emitcode ("movwf", "%s", fReturn[offset]);
2741 if (strcmp (fReturn[pushed], "a"))
2742 emitcode ("pop", fReturn[pushed]);
2744 emitcode ("pop", "acc");
2747 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
2750 /* generate a jump to the return label
2751 if the next is not the return statement */
2752 if (!(ic->next && ic->next->op == LABEL &&
2753 IC_LABEL (ic->next) == returnLabel))
2755 emitcode ("goto", "_%05d_DS_", returnLabel->key + 100 + labelOffset);
2759 /*-----------------------------------------------------------------*/
2760 /* genLabel - generates a label */
2761 /*-----------------------------------------------------------------*/
2763 genLabel (iCode * ic)
2765 /* special case never generate */
2766 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2767 if (IC_LABEL (ic) == entryLabel)
2770 emitcode ("", "_%05d_DS_:", (IC_LABEL (ic)->key + 100 + labelOffset));
2773 /*-----------------------------------------------------------------*/
2774 /* genGoto - generates a goto */
2775 /*-----------------------------------------------------------------*/
2778 genGoto (iCode * ic)
2780 emitcode ("goto", "_%05d_DS_", (IC_LABEL (ic)->key + 100) + labelOffset);
2783 /*-----------------------------------------------------------------*/
2784 /* findLabelBackwards: walks back through the iCode chain looking */
2785 /* for the given label. Returns number of iCode instructions */
2786 /* between that label and given ic. */
2787 /* Returns zero if label not found. */
2788 /*-----------------------------------------------------------------*/
2791 findLabelBackwards (iCode * ic, int key)
2795 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2801 if (ic->op == LABEL && IC_LABEL (ic)->key == key)
2803 /* printf("findLabelBackwards = %d\n", count); */
2811 /*-----------------------------------------------------------------*/
2812 /* genPlusIncr :- does addition with increment if possible */
2813 /*-----------------------------------------------------------------*/
2815 genPlusIncr (iCode * ic)
2817 unsigned int icount;
2818 unsigned int size = getDataSize (IC_RESULT (ic));
2820 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2821 DEBUGemitcode ("; ", "result %d, left %d, right %d",
2822 AOP_TYPE (IC_RESULT (ic)),
2823 AOP_TYPE (IC_LEFT (ic)),
2824 AOP_TYPE (IC_RIGHT (ic)));
2826 /* will try to generate an increment */
2827 /* if the right side is not a literal
2829 if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
2832 DEBUGemitcode ("; ", "%s %d", __FUNCTION__, __LINE__);
2833 /* if the literal value of the right hand side
2834 is greater than 1 then it is faster to add */
2835 if ((icount = floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
2838 /* if increment 16 bits in register */
2839 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
2845 emitcode ("incf", "%s,f", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE));
2850 emitcode (" incf", "%s,f", aopGet (AOP (IC_RESULT (ic)), offset++, FALSE, FALSE));
2856 DEBUGemitcode ("; ", "%s %d", __FUNCTION__, __LINE__);
2857 /* if left is in accumulator - probably a bit operation */
2858 if (strcmp (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE), "a") &&
2859 (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY))
2862 emitcode ("bcf", "(%s >> 3), (%s & 7)",
2863 AOP (IC_RESULT (ic))->aopu.aop_dir,
2864 AOP (IC_RESULT (ic))->aopu.aop_dir);
2866 emitcode ("xorlw", "1");
2868 emitcode ("andlw", "1");
2871 emitcode ("bsf", "(%s >> 3), (%s & 7)",
2872 AOP (IC_RESULT (ic))->aopu.aop_dir,
2873 AOP (IC_RESULT (ic))->aopu.aop_dir);
2880 /* if the sizes are greater than 1 then we cannot */
2881 if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
2882 AOP_SIZE (IC_LEFT (ic)) > 1)
2885 /* If we are incrementing the same register by two: */
2887 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
2891 emitcode ("incf", "%s,f", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
2896 DEBUGemitcode ("; ", "couldn't increment result-%s left-%s",
2897 aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE),
2898 aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
2902 /*-----------------------------------------------------------------*/
2903 /* outBitAcc - output a bit in acc */
2904 /*-----------------------------------------------------------------*/
2906 outBitAcc (operand * result)
2908 symbol *tlbl = newiTempLabel (NULL);
2909 /* if the result is a bit */
2910 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2912 if (AOP_TYPE (result) == AOP_CRY)
2914 aopPut (AOP (result), "a", 0);
2918 emitcode ("jz", "%05d_DS_", tlbl->key + 100);
2919 emitcode ("mov", "a,%s", one);
2920 emitcode ("", "%05d_DS_:", tlbl->key + 100);
2925 /*-----------------------------------------------------------------*/
2926 /* genPlusBits - generates code for addition of two bits */
2927 /*-----------------------------------------------------------------*/
2929 genPlusBits (iCode * ic)
2932 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
2934 The following block of code will add two bits.
2935 Note that it'll even work if the destination is
2936 the carry (C in the status register).
2937 It won't work if the 'Z' bit is a source or destination.
2940 /* If the result is stored in the accumulator (w) */
2941 if (strcmp (aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE), "a") == 0)
2943 emitcode ("movlw", "(1 << (%s & 7))",
2944 AOP (IC_RESULT (ic))->aopu.aop_dir,
2945 AOP (IC_RESULT (ic))->aopu.aop_dir);
2946 emitcode ("bcf", "(%s >> 3), (%s & 7)",
2947 AOP (IC_RESULT (ic))->aopu.aop_dir,
2948 AOP (IC_RESULT (ic))->aopu.aop_dir);
2949 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
2950 AOP (IC_RIGHT (ic))->aopu.aop_dir,
2951 AOP (IC_RIGHT (ic))->aopu.aop_dir);
2952 emitcode ("xorwf", "(%s >>3),f",
2953 AOP (IC_RESULT (ic))->aopu.aop_dir);
2954 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
2955 AOP (IC_LEFT (ic))->aopu.aop_dir,
2956 AOP (IC_LEFT (ic))->aopu.aop_dir);
2957 emitcode ("xorwf", "(%s>>3),f",
2958 AOP (IC_RESULT (ic))->aopu.aop_dir);
2963 emitcode ("clrw", "");
2964 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
2965 AOP (IC_RIGHT (ic))->aopu.aop_dir,
2966 AOP (IC_RIGHT (ic))->aopu.aop_dir);
2967 emitcode ("xorlw", "1");
2968 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
2969 AOP (IC_LEFT (ic))->aopu.aop_dir,
2970 AOP (IC_LEFT (ic))->aopu.aop_dir);
2971 emitcode ("xorlw", "1");
2977 /* This is the original version of this code.
2979 * This is being kept around for reference,
2980 * because I am not entirely sure I got it right...
2983 adjustArithmeticResult (iCode * ic)
2985 if (AOP_SIZE (IC_RESULT (ic)) == 3 &&
2986 AOP_SIZE (IC_LEFT (ic)) == 3 &&
2987 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
2988 aopPut (AOP (IC_RESULT (ic)),
2989 aopGet (AOP (IC_LEFT (ic)), 2, FALSE, FALSE),
2992 if (AOP_SIZE (IC_RESULT (ic)) == 3 &&
2993 AOP_SIZE (IC_RIGHT (ic)) == 3 &&
2994 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
2995 aopPut (AOP (IC_RESULT (ic)),
2996 aopGet (AOP (IC_RIGHT (ic)), 2, FALSE, FALSE),
2999 if (AOP_SIZE (IC_RESULT (ic)) == 3 &&
3000 AOP_SIZE (IC_LEFT (ic)) < 3 &&
3001 AOP_SIZE (IC_RIGHT (ic)) < 3 &&
3002 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
3003 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
3006 sprintf (buffer, "#%d", pointerCode (getSpec (operandType (IC_LEFT (ic)))));
3007 aopPut (AOP (IC_RESULT (ic)), buffer, 2);
3011 /* This is the pure and virtuous version of this code.
3012 * I'm pretty certain it's right, but not enough to toss the old
3016 adjustArithmeticResult (iCode * ic)
3018 if (opIsGptr (IC_RESULT (ic)) &&
3019 opIsGptr (IC_LEFT (ic)) &&
3020 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
3022 aopPut (AOP (IC_RESULT (ic)),
3023 aopGet (AOP (IC_LEFT (ic)), GPTRSIZE - 1, FALSE, FALSE),
3027 if (opIsGptr (IC_RESULT (ic)) &&
3028 opIsGptr (IC_RIGHT (ic)) &&
3029 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
3031 aopPut (AOP (IC_RESULT (ic)),
3032 aopGet (AOP (IC_RIGHT (ic)), GPTRSIZE - 1, FALSE, FALSE),
3036 if (opIsGptr (IC_RESULT (ic)) &&
3037 AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
3038 AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
3039 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
3040 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
3043 sprintf (buffer, "#%d", pointerCode (getSpec (operandType (IC_LEFT (ic)))));
3044 aopPut (AOP (IC_RESULT (ic)), buffer, GPTRSIZE - 1);
3049 /*-----------------------------------------------------------------*/
3050 /* genPlus - generates code for addition */
3051 /*-----------------------------------------------------------------*/
3053 genPlus (iCode * ic)
3055 int size, offset = 0;
3057 /* special cases :- */
3058 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3060 aopOp (IC_LEFT (ic), ic, FALSE);
3061 aopOp (IC_RIGHT (ic), ic, FALSE);
3062 aopOp (IC_RESULT (ic), ic, TRUE);
3064 /* if literal, literal on the right or
3065 if left requires ACC or right is already
3068 if (AOP_TYPE (IC_LEFT (ic)) == AOP_LIT)
3070 operand *t = IC_RIGHT (ic);
3071 IC_RIGHT (ic) = IC_LEFT (ic);
3075 /* if both left & right are in bit space */
3076 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
3077 AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
3083 /* if left in bit space & right literal */
3084 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
3085 AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT)
3087 /* if result in bit space */
3088 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
3090 if ((unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
3092 emitcode ("movlw", "(1 << (%s & 7)) ;%d", AOP (IC_RESULT (ic))->aopu.aop_dir, __LINE__);
3093 if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3094 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
3095 AOP (IC_LEFT (ic))->aopu.aop_dir,
3096 AOP (IC_LEFT (ic))->aopu.aop_dir);
3098 emitcode ("xorwf", "(%s>>3),f", AOP (IC_RESULT (ic))->aopu.aop_dir);
3103 size = getDataSize (IC_RESULT (ic));
3106 MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
3107 emitcode ("addc", "a,#00 ;%d", __LINE__);
3108 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
3114 /* if I can do an increment instead
3115 of add then GOOD for ME */
3116 if (genPlusIncr (ic) == TRUE)
3119 size = getDataSize (IC_RESULT (ic));
3121 if (AOP (IC_RIGHT (ic))->type == AOP_LIT)
3123 /* Add a literal to something else */
3125 unsigned lit = floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3129 DEBUGemitcode (";", "adding lit to something. size %d", size);
3133 DEBUGemitcode (";", "size %d", size);
3140 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3141 emitcode ("incf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3145 emitcode ("incf", "%s,w", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3146 if (AOP_TYPE (IC_RESULT (ic)) != AOP_ACC)
3147 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), offset, FALSE, FALSE));
3151 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3152 emitcode ("decf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3156 emitcode ("decf", "%s,w", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3157 if (AOP_TYPE (IC_RESULT (ic)) != AOP_ACC)
3158 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), offset, FALSE, FALSE));
3162 if (!know_W || ((lit & 0xff) != l1))
3165 emitcode ("movlw", "0x%x", lit & 0xff);
3167 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3168 emitcode ("addwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3172 emitcode ("addwf", "%s,w", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3173 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), offset, FALSE, FALSE));
3177 emitcode ("incf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset + 1, FALSE, FALSE));
3188 else if (AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
3191 emitcode (";bitadd", "right is bit: %s", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
3192 emitcode (";bitadd", "left is bit: %s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3193 emitcode (";bitadd", "result is bit: %s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3195 /* here we are adding a bit to a char or int */
3198 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
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));
3209 if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
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");
3218 emitcode ("movf", "%s,w", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3219 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
3220 AOP (IC_RIGHT (ic))->aopu.aop_dir,
3221 AOP (IC_RIGHT (ic))->aopu.aop_dir);
3222 emitcode (" incf", "%s,w", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3225 if (AOP_TYPE (IC_RESULT (ic)) != AOP_ACC)
3228 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
3230 emitcode ("andlw", "1");
3231 emitcode ("bcf", "(%s >> 3), (%s & 7)",
3232 AOP (IC_RESULT (ic))->aopu.aop_dir,
3233 AOP (IC_RESULT (ic))->aopu.aop_dir);
3235 emitcode ("bsf", "(%s >> 3), (%s & 7)",
3236 AOP (IC_RESULT (ic))->aopu.aop_dir,
3237 AOP (IC_RESULT (ic))->aopu.aop_dir);
3241 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3250 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3252 emitcode ("clrz", "");
3254 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
3255 AOP (IC_RIGHT (ic))->aopu.aop_dir,
3256 AOP (IC_RIGHT (ic))->aopu.aop_dir);
3257 emitcode (" incf", "%s,f", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3263 emitcode ("movf", "%s,w", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3264 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
3265 AOP (IC_RIGHT (ic))->aopu.aop_dir,
3266 AOP (IC_RIGHT (ic))->aopu.aop_dir);
3267 emitcode (" incf", "%s,w", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3268 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3275 emitcode (" incf", "%s,f", aopGet (AOP (IC_RIGHT (ic)), offset++, FALSE, FALSE));
3284 if (strcmp (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE), "a") == 0)
3286 emitcode ("addwf", "%s,w", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
3287 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3291 //if ( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) || (AOP_TYPE(IC_RESULT(ic)) == AOP_ACC) )
3292 if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
3294 emitcode ("addwf", "%s,w", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
3295 if (AOP_TYPE (IC_RESULT (ic)) != AOP_ACC)
3296 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3301 emitcode ("movf", "%s,w", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
3303 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3304 emitcode ("addwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3307 if ((AOP_TYPE (IC_LEFT (ic)) == AOP_IMMD) ||
3308 (AOP_TYPE (IC_LEFT (ic)) == AOP_LIT))
3310 emitcode ("addlw", "%s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3314 emitcode ("addwf", "%s,w", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3315 if (AOP_TYPE (IC_RESULT (ic)) != AOP_ACC)
3316 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3327 if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3329 emitcode ("movf", "%s,w", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3330 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), offset, FALSE, FALSE));
3332 emitcode ("movf", "%s,w", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
3334 emitcode ("incfsz", "%s,w", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
3335 emitcode ("addwf", "%s,f", aopGet (AOP (IC_RESULT (ic)), offset, FALSE, FALSE));
3341 //adjustArithmeticResult(ic);
3344 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3345 freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3346 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
3349 /*-----------------------------------------------------------------*/
3350 /* genMinusDec :- does subtraction with decrement if possible */
3351 /*-----------------------------------------------------------------*/
3353 genMinusDec (iCode * ic)
3355 unsigned int icount;
3356 unsigned int size = getDataSize (IC_RESULT (ic));
3358 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3359 /* will try to generate an increment */
3360 /* if the right side is not a literal
3362 if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
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))) &&
3380 emitcode ("decf", "%s,f", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE));
3381 emitcode ("incfsz", "%s,w", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE));
3382 emitcode (" decf", "%s,f", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE));
3386 /* size is 3 or 4 */
3387 emitcode ("movlw", "0xff");
3388 emitcode ("addwf", "%s,f", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE));
3391 emitcode ("addwf", "%s,f", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE));
3393 emitcode ("addwf", "%s,f", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE));
3397 emitcode ("skpnc", "");
3399 emitcode ("addwf", "%s,f", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE));
3408 /* if the sizes are greater than 1 then we cannot */
3409 if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
3410 AOP_SIZE (IC_LEFT (ic)) > 1)
3413 /* we can if the aops of the left & result match or
3414 if they are in registers and the registers are the
3416 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3420 emitcode ("decf", "%s,f", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3425 DEBUGemitcode ("; returning", " result=%s, left=%s",
3426 aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE),
3427 aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3430 emitcode ("decf", "%s,w", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3431 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3438 /*-----------------------------------------------------------------*/
3439 /* addSign - complete with sign */
3440 /*-----------------------------------------------------------------*/
3442 addSign (operand * result, int offset, int sign)
3444 int size = (getDataSize (result) - offset);
3445 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3450 emitcode ("rlc", "a");
3451 emitcode ("subb", "a,acc");
3453 aopPut (AOP (result), "a", offset++);
3457 aopPut (AOP (result), zero, offset++);
3461 /*-----------------------------------------------------------------*/
3462 /* genMinusBits - generates code for subtraction of two bits */
3463 /*-----------------------------------------------------------------*/
3465 genMinusBits (iCode * ic)
3467 symbol *lbl = newiTempLabel (NULL);
3468 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3469 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
3471 emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
3472 emitcode ("jnb", "%s,%05d_DS_", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
3473 emitcode ("cpl", "c");
3474 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3475 outBitC (IC_RESULT (ic));
3479 emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
3480 emitcode ("subb", "a,acc");
3481 emitcode ("jnb", "%s,%05d_DS_", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100));
3482 emitcode ("inc", "a");
3483 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3484 aopPut (AOP (IC_RESULT (ic)), "a", 0);
3485 addSign (IC_RESULT (ic), MSB16, SPEC_USIGN (getSpec (operandType (IC_RESULT (ic)))));
3489 /*-----------------------------------------------------------------*/
3490 /* genMinus - generates code for subtraction */
3491 /*-----------------------------------------------------------------*/
3493 genMinus (iCode * ic)
3495 int size, offset = 0;
3496 unsigned long lit = 0L;
3498 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3499 aopOp (IC_LEFT (ic), ic, FALSE);
3500 aopOp (IC_RIGHT (ic), ic, FALSE);
3501 aopOp (IC_RESULT (ic), ic, TRUE);
3503 /* special cases :- */
3504 /* if both left & right are in bit space */
3505 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
3506 AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
3512 /* if I can do an decrement instead
3513 of subtract then GOOD for ME */
3514 if (genMinusDec (ic) == TRUE)
3517 size = getDataSize (IC_RESULT (ic));
3519 if (AOP (IC_RIGHT (ic))->type == AOP_LIT)
3521 /* Add a literal to something else */
3523 lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3526 /* add the first byte: */
3527 emitcode ("movlw", "0x%x", lit & 0xff);
3528 emitcode ("addwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3536 emitcode ("rlf", "_known_zero,w");
3537 emitcode ("addwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3542 emitcode ("movlw", "0x%x", lit & 0xff);
3543 emitcode ("addwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3553 emitcode ("movf", "%s", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
3554 emitcode ("subwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
3561 emitcode ("movf", "%s,w", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
3563 emitcode ("incfsz", "%s,w", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
3564 emitcode ("subwf", "%s,f", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3571 // adjustArithmeticResult(ic);
3574 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3575 freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3576 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
3580 /*-----------------------------------------------------------------*/
3581 /* genMultbits :- multiplication of bits */
3582 /*-----------------------------------------------------------------*/
3584 genMultbits (operand * left,
3588 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3590 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3591 emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
3596 /*-----------------------------------------------------------------*/
3597 /* genMultOneByte : 8 bit multiplication & division */
3598 /*-----------------------------------------------------------------*/
3600 genMultOneByte (operand * left,
3604 sym_link *opetype = operandType (result);
3609 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3610 /* (if two literals, the value is computed before) */
3611 /* if one literal, literal on the right */
3612 if (AOP_TYPE (left) == AOP_LIT)
3619 size = AOP_SIZE (result);
3620 /* signed or unsigned */
3621 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3622 l = aopGet (AOP (left), 0, FALSE, FALSE);
3624 emitcode ("mul", "ab");
3625 /* if result size = 1, mul signed = mul unsigned */
3626 aopPut (AOP (result), "a", 0);
3629 if (SPEC_USIGN (opetype))
3631 aopPut (AOP (result), "b", 1);
3633 /* for filling the MSBs */
3634 emitcode ("clr", "a");
3638 emitcode ("mov", "a,b");
3640 /* adjust the MSB if left or right neg */
3642 /* if one literal */
3643 if (AOP_TYPE (right) == AOP_LIT)
3645 /* AND literal negative */
3646 if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0)
3648 /* adjust MSB (c==0 after mul) */
3649 emitcode ("subb", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE));
3654 lbl = newiTempLabel (NULL);
3655 emitcode ("xch", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3656 emitcode ("cjne", "a,#0x80,%05d_DS_", (lbl->key + 100));
3657 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3658 emitcode ("xch", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3659 lbl = newiTempLabel (NULL);
3660 emitcode ("jc", "%05d_DS_", (lbl->key + 100));
3661 emitcode ("subb", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE));
3662 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3665 lbl = newiTempLabel (NULL);
3666 emitcode ("xch", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE));
3667 emitcode ("cjne", "a,#0x80,%05d_DS_", (lbl->key + 100));
3668 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3669 emitcode ("xch", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE));
3670 lbl = newiTempLabel (NULL);
3671 emitcode ("jc", "%05d_DS_", (lbl->key + 100));
3672 emitcode ("subb", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3673 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3675 aopPut (AOP (result), "a", 1);
3679 emitcode ("rlc", "a");
3680 emitcode ("subb", "a,acc");
3687 aopPut (AOP (result), "a", offset++);
3691 /*-----------------------------------------------------------------*/
3692 /* genMult - generates code for multiplication */
3693 /*-----------------------------------------------------------------*/
3695 genMult (iCode * ic)
3697 operand *left = IC_LEFT (ic);
3698 operand *right = IC_RIGHT (ic);
3699 operand *result = IC_RESULT (ic);
3701 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3702 /* assign the amsops */
3703 aopOp (left, ic, FALSE);
3704 aopOp (right, ic, FALSE);
3705 aopOp (result, ic, TRUE);
3707 /* special cases first */
3709 if (AOP_TYPE (left) == AOP_CRY &&
3710 AOP_TYPE (right) == AOP_CRY)
3712 genMultbits (left, right, result);
3716 /* if both are of size == 1 */
3717 if (AOP_SIZE (left) == 1 &&
3718 AOP_SIZE (right) == 1)
3720 genMultOneByte (left, right, result);
3724 /* should have been converted to function call */
3728 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3729 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3730 freeAsmop (result, NULL, ic, TRUE);
3733 /*-----------------------------------------------------------------*/
3734 /* genDivbits :- division of bits */
3735 /*-----------------------------------------------------------------*/
3737 genDivbits (operand * left,
3744 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3745 /* the result must be bit */
3746 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3747 l = aopGet (AOP (left), 0, FALSE, FALSE);
3751 emitcode ("div", "ab");
3752 emitcode ("rrc", "a");
3753 aopPut (AOP (result), "c", 0);
3756 /*-----------------------------------------------------------------*/
3757 /* genDivOneByte : 8 bit division */
3758 /*-----------------------------------------------------------------*/
3760 genDivOneByte (operand * left,
3764 sym_link *opetype = operandType (result);
3769 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3770 size = AOP_SIZE (result) - 1;
3772 /* signed or unsigned */
3773 if (SPEC_USIGN (opetype))
3775 /* unsigned is easy */
3776 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3777 l = aopGet (AOP (left), 0, FALSE, FALSE);
3779 emitcode ("div", "ab");
3780 aopPut (AOP (result), "a", 0);
3782 aopPut (AOP (result), zero, offset++);
3786 /* signed is a little bit more difficult */
3788 /* save the signs of the operands */
3789 l = aopGet (AOP (left), 0, FALSE, FALSE);
3791 emitcode ("xrl", "a,%s", aopGet (AOP (right), 0, FALSE, TRUE));
3792 emitcode ("push", "acc"); /* save it on the stack */
3794 /* now sign adjust for both left & right */
3795 l = aopGet (AOP (right), 0, FALSE, FALSE);
3797 lbl = newiTempLabel (NULL);
3798 emitcode ("jnb", "acc.7,%05d_DS_", (lbl->key + 100));
3799 emitcode ("cpl", "a");
3800 emitcode ("inc", "a");
3801 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3802 emitcode ("mov", "b,a");
3804 /* sign adjust left side */
3805 l = aopGet (AOP (left), 0, FALSE, FALSE);
3808 lbl = newiTempLabel (NULL);
3809 emitcode ("jnb", "acc.7,%05d_DS_", (lbl->key + 100));
3810 emitcode ("cpl", "a");
3811 emitcode ("inc", "a");
3812 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3814 /* now the division */
3815 emitcode ("div", "ab");
3816 /* we are interested in the lower order
3818 emitcode ("mov", "b,a");
3819 lbl = newiTempLabel (NULL);
3820 emitcode ("pop", "acc");
3821 /* if there was an over flow we don't
3822 adjust the sign of the result */
3823 emitcode ("jb", "ov,%05d_DS_", (lbl->key + 100));
3824 emitcode ("jnb", "acc.7,%05d_DS_", (lbl->key + 100));
3826 emitcode ("clr", "a");
3827 emitcode ("subb", "a,b");
3828 emitcode ("mov", "b,a");
3829 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3831 /* now we are done */
3832 aopPut (AOP (result), "b", 0);
3835 emitcode ("mov", "c,b.7");
3836 emitcode ("subb", "a,acc");
3839 aopPut (AOP (result), "a", offset++);
3843 /*-----------------------------------------------------------------*/
3844 /* genDiv - generates code for division */
3845 /*-----------------------------------------------------------------*/
3849 operand *left = IC_LEFT (ic);
3850 operand *right = IC_RIGHT (ic);
3851 operand *result = IC_RESULT (ic);
3853 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3854 /* assign the amsops */
3855 aopOp (left, ic, FALSE);
3856 aopOp (right, ic, FALSE);
3857 aopOp (result, ic, TRUE);
3859 /* special cases first */
3861 if (AOP_TYPE (left) == AOP_CRY &&
3862 AOP_TYPE (right) == AOP_CRY)
3864 genDivbits (left, right, result);
3868 /* if both are of size == 1 */
3869 if (AOP_SIZE (left) == 1 &&
3870 AOP_SIZE (right) == 1)
3872 genDivOneByte (left, right, result);
3876 /* should have been converted to function call */
3879 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3880 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3881 freeAsmop (result, NULL, ic, TRUE);
3884 /*-----------------------------------------------------------------*/
3885 /* genModbits :- modulus of bits */
3886 /*-----------------------------------------------------------------*/
3888 genModbits (operand * left,
3895 /* the result must be bit */
3896 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3897 l = aopGet (AOP (left), 0, FALSE, FALSE);
3901 emitcode ("div", "ab");
3902 emitcode ("mov", "a,b");
3903 emitcode ("rrc", "a");
3904 aopPut (AOP (result), "c", 0);
3907 /*-----------------------------------------------------------------*/
3908 /* genModOneByte : 8 bit modulus */
3909 /*-----------------------------------------------------------------*/
3911 genModOneByte (operand * left,
3915 sym_link *opetype = operandType (result);
3919 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3920 /* signed or unsigned */
3921 if (SPEC_USIGN (opetype))
3923 /* unsigned is easy */
3924 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3925 l = aopGet (AOP (left), 0, FALSE, FALSE);
3927 emitcode ("div", "ab");
3928 aopPut (AOP (result), "b", 0);
3932 /* signed is a little bit more difficult */
3934 /* save the signs of the operands */
3935 l = aopGet (AOP (left), 0, FALSE, FALSE);
3938 emitcode ("xrl", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3939 emitcode ("push", "acc"); /* save it on the stack */
3941 /* now sign adjust for both left & right */
3942 l = aopGet (AOP (right), 0, FALSE, FALSE);
3945 lbl = newiTempLabel (NULL);
3946 emitcode ("jnb", "acc.7,%05d_DS_", (lbl->key + 100));
3947 emitcode ("cpl", "a");
3948 emitcode ("inc", "a");
3949 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3950 emitcode ("mov", "b,a");
3952 /* sign adjust left side */
3953 l = aopGet (AOP (left), 0, FALSE, FALSE);
3956 lbl = newiTempLabel (NULL);
3957 emitcode ("jnb", "acc.7,%05d_DS_", (lbl->key + 100));
3958 emitcode ("cpl", "a");
3959 emitcode ("inc", "a");
3960 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3962 /* now the multiplication */
3963 emitcode ("div", "ab");
3964 /* we are interested in the lower order
3966 lbl = newiTempLabel (NULL);
3967 emitcode ("pop", "acc");
3968 /* if there was an over flow we don't
3969 adjust the sign of the result */
3970 emitcode ("jb", "ov,%05d_DS_", (lbl->key + 100));
3971 emitcode ("jnb", "acc.7,%05d_DS_", (lbl->key + 100));
3973 emitcode ("clr", "a");
3974 emitcode ("subb", "a,b");
3975 emitcode ("mov", "b,a");
3976 emitcode ("", "%05d_DS_:", (lbl->key + 100));
3978 /* now we are done */
3979 aopPut (AOP (result), "b", 0);
3983 /*-----------------------------------------------------------------*/
3984 /* genMod - generates code for division */
3985 /*-----------------------------------------------------------------*/
3989 operand *left = IC_LEFT (ic);
3990 operand *right = IC_RIGHT (ic);
3991 operand *result = IC_RESULT (ic);
3993 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
3994 /* assign the amsops */
3995 aopOp (left, ic, FALSE);
3996 aopOp (right, ic, FALSE);
3997 aopOp (result, ic, TRUE);
3999 /* special cases first */
4001 if (AOP_TYPE (left) == AOP_CRY &&
4002 AOP_TYPE (right) == AOP_CRY)
4004 genModbits (left, right, result);
4008 /* if both are of size == 1 */
4009 if (AOP_SIZE (left) == 1 &&
4010 AOP_SIZE (right) == 1)
4012 genModOneByte (left, right, result);
4016 /* should have been converted to function call */
4020 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4021 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4022 freeAsmop (result, NULL, ic, TRUE);
4025 /*-----------------------------------------------------------------*/
4026 /* genIfxJump :- will create a jump depending on the ifx */
4027 /*-----------------------------------------------------------------*/
4029 genIfxJump (iCode * ic, char *jval)
4032 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4033 /* if true label then we jump if condition
4038 if (strcmp (jval, "a") == 0)
4040 else if (strcmp (jval, "c") == 0)
4043 emitcode ("btfsc", "(%s >> 3),(%s & 7)", jval, jval);
4045 emitcode (" goto", "_%05d_DS_", IC_TRUE (ic)->key + 100 + labelOffset);
4050 /* false label is present */
4051 if (strcmp (jval, "a") == 0)
4053 else if (strcmp (jval, "c") == 0)
4056 emitcode ("btfss", "(%s >> 3),(%s & 7)", jval, jval);
4058 emitcode (" goto", "_%05d_DS_", IC_FALSE (ic)->key + 100 + labelOffset);
4063 /* mark the icode as generated */
4067 /*-----------------------------------------------------------------*/
4069 /*-----------------------------------------------------------------*/
4071 genSkip (iCode * ifx, int status_bit)
4089 emitcode ("skpndc", "");
4094 emitcode ("goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4112 emitcode ("skpdc", "");
4115 emitcode ("goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4121 /*-----------------------------------------------------------------*/
4123 /*-----------------------------------------------------------------*/
4125 genSkipc (iCode * ifx, int condition)
4136 emitcode ("goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4138 emitcode ("goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4142 /*-----------------------------------------------------------------*/
4144 /*-----------------------------------------------------------------*/
4146 genSkipz (iCode * ifx, int condition)
4157 emitcode ("goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4159 emitcode ("goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4162 /*-----------------------------------------------------------------*/
4163 /* genCmp :- greater or less than comparison */
4164 /*-----------------------------------------------------------------*/
4166 genCmp (operand * left, operand * right,
4167 operand * result, iCode * ifx, int sign)
4169 int size, offset = 0;
4170 unsigned long lit = 0L, i = 0;
4172 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4173 /* if left & right are bit variables */
4174 if (AOP_TYPE (left) == AOP_CRY &&
4175 AOP_TYPE (right) == AOP_CRY)
4177 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4178 emitcode ("anl", "c,/%s", AOP (left)->aopu.aop_dir);
4182 /* subtract right from left if at the
4183 end the carry flag is set then we know that
4184 left is greater than right */
4185 size = max (AOP_SIZE (left), AOP_SIZE (right));
4187 /* if unsigned char cmp with lit, do cjne left,#right,zz */
4188 if ((size == 1) && !sign &&
4189 (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
4191 symbol *lbl = newiTempLabel (NULL);
4192 emitcode ("cjne", "%s,%s,%05d_DS_",
4193 aopGet (AOP (left), offset, FALSE, FALSE),
4194 aopGet (AOP (right), offset, FALSE, FALSE),
4196 emitcode ("", "%05d_DS_:", lbl->key + 100);
4201 if (AOP_TYPE (right) == AOP_LIT)
4204 DEBUGemitcode (";right lit", "%d", sign);
4206 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4210 i = (lit >> (size * 8)) & 0xff;
4213 emitcode ("movf", "%s,w", aopGet (AOP (left), size, FALSE, FALSE));
4214 genSkipz (ifx, IC_TRUE (ifx) == NULL);
4218 emitcode ("movlw", "0x%x", i);
4219 emitcode ("subwf", "%s,w", aopGet (AOP (left), size, FALSE, FALSE));
4220 genSkipc (ifx, IC_TRUE (ifx) == NULL);
4227 if (AOP_TYPE (left) == AOP_LIT)
4230 DEBUGemitcode (";left lit", "%d", sign);
4232 lit = (unsigned long) (floatFromVal (AOP (left)->aopu.aop_lit)) + 1;
4237 i = (lit >> (size * 8)) & 0xff;
4240 emitcode ("movf", "%s,w", aopGet (AOP (right), size, FALSE, FALSE));
4241 genSkipz (ifx, IC_TRUE (ifx) != NULL);
4245 emitcode ("decf", "%s,w", aopGet (AOP (right), size, FALSE, FALSE));
4246 genSkipz (ifx, IC_TRUE (ifx) != NULL);
4251 emitcode ("movlw", "0x%x", i);
4252 emitcode ("subwf", "%s,w", aopGet (AOP (right), size, FALSE, FALSE));
4253 genSkipc (ifx, IC_TRUE (ifx) != NULL);
4262 DEBUGemitcode (";sign", "%d", sign);
4263 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
4264 emitcode ("subwf", "%s,w", aopGet (AOP (left), offset++, FALSE, FALSE));
4269 /*if (AOP_TYPE(right) == AOP_LIT){
4270 unsigned long lit = (unsigned long)
4271 floatFromVal(AOP(right)->aopu.aop_lit);
4272 emitcode("subb","a,#0x%02x",
4273 0x80 ^ (unsigned int)((lit >> (offset*8)) & 0x0FFL));
4275 emitcode("mov","b,%s",aopGet(AOP(right),offset++,FALSE,FALSE));
4276 emitcode("xrl","b,#0x80");
4277 emitcode("subb","a,b");
4280 emitcode("subb","a,%s",aopGet(AOP(right),offset++,FALSE,FALSE));
4282 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
4284 emitcode ("incfsz", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
4285 emitcode ("subwf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4292 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4298 /* if the result is used in the next
4299 ifx conditional branch then generate
4300 code a little differently */
4302 genIfxJump (ifx, "c");
4305 /* leave the result in acc */
4310 /*-----------------------------------------------------------------*/
4311 /* genCmpGt :- greater than comparison */
4312 /*-----------------------------------------------------------------*/
4314 genCmpGt (iCode * ic, iCode * ifx)
4316 operand *left, *right, *result;
4317 sym_link *letype, *retype;
4320 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4321 left = IC_LEFT (ic);
4322 right = IC_RIGHT (ic);
4323 result = IC_RESULT (ic);
4325 letype = getSpec (operandType (left));
4326 retype = getSpec (operandType (right));
4327 sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
4328 /* assign the amsops */
4329 aopOp (left, ic, FALSE);
4330 aopOp (right, ic, FALSE);
4331 aopOp (result, ic, TRUE);
4333 genCmp (right, left, result, ifx, sign);
4335 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4336 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4337 freeAsmop (result, NULL, ic, TRUE);
4340 /*-----------------------------------------------------------------*/
4341 /* genCmpLt - less than comparisons */
4342 /*-----------------------------------------------------------------*/
4344 genCmpLt (iCode * ic, iCode * ifx)
4346 operand *left, *right, *result;
4347 sym_link *letype, *retype;
4350 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4351 left = IC_LEFT (ic);
4352 right = IC_RIGHT (ic);
4353 result = IC_RESULT (ic);
4355 letype = getSpec (operandType (left));
4356 retype = getSpec (operandType (right));
4357 sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
4359 /* assign the amsops */
4360 aopOp (left, ic, FALSE);
4361 aopOp (right, ic, FALSE);
4362 aopOp (result, ic, TRUE);
4364 genCmp (left, right, result, ifx, sign);
4366 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4367 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4368 freeAsmop (result, NULL, ic, TRUE);
4371 /*-----------------------------------------------------------------*/
4372 /* gencjneshort - compare and jump if not equal */
4373 /*-----------------------------------------------------------------*/
4375 gencjneshort (operand * left, operand * right, symbol * lbl)
4377 int size = max (AOP_SIZE (left), AOP_SIZE (right));
4379 unsigned long lit = 0L;
4381 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4382 /* if the left side is a literal or
4383 if the right is in a pointer register and left
4385 if ((AOP_TYPE (left) == AOP_LIT) ||
4386 (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
4392 if (AOP_TYPE (right) == AOP_LIT)
4393 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4395 /* if the right side is a literal then anything goes */
4396 if (AOP_TYPE (right) == AOP_LIT &&
4397 AOP_TYPE (left) != AOP_DIR)
4403 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4404 emitcode ("xorlw", "0x%x", lit & 0xff);
4407 emitcode ("movf", "%s,f", aopGet (AOP (left), offset, FALSE, FALSE));
4410 emitcode ("goto", "_%05d_DS_", lbl->key + 100 + labelOffset);
4416 /* if the right side is in a register or in direct space or
4417 if the left is a pointer register & right is not */
4418 else if (AOP_TYPE (right) == AOP_REG ||
4419 AOP_TYPE (right) == AOP_DIR ||
4420 (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) ||
4421 (IS_AOP_PREG (left) && !IS_AOP_PREG (right)))
4425 if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
4426 ((lit & 0xff) != 0))
4428 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4429 emitcode ("xorlw", "0x%x", lit & 0xff);
4433 emitcode ("movf", "%s,f", aopGet (AOP (left), offset, FALSE, FALSE));
4436 emitcode ("goto", "_%05d_DS_", lbl->key + 100 + labelOffset);
4439 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4440 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
4441 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
4442 emitcode("jnz","%05d_DS_",lbl->key+100);
4444 emitcode("cjne","a,%s,%05d_DS_",
4445 aopGet(AOP(right),offset,FALSE,TRUE),
4453 /* right is a pointer reg need both a & b */
4456 char *l = aopGet (AOP (left), offset, FALSE, FALSE);
4457 if (strcmp (l, "b"))
4458 emitcode ("mov", "b,%s", l);
4459 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4460 emitcode ("cjne", "a,b,%05d_DS_", lbl->key + 100);
4466 /*-----------------------------------------------------------------*/
4467 /* gencjne - compare and jump if not equal */
4468 /*-----------------------------------------------------------------*/
4470 gencjne (operand * left, operand * right, symbol * lbl)
4472 symbol *tlbl = newiTempLabel (NULL);
4474 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4475 gencjneshort (left, right, lbl);
4477 emitcode ("mov", "a,%s", one);
4478 emitcode ("sjmp", "%05d_DS_", tlbl->key + 100);
4479 emitcode ("", "%05d_DS_:", lbl->key + 100);
4480 emitcode ("clr", "a");
4481 emitcode ("", "%05d_DS_:", tlbl->key + 100);
4485 /*-----------------------------------------------------------------*/
4486 /* genCmpEq - generates code for equal to */
4487 /*-----------------------------------------------------------------*/
4489 genCmpEq (iCode * ic, iCode * ifx)
4491 operand *left, *right, *result;
4492 unsigned long lit = 0L;
4493 int size, offset = 0;
4495 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4497 DEBUGemitcode ("; ifx is non-null", "");
4499 DEBUGemitcode ("; ifx is null", "");
4501 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4502 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4503 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4505 size = max (AOP_SIZE (left), AOP_SIZE (right));
4507 /* if literal, literal on the right or
4508 if the right is in a pointer register and left
4510 if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
4511 (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
4513 operand *t = IC_RIGHT (ic);
4514 IC_RIGHT (ic) = IC_LEFT (ic);
4518 if (ifx && !AOP_SIZE (result))
4521 /* if they are both bit variables */
4522 if (AOP_TYPE (left) == AOP_CRY &&
4523 ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
4525 if (AOP_TYPE (right) == AOP_LIT)
4527 unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
4530 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4531 emitcode ("cpl", "c");
4535 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4539 emitcode ("clr", "c");
4541 /* AOP_TYPE(right) == AOP_CRY */
4545 symbol *lbl = newiTempLabel (NULL);
4546 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4547 emitcode ("jb", "%s,%05d_DS_", AOP (right)->aopu.aop_dir, (lbl->key + 100));
4548 emitcode ("cpl", "c");
4549 emitcode ("", "%05d_DS_:", (lbl->key + 100));
4551 /* if true label then we jump if condition
4553 tlbl = newiTempLabel (NULL);
4556 emitcode ("jnc", "%05d_DS_", tlbl->key + 100);
4557 emitcode ("ljmp", "%05d_DS_", IC_TRUE (ifx)->key + 100);
4561 emitcode ("jc", "%05d_DS_", tlbl->key + 100);
4562 emitcode ("ljmp", "%05d_DS_", IC_FALSE (ifx)->key + 100);
4564 emitcode ("", "%05d_DS_:", tlbl->key + 100 + labelOffset);
4569 /* They're not both bit variables. Is the right a literal? */
4570 if (AOP_TYPE (right) == AOP_LIT)
4573 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4580 int h = (lit >> 8) & 0xff;
4583 /* Check special cases for integers */
4584 switch (lit & 0xffff)
4587 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4588 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4593 emitcode ("decf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4594 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4599 emitcode ("decf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4600 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4605 emitcode ("incf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4606 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4611 emitcode ("incf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4612 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4619 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4620 emitcode ("xorlw", "0x%x", l);
4621 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4627 emitcode ("movf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4628 emitcode ("xorlw", "0x%x", h);
4629 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4635 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4636 emitcode ("xorlw", "0x%x", l);
4637 emitcode ("movlw", "0x%x", h);
4639 emitcode ("xorwf", "%s,w", aopGet (AOP (left), offset + 1, FALSE, FALSE));
4661 emitcode ("decf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4663 emitcode ("goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4667 emitcode ("decfsz", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4668 emitcode ("goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4674 emitcode ("incf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4676 emitcode ("goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4680 emitcode ("incfsz", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4681 emitcode ("goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4685 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4687 emitcode ("xorlw", "0x%x", lit & 0xff);
4692 // emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
4693 //emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4699 else if (AOP_TYPE (right) == AOP_CRY)
4701 /* we know the left is not a bit, but that the right is */
4702 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4704 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
4705 AOP (right)->aopu.aop_dir,
4706 AOP (right)->aopu.aop_dir);
4708 emitcode ("btfss", "(%s >> 3), (%s & 7)",
4709 AOP (right)->aopu.aop_dir,
4710 AOP (right)->aopu.aop_dir);
4712 emitcode ("xorlw", "1");
4714 /* if the two are equal, then W will be 0 and the Z bit is set
4715 * we could test Z now, or go ahead and check the high order bytes if
4716 * the variable we're comparing is larger than a byte. */
4719 emitcode ("iorwf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4724 emitcode (" goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4729 emitcode (" goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4735 /* They're both variables that are larger than bits */
4738 tlbl = newiTempLabel (NULL);
4743 emitcode ("movf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
4744 emitcode ("xorwf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
4751 emitcode (" goto", "_%05d_DS_", tlbl->key + 100 + labelOffset);
4756 emitcode (" goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
4762 emitcode (" goto", "_%05d_DS_", IC_FALSE (ifx)->key + 100 + labelOffset);
4766 if (s > 1 && IC_TRUE (ifx))
4767 emitcode ("", "_%05d_DS_:", tlbl->key + 100 + labelOffset);
4770 /* mark the icode as generated */
4775 /* if they are both bit variables */
4776 if (AOP_TYPE (left) == AOP_CRY &&
4777 ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
4779 if (AOP_TYPE (right) == AOP_LIT)
4781 unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
4784 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4785 emitcode ("cpl", "c");
4789 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4793 emitcode ("clr", "c");
4795 /* AOP_TYPE(right) == AOP_CRY */
4799 symbol *lbl = newiTempLabel (NULL);
4800 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4801 emitcode ("jb", "%s,%05d_DS_", AOP (right)->aopu.aop_dir, (lbl->key + 100));
4802 emitcode ("cpl", "c");
4803 emitcode ("", "%05d_DS_:", (lbl->key + 100));
4806 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4813 genIfxJump (ifx, "c");
4816 /* if the result is used in an arithmetic operation
4817 then put the result in place */
4822 gencjne (left, right, newiTempLabel (NULL));
4823 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4825 aopPut (AOP (result), "a", 0);
4830 genIfxJump (ifx, "a");
4833 /* if the result is used in an arithmetic operation
4834 then put the result in place */
4835 if (AOP_TYPE (result) != AOP_CRY)
4837 /* leave the result in acc */
4841 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4842 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4843 freeAsmop (result, NULL, ic, TRUE);
4846 /*-----------------------------------------------------------------*/
4847 /* ifxForOp - returns the icode containing the ifx for operand */
4848 /*-----------------------------------------------------------------*/
4850 ifxForOp (operand * op, iCode * ic)
4852 /* if true symbol then needs to be assigned */
4853 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4854 if (IS_TRUE_SYMOP (op))
4857 /* if this has register type condition and
4858 the next instruction is ifx with the same operand
4859 and live to of the operand is upto the ifx only then */
4861 ic->next->op == IFX &&
4862 IC_COND (ic->next)->key == op->key &&
4863 OP_SYMBOL (op)->liveTo <= ic->next->seq)
4868 /*-----------------------------------------------------------------*/
4869 /* genAndOp - for && operation */
4870 /*-----------------------------------------------------------------*/
4872 genAndOp (iCode * ic)
4874 operand *left, *right, *result;
4877 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4878 /* note here that && operations that are in an
4879 if statement are taken away by backPatchLabels
4880 only those used in arthmetic operations remain */
4881 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4882 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4883 aopOp ((result = IC_RESULT (ic)), ic, FALSE);
4885 /* if both are bit variables */
4886 if (AOP_TYPE (left) == AOP_CRY &&
4887 AOP_TYPE (right) == AOP_CRY)
4889 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4890 emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
4895 tlbl = newiTempLabel (NULL);
4897 emitcode ("jz", "%05d_DS_", tlbl->key + 100);
4899 emitcode ("", "%05d_DS_:", tlbl->key + 100);
4903 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4904 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4905 freeAsmop (result, NULL, ic, TRUE);
4909 /*-----------------------------------------------------------------*/
4910 /* genOrOp - for || operation */
4911 /*-----------------------------------------------------------------*/
4914 modified this code, but it doesn't appear to ever get called
4918 genOrOp (iCode * ic)
4920 operand *left, *right, *result;
4923 /* note here that || operations that are in an
4924 if statement are taken away by backPatchLabels
4925 only those used in arthmetic operations remain */
4926 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4927 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4928 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4929 aopOp ((result = IC_RESULT (ic)), ic, FALSE);
4931 /* if both are bit variables */
4932 if (AOP_TYPE (left) == AOP_CRY &&
4933 AOP_TYPE (right) == AOP_CRY)
4935 emitcode ("clrc", "");
4936 emitcode ("btfss", "(%s >> 3), (%s & 7)",
4937 AOP (left)->aopu.aop_dir,
4938 AOP (left)->aopu.aop_dir);
4939 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
4940 AOP (right)->aopu.aop_dir,
4941 AOP (right)->aopu.aop_dir);
4942 emitcode ("setc", "");
4947 tlbl = newiTempLabel (NULL);
4950 emitcode ("goto", "%05d_DS_", tlbl->key + 100 + labelOffset);
4952 emitcode ("", "%05d_DS_:", tlbl->key + 100 + labelOffset);
4957 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4958 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4959 freeAsmop (result, NULL, ic, TRUE);
4962 /*-----------------------------------------------------------------*/
4963 /* isLiteralBit - test if lit == 2^n */
4964 /*-----------------------------------------------------------------*/
4966 isLiteralBit (unsigned long lit)
4968 unsigned long pw[32] =
4969 {1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
4970 0x100L, 0x200L, 0x400L, 0x800L,
4971 0x1000L, 0x2000L, 0x4000L, 0x8000L,
4972 0x10000L, 0x20000L, 0x40000L, 0x80000L,
4973 0x100000L, 0x200000L, 0x400000L, 0x800000L,
4974 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
4975 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L};
4978 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4979 for (idx = 0; idx < 32; idx++)
4985 /*-----------------------------------------------------------------*/
4986 /* continueIfTrue - */
4987 /*-----------------------------------------------------------------*/
4989 continueIfTrue (iCode * ic)
4991 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
4993 emitcode ("ljmp", "%05d_DS_", IC_TRUE (ic)->key + 100);
4997 /*-----------------------------------------------------------------*/
4999 /*-----------------------------------------------------------------*/
5001 jumpIfTrue (iCode * ic)
5003 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
5005 emitcode ("ljmp", "%05d_DS_", IC_FALSE (ic)->key + 100);
5009 /*-----------------------------------------------------------------*/
5010 /* jmpTrueOrFalse - */
5011 /*-----------------------------------------------------------------*/
5013 jmpTrueOrFalse (iCode * ic, symbol * tlbl)
5015 // ugly but optimized by peephole
5016 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
5019 symbol *nlbl = newiTempLabel (NULL);
5020 emitcode ("sjmp", "%05d_DS_", nlbl->key + 100);
5021 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5022 emitcode ("ljmp", "%05d_DS_", IC_TRUE (ic)->key + 100);
5023 emitcode ("", "%05d_DS_:", nlbl->key + 100);
5027 emitcode ("ljmp", "%05d_DS_", IC_FALSE (ic)->key + 100);
5028 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5033 /*-----------------------------------------------------------------*/
5034 /* genAnd - code for and */
5035 /*-----------------------------------------------------------------*/
5037 genAnd (iCode * ic, iCode * ifx)
5039 operand *left, *right, *result;
5040 int size, offset = 0;
5041 unsigned long lit = 0L;
5045 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
5046 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
5047 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
5048 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
5051 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
5053 AOP_TYPE (left), AOP_TYPE (right));
5054 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
5056 AOP_SIZE (left), AOP_SIZE (right));
5059 /* if left is a literal & right is not then exchange them */
5060 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
5061 AOP_NEEDSACC (left))
5063 operand *tmp = right;
5068 /* if result = right then exchange them */
5069 if (sameRegs (AOP (result), AOP (right)))
5071 operand *tmp = right;
5076 /* if right is bit then exchange them */
5077 if (AOP_TYPE (right) == AOP_CRY &&
5078 AOP_TYPE (left) != AOP_CRY)
5080 operand *tmp = right;
5084 if (AOP_TYPE (right) == AOP_LIT)
5085 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
5087 size = AOP_SIZE (result);
5090 // result = bit & yy;
5091 if (AOP_TYPE (left) == AOP_CRY)
5093 // c = bit & literal;
5094 if (AOP_TYPE (right) == AOP_LIT)
5098 if (size && sameRegs (AOP (result), AOP (left)))
5101 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
5106 if (size && (AOP_TYPE (result) == AOP_CRY))
5108 emitcode ("clr", "%s", AOP (result)->aopu.aop_dir);
5111 if ((AOP_TYPE (result) == AOP_CRY) && ifx)
5116 emitcode ("clr", "c");
5121 if (AOP_TYPE (right) == AOP_CRY)
5124 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
5125 emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
5130 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
5132 emitcode ("rrc", "a");
5133 emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
5141 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
5142 genIfxJump (ifx, "c");
5146 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5147 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5148 if ((AOP_TYPE (right) == AOP_LIT) &&
5149 (AOP_TYPE (result) == AOP_CRY) &&
5150 (AOP_TYPE (left) != AOP_CRY))
5152 int posbit = isLiteralBit (lit);
5157 MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE));
5160 emitcode ("mov", "c,acc.%d", posbit & 0x07);
5166 sprintf (buffer, "acc.%d", posbit & 0x07);
5167 genIfxJump (ifx, buffer);
5174 symbol *tlbl = newiTempLabel (NULL);
5175 int sizel = AOP_SIZE (left);
5177 emitcode ("setb", "c");
5180 if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
5182 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
5184 if ((posbit = isLiteralBit (bytelit)) != 0)
5185 emitcode ("jb", "acc.%d,%05d_DS_", (posbit - 1) & 0x07, tlbl->key + 100);
5188 if (bytelit != 0x0FFL)
5189 emitcode ("anl", "a,%s",
5190 aopGet (AOP (right), offset, FALSE, TRUE));
5191 emitcode ("jnz", "%05d_DS_", tlbl->key + 100);
5196 // bit = left & literal
5199 emitcode ("clr", "c");
5200 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5202 // if(left & literal)
5206 jmpTrueOrFalse (ifx, tlbl);
5214 /* if left is same as result */
5215 if (sameRegs (AOP (result), AOP (left)))
5217 for (; size--; offset++, lit >>= 8)
5219 if (AOP_TYPE (right) == AOP_LIT)
5224 /* and'ing with 0 has clears the result */
5225 emitcode ("clrf", "%s", aopGet (AOP (result), offset, FALSE, FALSE));
5228 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5233 int p = my_powof2 ((~lit) & 0xff);
5236 /* only one bit is set in the literal, so use a bcf instruction */
5237 emitcode ("bcf", "%s,%d", aopGet (AOP (left), offset, FALSE, TRUE), p);
5241 emitcode ("movlw", "0x%x", (lit & 0xff));
5242 emitcode ("andwf", "%s,f", aopGet (AOP (left), offset, FALSE, TRUE), p);
5249 if (AOP_TYPE (left) == AOP_ACC)
5250 emitcode ("iorwf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5253 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5254 emitcode ("iorwf", "%s,f", aopGet (AOP (left), offset, FALSE, FALSE));
5263 // left & result in different registers
5264 if (AOP_TYPE (result) == AOP_CRY)
5267 // if(size), result in bit
5268 // if(!size && ifx), conditional oper: if(left & right)
5269 symbol *tlbl = newiTempLabel (NULL);
5270 int sizer = min (AOP_SIZE (left), AOP_SIZE (right));
5272 emitcode ("setb", "c");
5275 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5276 emitcode ("anl", "a,%s",
5277 aopGet (AOP (left), offset, FALSE, FALSE));
5278 emitcode ("jnz", "%05d_DS_", tlbl->key + 100);
5284 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5288 jmpTrueOrFalse (ifx, tlbl);
5292 for (; (size--); offset++)
5295 // result = left & right
5296 if (AOP_TYPE (right) == AOP_LIT)
5298 int t = (lit >> (offset * 8)) & 0x0FFL;
5302 emitcode ("clrf", "%s",
5303 aopGet (AOP (result), offset, FALSE, FALSE));
5306 emitcode ("movf", "%s,w",
5307 aopGet (AOP (left), offset, FALSE, FALSE));
5308 emitcode ("movwf", "%s",
5309 aopGet (AOP (result), offset, FALSE, FALSE));
5312 emitcode ("movlw", "0x%x", t);
5313 emitcode ("andwf", "%s,w",
5314 aopGet (AOP (left), offset, FALSE, FALSE));
5315 emitcode ("movwf", "%s",
5316 aopGet (AOP (result), offset, FALSE, FALSE));
5322 if (AOP_TYPE (left) == AOP_ACC)
5323 emitcode ("andwf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5326 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5327 emitcode ("andwf", "%s,w",
5328 aopGet (AOP (left), offset, FALSE, FALSE));
5330 emitcode ("movwf", "%s", aopGet (AOP (result), offset, FALSE, FALSE));
5336 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5337 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5338 freeAsmop (result, NULL, ic, TRUE);
5341 /*-----------------------------------------------------------------*/
5342 /* genOr - code for or */
5343 /*-----------------------------------------------------------------*/
5345 genOr (iCode * ic, iCode * ifx)
5347 operand *left, *right, *result;
5348 int size, offset = 0;
5349 unsigned long lit = 0L;
5351 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
5353 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
5354 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
5355 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
5358 /* if left is a literal & right is not then exchange them */
5359 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
5360 AOP_NEEDSACC (left))
5362 operand *tmp = right;
5367 /* if result = right then exchange them */
5368 if (sameRegs (AOP (result), AOP (right)))
5370 operand *tmp = right;
5375 /* if right is bit then exchange them */
5376 if (AOP_TYPE (right) == AOP_CRY &&
5377 AOP_TYPE (left) != AOP_CRY)
5379 operand *tmp = right;
5384 if (AOP_TYPE (right) == AOP_LIT)
5385 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
5387 size = AOP_SIZE (result);
5391 if (AOP_TYPE (left) == AOP_CRY)
5393 if (AOP_TYPE (right) == AOP_LIT)
5395 // c = bit & literal;
5398 // lit != 0 => result = 1
5399 if (AOP_TYPE (result) == AOP_CRY)
5402 emitcode ("bsf", "(%s >> 3), (%s & 7)",
5403 AOP (result)->aopu.aop_dir,
5404 AOP (result)->aopu.aop_dir);
5406 continueIfTrue (ifx);
5409 emitcode (";XXXsetb", "c %s,%d", __FILE__, __LINE__);
5413 // lit == 0 => result = left
5414 if (size && sameRegs (AOP (result), AOP (left)))
5416 emitcode (";XXX mov", "c,%s %s,%d", AOP (left)->aopu.aop_dir, __FILE__, __LINE__);
5421 if (AOP_TYPE (right) == AOP_CRY)
5423 if (sameRegs (AOP (result), AOP (left)))
5426 emitcode ("bcf", "(%s >> 3), (%s & 7)",
5427 AOP (result)->aopu.aop_dir,
5428 AOP (result)->aopu.aop_dir);
5429 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
5430 AOP (right)->aopu.aop_dir,
5431 AOP (right)->aopu.aop_dir);
5432 emitcode ("bsf", "(%s >> 3), (%s & 7)",
5433 AOP (result)->aopu.aop_dir,
5434 AOP (result)->aopu.aop_dir);
5439 emitcode ("bcf", "(%s >> 3), (%s & 7)",
5440 AOP (result)->aopu.aop_dir,
5441 AOP (result)->aopu.aop_dir);
5442 emitcode ("btfss", "(%s >> 3), (%s & 7)",
5443 AOP (right)->aopu.aop_dir,
5444 AOP (right)->aopu.aop_dir);
5445 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
5446 AOP (left)->aopu.aop_dir,
5447 AOP (left)->aopu.aop_dir);
5448 emitcode ("bsf", "(%s >> 3), (%s & 7)",
5449 AOP (result)->aopu.aop_dir,
5450 AOP (result)->aopu.aop_dir);
5456 symbol *tlbl = newiTempLabel (NULL);
5457 emitcode (";XXX ", " %s,%d", __FILE__, __LINE__);
5458 if (!((AOP_TYPE (result) == AOP_CRY) && ifx))
5459 emitcode (";XXX setb", "c");
5460 emitcode (";XXX jb", "%s,%05d_DS_",
5461 AOP (left)->aopu.aop_dir, tlbl->key + 100);
5463 emitcode (";XXX jnz", "%05d_DS_", tlbl->key + 100);
5464 if ((AOP_TYPE (result) == AOP_CRY) && ifx)
5466 jmpTrueOrFalse (ifx, tlbl);
5472 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5481 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
5482 genIfxJump (ifx, "c");
5486 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5487 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5488 if ((AOP_TYPE (right) == AOP_LIT) &&
5489 (AOP_TYPE (result) == AOP_CRY) &&
5490 (AOP_TYPE (left) != AOP_CRY))
5494 emitcode (";XXX ", " %s,%d", __FILE__, __LINE__);
5497 emitcode (";XXX setb", "%s", AOP (result)->aopu.aop_dir);
5499 continueIfTrue (ifx);
5504 emitcode (";XXX ", " %s,%d", __FILE__, __LINE__);
5505 // lit = 0, result = boolean(left)
5507 emitcode (";XXX setb", "c");
5511 symbol *tlbl = newiTempLabel (NULL);
5512 emitcode (";XXX jnz", "%05d_DS_", tlbl->key + 100);
5514 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5518 genIfxJump (ifx, "a");
5526 /* if left is same as result */
5527 if (sameRegs (AOP (result), AOP (left)))
5529 for (; size--; offset++, lit >>= 8)
5531 if (AOP_TYPE (right) == AOP_LIT)
5533 if ((lit & 0xff) == 0)
5534 /* or'ing with 0 has no effect */
5538 int p = my_powof2 (lit & 0xff);
5541 /* only one bit is set in the literal, so use a bsf instruction */
5542 emitcode ("bsf", "%s,%d", aopGet (AOP (left), offset, FALSE, TRUE), p);
5546 emitcode ("movlw", "0x%x", (lit & 0xff));
5547 emitcode ("iorwf", "%s,f", aopGet (AOP (left), offset, FALSE, TRUE), p);
5554 if (AOP_TYPE (left) == AOP_ACC)
5555 emitcode ("iorwf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5558 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5559 emitcode ("iorwf", "%s,f", aopGet (AOP (left), offset, FALSE, FALSE));
5567 // left & result in different registers
5568 if (AOP_TYPE (result) == AOP_CRY)
5571 // if(size), result in bit
5572 // if(!size && ifx), conditional oper: if(left | right)
5573 symbol *tlbl = newiTempLabel (NULL);
5574 int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
5575 emitcode (";XXX ", " %s,%d", __FILE__, __LINE__);
5578 emitcode (";XXX setb", "c");
5581 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5582 emitcode (";XXX orl", "a,%s",
5583 aopGet (AOP (left), offset, FALSE, FALSE));
5584 emitcode (";XXX jnz", "%05d_DS_", tlbl->key + 100);
5590 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5594 jmpTrueOrFalse (ifx, tlbl);
5597 for (; (size--); offset++)
5600 // result = left & right
5601 if (AOP_TYPE (right) == AOP_LIT)
5603 int t = (lit >> (offset * 8)) & 0x0FFL;
5607 emitcode ("movf", "%s,w",
5608 aopGet (AOP (left), offset, FALSE, FALSE));
5609 emitcode ("movwf", "%s",
5610 aopGet (AOP (result), offset, FALSE, FALSE));
5613 emitcode ("movlw", "0x%x", t);
5614 emitcode ("iorwf", "%s,w",
5615 aopGet (AOP (left), offset, FALSE, FALSE));
5616 emitcode ("movwf", "%s",
5617 aopGet (AOP (result), offset, FALSE, FALSE));
5623 // faster than result <- left, anl result,right
5624 // and better if result is SFR
5625 if (AOP_TYPE (left) == AOP_ACC)
5626 emitcode ("iorwf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5629 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5630 emitcode ("iorwf", "%s,w",
5631 aopGet (AOP (left), offset, FALSE, FALSE));
5633 emitcode ("movwf", "%s", aopGet (AOP (result), offset, FALSE, FALSE));
5638 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5639 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5640 freeAsmop (result, NULL, ic, TRUE);
5643 /*-----------------------------------------------------------------*/
5644 /* genXor - code for xclusive or */
5645 /*-----------------------------------------------------------------*/
5647 genXor (iCode * ic, iCode * ifx)
5649 operand *left, *right, *result;
5650 int size, offset = 0;
5651 unsigned long lit = 0L;
5653 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
5655 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
5656 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
5657 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
5659 /* if left is a literal & right is not ||
5660 if left needs acc & right does not */
5661 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
5662 (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)))
5664 operand *tmp = right;
5669 /* if result = right then exchange them */
5670 if (sameRegs (AOP (result), AOP (right)))
5672 operand *tmp = right;
5677 /* if right is bit then exchange them */
5678 if (AOP_TYPE (right) == AOP_CRY &&
5679 AOP_TYPE (left) != AOP_CRY)
5681 operand *tmp = right;
5685 if (AOP_TYPE (right) == AOP_LIT)
5686 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
5688 size = AOP_SIZE (result);
5692 if (AOP_TYPE (left) == AOP_CRY)
5694 if (AOP_TYPE (right) == AOP_LIT)
5696 // c = bit & literal;
5699 // lit>>1 != 0 => result = 1
5700 if (AOP_TYPE (result) == AOP_CRY)
5703 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
5705 continueIfTrue (ifx);
5708 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);
5722 // lit == 1, result = not(left)
5723 if (size && sameRegs (AOP (result), AOP (left)))
5725 emitcode ("cpl", "%s", AOP (result)->aopu.aop_dir);
5730 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
5731 emitcode ("cpl", "c");
5740 symbol *tlbl = newiTempLabel (NULL);
5741 if (AOP_TYPE (right) == AOP_CRY)
5744 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
5748 int sizer = AOP_SIZE (right);
5750 // if val>>1 != 0, result = 1
5751 emitcode ("setb", "c");
5754 MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE));
5756 // test the msb of the lsb
5757 emitcode ("anl", "a,#0xfe");
5758 emitcode ("jnz", "%05d_DS_", tlbl->key + 100);
5762 emitcode ("rrc", "a");
5764 emitcode ("jnb", "%s,%05d_DS_", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
5765 emitcode ("cpl", "c");
5766 emitcode ("", "%05d_DS_:", (tlbl->key + 100));
5773 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
5774 genIfxJump (ifx, "c");
5778 if (sameRegs (AOP (result), AOP (left)))
5780 /* if left is same as result */
5781 for (; size--; offset++)
5783 if (AOP_TYPE (right) == AOP_LIT)
5785 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
5787 else if (IS_AOP_PREG (left))
5789 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5790 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
5791 aopPut (AOP (result), "a", offset);
5794 emitcode ("xrl", "%s,%s",
5795 aopGet (AOP (left), offset, FALSE, TRUE),
5796 aopGet (AOP (right), offset, FALSE, FALSE));
5800 if (AOP_TYPE (left) == AOP_ACC)
5801 emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
5804 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5805 if (IS_AOP_PREG (left))
5807 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
5808 aopPut (AOP (result), "a", offset);
5811 emitcode ("xrl", "%s,a",
5812 aopGet (AOP (left), offset, FALSE, TRUE));
5819 // left & result in different registers
5820 if (AOP_TYPE (result) == AOP_CRY)
5823 // if(size), result in bit
5824 // if(!size && ifx), conditional oper: if(left ^ right)
5825 symbol *tlbl = newiTempLabel (NULL);
5826 int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
5828 emitcode ("setb", "c");
5831 if ((AOP_TYPE (right) == AOP_LIT) &&
5832 (((lit >> (offset * 8)) & 0x0FFL) == 0x00L))
5834 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
5838 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5839 emitcode ("xrl", "a,%s",
5840 aopGet (AOP (left), offset, FALSE, FALSE));
5842 emitcode ("jnz", "%05d_DS_", tlbl->key + 100);
5848 emitcode ("", "%05d_DS_:", tlbl->key + 100);
5852 jmpTrueOrFalse (ifx, tlbl);
5855 for (; (size--); offset++)
5858 // result = left & right
5859 if (AOP_TYPE (right) == AOP_LIT)
5861 int t = (lit >> (offset * 8)) & 0x0FFL;
5865 emitcode ("movf", "%s,w",
5866 aopGet (AOP (left), offset, FALSE, FALSE));
5867 emitcode ("movwf", "%s",
5868 aopGet (AOP (result), offset, FALSE, FALSE));
5871 emitcode ("comf", "%s,w",
5872 aopGet (AOP (left), offset, FALSE, FALSE));
5873 emitcode ("movwf", "%s",
5874 aopGet (AOP (result), offset, FALSE, FALSE));
5877 emitcode ("movlw", "0x%x", t);
5878 emitcode ("xorwf", "%s,w",
5879 aopGet (AOP (left), offset, FALSE, FALSE));
5880 emitcode ("movwf", "%s",
5881 aopGet (AOP (result), offset, FALSE, FALSE));
5887 // faster than result <- left, anl result,right
5888 // and better if result is SFR
5889 if (AOP_TYPE (left) == AOP_ACC)
5890 emitcode ("xorwf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5893 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
5894 emitcode ("xorwf", "%s,w", aopGet (AOP (left), offset, FALSE, FALSE));
5896 if (AOP_TYPE (result) != AOP_ACC)
5897 emitcode ("movwf", "%s", aopGet (AOP (result), offset, FALSE, FALSE));
5902 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5903 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5904 freeAsmop (result, NULL, ic, TRUE);
5907 /*-----------------------------------------------------------------*/
5908 /* genInline - write the inline code out */
5909 /*-----------------------------------------------------------------*/
5911 genInline (iCode * ic)
5913 char buffer[MAX_INLINEASM];
5917 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
5919 _G.inLine += (!options.asmpeep);
5920 strcpy (buffer, IC_INLINE (ic));
5922 /* emit each line as a code */
5947 /* emitcode("",buffer); */
5948 _G.inLine -= (!options.asmpeep);
5951 /*-----------------------------------------------------------------*/
5952 /* genRRC - rotate right with carry */
5953 /*-----------------------------------------------------------------*/
5957 operand *left, *result;
5958 int size, offset = 0;
5961 /* rotate right with carry */
5962 left = IC_LEFT (ic);
5963 result = IC_RESULT (ic);
5964 aopOp (left, ic, FALSE);
5965 aopOp (result, ic, FALSE);
5967 /* move it to the result */
5968 size = AOP_SIZE (result);
5973 l = aopGet (AOP (left), offset, FALSE, FALSE);
5975 emitcode ("rrc", "a");
5976 if (AOP_SIZE (result) > 1)
5977 aopPut (AOP (result), "a", offset--);
5979 /* now we need to put the carry into the
5980 highest order byte of the result */
5981 if (AOP_SIZE (result) > 1)
5983 l = aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE);
5986 emitcode ("mov", "acc.7,c");
5987 aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
5988 freeAsmop (left, NULL, ic, TRUE);
5989 freeAsmop (result, NULL, ic, TRUE);
5992 /*-----------------------------------------------------------------*/
5993 /* genRLC - generate code for rotate left with carry */
5994 /*-----------------------------------------------------------------*/
5998 operand *left, *result;
5999 int size, offset = 0;
6002 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6003 /* rotate right with carry */
6004 left = IC_LEFT (ic);
6005 result = IC_RESULT (ic);
6006 aopOp (left, ic, FALSE);
6007 aopOp (result, ic, FALSE);
6009 /* move it to the result */
6010 size = AOP_SIZE (result);
6014 l = aopGet (AOP (left), offset, FALSE, FALSE);
6016 emitcode ("add", "a,acc");
6017 if (AOP_SIZE (result) > 1)
6018 aopPut (AOP (result), "a", offset++);
6021 l = aopGet (AOP (left), offset, FALSE, FALSE);
6023 emitcode ("rlc", "a");
6024 if (AOP_SIZE (result) > 1)
6025 aopPut (AOP (result), "a", offset++);
6028 /* now we need to put the carry into the
6029 highest order byte of the result */
6030 if (AOP_SIZE (result) > 1)
6032 l = aopGet (AOP (result), 0, FALSE, FALSE);
6035 emitcode ("mov", "acc.0,c");
6036 aopPut (AOP (result), "a", 0);
6037 freeAsmop (left, NULL, ic, TRUE);
6038 freeAsmop (result, NULL, ic, TRUE);
6041 /*-----------------------------------------------------------------*/
6042 /* genGetHbit - generates code get highest order bit */
6043 /*-----------------------------------------------------------------*/
6045 genGetHbit (iCode * ic)
6047 operand *left, *result;
6048 left = IC_LEFT (ic);
6049 result = IC_RESULT (ic);
6050 aopOp (left, ic, FALSE);
6051 aopOp (result, ic, FALSE);
6053 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6054 /* get the highest order byte into a */
6055 MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE));
6056 if (AOP_TYPE (result) == AOP_CRY)
6058 emitcode ("rlc", "a");
6063 emitcode ("rl", "a");
6064 emitcode ("anl", "a,#0x01");
6069 freeAsmop (left, NULL, ic, TRUE);
6070 freeAsmop (result, NULL, ic, TRUE);
6073 /*-----------------------------------------------------------------*/
6074 /* AccRol - rotate left accumulator by known count */
6075 /*-----------------------------------------------------------------*/
6077 AccRol (int shCount)
6079 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6080 shCount &= 0x0007; // shCount : 0..7
6087 emitcode ("rl", "a");
6090 emitcode ("rl", "a");
6091 emitcode ("rl", "a");
6094 emitcode ("swap", "a");
6095 emitcode ("rr", "a");
6098 emitcode ("swap", "a");
6101 emitcode ("swap", "a");
6102 emitcode ("rl", "a");
6105 emitcode ("rr", "a");
6106 emitcode ("rr", "a");
6109 emitcode ("rr", "a");
6114 /*-----------------------------------------------------------------*/
6115 /* AccLsh - left shift accumulator by known count */
6116 /*-----------------------------------------------------------------*/
6118 AccLsh (int shCount)
6120 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6124 emitcode ("add", "a,acc");
6125 else if (shCount == 2)
6127 emitcode ("add", "a,acc");
6128 emitcode ("add", "a,acc");
6132 /* rotate left accumulator */
6134 /* and kill the lower order bits */
6135 emitcode ("anl", "a,#0x%02x", SLMask[shCount]);
6140 /*-----------------------------------------------------------------*/
6141 /* AccRsh - right shift accumulator by known count */
6142 /*-----------------------------------------------------------------*/
6144 AccRsh (int shCount)
6146 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6152 emitcode ("rrc", "a");
6156 /* rotate right accumulator */
6157 AccRol (8 - shCount);
6158 /* and kill the higher order bits */
6159 emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
6164 /*-----------------------------------------------------------------*/
6165 /* AccSRsh - signed right shift accumulator by known count */
6166 /*-----------------------------------------------------------------*/
6168 AccSRsh (int shCount)
6171 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6176 emitcode ("mov", "c,acc.7");
6177 emitcode ("rrc", "a");
6179 else if (shCount == 2)
6181 emitcode ("mov", "c,acc.7");
6182 emitcode ("rrc", "a");
6183 emitcode ("mov", "c,acc.7");
6184 emitcode ("rrc", "a");
6188 tlbl = newiTempLabel (NULL);
6189 /* rotate right accumulator */
6190 AccRol (8 - shCount);
6191 /* and kill the higher order bits */
6192 emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
6193 emitcode ("jnb", "acc.%d,%05d_DS_", 7 - shCount, tlbl->key + 100);
6194 emitcode ("orl", "a,#0x%02x",
6195 (unsigned char) ~SRMask[shCount]);
6196 emitcode ("", "%05d_DS_:", tlbl->key + 100);
6201 /*-----------------------------------------------------------------*/
6202 /* shiftR1Left2Result - shift right one byte from left to result */
6203 /*-----------------------------------------------------------------*/
6205 shiftR1Left2Result (operand * left, int offl,
6206 operand * result, int offr,
6207 int shCount, int sign)
6209 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6210 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
6211 /* shift right accumulator */
6216 aopPut (AOP (result), "a", offr);
6219 /*-----------------------------------------------------------------*/
6220 /* shiftL1Left2Result - shift left one byte from left to result */
6221 /*-----------------------------------------------------------------*/
6223 shiftL1Left2Result (operand * left, int offl,
6224 operand * result, int offr, int shCount)
6227 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6228 l = aopGet (AOP (left), offl, FALSE, FALSE);
6230 /* shift left accumulator */
6232 aopPut (AOP (result), "a", offr);
6235 /*-----------------------------------------------------------------*/
6236 /* movLeft2Result - move byte from left to result */
6237 /*-----------------------------------------------------------------*/
6239 movLeft2Result (operand * left, int offl,
6240 operand * result, int offr, int sign)
6243 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6244 if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
6246 l = aopGet (AOP (left), offl, FALSE, FALSE);
6248 if (*l == '@' && (IS_AOP_PREG (result)))
6250 emitcode ("mov", "a,%s", l);
6251 aopPut (AOP (result), "a", offr);
6256 aopPut (AOP (result), l, offr);
6259 /* MSB sign in acc.7 ! */
6260 if (getDataSize (left) == offl + 1)
6262 emitcode ("mov", "a,%s", l);
6263 aopPut (AOP (result), "a", offr);
6270 /*-----------------------------------------------------------------*/
6271 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
6272 /*-----------------------------------------------------------------*/
6276 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6277 emitcode ("rrc", "a");
6278 emitcode ("xch", "a,%s", x);
6279 emitcode ("rrc", "a");
6280 emitcode ("xch", "a,%s", x);
6283 /*-----------------------------------------------------------------*/
6284 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
6285 /*-----------------------------------------------------------------*/
6289 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6290 emitcode ("xch", "a,%s", x);
6291 emitcode ("rlc", "a");
6292 emitcode ("xch", "a,%s", x);
6293 emitcode ("rlc", "a");
6296 /*-----------------------------------------------------------------*/
6297 /* AccAXLsh1 - left shift a:x<-0 by 1 */
6298 /*-----------------------------------------------------------------*/
6302 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6303 emitcode ("xch", "a,%s", x);
6304 emitcode ("add", "a,acc");
6305 emitcode ("xch", "a,%s", x);
6306 emitcode ("rlc", "a");
6309 /*-----------------------------------------------------------------*/
6310 /* AccAXLsh - left shift a:x by known count (0..7) */
6311 /*-----------------------------------------------------------------*/
6313 AccAXLsh (char *x, int shCount)
6315 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6329 case 5: // AAAAABBB:CCCCCDDD
6331 AccRol (shCount); // BBBAAAAA:CCCCCDDD
6333 emitcode ("anl", "a,#0x%02x",
6334 SLMask[shCount]); // BBB00000:CCCCCDDD
6336 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBB00000
6338 AccRol (shCount); // DDDCCCCC:BBB00000
6340 emitcode ("xch", "a,%s", x); // BBB00000:DDDCCCCC
6342 emitcode ("xrl", "a,%s", x); // (BBB^DDD)CCCCC:DDDCCCCC
6344 emitcode ("xch", "a,%s", x); // DDDCCCCC:(BBB^DDD)CCCCC
6346 emitcode ("anl", "a,#0x%02x",
6347 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
6349 emitcode ("xch", "a,%s", x); // (BBB^DDD)CCCCC:DDD00000
6351 emitcode ("xrl", "a,%s", x); // BBBCCCCC:DDD00000
6354 case 6: // AAAAAABB:CCCCCCDD
6356 emitcode ("anl", "a,#0x%02x",
6357 SRMask[shCount]); // 000000BB:CCCCCCDD
6359 emitcode ("mov", "c,acc.0"); // c = B
6361 emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB
6363 AccAXRrl1 (x); // BCCCCCCD:D000000B
6365 AccAXRrl1 (x); // BBCCCCCC:DD000000
6368 case 7: // a:x <<= 7
6370 emitcode ("anl", "a,#0x%02x",
6371 SRMask[shCount]); // 0000000B:CCCCCCCD
6373 emitcode ("mov", "c,acc.0"); // c = B
6375 emitcode ("xch", "a,%s", x); // CCCCCCCD:0000000B
6377 AccAXRrl1 (x); // BCCCCCCC:D0000000
6385 /*-----------------------------------------------------------------*/
6386 /* AccAXRsh - right shift a:x known count (0..7) */
6387 /*-----------------------------------------------------------------*/
6389 AccAXRsh (char *x, int shCount)
6391 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6398 AccAXRrl1 (x); // 0->a:x
6403 AccAXRrl1 (x); // 0->a:x
6406 AccAXRrl1 (x); // 0->a:x
6411 case 5: // AAAAABBB:CCCCCDDD = a:x
6413 AccRol (8 - shCount); // BBBAAAAA:DDDCCCCC
6415 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
6417 AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
6419 emitcode ("anl", "a,#0x%02x",
6420 SRMask[shCount]); // 000CCCCC:BBBAAAAA
6422 emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA
6424 emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA)
6426 emitcode ("anl", "a,#0x%02x",
6427 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
6429 emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA
6431 emitcode ("xrl", "a,%s", x); // BBBCCCCC:000AAAAA
6433 emitcode ("xch", "a,%s", x); // 000AAAAA:BBBCCCCC
6436 case 6: // AABBBBBB:CCDDDDDD
6438 emitcode ("mov", "c,acc.7");
6439 AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
6441 AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
6443 emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
6445 emitcode ("anl", "a,#0x%02x",
6446 SRMask[shCount]); // 000000AA:BBBBBBCC
6449 case 7: // ABBBBBBB:CDDDDDDD
6451 emitcode ("mov", "c,acc.7"); // c = A
6453 AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
6455 emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
6457 emitcode ("anl", "a,#0x%02x",
6458 SRMask[shCount]); // 0000000A:BBBBBBBC
6466 /*-----------------------------------------------------------------*/
6467 /* AccAXRshS - right shift signed a:x known count (0..7) */
6468 /*-----------------------------------------------------------------*/
6470 AccAXRshS (char *x, int shCount)
6473 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6479 emitcode ("mov", "c,acc.7");
6480 AccAXRrl1 (x); // s->a:x
6484 emitcode ("mov", "c,acc.7");
6485 AccAXRrl1 (x); // s->a:x
6487 emitcode ("mov", "c,acc.7");
6488 AccAXRrl1 (x); // s->a:x
6493 case 5: // AAAAABBB:CCCCCDDD = a:x
6495 tlbl = newiTempLabel (NULL);
6496 AccRol (8 - shCount); // BBBAAAAA:CCCCCDDD
6498 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
6500 AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
6502 emitcode ("anl", "a,#0x%02x",
6503 SRMask[shCount]); // 000CCCCC:BBBAAAAA
6505 emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA
6507 emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA)
6509 emitcode ("anl", "a,#0x%02x",
6510 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
6512 emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA
6514 emitcode ("xrl", "a,%s", x); // BBBCCCCC:000AAAAA
6516 emitcode ("xch", "a,%s", x); // 000SAAAA:BBBCCCCC
6518 emitcode ("jnb", "acc.%d,%05d_DS_", 7 - shCount, tlbl->key + 100);
6519 emitcode ("orl", "a,#0x%02x",
6520 (unsigned char) ~SRMask[shCount]); // 111AAAAA:BBBCCCCC
6522 emitcode ("", "%05d_DS_:", tlbl->key + 100);
6523 break; // SSSSAAAA:BBBCCCCC
6525 case 6: // AABBBBBB:CCDDDDDD
6527 tlbl = newiTempLabel (NULL);
6528 emitcode ("mov", "c,acc.7");
6529 AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
6531 AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
6533 emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
6535 emitcode ("anl", "a,#0x%02x",
6536 SRMask[shCount]); // 000000AA:BBBBBBCC
6538 emitcode ("jnb", "acc.%d,%05d_DS_", 7 - shCount, tlbl->key + 100);
6539 emitcode ("orl", "a,#0x%02x",
6540 (unsigned char) ~SRMask[shCount]); // 111111AA:BBBBBBCC
6542 emitcode ("", "%05d_DS_:", tlbl->key + 100);
6544 case 7: // ABBBBBBB:CDDDDDDD
6546 tlbl = newiTempLabel (NULL);
6547 emitcode ("mov", "c,acc.7"); // c = A
6549 AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
6551 emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
6553 emitcode ("anl", "a,#0x%02x",
6554 SRMask[shCount]); // 0000000A:BBBBBBBC
6556 emitcode ("jnb", "acc.%d,%05d_DS_", 7 - shCount, tlbl->key + 100);
6557 emitcode ("orl", "a,#0x%02x",
6558 (unsigned char) ~SRMask[shCount]); // 1111111A:BBBBBBBC
6560 emitcode ("", "%05d_DS_:", tlbl->key + 100);
6567 /*-----------------------------------------------------------------*/
6568 /* shiftL2Left2Result - shift left two bytes from left to result */
6569 /*-----------------------------------------------------------------*/
6571 shiftL2Left2Result (operand * left, int offl,
6572 operand * result, int offr, int shCount)
6574 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6575 if (sameRegs (AOP (result), AOP (left)) &&
6576 ((offl + MSB16) == offr))
6578 /* don't crash result[offr] */
6579 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
6580 emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
6584 movLeft2Result (left, offl, result, offr, 0);
6585 MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
6587 /* ax << shCount (x = lsb(result)) */
6588 AccAXLsh (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
6589 aopPut (AOP (result), "a", offr + MSB16);
6593 /*-----------------------------------------------------------------*/
6594 /* shiftR2Left2Result - shift right two bytes from left to result */
6595 /*-----------------------------------------------------------------*/
6597 shiftR2Left2Result (operand * left, int offl,
6598 operand * result, int offr,
6599 int shCount, int sign)
6601 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6602 if (sameRegs (AOP (result), AOP (left)) &&
6603 ((offl + MSB16) == offr))
6605 /* don't crash result[offr] */
6606 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
6607 emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
6611 movLeft2Result (left, offl, result, offr, 0);
6612 MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
6614 /* a:x >> shCount (x = lsb(result)) */
6616 AccAXRshS (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
6618 AccAXRsh (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
6619 if (getDataSize (result) > 1)
6620 aopPut (AOP (result), "a", offr + MSB16);
6623 /*-----------------------------------------------------------------*/
6624 /* shiftLLeftOrResult - shift left one byte from left, or to result */
6625 /*-----------------------------------------------------------------*/
6627 shiftLLeftOrResult (operand * left, int offl,
6628 operand * result, int offr, int shCount)
6630 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6631 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
6632 /* shift left accumulator */
6634 /* or with result */
6635 emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE));
6636 /* back to result */
6637 aopPut (AOP (result), "a", offr);
6640 /*-----------------------------------------------------------------*/
6641 /* shiftRLeftOrResult - shift right one byte from left,or to result */
6642 /*-----------------------------------------------------------------*/
6644 shiftRLeftOrResult (operand * left, int offl,
6645 operand * result, int offr, int shCount)
6647 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6648 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
6649 /* shift right accumulator */
6651 /* or with result */
6652 emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE));
6653 /* back to result */
6654 aopPut (AOP (result), "a", offr);
6657 /*-----------------------------------------------------------------*/
6658 /* genlshOne - left shift a one byte quantity by known count */
6659 /*-----------------------------------------------------------------*/
6661 genlshOne (operand * result, operand * left, int shCount)
6663 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6664 shiftL1Left2Result (left, LSB, result, LSB, shCount);
6667 /*-----------------------------------------------------------------*/
6668 /* genlshTwo - left shift two bytes by known amount != 0 */
6669 /*-----------------------------------------------------------------*/
6671 genlshTwo (operand * result, operand * left, int shCount)
6675 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6676 size = getDataSize (result);
6678 /* if shCount >= 8 */
6686 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
6688 movLeft2Result (left, LSB, result, MSB16, 0);
6690 aopPut (AOP (result), zero, LSB);
6693 /* 1 <= shCount <= 7 */
6697 shiftL1Left2Result (left, LSB, result, LSB, shCount);
6699 shiftL2Left2Result (left, LSB, result, LSB, shCount);
6703 /*-----------------------------------------------------------------*/
6704 /* shiftLLong - shift left one long from left to result */
6705 /* offl = LSB or MSB16 */
6706 /*-----------------------------------------------------------------*/
6708 shiftLLong (operand * left, operand * result, int offr)
6711 int size = AOP_SIZE (result);
6713 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6714 if (size >= LSB + offr)
6716 l = aopGet (AOP (left), LSB, FALSE, FALSE);
6718 emitcode ("add", "a,acc");
6719 if (sameRegs (AOP (left), AOP (result)) &&
6720 size >= MSB16 + offr && offr != LSB)
6721 emitcode ("xch", "a,%s",
6722 aopGet (AOP (left), LSB + offr, FALSE, FALSE));
6724 aopPut (AOP (result), "a", LSB + offr);
6727 if (size >= MSB16 + offr)
6729 if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB16 + offr && offr != LSB))
6731 l = aopGet (AOP (left), MSB16, FALSE, FALSE);
6734 emitcode ("rlc", "a");
6735 if (sameRegs (AOP (left), AOP (result)) &&
6736 size >= MSB24 + offr && offr != LSB)
6737 emitcode ("xch", "a,%s",
6738 aopGet (AOP (left), MSB16 + offr, FALSE, FALSE));
6740 aopPut (AOP (result), "a", MSB16 + offr);
6743 if (size >= MSB24 + offr)
6745 if (!(sameRegs (AOP (left), AOP (left)) && size >= MSB24 + offr && offr != LSB))
6747 l = aopGet (AOP (left), MSB24, FALSE, FALSE);
6750 emitcode ("rlc", "a");
6751 if (sameRegs (AOP (left), AOP (result)) &&
6752 size >= MSB32 + offr && offr != LSB)
6753 emitcode ("xch", "a,%s",
6754 aopGet (AOP (left), MSB24 + offr, FALSE, FALSE));
6756 aopPut (AOP (result), "a", MSB24 + offr);
6759 if (size > MSB32 + offr)
6761 if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB32 + offr && offr != LSB))
6763 l = aopGet (AOP (left), MSB32, FALSE, FALSE);
6766 emitcode ("rlc", "a");
6767 aopPut (AOP (result), "a", MSB32 + offr);
6770 aopPut (AOP (result), zero, LSB);
6773 /*-----------------------------------------------------------------*/
6774 /* genlshFour - shift four byte by a known amount != 0 */
6775 /*-----------------------------------------------------------------*/
6777 genlshFour (operand * result, operand * left, int shCount)
6781 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6782 size = AOP_SIZE (result);
6784 /* if shifting more that 3 bytes */
6789 /* lowest order of left goes to the highest
6790 order of the destination */
6791 shiftL1Left2Result (left, LSB, result, MSB32, shCount);
6793 movLeft2Result (left, LSB, result, MSB32, 0);
6794 aopPut (AOP (result), zero, LSB);
6795 aopPut (AOP (result), zero, MSB16);
6796 aopPut (AOP (result), zero, MSB32);
6800 /* more than two bytes */
6801 else if (shCount >= 16)
6803 /* lower order two bytes goes to higher order two bytes */
6805 /* if some more remaining */
6807 shiftL2Left2Result (left, LSB, result, MSB24, shCount);
6810 movLeft2Result (left, MSB16, result, MSB32, 0);
6811 movLeft2Result (left, LSB, result, MSB24, 0);
6813 aopPut (AOP (result), zero, MSB16);
6814 aopPut (AOP (result), zero, LSB);
6818 /* if more than 1 byte */
6819 else if (shCount >= 8)
6821 /* lower order three bytes goes to higher order three bytes */
6826 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
6828 movLeft2Result (left, LSB, result, MSB16, 0);
6834 movLeft2Result (left, MSB24, result, MSB32, 0);
6835 movLeft2Result (left, MSB16, result, MSB24, 0);
6836 movLeft2Result (left, LSB, result, MSB16, 0);
6837 aopPut (AOP (result), zero, LSB);
6839 else if (shCount == 1)
6840 shiftLLong (left, result, MSB16);
6843 shiftL2Left2Result (left, MSB16, result, MSB24, shCount);
6844 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
6845 shiftRLeftOrResult (left, LSB, result, MSB24, 8 - shCount);
6846 aopPut (AOP (result), zero, LSB);
6851 /* 1 <= shCount <= 7 */
6852 else if (shCount <= 2)
6854 shiftLLong (left, result, LSB);
6856 shiftLLong (result, result, LSB);
6858 /* 3 <= shCount <= 7, optimize */
6861 shiftL2Left2Result (left, MSB24, result, MSB24, shCount);
6862 shiftRLeftOrResult (left, MSB16, result, MSB24, 8 - shCount);
6863 shiftL2Left2Result (left, LSB, result, LSB, shCount);
6867 /*-----------------------------------------------------------------*/
6868 /* genLeftShiftLiteral - left shifting by known count */
6869 /*-----------------------------------------------------------------*/
6871 genLeftShiftLiteral (operand * left,
6876 int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
6879 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6880 freeAsmop (right, NULL, ic, TRUE);
6882 aopOp (left, ic, FALSE);
6883 aopOp (result, ic, FALSE);
6885 size = getSize (operandType (result));
6888 emitcode ("; shift left ", "result %d, left %d", size,
6892 /* I suppose that the left size >= result size */
6897 movLeft2Result (left, size, result, size, 0);
6901 else if (shCount >= (size * 8))
6903 aopPut (AOP (result), zero, size);
6909 genlshOne (result, left, shCount);
6914 genlshTwo (result, left, shCount);
6918 genlshFour (result, left, shCount);
6922 freeAsmop (left, NULL, ic, TRUE);
6923 freeAsmop (result, NULL, ic, TRUE);
6926 /*-----------------------------------------------------------------*/
6927 /* genLeftShift - generates code for left shifting */
6928 /*-----------------------------------------------------------------*/
6930 genLeftShift (iCode * ic)
6932 operand *left, *right, *result;
6935 symbol *tlbl, *tlbl1;
6937 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
6939 right = IC_RIGHT (ic);
6940 left = IC_LEFT (ic);
6941 result = IC_RESULT (ic);
6943 aopOp (right, ic, FALSE);
6945 /* if the shift count is known then do it
6946 as efficiently as possible */
6947 if (AOP_TYPE (right) == AOP_LIT)
6949 genLeftShiftLiteral (left, right, result, ic);
6953 /* shift count is unknown then we have to form
6954 a loop get the loop count in B : Note: we take
6955 only the lower order byte since shifting
6956 more that 32 bits make no sense anyway, ( the
6957 largest size of an object can be only 32 bits ) */
6959 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6960 emitcode ("inc", "b");
6961 freeAsmop (right, NULL, ic, TRUE);
6962 aopOp (left, ic, FALSE);
6963 aopOp (result, ic, FALSE);
6965 /* now move the left to the result if they are not the
6967 if (!sameRegs (AOP (left), AOP (result)) &&
6968 AOP_SIZE (result) > 1)
6971 size = AOP_SIZE (result);
6975 l = aopGet (AOP (left), offset, FALSE, TRUE);
6976 if (*l == '@' && (IS_AOP_PREG (result)))
6979 emitcode ("mov", "a,%s", l);
6980 aopPut (AOP (result), "a", offset);
6983 aopPut (AOP (result), l, offset);
6988 tlbl = newiTempLabel (NULL);
6989 size = AOP_SIZE (result);
6991 tlbl1 = newiTempLabel (NULL);
6993 /* if it is only one byte then */
6996 symbol *tlbl1 = newiTempLabel (NULL);
6998 l = aopGet (AOP (left), 0, FALSE, FALSE);
7000 emitcode ("sjmp", "%05d_DS_", tlbl1->key + 100);
7001 emitcode ("", "%05d_DS_:", tlbl->key + 100);
7002 emitcode ("add", "a,acc");
7003 emitcode ("", "%05d_DS_:", tlbl1->key + 100);
7004 emitcode ("djnz", "b,%05d_DS_", tlbl->key + 100);
7005 aopPut (AOP (result), "a", 0);
7009 reAdjustPreg (AOP (result));
7011 emitcode ("sjmp", "%05d_DS_", tlbl1->key + 100);
7012 emitcode ("", "%05d_DS_:", tlbl->key + 100);
7013 l = aopGet (AOP (result), offset, FALSE, FALSE);
7015 emitcode ("add", "a,acc");
7016 aopPut (AOP (result), "a", offset++);
7019 l = aopGet (AOP (result), offset, FALSE, FALSE);
7021 emitcode ("rlc", "a");
7022 aopPut (AOP (result), "a", offset++);
7024 reAdjustPreg (AOP (result));
7026 emitcode ("", "%05d_DS_:", tlbl1->key + 100);
7027 emitcode ("djnz", "b,%05d_DS_", tlbl->key + 100);
7029 freeAsmop (left, NULL, ic, TRUE);
7030 freeAsmop (result, NULL, ic, TRUE);
7033 /*-----------------------------------------------------------------*/
7034 /* genrshOne - right shift a one byte quantity by known count */
7035 /*-----------------------------------------------------------------*/
7037 genrshOne (operand * result, operand * left,
7038 int shCount, int sign)
7040 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7041 shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
7044 /*-----------------------------------------------------------------*/
7045 /* genrshTwo - right shift two bytes by known amount != 0 */
7046 /*-----------------------------------------------------------------*/
7048 genrshTwo (operand * result, operand * left,
7049 int shCount, int sign)
7051 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7052 /* if shCount >= 8 */
7057 shiftR1Left2Result (left, MSB16, result, LSB,
7060 movLeft2Result (left, MSB16, result, LSB, sign);
7061 addSign (result, MSB16, sign);
7064 /* 1 <= shCount <= 7 */
7066 shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
7069 /*-----------------------------------------------------------------*/
7070 /* shiftRLong - shift right one long from left to result */
7071 /* offl = LSB or MSB16 */
7072 /*-----------------------------------------------------------------*/
7074 shiftRLong (operand * left, int offl,
7075 operand * result, int sign)
7077 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7079 emitcode ("clr", "c");
7080 MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
7082 emitcode ("mov", "c,acc.7");
7083 emitcode ("rrc", "a");
7084 aopPut (AOP (result), "a", MSB32 - offl);
7086 /* add sign of "a" */
7087 addSign (result, MSB32, sign);
7089 MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
7090 emitcode ("rrc", "a");
7091 aopPut (AOP (result), "a", MSB24 - offl);
7093 MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
7094 emitcode ("rrc", "a");
7095 aopPut (AOP (result), "a", MSB16 - offl);
7099 MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
7100 emitcode ("rrc", "a");
7101 aopPut (AOP (result), "a", LSB);
7105 /*-----------------------------------------------------------------*/
7106 /* genrshFour - shift four byte by a known amount != 0 */
7107 /*-----------------------------------------------------------------*/
7109 genrshFour (operand * result, operand * left,
7110 int shCount, int sign)
7112 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7113 /* if shifting more that 3 bytes */
7118 shiftR1Left2Result (left, MSB32, result, LSB, shCount, sign);
7120 movLeft2Result (left, MSB32, result, LSB, sign);
7121 addSign (result, MSB16, sign);
7123 else if (shCount >= 16)
7127 shiftR2Left2Result (left, MSB24, result, LSB, shCount, sign);
7130 movLeft2Result (left, MSB24, result, LSB, 0);
7131 movLeft2Result (left, MSB32, result, MSB16, sign);
7133 addSign (result, MSB24, sign);
7135 else if (shCount >= 8)
7139 shiftRLong (left, MSB16, result, sign);
7140 else if (shCount == 0)
7142 movLeft2Result (left, MSB16, result, LSB, 0);
7143 movLeft2Result (left, MSB24, result, MSB16, 0);
7144 movLeft2Result (left, MSB32, result, MSB24, sign);
7145 addSign (result, MSB32, sign);
7149 shiftR2Left2Result (left, MSB16, result, LSB, shCount, 0);
7150 shiftLLeftOrResult (left, MSB32, result, MSB16, 8 - shCount);
7151 /* the last shift is signed */
7152 shiftR1Left2Result (left, MSB32, result, MSB24, shCount, sign);
7153 addSign (result, MSB32, sign);
7157 { /* 1 <= shCount <= 7 */
7160 shiftRLong (left, LSB, result, sign);
7162 shiftRLong (result, LSB, result, sign);
7166 shiftR2Left2Result (left, LSB, result, LSB, shCount, 0);
7167 shiftLLeftOrResult (left, MSB24, result, MSB16, 8 - shCount);
7168 shiftR2Left2Result (left, MSB24, result, MSB24, shCount, sign);
7173 /*-----------------------------------------------------------------*/
7174 /* genRightShiftLiteral - right shifting by known count */
7175 /*-----------------------------------------------------------------*/
7177 genRightShiftLiteral (operand * left,
7183 int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
7186 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7187 freeAsmop (right, NULL, ic, TRUE);
7189 aopOp (left, ic, FALSE);
7190 aopOp (result, ic, FALSE);
7193 emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
7197 size = getDataSize (left);
7198 /* test the LEFT size !!! */
7200 /* I suppose that the left size >= result size */
7203 size = getDataSize (result);
7205 movLeft2Result (left, size, result, size, 0);
7208 else if (shCount >= (size * 8))
7211 /* get sign in acc.7 */
7212 MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE));
7213 addSign (result, LSB, sign);
7220 genrshOne (result, left, shCount, sign);
7224 genrshTwo (result, left, shCount, sign);
7228 genrshFour (result, left, shCount, sign);
7234 freeAsmop (left, NULL, ic, TRUE);
7235 freeAsmop (result, NULL, ic, TRUE);
7239 /*-----------------------------------------------------------------*/
7240 /* genSignedRightShift - right shift of signed number */
7241 /*-----------------------------------------------------------------*/
7243 genSignedRightShift (iCode * ic)
7245 operand *right, *left, *result;
7248 symbol *tlbl, *tlbl1;
7250 /* we do it the hard way put the shift count in b
7251 and loop thru preserving the sign */
7252 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7254 right = IC_RIGHT (ic);
7255 left = IC_LEFT (ic);
7256 result = IC_RESULT (ic);
7258 aopOp (right, ic, FALSE);
7261 if (AOP_TYPE (right) == AOP_LIT)
7263 genRightShiftLiteral (left, right, result, ic, 1);
7266 /* shift count is unknown then we have to form
7267 a loop get the loop count in B : Note: we take
7268 only the lower order byte since shifting
7269 more that 32 bits make no sense anyway, ( the
7270 largest size of an object can be only 32 bits ) */
7272 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
7273 emitcode ("inc", "b");
7274 freeAsmop (right, NULL, ic, TRUE);
7275 aopOp (left, ic, FALSE);
7276 aopOp (result, ic, FALSE);
7278 /* now move the left to the result if they are not the
7280 if (!sameRegs (AOP (left), AOP (result)) &&
7281 AOP_SIZE (result) > 1)
7284 size = AOP_SIZE (result);
7288 l = aopGet (AOP (left), offset, FALSE, TRUE);
7289 if (*l == '@' && IS_AOP_PREG (result))
7292 emitcode ("mov", "a,%s", l);
7293 aopPut (AOP (result), "a", offset);
7296 aopPut (AOP (result), l, offset);
7301 /* mov the highest order bit to OVR */
7302 tlbl = newiTempLabel (NULL);
7303 tlbl1 = newiTempLabel (NULL);
7305 size = AOP_SIZE (result);
7307 emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE));
7308 emitcode ("rlc", "a");
7309 emitcode ("mov", "ov,c");
7310 /* if it is only one byte then */
7313 l = aopGet (AOP (left), 0, FALSE, FALSE);
7315 emitcode ("sjmp", "%05d_DS_", tlbl1->key + 100);
7316 emitcode ("", "%05d_DS_:", tlbl->key + 100);
7317 emitcode ("mov", "c,ov");
7318 emitcode ("rrc", "a");
7319 emitcode ("", "%05d_DS_:", tlbl1->key + 100);
7320 emitcode ("djnz", "b,%05d_DS_", tlbl->key + 100);
7321 aopPut (AOP (result), "a", 0);
7325 reAdjustPreg (AOP (result));
7326 emitcode ("sjmp", "%05d_DS_", tlbl1->key + 100);
7327 emitcode ("", "%05d_DS_:", tlbl->key + 100);
7328 emitcode ("mov", "c,ov");
7331 l = aopGet (AOP (result), offset, FALSE, FALSE);
7333 emitcode ("rrc", "a");
7334 aopPut (AOP (result), "a", offset--);
7336 reAdjustPreg (AOP (result));
7337 emitcode ("", "%05d_DS_:", tlbl1->key + 100);
7338 emitcode ("djnz", "b,%05d_DS_", tlbl->key + 100);
7341 freeAsmop (left, NULL, ic, TRUE);
7342 freeAsmop (result, NULL, ic, TRUE);
7345 /*-----------------------------------------------------------------*/
7346 /* genRightShift - generate code for right shifting */
7347 /*-----------------------------------------------------------------*/
7349 genRightShift (iCode * ic)
7351 operand *right, *left, *result;
7355 symbol *tlbl, *tlbl1;
7357 /* if signed then we do it the hard way preserve the
7358 sign bit moving it inwards */
7359 retype = getSpec (operandType (IC_RESULT (ic)));
7360 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7362 if (!SPEC_USIGN (retype))
7364 genSignedRightShift (ic);
7368 /* signed & unsigned types are treated the same : i.e. the
7369 signed is NOT propagated inwards : quoting from the
7370 ANSI - standard : "for E1 >> E2, is equivalent to division
7371 by 2**E2 if unsigned or if it has a non-negative value,
7372 otherwise the result is implementation defined ", MY definition
7373 is that the sign does not get propagated */
7375 right = IC_RIGHT (ic);
7376 left = IC_LEFT (ic);
7377 result = IC_RESULT (ic);
7379 aopOp (right, ic, FALSE);
7381 /* if the shift count is known then do it
7382 as efficiently as possible */
7383 if (AOP_TYPE (right) == AOP_LIT)
7385 genRightShiftLiteral (left, right, result, ic, 0);
7389 /* shift count is unknown then we have to form
7390 a loop get the loop count in B : Note: we take
7391 only the lower order byte since shifting
7392 more that 32 bits make no sense anyway, ( the
7393 largest size of an object can be only 32 bits ) */
7395 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
7396 emitcode ("inc", "b");
7397 freeAsmop (right, NULL, ic, TRUE);
7398 aopOp (left, ic, FALSE);
7399 aopOp (result, ic, FALSE);
7401 /* now move the left to the result if they are not the
7403 if (!sameRegs (AOP (left), AOP (result)) &&
7404 AOP_SIZE (result) > 1)
7407 size = AOP_SIZE (result);
7411 l = aopGet (AOP (left), offset, FALSE, TRUE);
7412 if (*l == '@' && IS_AOP_PREG (result))
7415 emitcode ("mov", "a,%s", l);
7416 aopPut (AOP (result), "a", offset);
7419 aopPut (AOP (result), l, offset);
7424 tlbl = newiTempLabel (NULL);
7425 tlbl1 = newiTempLabel (NULL);
7426 size = AOP_SIZE (result);
7429 /* if it is only one byte then */
7432 l = aopGet (AOP (left), 0, FALSE, FALSE);
7434 emitcode ("sjmp", "%05d_DS_", tlbl1->key + 100);
7435 emitcode ("", "%05d_DS_:", tlbl->key + 100);
7437 emitcode ("rrc", "a");
7438 emitcode ("", "%05d_DS_:", tlbl1->key + 100);
7439 emitcode ("djnz", "b,%05d_DS_", tlbl->key + 100);
7440 aopPut (AOP (result), "a", 0);
7444 reAdjustPreg (AOP (result));
7445 emitcode ("sjmp", "%05d_DS_", tlbl1->key + 100);
7446 emitcode ("", "%05d_DS_:", tlbl->key + 100);
7450 l = aopGet (AOP (result), offset, FALSE, FALSE);
7452 emitcode ("rrc", "a");
7453 aopPut (AOP (result), "a", offset--);
7455 reAdjustPreg (AOP (result));
7457 emitcode ("", "%05d_DS_:", tlbl1->key + 100);
7458 emitcode ("djnz", "b,%05d_DS_", tlbl->key + 100);
7461 freeAsmop (left, NULL, ic, TRUE);
7462 freeAsmop (result, NULL, ic, TRUE);
7465 /*-----------------------------------------------------------------*/
7466 /* genUnpackBits - generates code for unpacking bits */
7467 /*-----------------------------------------------------------------*/
7469 genUnpackBits (operand * result, char *rname, int ptype)
7476 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7477 etype = getSpec (operandType (result));
7479 /* read the first byte */
7485 emitcode ("mov", "a,@%s", rname);
7489 emitcode ("movx", "a,@%s", rname);
7493 emitcode ("movx", "a,@dptr");
7497 emitcode ("clr", "a");
7498 emitcode ("movc", "a", "@a+dptr");
7502 emitcode ("lcall", "__gptrget");
7506 /* if we have bitdisplacement then it fits */
7507 /* into this byte completely or if length is */
7508 /* less than a byte */
7509 if ((shCnt = SPEC_BSTR (etype)) ||
7510 (SPEC_BLEN (etype) <= 8))
7513 /* shift right acc */
7516 emitcode ("anl", "a,#0x%02x",
7517 ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
7518 aopPut (AOP (result), "a", offset);
7522 /* bit field did not fit in a byte */
7523 rlen = SPEC_BLEN (etype) - 8;
7524 aopPut (AOP (result), "a", offset++);
7533 emitcode ("inc", "%s", rname);
7534 emitcode ("mov", "a,@%s", rname);
7538 emitcode ("inc", "%s", rname);
7539 emitcode ("movx", "a,@%s", rname);
7543 emitcode ("inc", "dptr");
7544 emitcode ("movx", "a,@dptr");
7548 emitcode ("clr", "a");
7549 emitcode ("inc", "dptr");
7550 emitcode ("movc", "a", "@a+dptr");
7554 emitcode ("inc", "dptr");
7555 emitcode ("lcall", "__gptrget");
7560 /* if we are done */
7564 aopPut (AOP (result), "a", offset++);
7570 emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (-rlen));
7571 aopPut (AOP (result), "a", offset);
7578 /*-----------------------------------------------------------------*/
7579 /* genDataPointerGet - generates code when ptr offset is known */
7580 /*-----------------------------------------------------------------*/
7582 genDataPointerGet (operand * left,
7588 int size, offset = 0;
7589 aopOp (result, ic, TRUE);
7591 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7593 /* get the string representation of the name */
7594 l = aopGet (AOP (left), 0, FALSE, TRUE);
7595 size = AOP_SIZE (result);
7596 // tsd, was l+1 - the underline `_' prefix was being stripped
7600 sprintf (buffer, "(%s + %d)", l, offset);
7602 sprintf (buffer, "%s", l);
7603 aopPut (AOP (result), buffer, offset++);
7606 freeAsmop (left, NULL, ic, TRUE);
7607 freeAsmop (result, NULL, ic, TRUE);
7610 /*-----------------------------------------------------------------*/
7611 /* genNearPointerGet - emitcode for near pointer fetch */
7612 /*-----------------------------------------------------------------*/
7614 genNearPointerGet (operand * left,
7621 sym_link *rtype, *retype;
7622 sym_link *ltype = operandType (left);
7625 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7627 rtype = operandType (result);
7628 retype = getSpec (rtype);
7630 aopOp (left, ic, FALSE);
7632 /* if left is rematerialisable and
7633 result is not bit variable type and
7634 the left is pointer to data space i.e
7635 lower 128 bytes of space */
7636 if (AOP_TYPE (left) == AOP_IMMD &&
7637 !IS_BITVAR (retype) &&
7638 DCL_TYPE (ltype) == POINTER)
7640 genDataPointerGet (left, result, ic);
7644 /* if the value is already in a pointer register
7645 then don't need anything more */
7646 if (!AOP_INPREG (AOP (left)))
7648 /* otherwise get a free pointer register */
7650 preg = getFreePtr (ic, &aop, FALSE);
7651 emitcode ("mov", "%s,%s",
7653 aopGet (AOP (left), 0, FALSE, TRUE));
7657 rname = aopGet (AOP (left), 0, FALSE, FALSE);
7659 freeAsmop (left, NULL, ic, TRUE);
7660 aopOp (result, ic, FALSE);
7662 /* if bitfield then unpack the bits */
7663 if (IS_BITVAR (retype))
7664 genUnpackBits (result, rname, POINTER);
7667 /* we have can just get the values */
7668 int size = AOP_SIZE (result);
7673 if (IS_AOP_PREG (result) || AOP_TYPE (result) == AOP_STK)
7676 emitcode ("mov", "a,@%s", rname);
7677 aopPut (AOP (result), "a", offset);
7681 sprintf (buffer, "@%s", rname);
7682 aopPut (AOP (result), buffer, offset);
7686 emitcode ("inc", "%s", rname);
7690 /* now some housekeeping stuff */
7693 /* we had to allocate for this iCode */
7694 freeAsmop (NULL, aop, ic, TRUE);
7698 /* we did not allocate which means left
7699 already in a pointer register, then
7700 if size > 0 && this could be used again
7701 we have to point it back to where it
7703 if (AOP_SIZE (result) > 1 &&
7704 !OP_SYMBOL (left)->remat &&
7705 (OP_SYMBOL (left)->liveTo > ic->seq ||
7708 int size = AOP_SIZE (result) - 1;
7710 emitcode ("dec", "%s", rname);
7715 freeAsmop (result, NULL, ic, TRUE);
7719 /*-----------------------------------------------------------------*/
7720 /* genPagedPointerGet - emitcode for paged pointer fetch */
7721 /*-----------------------------------------------------------------*/
7723 genPagedPointerGet (operand * left,
7730 sym_link *rtype, *retype;
7732 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7734 rtype = operandType (result);
7735 retype = getSpec (rtype);
7737 aopOp (left, ic, FALSE);
7739 /* if the value is already in a pointer register
7740 then don't need anything more */
7741 if (!AOP_INPREG (AOP (left)))
7743 /* otherwise get a free pointer register */
7745 preg = getFreePtr (ic, &aop, FALSE);
7746 emitcode ("mov", "%s,%s",
7748 aopGet (AOP (left), 0, FALSE, TRUE));
7752 rname = aopGet (AOP (left), 0, FALSE, FALSE);
7754 freeAsmop (left, NULL, ic, TRUE);
7755 aopOp (result, ic, FALSE);
7757 /* if bitfield then unpack the bits */
7758 if (IS_BITVAR (retype))
7759 genUnpackBits (result, rname, PPOINTER);
7762 /* we have can just get the values */
7763 int size = AOP_SIZE (result);
7769 emitcode ("movx", "a,@%s", rname);
7770 aopPut (AOP (result), "a", offset);
7775 emitcode ("inc", "%s", rname);
7779 /* now some housekeeping stuff */
7782 /* we had to allocate for this iCode */
7783 freeAsmop (NULL, aop, ic, TRUE);
7787 /* we did not allocate which means left
7788 already in a pointer register, then
7789 if size > 0 && this could be used again
7790 we have to point it back to where it
7792 if (AOP_SIZE (result) > 1 &&
7793 !OP_SYMBOL (left)->remat &&
7794 (OP_SYMBOL (left)->liveTo > ic->seq ||
7797 int size = AOP_SIZE (result) - 1;
7799 emitcode ("dec", "%s", rname);
7804 freeAsmop (result, NULL, ic, TRUE);
7809 /*-----------------------------------------------------------------*/
7810 /* genFarPointerGet - gget value from far space */
7811 /*-----------------------------------------------------------------*/
7813 genFarPointerGet (operand * left,
7814 operand * result, iCode * ic)
7817 sym_link *retype = getSpec (operandType (result));
7819 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7821 aopOp (left, ic, FALSE);
7823 /* if the operand is already in dptr
7824 then we do nothing else we move the value to dptr */
7825 if (AOP_TYPE (left) != AOP_STR)
7827 /* if this is remateriazable */
7828 if (AOP_TYPE (left) == AOP_IMMD)
7829 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
7831 { /* we need to get it byte by byte */
7832 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
7833 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
7834 if (options.model == MODEL_FLAT24)
7836 emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE));
7840 /* so dptr know contains the address */
7841 freeAsmop (left, NULL, ic, TRUE);
7842 aopOp (result, ic, FALSE);
7844 /* if bit then unpack */
7845 if (IS_BITVAR (retype))
7846 genUnpackBits (result, "dptr", FPOINTER);
7849 size = AOP_SIZE (result);
7854 emitcode ("movx", "a,@dptr");
7855 aopPut (AOP (result), "a", offset++);
7857 emitcode ("inc", "dptr");
7861 freeAsmop (result, NULL, ic, TRUE);
7864 /*-----------------------------------------------------------------*/
7865 /* emitcodePointerGet - gget value from code space */
7866 /*-----------------------------------------------------------------*/
7868 emitcodePointerGet (operand * left,
7869 operand * result, iCode * ic)
7872 sym_link *retype = getSpec (operandType (result));
7874 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7876 aopOp (left, ic, FALSE);
7878 /* if the operand is already in dptr
7879 then we do nothing else we move the value to dptr */
7880 if (AOP_TYPE (left) != AOP_STR)
7882 /* if this is remateriazable */
7883 if (AOP_TYPE (left) == AOP_IMMD)
7884 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
7886 { /* we need to get it byte by byte */
7887 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
7888 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
7889 if (options.model == MODEL_FLAT24)
7891 emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE));
7895 /* so dptr know contains the address */
7896 freeAsmop (left, NULL, ic, TRUE);
7897 aopOp (result, ic, FALSE);
7899 /* if bit then unpack */
7900 if (IS_BITVAR (retype))
7901 genUnpackBits (result, "dptr", CPOINTER);
7904 size = AOP_SIZE (result);
7909 emitcode ("clr", "a");
7910 emitcode ("movc", "a,@a+dptr");
7911 aopPut (AOP (result), "a", offset++);
7913 emitcode ("inc", "dptr");
7917 freeAsmop (result, NULL, ic, TRUE);
7920 /*-----------------------------------------------------------------*/
7921 /* genGenPointerGet - gget value from generic pointer space */
7922 /*-----------------------------------------------------------------*/
7924 genGenPointerGet (operand * left,
7925 operand * result, iCode * ic)
7928 sym_link *retype = getSpec (operandType (result));
7930 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
7931 aopOp (left, ic, FALSE);
7933 /* if the operand is already in dptr
7934 then we do nothing else we move the value to dptr */
7935 if (AOP_TYPE (left) != AOP_STR)
7937 /* if this is remateriazable */
7938 if (AOP_TYPE (left) == AOP_IMMD)
7940 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
7941 emitcode ("mov", "b,#%d", pointerCode (retype));
7944 { /* we need to get it byte by byte */
7946 emitcode ("movf", "%s,w", aopGet (AOP (left), 0, FALSE, FALSE));
7947 emitcode ("movwf", "FSR");
7949 emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7950 emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7951 if (options.model == MODEL_FLAT24)
7953 emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7954 emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7958 emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7963 /* so dptr know contains the address */
7964 freeAsmop (left, NULL, ic, TRUE);
7965 aopOp (result, ic, FALSE);
7967 /* if bit then unpack */
7968 if (IS_BITVAR (retype))
7969 genUnpackBits (result, "dptr", GPOINTER);
7972 size = AOP_SIZE (result);
7977 //emitcode("lcall","__gptrget");
7978 emitcode ("movf", "indf,w");
7979 //aopPut(AOP(result),"a",offset++);
7980 emitcode ("movwf", "%s",
7981 aopGet (AOP (result), offset++, FALSE, FALSE));
7983 emitcode ("incf", "fsr,f");
7987 freeAsmop (result, NULL, ic, TRUE);
7990 /*-----------------------------------------------------------------*/
7991 /* genPointerGet - generate code for pointer get */
7992 /*-----------------------------------------------------------------*/
7994 genPointerGet (iCode * ic)
7996 operand *left, *result;
7997 sym_link *type, *etype;
8000 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8002 left = IC_LEFT (ic);
8003 result = IC_RESULT (ic);
8005 /* depending on the type of pointer we need to
8006 move it to the correct pointer register */
8007 type = operandType (left);
8008 etype = getSpec (type);
8009 /* if left is of type of pointer then it is simple */
8010 if (IS_PTR (type) && !IS_FUNC (type->next))
8011 p_type = DCL_TYPE (type);
8014 /* we have to go by the storage class */
8015 p_type = PTR_TYPE (SPEC_OCLS (etype));
8017 /* if (SPEC_OCLS(etype)->codesp ) { */
8018 /* p_type = CPOINTER ; */
8021 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8022 /* p_type = FPOINTER ; */
8024 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8025 /* p_type = PPOINTER; */
8027 /* if (SPEC_OCLS(etype) == idata ) */
8028 /* p_type = IPOINTER; */
8030 /* p_type = POINTER ; */
8033 /* now that we have the pointer type we assign
8034 the pointer values */
8040 genNearPointerGet (left, result, ic);
8044 genPagedPointerGet (left, result, ic);
8048 genFarPointerGet (left, result, ic);
8052 emitcodePointerGet (left, result, ic);
8056 genGenPointerGet (left, result, ic);
8062 /*-----------------------------------------------------------------*/
8063 /* genPackBits - generates code for packed bit storage */
8064 /*-----------------------------------------------------------------*/
8066 genPackBits (sym_link * etype,
8068 char *rname, int p_type)
8076 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8077 blen = SPEC_BLEN (etype);
8078 bstr = SPEC_BSTR (etype);
8080 l = aopGet (AOP (right), offset++, FALSE, FALSE);
8083 /* if the bit lenth is less than or */
8084 /* it exactly fits a byte then */
8085 if (SPEC_BLEN (etype) <= 8)
8087 shCount = SPEC_BSTR (etype);
8089 /* shift left acc */
8092 if (SPEC_BLEN (etype) < 8)
8093 { /* if smaller than a byte */
8099 emitcode ("mov", "b,a");
8100 emitcode ("mov", "a,@%s", rname);
8104 emitcode ("mov", "b,a");
8105 emitcode ("movx", "a,@dptr");
8109 emitcode ("push", "b");
8110 emitcode ("push", "acc");
8111 emitcode ("lcall", "__gptrget");
8112 emitcode ("pop", "b");
8116 emitcode ("anl", "a,#0x%02x", (unsigned char)
8117 ((unsigned char) (0xFF << (blen + bstr)) |
8118 (unsigned char) (0xFF >> (8 - bstr))));
8119 emitcode ("orl", "a,b");
8120 if (p_type == GPOINTER)
8121 emitcode ("pop", "b");
8128 emitcode ("mov", "@%s,a", rname);
8132 emitcode ("movx", "@dptr,a");
8136 DEBUGemitcode (";lcall", "__gptrput");
8141 if (SPEC_BLEN (etype) <= 8)
8144 emitcode ("inc", "%s", rname);
8145 rLen = SPEC_BLEN (etype);
8147 /* now generate for lengths greater than one byte */
8151 l = aopGet (AOP (right), offset++, FALSE, TRUE);
8163 emitcode ("mov", "@%s,a", rname);
8166 emitcode ("mov", "@%s,%s", rname, l);
8171 emitcode ("movx", "@dptr,a");
8176 DEBUGemitcode (";lcall", "__gptrput");
8179 emitcode ("inc", "%s", rname);
8184 /* last last was not complete */
8187 /* save the byte & read byte */
8191 emitcode ("mov", "b,a");
8192 emitcode ("mov", "a,@%s", rname);
8196 emitcode ("mov", "b,a");
8197 emitcode ("movx", "a,@dptr");
8201 emitcode ("push", "b");
8202 emitcode ("push", "acc");
8203 emitcode ("lcall", "__gptrget");
8204 emitcode ("pop", "b");
8208 emitcode ("anl", "a,#0x%02x", ((unsigned char) -1 << -rLen));
8209 emitcode ("orl", "a,b");
8212 if (p_type == GPOINTER)
8213 emitcode ("pop", "b");
8219 emitcode ("mov", "@%s,a", rname);
8223 emitcode ("movx", "@dptr,a");
8227 DEBUGemitcode (";lcall", "__gptrput");
8231 /*-----------------------------------------------------------------*/
8232 /* genDataPointerSet - remat pointer to data space */
8233 /*-----------------------------------------------------------------*/
8235 genDataPointerSet (operand * right,
8239 int size, offset = 0;
8240 char *l, buffer[256];
8242 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8243 aopOp (right, ic, FALSE);
8245 l = aopGet (AOP (result), 0, FALSE, TRUE);
8246 size = AOP_SIZE (right);
8247 // tsd, was l+1 - the underline `_' prefix was being stripped
8251 sprintf (buffer, "(%s + %d)", l, offset);
8253 sprintf (buffer, "%s", l);
8255 if (AOP_TYPE (right) == AOP_LIT)
8257 unsigned int lit = floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
8258 lit = lit >> (8 * offset);
8261 emitcode ("movlw", "%s", lit);
8262 emitcode ("movwf", "%s", buffer);
8265 emitcode ("clrf", "%s", buffer);
8269 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
8270 emitcode ("movwf", "%s", buffer);
8276 freeAsmop (right, NULL, ic, TRUE);
8277 freeAsmop (result, NULL, ic, TRUE);
8280 /*-----------------------------------------------------------------*/
8281 /* genNearPointerSet - emitcode for near pointer put */
8282 /*-----------------------------------------------------------------*/
8284 genNearPointerSet (operand * right,
8291 sym_link *ptype = operandType (result);
8294 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8295 retype = getSpec (operandType (right));
8297 aopOp (result, ic, FALSE);
8299 /* if the result is rematerializable &
8300 in data space & not a bit variable */
8301 if (AOP_TYPE (result) == AOP_IMMD &&
8302 DCL_TYPE (ptype) == POINTER &&
8303 !IS_BITVAR (retype))
8305 genDataPointerSet (right, result, ic);
8309 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8311 /* if the value is already in a pointer register
8312 then don't need anything more */
8313 if (!AOP_INPREG (AOP (result)))
8315 /* otherwise get a free pointer register */
8316 //aop = newAsmop(0);
8317 //preg = getFreePtr(ic,&aop,FALSE);
8318 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8319 //emitcode("mov","%s,%s",
8321 // aopGet(AOP(result),0,FALSE,TRUE));
8322 //rname = preg->name ;
8323 emitcode ("movwf", "fsr");
8325 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8327 freeAsmop (result, NULL, ic, TRUE);
8328 aopOp (right, ic, FALSE);
8329 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8331 /* if bitfield then unpack the bits */
8332 if (IS_BITVAR (retype))
8334 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8335 "The programmer is obviously confused");
8336 //genPackBits (retype,right,rname,POINTER);
8341 /* we have can just get the values */
8342 int size = AOP_SIZE (right);
8345 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8348 l = aopGet (AOP (right), offset, FALSE, TRUE);
8352 //emitcode("mov","@%s,a",rname);
8353 emitcode ("movf", "indf,w ;1");
8358 if (AOP_TYPE (right) == AOP_LIT)
8360 unsigned int lit = floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
8363 emitcode ("movlw", "%s", l);
8364 emitcode ("movwf", "indf ;2");
8367 emitcode ("clrf", "indf");
8371 emitcode ("movf", "%s,w", l);
8372 emitcode ("movwf", "indf ;2");
8374 //emitcode("mov","@%s,%s",rname,l);
8377 emitcode ("incf", "fsr,f ;3");
8378 //emitcode("inc","%s",rname);
8383 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8384 /* now some housekeeping stuff */
8387 /* we had to allocate for this iCode */
8388 freeAsmop (NULL, aop, ic, TRUE);
8392 /* we did not allocate which means left
8393 already in a pointer register, then
8394 if size > 0 && this could be used again
8395 we have to point it back to where it
8397 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8398 if (AOP_SIZE (right) > 1 &&
8399 !OP_SYMBOL (result)->remat &&
8400 (OP_SYMBOL (result)->liveTo > ic->seq ||
8403 int size = AOP_SIZE (right) - 1;
8405 emitcode ("decf", "fsr,f");
8406 //emitcode("dec","%s",rname);
8410 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8412 freeAsmop (right, NULL, ic, TRUE);
8417 /*-----------------------------------------------------------------*/
8418 /* genPagedPointerSet - emitcode for Paged pointer put */
8419 /*-----------------------------------------------------------------*/
8421 genPagedPointerSet (operand * right,
8430 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8432 retype = getSpec (operandType (right));
8434 aopOp (result, ic, FALSE);
8436 /* if the value is already in a pointer register
8437 then don't need anything more */
8438 if (!AOP_INPREG (AOP (result)))
8440 /* otherwise get a free pointer register */
8442 preg = getFreePtr (ic, &aop, FALSE);
8443 emitcode ("mov", "%s,%s",
8445 aopGet (AOP (result), 0, FALSE, TRUE));
8449 rname = aopGet (AOP (result), 0, FALSE, FALSE);
8451 freeAsmop (result, NULL, ic, TRUE);
8452 aopOp (right, ic, FALSE);
8454 /* if bitfield then unpack the bits */
8455 if (IS_BITVAR (retype))
8456 genPackBits (retype, right, rname, PPOINTER);
8459 /* we have can just get the values */
8460 int size = AOP_SIZE (right);
8465 l = aopGet (AOP (right), offset, FALSE, TRUE);
8468 emitcode ("movx", "@%s,a", rname);
8471 emitcode ("inc", "%s", rname);
8477 /* now some housekeeping stuff */
8480 /* we had to allocate for this iCode */
8481 freeAsmop (NULL, aop, ic, TRUE);
8485 /* we did not allocate which means left
8486 already in a pointer register, then
8487 if size > 0 && this could be used again
8488 we have to point it back to where it
8490 if (AOP_SIZE (right) > 1 &&
8491 !OP_SYMBOL (result)->remat &&
8492 (OP_SYMBOL (result)->liveTo > ic->seq ||
8495 int size = AOP_SIZE (right) - 1;
8497 emitcode ("dec", "%s", rname);
8502 freeAsmop (right, NULL, ic, TRUE);
8507 /*-----------------------------------------------------------------*/
8508 /* genFarPointerSet - set value from far space */
8509 /*-----------------------------------------------------------------*/
8511 genFarPointerSet (operand * right,
8512 operand * result, iCode * ic)
8515 sym_link *retype = getSpec (operandType (right));
8517 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8518 aopOp (result, ic, FALSE);
8520 /* if the operand is already in dptr
8521 then we do nothing else we move the value to dptr */
8522 if (AOP_TYPE (result) != AOP_STR)
8524 /* if this is remateriazable */
8525 if (AOP_TYPE (result) == AOP_IMMD)
8526 emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
8528 { /* we need to get it byte by byte */
8529 emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
8530 emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
8531 if (options.model == MODEL_FLAT24)
8533 emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE));
8537 /* so dptr know contains the address */
8538 freeAsmop (result, NULL, ic, TRUE);
8539 aopOp (right, ic, FALSE);
8541 /* if bit then unpack */
8542 if (IS_BITVAR (retype))
8543 genPackBits (retype, right, "dptr", FPOINTER);
8546 size = AOP_SIZE (right);
8551 char *l = aopGet (AOP (right), offset++, FALSE, FALSE);
8553 emitcode ("movx", "@dptr,a");
8555 emitcode ("inc", "dptr");
8559 freeAsmop (right, NULL, ic, TRUE);
8562 /*-----------------------------------------------------------------*/
8563 /* genGenPointerSet - set value from generic pointer space */
8564 /*-----------------------------------------------------------------*/
8566 genGenPointerSet (operand * right,
8567 operand * result, iCode * ic)
8570 sym_link *retype = getSpec (operandType (right));
8572 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8574 aopOp (result, ic, FALSE);
8576 /* if the operand is already in dptr
8577 then we do nothing else we move the value to dptr */
8578 if (AOP_TYPE (result) != AOP_STR)
8580 /* if this is remateriazable */
8581 if (AOP_TYPE (result) == AOP_IMMD)
8583 emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
8584 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
8587 { /* we need to get it byte by byte */
8588 char *l = aopGet (AOP (result), 0, FALSE, FALSE);
8589 if (strcmp ("FSR", l))
8590 emitcode ("movlw", "%s", aopGet (AOP (result), 0, FALSE, FALSE));
8592 emitcode ("movwf", "INDF");
8595 /* so dptr know contains the address */
8596 freeAsmop (result, NULL, ic, TRUE);
8597 aopOp (right, ic, FALSE);
8599 /* if bit then unpack */
8600 if (IS_BITVAR (retype))
8601 genPackBits (retype, right, "dptr", GPOINTER);
8604 size = AOP_SIZE (right);
8609 char *l = aopGet (AOP (right), offset++, FALSE, FALSE);
8611 emitcode ("incf", "fsr,f");
8612 emitcode ("movf", "%s,w", aopGet (AOP (right), offset++, FALSE, FALSE));
8613 emitcode ("movwf", "indf");
8615 //DEBUGemitcode(";lcall","__gptrput");
8617 // emitcode("inc","dptr");
8621 freeAsmop (right, NULL, ic, TRUE);
8624 /*-----------------------------------------------------------------*/
8625 /* genPointerSet - stores the value into a pointer location */
8626 /*-----------------------------------------------------------------*/
8628 genPointerSet (iCode * ic)
8630 operand *right, *result;
8631 sym_link *type, *etype;
8634 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8636 right = IC_RIGHT (ic);
8637 result = IC_RESULT (ic);
8639 /* depending on the type of pointer we need to
8640 move it to the correct pointer register */
8641 type = operandType (result);
8642 etype = getSpec (type);
8643 /* if left is of type of pointer then it is simple */
8644 if (IS_PTR (type) && !IS_FUNC (type->next))
8646 p_type = DCL_TYPE (type);
8650 /* we have to go by the storage class */
8651 p_type = PTR_TYPE (SPEC_OCLS (etype));
8653 /* if (SPEC_OCLS(etype)->codesp ) { */
8654 /* p_type = CPOINTER ; */
8657 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8658 /* p_type = FPOINTER ; */
8660 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8661 /* p_type = PPOINTER ; */
8663 /* if (SPEC_OCLS(etype) == idata ) */
8664 /* p_type = IPOINTER ; */
8666 /* p_type = POINTER ; */
8669 /* now that we have the pointer type we assign
8670 the pointer values */
8676 genNearPointerSet (right, result, ic);
8680 genPagedPointerSet (right, result, ic);
8684 genFarPointerSet (right, result, ic);
8688 genGenPointerSet (right, result, ic);
8694 /*-----------------------------------------------------------------*/
8695 /* genIfx - generate code for Ifx statement */
8696 /*-----------------------------------------------------------------*/
8698 genIfx (iCode * ic, iCode * popIc)
8700 operand *cond = IC_COND (ic);
8703 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8704 aopOp (cond, ic, FALSE);
8706 /* get the value into acc */
8707 if (AOP_TYPE (cond) != AOP_CRY)
8711 /* the result is now in the accumulator */
8712 freeAsmop (cond, NULL, ic, TRUE);
8714 /* if there was something to be popped then do it */
8718 /* if the condition is a bit variable */
8719 if (isbit && IS_ITEMP (cond) &&
8722 genIfxJump (ic, SPIL_LOC (cond)->rname);
8723 DEBUGemitcode ("; isbit SPIL_LOC", "%s", SPIL_LOC (cond)->rname);
8728 if (isbit && !IS_ITEMP(cond))
8729 DEBUGemitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
8731 DEBUGemitcode ("; isbit","a");
8734 if (isbit && !IS_ITEMP (cond))
8735 genIfxJump (ic, OP_SYMBOL (cond)->rname);
8737 genIfxJump (ic, "a");
8742 /*-----------------------------------------------------------------*/
8743 /* genAddrOf - generates code for address of */
8744 /*-----------------------------------------------------------------*/
8746 genAddrOf (iCode * ic)
8748 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
8751 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8753 aopOp (IC_RESULT (ic), ic, FALSE);
8755 /* if the operand is on the stack then we
8756 need to get the stack offset of this
8760 /* if it has an offset then we need to compute
8764 emitcode ("mov", "a,_bp");
8765 emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
8766 aopPut (AOP (IC_RESULT (ic)), "a", 0);
8770 /* we can just move _bp */
8771 aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
8773 /* fill the result with zero */
8774 size = AOP_SIZE (IC_RESULT (ic)) - 1;
8777 if (options.stack10bit && size < (FPTRSIZE - 1))
8780 "*** warning: pointer to stack var truncated.\n");
8787 if (options.stack10bit && offset == 2)
8789 aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++);
8793 aopPut (AOP (IC_RESULT (ic)), zero, offset++);
8800 /* object not on stack then we need the name */
8801 size = AOP_SIZE (IC_RESULT (ic));
8806 char s[SDCC_NAME_MAX];
8808 sprintf (s, "#(%s >> %d)",
8812 sprintf (s, "#%s", sym->rname);
8813 aopPut (AOP (IC_RESULT (ic)), s, offset++);
8817 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
8822 /*-----------------------------------------------------------------*/
8823 /* genFarFarAssign - assignment when both are in far space */
8824 /*-----------------------------------------------------------------*/
8826 genFarFarAssign (operand * result, operand * right, iCode * ic)
8828 int size = AOP_SIZE (right);
8831 /* first push the right side on to the stack */
8834 l = aopGet (AOP (right), offset++, FALSE, FALSE);
8836 emitcode ("push", "acc");
8839 freeAsmop (right, NULL, ic, FALSE);
8840 /* now assign DPTR to result */
8841 aopOp (result, ic, FALSE);
8842 size = AOP_SIZE (result);
8845 emitcode ("pop", "acc");
8846 aopPut (AOP (result), "a", --offset);
8848 freeAsmop (result, NULL, ic, FALSE);
8853 /*-----------------------------------------------------------------*/
8854 /* genAssign - generate code for assignment */
8855 /*-----------------------------------------------------------------*/
8857 genAssign (iCode * ic)
8859 operand *result, *right;
8861 unsigned long lit = 0L;
8863 result = IC_RESULT (ic);
8864 right = IC_RIGHT (ic);
8866 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8868 /* if they are the same */
8869 if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
8872 aopOp (right, ic, FALSE);
8873 aopOp (result, ic, TRUE);
8875 /* if they are the same registers */
8876 if (sameRegs (AOP (right), AOP (result)))
8879 /* if the result is a bit */
8880 if (AOP_TYPE (result) == AOP_CRY)
8883 /* if the right size is a literal then
8884 we know what the value is */
8885 if (AOP_TYPE (right) == AOP_LIT)
8887 if (((int) operandLitValue (right)))
8888 emitcode ("bsf", "(%s >> 3),(%s & 7)",
8889 AOP (result)->aopu.aop_dir,
8890 AOP (result)->aopu.aop_dir);
8892 emitcode ("bcf", "(%s >> 3),(%s & 7)",
8893 AOP (result)->aopu.aop_dir,
8894 AOP (result)->aopu.aop_dir);
8898 /* the right is also a bit variable */
8899 if (AOP_TYPE (right) == AOP_CRY)
8901 emitcode ("bcf", "(%s >> 3),(%s & 7)",
8902 AOP (result)->aopu.aop_dir,
8903 AOP (result)->aopu.aop_dir);
8904 emitcode ("btfsc", "(%s >> 3),(%s & 7)",
8905 AOP (right)->aopu.aop_dir,
8906 AOP (right)->aopu.aop_dir);
8907 emitcode ("bsf", "(%s >> 3),(%s & 7)",
8908 AOP (result)->aopu.aop_dir,
8909 AOP (result)->aopu.aop_dir);
8915 aopPut (AOP (result), "a", 0);
8919 /* bit variables done */
8921 size = AOP_SIZE (result);
8923 if (AOP_TYPE (right) == AOP_LIT)
8924 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
8925 if ((AOP_TYPE (result) != AOP_REG) &&
8926 (AOP_TYPE (right) == AOP_LIT) &&
8927 !IS_FLOAT (operandType (right)) &&
8933 if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) == 0)
8934 emitcode ("clrf", "%s", aopGet (AOP (result), size, FALSE, FALSE));
8937 emitcode ("movlw", "%s", aopGet (AOP (right), size, FALSE, FALSE));
8938 emitcode ("movwf", "%s", aopGet (AOP (result), size, FALSE, FALSE));
8946 if (AOP_TYPE (right) == AOP_LIT)
8947 emitcode ("movlw", "%s", aopGet (AOP (right), offset, FALSE, FALSE));
8949 emitcode ("movf", "%s,w", aopGet (AOP (right), offset, FALSE, FALSE));
8951 emitcode ("movwf", "%s", aopGet (AOP (result), offset, FALSE, FALSE));
8957 freeAsmop (right, NULL, ic, FALSE);
8958 freeAsmop (result, NULL, ic, TRUE);
8961 /*-----------------------------------------------------------------*/
8962 /* genJumpTab - genrates code for jump table */
8963 /*-----------------------------------------------------------------*/
8965 genJumpTab (iCode * ic)
8970 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
8972 aopOp (IC_JTCOND (ic), ic, FALSE);
8973 /* get the condition into accumulator */
8974 l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
8976 /* multiply by three */
8977 emitcode ("add", "a,acc");
8978 emitcode ("add", "a,%s", aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE));
8979 freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
8981 jtab = newiTempLabel (NULL);
8982 emitcode ("mov", "dptr,#%05d_DS_", jtab->key + 100);
8983 emitcode ("jmp", "@a+dptr");
8984 emitcode ("", "%05d_DS_:", jtab->key + 100);
8985 /* now generate the jump labels */
8986 for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
8987 jtab = setNextItem (IC_JTLABELS (ic)))
8988 emitcode ("ljmp", "%05d_DS_", jtab->key + 100);
8992 /*-----------------------------------------------------------------*/
8993 /* genMixedOperation - gen code for operators between mixed types */
8994 /*-----------------------------------------------------------------*/
8996 TSD - Written for the PIC port - but this unfortunately is buggy.
8997 This routine is good in that it is able to efficiently promote
8998 types to different (larger) sizes. Unfortunately, the temporary
8999 variables that are optimized out by this routine are sometimes
9000 used in other places. So until I know how to really parse the
9001 iCode tree, I'm going to not be using this routine :(.
9004 genMixedOperation (iCode * ic)
9007 operand *result = IC_RESULT (ic);
9008 sym_link *ctype = operandType (IC_LEFT (ic));
9009 operand *right = IC_RIGHT (ic);
9015 operand *nextright = NULL, *nextleft = NULL, *nextresult = NULL;
9017 emitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
9023 nextright = IC_RIGHT (nextic);
9024 nextleft = IC_LEFT (nextic);
9025 nextresult = IC_RESULT (nextic);
9027 aopOp (right, ic, FALSE);
9028 aopOp (result, ic, FALSE);
9029 aopOp (nextright, nextic, FALSE);
9030 aopOp (nextleft, nextic, FALSE);
9031 aopOp (nextresult, nextic, FALSE);
9033 if (sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (nextic))))
9040 emitcode (";remove right +", "");
9043 else if (sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (nextic))))
9050 emitcode (";remove left +", "");
9055 big = AOP_SIZE (nextleft);
9056 small = AOP_SIZE (nextright);
9062 emitcode (";optimize a +", "");
9063 /* if unsigned or not an integral type */
9064 if (AOP_TYPE (IC_LEFT (nextic)) == AOP_CRY)
9066 emitcode (";add a bit to something", "");
9071 emitcode ("movf", "%s,w", AOP (nextright)->aopu.aop_dir);
9073 if (!sameRegs (AOP (IC_LEFT (nextic)), AOP (IC_RESULT (nextic))))
9075 emitcode ("addwf", "%s,w", AOP (nextleft)->aopu.aop_dir);
9076 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (nextic)), 0, FALSE, FALSE));
9079 emitcode ("addwf", "%s,f", AOP (nextleft)->aopu.aop_dir);
9089 if (!sameRegs (AOP (IC_LEFT (nextic)), AOP (IC_RESULT (nextic))))
9091 emitcode ("movf", "%s,w", aopGet (AOP (IC_LEFT (nextic)), offset, FALSE, FALSE));
9092 emitcode ("movwf", "%s,f", aopGet (AOP (IC_RESULT (nextic)), offset, FALSE, FALSE));
9095 emitcode ("movf", "%s,w", aopGet (AOP (IC_LEFT (nextic)), offset, FALSE, FALSE));
9097 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
9098 AOP (IC_RIGHT (nextic))->aopu.aop_dir,
9099 AOP (IC_RIGHT (nextic))->aopu.aop_dir);
9100 emitcode (" incf", "%s,w", aopGet (AOP (IC_LEFT (nextic)), offset, FALSE, FALSE));
9101 emitcode ("movwf", "%s", aopGet (AOP (IC_RESULT (nextic)), offset, FALSE, FALSE));
9106 emitcode ("rlf", "known_zero,w");
9113 if (!sameRegs (AOP (IC_LEFT (nextic)), AOP (IC_RESULT (nextic))))
9115 emitcode ("addwf", "%s,w", aopGet (AOP (IC_LEFT (nextic)), offset, FALSE, FALSE));
9116 emitcode ("movwf", "%s,f", aopGet (AOP (IC_RESULT (nextic)), offset, FALSE, FALSE));
9120 emitcode ("addwf", "%s,f", aopGet (AOP (IC_RESULT (nextic)), offset, FALSE, FALSE));
9130 freeAsmop (right, NULL, ic, TRUE);
9131 freeAsmop (result, NULL, ic, TRUE);
9132 freeAsmop (nextright, NULL, ic, TRUE);
9133 freeAsmop (nextleft, NULL, ic, TRUE);
9135 nextic->generated = 1;
9142 /*-----------------------------------------------------------------*/
9143 /* genCast - gen code for casting */
9144 /*-----------------------------------------------------------------*/
9146 genCast (iCode * ic)
9148 operand *result = IC_RESULT (ic);
9149 sym_link *ctype = operandType (IC_LEFT (ic));
9150 operand *right = IC_RIGHT (ic);
9153 emitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
9154 /* if they are equivalent then do nothing */
9155 if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
9158 aopOp (right, ic, FALSE);
9159 aopOp (result, ic, FALSE);
9161 /* if the result is a bit */
9162 if (AOP_TYPE (result) == AOP_CRY)
9164 /* if the right size is a literal then
9165 we know what the value is */
9166 if (AOP_TYPE (right) == AOP_LIT)
9168 emitcode ("; *** right is a lit", "%s %d", __FUNCTION__, __LINE__);
9169 if (((int) operandLitValue (right)))
9170 emitcode ("bsf", "(%s >> 3), (%s & 7)",
9171 AOP (result)->aopu.aop_dir,
9172 AOP (result)->aopu.aop_dir);
9174 emitcode ("bcf", "(%s >> 3), (%s & 7)",
9175 AOP (result)->aopu.aop_dir,
9176 AOP (result)->aopu.aop_dir);
9181 /* the right is also a bit variable */
9182 if (AOP_TYPE (right) == AOP_CRY)
9184 emitcode ("clrc", "");
9185 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
9186 AOP (right)->aopu.aop_dir,
9187 AOP (right)->aopu.aop_dir);
9188 aopPut (AOP (result), "c", 0);
9194 aopPut (AOP (result), "a", 0);
9198 /* if they are the same size : or less */
9199 if (AOP_SIZE (result) <= AOP_SIZE (right))
9202 /* if they are in the same place */
9203 if (sameRegs (AOP (right), AOP (result)))
9206 /* if they in different places then copy */
9207 size = AOP_SIZE (result);
9211 aopPut (AOP (result),
9212 aopGet (AOP (right), offset, FALSE, FALSE),
9220 /* if the result is of type pointer */
9225 sym_link *type = operandType (right);
9226 sym_link *etype = getSpec (type);
9228 /* pointer to generic pointer */
9229 if (IS_GENPTR (ctype))
9234 p_type = DCL_TYPE (type);
9237 /* we have to go by the storage class */
9238 p_type = PTR_TYPE (SPEC_OCLS (etype));
9240 /* if (SPEC_OCLS(etype)->codesp ) */
9241 /* p_type = CPOINTER ; */
9243 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9244 /* p_type = FPOINTER ; */
9246 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9247 /* p_type = PPOINTER; */
9249 /* if (SPEC_OCLS(etype) == idata ) */
9250 /* p_type = IPOINTER ; */
9252 /* p_type = POINTER ; */
9255 /* the first two bytes are known */
9256 size = GPTRSIZE - 1;
9260 aopPut (AOP (result),
9261 aopGet (AOP (right), offset, FALSE, FALSE),
9265 /* the last byte depending on type */
9283 /* this should never happen */
9284 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9285 "got unknown pointer type");
9289 aopPut (AOP (result), l, GPTRSIZE - 1);
9293 /* just copy the pointers */
9294 size = AOP_SIZE (result);
9298 aopPut (AOP (result),
9299 aopGet (AOP (right), offset, FALSE, FALSE),
9307 if (AOP_TYPE (right) == AOP_CRY)
9310 size = AOP_SIZE (right);
9312 emitcode ("clrf", "%s ; %d", aopGet (AOP (result), 0, FALSE, FALSE), __LINE__);
9313 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
9314 AOP (right)->aopu.aop_dir,
9315 AOP (right)->aopu.aop_dir);
9316 emitcode ("incf", "%s,f", aopGet (AOP (result), 0, FALSE, FALSE), __LINE__);
9319 emitcode ("clrf", "%s", aopGet (AOP (result), offset++, FALSE, FALSE), __LINE__);
9324 /* so we now know that the size of destination is greater
9325 than the size of the source.
9326 Now, if the next iCode is an operator then we might be
9327 able to optimize the operation without performing a cast.
9329 if (genMixedOperation (ic))
9333 /* we move to result for the size of source */
9334 size = AOP_SIZE (right);
9338 emitcode (";", "%d", __LINE__);
9339 aopPut (AOP (result),
9340 aopGet (AOP (right), offset, FALSE, FALSE),
9345 /* now depending on the sign of the destination */
9346 size = AOP_SIZE (result) - AOP_SIZE (right);
9347 /* if unsigned or not an integral type */
9348 if (SPEC_USIGN (ctype) || !IS_SPEC (ctype))
9351 emitcode ("clrf", "%s", aopGet (AOP (result), offset++, FALSE, FALSE));
9355 /* we need to extend the sign :{ */
9356 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
9359 emitcode ("clrw", "");
9360 emitcode ("btfsc", "(%s >> 3), (%s & 7)",
9361 AOP (right)->aopu.aop_dir,
9362 AOP (right)->aopu.aop_dir);
9363 emitcode ("movlw", "0xff");
9366 emitcode ("movwf", "%s", aopGet (AOP (result), offset++, FALSE, FALSE));
9367 // aopPut(AOP(result),"a",offset++);
9372 /* we are done hurray !!!! */
9375 freeAsmop (right, NULL, ic, TRUE);
9376 freeAsmop (result, NULL, ic, TRUE);
9380 /*-----------------------------------------------------------------*/
9381 /* genDjnz - generate decrement & jump if not zero instrucion */
9382 /*-----------------------------------------------------------------*/
9384 genDjnz (iCode * ic, iCode * ifx)
9387 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
9392 /* if the if condition has a false label
9393 then we cannot save */
9397 /* if the minus is not of the form
9399 if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
9400 !IS_OP_LITERAL (IC_RIGHT (ic)))
9403 if (operandLitValue (IC_RIGHT (ic)) != 1)
9406 /* if the size of this greater than one then no
9408 if (getSize (operandType (IC_RESULT (ic))) > 1)
9411 /* otherwise we can save BIG */
9412 lbl = newiTempLabel (NULL);
9413 lbl1 = newiTempLabel (NULL);
9415 aopOp (IC_RESULT (ic), ic, FALSE);
9417 if (IS_AOP_PREG (IC_RESULT (ic)))
9419 emitcode ("dec", "%s",
9420 aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
9421 emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
9422 emitcode ("jnz", "%05d_DS_", lbl->key + 100);
9426 emitcode ("decfsz", "%s,f", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
9427 emitcode ("goto", "_%05d_DS_", IC_TRUE (ifx)->key + 100 + labelOffset);
9430 /* emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9431 /* emitcode ("","%05d_DS_:",lbl->key+100); */
9432 /* emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9433 /* emitcode ("","%05d_DS_:",lbl1->key+100); */
9436 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
9441 /*-----------------------------------------------------------------*/
9442 /* genReceive - generate code for a receive iCode */
9443 /*-----------------------------------------------------------------*/
9445 genReceive (iCode * ic)
9447 DEBUGemitcode ("; ***", "%s %d", __FUNCTION__, __LINE__);
9449 if (isOperandInFarSpace (IC_RESULT (ic)) &&
9450 (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
9451 IS_TRUE_SYMOP (IC_RESULT (ic))))
9454 int size = getSize (operandType (IC_RESULT (ic)));
9455 int offset = fReturnSize - size;
9458 emitcode ("push", "%s", (strcmp (fReturn[fReturnSize - offset - 1], "a") ?
9459 fReturn[fReturnSize - offset - 1] : "acc"));
9462 aopOp (IC_RESULT (ic), ic, FALSE);
9463 size = AOP_SIZE (IC_RESULT (ic));
9467 emitcode ("pop", "acc");
9468 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
9475 aopOp (IC_RESULT (ic), ic, FALSE);
9477 assignResultValue (IC_RESULT (ic));
9480 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
9483 /*-----------------------------------------------------------------*/
9484 /* genpic14Code - generate code for pic14 based controllers */
9485 /*-----------------------------------------------------------------*/
9487 genpic14Code (iCode * lic)
9492 lineHead = lineCurr = NULL;
9494 /* if debug information required */
9495 /* if (options.debug && currFunc) { */
9498 cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
9500 if (IS_STATIC (currFunc->etype))
9501 emitcode ("", ";F%s$%s$0$0 %d", moduleName, currFunc->name, __LINE__);
9503 emitcode ("", ";G$%s$0$0 %d", currFunc->name, __LINE__);
9508 for (ic = lic; ic; ic = ic->next)
9511 DEBUGemitcode (";ic", "");
9512 if (cln != ic->lineno)
9517 emitcode ("", ";C$%s$%d$%d$%d ==.",
9518 FileBaseName (ic->filename), ic->lineno,
9519 ic->level, ic->block);
9522 emitcode (";", "%s %d", ic->filename, ic->lineno);
9525 /* if the result is marked as
9526 spilt and rematerializable or code for
9527 this has already been generated then
9529 if (resultRemat (ic) || ic->generated)
9532 /* depending on the operation */
9552 /* IPOP happens only when trying to restore a
9553 spilt live range, if there is an ifx statement
9554 following this pop then the if statement might
9555 be using some of the registers being popped which
9556 would destory the contents of the register so
9557 we need to check for this condition and handle it */
9559 ic->next->op == IFX &&
9560 regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
9561 genIfx (ic->next, ic);
9579 genEndFunction (ic);
9599 if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
9616 genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
9620 genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
9627 /* note these two are xlated by algebraic equivalence
9628 during parsing SDCC.y */
9629 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9630 "got '>=' or '<=' shouldn't have come here");
9634 genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
9646 genXor (ic, ifxForOp (IC_RESULT (ic), ic));
9650 genOr (ic, ifxForOp (IC_RESULT (ic), ic));
9654 genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
9681 case GET_VALUE_AT_ADDRESS:
9686 if (POINTER_SET (ic))
9713 addSet (&_G.sendSet, ic);
9718 /* piCode(ic,stdout); */
9724 /* now we are ready to call the
9725 peep hole optimizer */
9726 if (!options.nopeep)
9728 printf ("peep hole optimizing\n");
9729 peepHole (&lineHead);
9731 /* now do the actual printing */
9732 printLine (lineHead, codeOutFile);