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)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
27 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
28 Made everything static
29 -------------------------------------------------------------------------*/
35 #include "SDCCglobl.h"
38 #ifdef HAVE_SYS_ISA_DEFS_H
39 #include <sys/isa_defs.h>
44 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
45 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
46 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
52 #include "SDCCpeeph.h"
56 char *aopLiteral (value * val, int offset);
59 /* this is the down and dirty file with all kinds of
60 kludgy & hacky stuff. This is what it is all about
61 CODE GENERATION for a specific MCU . some of the
62 routines may be reusable, will have to see */
64 static char *zero = "#0x00";
65 static char *one = "#0x01";
69 {"dpl", "dph", "b", "a"};
70 unsigned fReturnSizeMCS51 = 4; /* shared with ralloc.c */
71 char **fReturn = fReturn8051;
72 static char *accUse[] =
75 static short rbank = -1;
89 extern int mcs51_ptrRegReq;
90 extern int mcs51_nRegs;
91 extern FILE *codeOutFile;
92 static void saverbank (int, iCode *, bool);
93 #define RESULTONSTACK(x) \
94 (IC_RESULT(x) && IC_RESULT(x)->aop && \
95 IC_RESULT(x)->aop->type == AOP_STK )
97 #define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x);
98 #define CLRC emitcode("clr","c")
99 #define SETC emitcode("setb","c")
101 static lineNode *lineHead = NULL;
102 static lineNode *lineCurr = NULL;
104 static unsigned char SLMask[] =
105 {0xFF, 0xFE, 0xFC, 0xF8, 0xF0,
106 0xE0, 0xC0, 0x80, 0x00};
107 static unsigned char SRMask[] =
108 {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
109 0x07, 0x03, 0x01, 0x00};
116 /*-----------------------------------------------------------------*/
117 /* emitcode - writes the code into a file : for now it is simple */
118 /*-----------------------------------------------------------------*/
120 emitcode (char *inst, char *fmt,...)
123 char lb[MAX_INLINEASM];
131 sprintf (lb, "%s\t", inst);
133 sprintf (lb, "%s", inst);
134 vsprintf (lb + (strlen (lb)), fmt, ap);
137 vsprintf (lb, fmt, ap);
139 while (isspace (*lbp))
143 lineCurr = (lineCurr ?
144 connectLine (lineCurr, newLineNode (lb)) :
145 (lineHead = newLineNode (lb)));
146 lineCurr->isInline = _G.inLine;
147 lineCurr->isDebug = _G.debugLine;
151 /*-----------------------------------------------------------------*/
152 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed */
153 /*-----------------------------------------------------------------*/
155 getFreePtr (iCode * ic, asmop ** aopp, bool result)
157 bool r0iu = FALSE, r1iu = FALSE;
158 bool r0ou = FALSE, r1ou = FALSE;
160 /* the logic: if r0 & r1 used in the instruction
161 then we are in trouble otherwise */
163 /* first check if r0 & r1 are used by this
164 instruction, in which case we are in trouble */
165 if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
166 (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
171 r0ou = bitVectBitValue (ic->rMask, R0_IDX);
172 r1ou = bitVectBitValue (ic->rMask, R1_IDX);
174 /* if no usage of r0 then return it */
177 ic->rUsed = bitVectSetBit (ic->rUsed, R0_IDX);
178 (*aopp)->type = AOP_R0;
180 return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx (R0_IDX);
183 /* if no usage of r1 then return it */
186 ic->rUsed = bitVectSetBit (ic->rUsed, R1_IDX);
187 (*aopp)->type = AOP_R1;
189 return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx (R1_IDX);
192 /* now we know they both have usage */
193 /* if r0 not used in this instruction */
196 /* push it if not already pushed */
199 emitcode ("push", "%s",
200 mcs51_regWithIdx (R0_IDX)->dname);
204 ic->rUsed = bitVectSetBit (ic->rUsed, R0_IDX);
205 (*aopp)->type = AOP_R0;
207 return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx (R0_IDX);
210 /* if r1 not used then */
214 /* push it if not already pushed */
217 emitcode ("push", "%s",
218 mcs51_regWithIdx (R1_IDX)->dname);
222 ic->rUsed = bitVectSetBit (ic->rUsed, R1_IDX);
223 (*aopp)->type = AOP_R1;
224 return mcs51_regWithIdx (R1_IDX);
228 /* I said end of world but not quite end of world yet */
229 /* if this is a result then we can push it on the stack */
232 (*aopp)->type = AOP_STK;
236 /* other wise this is true end of the world */
237 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
238 "getFreePtr should never reach here");
242 /*-----------------------------------------------------------------*/
243 /* newAsmop - creates a new asmOp */
244 /*-----------------------------------------------------------------*/
246 newAsmop (short type)
250 aop = Safe_calloc (1, sizeof (asmop));
260 emitcode (";", "Select standard DPTR");
261 emitcode ("mov", "dps, #0x00");
265 emitcode (";", "Select alternate DPTR");
266 emitcode ("mov", "dps, #0x01");
270 /*-----------------------------------------------------------------*/
271 /* pointerCode - returns the code for a pointer type */
272 /*-----------------------------------------------------------------*/
274 pointerCode (sym_link * etype)
277 return PTR_TYPE (SPEC_OCLS (etype));
281 /*-----------------------------------------------------------------*/
282 /* aopForSym - for a true symbol */
283 /*-----------------------------------------------------------------*/
285 aopForSym (iCode * ic, symbol * sym, bool result)
288 memmap *space = SPEC_OCLS (sym->etype);
290 /* if already has one */
294 /* assign depending on the storage class */
295 /* if it is on the stack or indirectly addressable */
296 /* space we need to assign either r0 or r1 to it */
297 if (sym->onStack || sym->iaccess)
299 sym->aop = aop = newAsmop (0);
300 aop->aopu.aop_ptr = getFreePtr (ic, &aop, result);
301 aop->size = getSize (sym->type);
303 /* now assign the address of the variable to
304 the pointer register */
305 if (aop->type != AOP_STK)
311 emitcode ("push", "acc");
313 emitcode ("mov", "a,_bp");
314 emitcode ("add", "a,#0x%02x",
316 ((char) (sym->stack - _G.nRegsSaved)) :
317 ((char) sym->stack)) & 0xff);
318 emitcode ("mov", "%s,a",
319 aop->aopu.aop_ptr->name);
322 emitcode ("pop", "acc");
325 emitcode ("mov", "%s,#%s",
326 aop->aopu.aop_ptr->name,
328 aop->paged = space->paged;
331 aop->aopu.aop_stk = sym->stack;
335 /* if in bit space */
336 if (IN_BITSPACE (space))
338 sym->aop = aop = newAsmop (AOP_CRY);
339 aop->aopu.aop_dir = sym->rname;
340 aop->size = getSize (sym->type);
343 /* if it is in direct space */
344 if (IN_DIRSPACE (space))
346 sym->aop = aop = newAsmop (AOP_DIR);
347 aop->aopu.aop_dir = sym->rname;
348 aop->size = getSize (sym->type);
352 /* special case for a function */
353 if (IS_FUNC (sym->type))
355 sym->aop = aop = newAsmop (AOP_IMMD);
356 aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
357 strcpy (aop->aopu.aop_immd, sym->rname);
358 aop->size = FPTRSIZE;
362 /* only remaining is far space */
363 /* in which case DPTR gets the address */
364 sym->aop = aop = newAsmop (AOP_DPTR);
365 emitcode ("mov", "dptr,#%s", sym->rname);
366 aop->size = getSize (sym->type);
368 /* if it is in code space */
369 if (IN_CODESPACE (space))
375 /*-----------------------------------------------------------------*/
376 /* aopForRemat - rematerialzes an object */
377 /*-----------------------------------------------------------------*/
379 aopForRemat (symbol * sym)
381 iCode *ic = sym->rematiCode;
382 asmop *aop = newAsmop (AOP_IMMD);
388 val += (int) operandLitValue (IC_RIGHT (ic));
389 else if (ic->op == '-')
390 val -= (int) operandLitValue (IC_RIGHT (ic));
394 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
398 sprintf (buffer, "(%s %c 0x%04x)",
399 OP_SYMBOL (IC_LEFT (ic))->rname,
400 val >= 0 ? '+' : '-',
403 strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
405 aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
406 strcpy (aop->aopu.aop_immd, buffer);
410 /*-----------------------------------------------------------------*/
411 /* regsInCommon - two operands have some registers in common */
412 /*-----------------------------------------------------------------*/
414 regsInCommon (operand * op1, operand * op2)
419 /* if they have registers in common */
420 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
423 sym1 = OP_SYMBOL (op1);
424 sym2 = OP_SYMBOL (op2);
426 if (sym1->nRegs == 0 || sym2->nRegs == 0)
429 for (i = 0; i < sym1->nRegs; i++)
435 for (j = 0; j < sym2->nRegs; j++)
440 if (sym2->regs[j] == sym1->regs[i])
448 /*-----------------------------------------------------------------*/
449 /* operandsEqu - equivalent */
450 /*-----------------------------------------------------------------*/
452 operandsEqu (operand * op1, operand * op2)
456 /* if they not symbols */
457 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
460 sym1 = OP_SYMBOL (op1);
461 sym2 = OP_SYMBOL (op2);
463 /* if both are itemps & one is spilt
464 and the other is not then false */
465 if (IS_ITEMP (op1) && IS_ITEMP (op2) &&
466 sym1->isspilt != sym2->isspilt)
469 /* if they are the same */
473 if (strcmp (sym1->rname, sym2->rname) == 0)
477 /* if left is a tmp & right is not */
478 if (IS_ITEMP (op1) &&
481 (sym1->usl.spillLoc == sym2))
484 if (IS_ITEMP (op2) &&
488 (sym2->usl.spillLoc == sym1))
494 /*-----------------------------------------------------------------*/
495 /* sameRegs - two asmops have the same registers */
496 /*-----------------------------------------------------------------*/
498 sameRegs (asmop * aop1, asmop * aop2)
505 if (aop1->type != AOP_REG ||
506 aop2->type != AOP_REG)
509 if (aop1->size != aop2->size)
512 for (i = 0; i < aop1->size; i++)
513 if (aop1->aopu.aop_reg[i] !=
514 aop2->aopu.aop_reg[i])
520 /*-----------------------------------------------------------------*/
521 /* aopOp - allocates an asmop for an operand : */
522 /*-----------------------------------------------------------------*/
524 aopOp (operand * op, iCode * ic, bool result)
533 /* if this a literal */
534 if (IS_OP_LITERAL (op))
536 op->aop = aop = newAsmop (AOP_LIT);
537 aop->aopu.aop_lit = op->operand.valOperand;
538 aop->size = getSize (operandType (op));
542 /* if already has a asmop then continue */
546 /* if the underlying symbol has a aop */
547 if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
549 op->aop = OP_SYMBOL (op)->aop;
553 /* if this is a true symbol */
554 if (IS_TRUE_SYMOP (op))
556 op->aop = aopForSym (ic, OP_SYMBOL (op), result);
560 /* this is a temporary : this has
566 e) can be a return use only */
568 sym = OP_SYMBOL (op);
571 /* if the type is a conditional */
572 if (sym->regType == REG_CND)
574 aop = op->aop = sym->aop = newAsmop (AOP_CRY);
579 /* if it is spilt then two situations
581 b) has a spill location */
582 if (sym->isspilt || sym->nRegs == 0)
585 /* rematerialize it NOW */
588 sym->aop = op->aop = aop =
590 aop->size = getSize (sym->type);
597 aop = op->aop = sym->aop = newAsmop (AOP_ACC);
598 aop->size = getSize (sym->type);
599 for (i = 0; i < 2; i++)
600 aop->aopu.aop_str[i] = accUse[i];
607 aop = op->aop = sym->aop = newAsmop (AOP_STR);
608 aop->size = getSize (sym->type);
609 for (i = 0; i < fReturnSizeMCS51; i++)
610 aop->aopu.aop_str[i] = fReturn[i];
614 /* else spill location */
615 sym->aop = op->aop = aop =
616 aopForSym (ic, sym->usl.spillLoc, result);
617 aop->size = getSize (sym->type);
621 /* must be in a register */
622 sym->aop = op->aop = aop = newAsmop (AOP_REG);
623 aop->size = sym->nRegs;
624 for (i = 0; i < sym->nRegs; i++)
625 aop->aopu.aop_reg[i] = sym->regs[i];
628 /*-----------------------------------------------------------------*/
629 /* freeAsmop - free up the asmop given to an operand */
630 /*----------------------------------------------------------------*/
632 freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
649 /* depending on the asmop type only three cases need work AOP_RO
650 , AOP_R1 && AOP_STK */
658 emitcode ("pop", "ar0");
662 bitVectUnSetBit (ic->rUsed, R0_IDX);
670 emitcode ("pop", "ar1");
674 bitVectUnSetBit (ic->rUsed, R1_IDX);
680 int stk = aop->aopu.aop_stk + aop->size;
681 bitVectUnSetBit (ic->rUsed, R0_IDX);
682 bitVectUnSetBit (ic->rUsed, R1_IDX);
684 getFreePtr (ic, &aop, FALSE);
688 emitcode ("mov", "a,_bp");
689 emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff);
690 emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name);
694 emitcode ("mov", "%s,_bp", aop->aopu.aop_ptr->name);
699 emitcode ("pop", "acc");
700 emitcode ("mov", "@%s,a", aop->aopu.aop_ptr->name);
703 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
706 freeAsmop (op, NULL, ic, TRUE);
709 emitcode ("pop", "ar0");
715 emitcode ("pop", "ar1");
722 /* all other cases just dealloc */
728 OP_SYMBOL (op)->aop = NULL;
729 /* if the symbol has a spill */
731 SPIL_LOC (op)->aop = NULL;
736 /*-----------------------------------------------------------------*/
737 /* aopGet - for fetching value of the aop */
738 /*-----------------------------------------------------------------*/
740 aopGet (asmop * aop, int offset, bool bit16, bool dname)
745 /* offset is greater than
747 if (offset > (aop->size - 1) &&
748 aop->type != AOP_LIT)
751 /* depending on type */
757 /* if we need to increment it */
758 while (offset > aop->coff)
760 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
764 while (offset < aop->coff)
766 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
773 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
774 return (dname ? "acc" : "a");
776 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
777 rs = Safe_calloc (1, strlen (s) + 1);
784 if (aop->type == AOP_DPTR2)
789 while (offset > aop->coff)
791 emitcode ("inc", "dptr");
795 while (offset < aop->coff)
797 emitcode ("lcall", "__decdptr");
804 emitcode ("clr", "a");
805 emitcode ("movc", "a,@a+dptr");
809 emitcode ("movx", "a,@dptr");
812 if (aop->type == AOP_DPTR2)
817 return (dname ? "acc" : "a");
822 sprintf (s, "#%s", aop->aopu.aop_immd);
824 sprintf (s, "#(%s >> %d)",
830 rs = Safe_calloc (1, strlen (s) + 1);
836 sprintf (s, "(%s + %d)",
840 sprintf (s, "%s", aop->aopu.aop_dir);
841 rs = Safe_calloc (1, strlen (s) + 1);
847 return aop->aopu.aop_reg[offset]->dname;
849 return aop->aopu.aop_reg[offset]->name;
852 emitcode ("clr", "a");
853 emitcode ("mov", "c,%s", aop->aopu.aop_dir);
854 emitcode ("rlc", "a");
855 return (dname ? "acc" : "a");
858 if (!offset && dname)
860 return aop->aopu.aop_str[offset];
863 return aopLiteral (aop->aopu.aop_lit, offset);
867 if (strcmp (aop->aopu.aop_str[offset], "a") == 0 &&
871 return aop->aopu.aop_str[offset];
875 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
876 "aopget got unsupported aop->type");
879 /*-----------------------------------------------------------------*/
880 /* aopPut - puts a string for a aop */
881 /*-----------------------------------------------------------------*/
883 aopPut (asmop * aop, char *s, int offset)
887 if (aop->size && offset > (aop->size - 1))
889 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
890 "aopPut got offset > aop->size");
894 /* will assign value to value */
895 /* depending on where it is ofcourse */
900 sprintf (d, "(%s + %d)",
901 aop->aopu.aop_dir, offset);
903 sprintf (d, "%s", aop->aopu.aop_dir);
906 emitcode ("mov", "%s,%s", d, s);
911 if (strcmp (aop->aopu.aop_reg[offset]->name, s) != 0 &&
912 strcmp (aop->aopu.aop_reg[offset]->dname, s) != 0)
915 strcmp (s, "r0") == 0 ||
916 strcmp (s, "r1") == 0 ||
917 strcmp (s, "r2") == 0 ||
918 strcmp (s, "r3") == 0 ||
919 strcmp (s, "r4") == 0 ||
920 strcmp (s, "r5") == 0 ||
921 strcmp (s, "r6") == 0 ||
922 strcmp (s, "r7") == 0)
923 emitcode ("mov", "%s,%s",
924 aop->aopu.aop_reg[offset]->dname, s);
926 emitcode ("mov", "%s,%s",
927 aop->aopu.aop_reg[offset]->name, s);
934 if (aop->type == AOP_DPTR2)
941 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
942 "aopPut writting to code space");
946 while (offset > aop->coff)
949 emitcode ("inc", "dptr");
952 while (offset < aop->coff)
955 emitcode ("lcall", "__decdptr");
960 /* if not in accumulater */
963 emitcode ("movx", "@dptr,a");
965 if (aop->type == AOP_DPTR2)
973 while (offset > aop->coff)
976 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
978 while (offset < aop->coff)
981 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
988 emitcode ("movx", "@%s,a", aop->aopu.aop_ptr->name);
994 emitcode ("mov", "@%s,a", aop->aopu.aop_ptr->name);
996 else if (strcmp (s, "r0") == 0 ||
997 strcmp (s, "r1") == 0 ||
998 strcmp (s, "r2") == 0 ||
999 strcmp (s, "r3") == 0 ||
1000 strcmp (s, "r4") == 0 ||
1001 strcmp (s, "r5") == 0 ||
1002 strcmp (s, "r6") == 0 ||
1003 strcmp (s, "r7") == 0)
1006 sprintf (buffer, "a%s", s);
1007 emitcode ("mov", "@%s,%s",
1008 aop->aopu.aop_ptr->name, buffer);
1011 emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
1016 if (strcmp (s, "a") == 0)
1017 emitcode ("push", "acc");
1019 emitcode ("push", "%s", s);
1024 /* if bit variable */
1025 if (!aop->aopu.aop_dir)
1027 emitcode ("clr", "a");
1028 emitcode ("rlc", "a");
1033 emitcode ("clr", "%s", aop->aopu.aop_dir);
1035 emitcode ("setb", "%s", aop->aopu.aop_dir);
1036 else if (!strcmp (s, "c"))
1037 emitcode ("mov", "%s,c", aop->aopu.aop_dir);
1040 if (strcmp (s, "a"))
1045 symbol *lbl = newiTempLabel (NULL);
1046 emitcode ("clr", "c");
1047 emitcode ("jz", "%05d$", lbl->key + 100);
1048 emitcode ("cpl", "c");
1049 emitcode ("", "%05d$:", lbl->key + 100);
1050 emitcode ("mov", "%s,c", aop->aopu.aop_dir);
1058 if (strcmp (aop->aopu.aop_str[offset], s))
1059 emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset], s);
1064 if (!offset && (strcmp (s, "acc") == 0))
1067 if (strcmp (aop->aopu.aop_str[offset], s))
1068 emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset], s);
1072 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1073 "aopPut got unsupported aop->type");
1081 /*-----------------------------------------------------------------*/
1082 /* pointToEnd :- points to the last byte of the operand */
1083 /*-----------------------------------------------------------------*/
1085 pointToEnd (asmop * aop)
1091 aop->coff = count = (aop->size - 1);
1097 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1101 emitcode ("inc", "dptr");
1108 /*-----------------------------------------------------------------*/
1109 /* reAdjustPreg - points a register back to where it should */
1110 /*-----------------------------------------------------------------*/
1112 reAdjustPreg (asmop * aop)
1115 if ((aop->coff==0) || aop->size <= 1)
1123 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1127 if (aop->type == AOP_DPTR2)
1133 emitcode ("lcall", "__decdptr");
1136 if (aop->type == AOP_DPTR2)
1146 #define AOP(op) op->aop
1147 #define AOP_TYPE(op) AOP(op)->type
1148 #define AOP_SIZE(op) AOP(op)->size
1149 #define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
1150 AOP_TYPE(x) == AOP_R0))
1152 #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
1153 AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
1156 #define AOP_INPREG(x) (x && (x->type == AOP_REG && \
1157 (x->aopu.aop_reg[0] == mcs51_regWithIdx(R0_IDX) || \
1158 x->aopu.aop_reg[0] == mcs51_regWithIdx(R1_IDX) )))
1160 /*-----------------------------------------------------------------*/
1161 /* genNotFloat - generates not for float operations */
1162 /*-----------------------------------------------------------------*/
1164 genNotFloat (operand * op, operand * res)
1170 /* we will put 127 in the first byte of
1172 aopPut (AOP (res), "#127", 0);
1173 size = AOP_SIZE (op) - 1;
1176 l = aopGet (op->aop, offset++, FALSE, FALSE);
1181 emitcode ("orl", "a,%s",
1183 offset++, FALSE, FALSE));
1186 tlbl = newiTempLabel (NULL);
1187 aopPut (res->aop, one, 1);
1188 emitcode ("jz", "%05d$", (tlbl->key + 100));
1189 aopPut (res->aop, zero, 1);
1190 emitcode ("", "%05d$:", (tlbl->key + 100));
1192 size = res->aop->size - 2;
1194 /* put zeros in the rest */
1196 aopPut (res->aop, zero, offset++);
1199 /*-----------------------------------------------------------------*/
1200 /* opIsGptr: returns non-zero if the passed operand is */
1201 /* a generic pointer type. */
1202 /*-----------------------------------------------------------------*/
1204 opIsGptr (operand * op)
1206 sym_link *type = operandType (op);
1208 if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type))
1215 /*-----------------------------------------------------------------*/
1216 /* getDataSize - get the operand data size */
1217 /*-----------------------------------------------------------------*/
1219 getDataSize (operand * op)
1222 size = AOP_SIZE (op);
1223 if (size == GPTRSIZE)
1225 sym_link *type = operandType (op);
1226 if (IS_GENPTR (type))
1228 /* generic pointer; arithmetic operations
1229 * should ignore the high byte (pointer type).
1237 /*-----------------------------------------------------------------*/
1238 /* outAcc - output Acc */
1239 /*-----------------------------------------------------------------*/
1241 outAcc (operand * result)
1244 size = getDataSize (result);
1247 aopPut (AOP (result), "a", 0);
1250 /* unsigned or positive */
1253 aopPut (AOP (result), zero, offset++);
1258 /*-----------------------------------------------------------------*/
1259 /* outBitC - output a bit C */
1260 /*-----------------------------------------------------------------*/
1262 outBitC (operand * result)
1264 /* if the result is bit */
1265 if (AOP_TYPE (result) == AOP_CRY)
1266 aopPut (AOP (result), "c", 0);
1269 emitcode ("clr", "a");
1270 emitcode ("rlc", "a");
1275 /*-----------------------------------------------------------------*/
1276 /* toBoolean - emit code for orl a,operator(sizeop) */
1277 /*-----------------------------------------------------------------*/
1279 toBoolean (operand * oper)
1281 int size = AOP_SIZE (oper) - 1;
1283 MOVA (aopGet (AOP (oper), 0, FALSE, FALSE));
1285 emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE));
1289 /*-----------------------------------------------------------------*/
1290 /* genNot - generate code for ! operation */
1291 /*-----------------------------------------------------------------*/
1296 sym_link *optype = operandType (IC_LEFT (ic));
1298 /* assign asmOps to operand & result */
1299 aopOp (IC_LEFT (ic), ic, FALSE);
1300 aopOp (IC_RESULT (ic), ic, TRUE);
1302 /* if in bit space then a special case */
1303 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
1305 emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
1306 emitcode ("cpl", "c");
1307 outBitC (IC_RESULT (ic));
1311 /* if type float then do float */
1312 if (IS_FLOAT (optype))
1314 genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
1318 toBoolean (IC_LEFT (ic));
1320 tlbl = newiTempLabel (NULL);
1321 emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
1322 emitcode ("", "%05d$:", tlbl->key + 100);
1323 outBitC (IC_RESULT (ic));
1326 /* release the aops */
1327 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
1328 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1332 /*-----------------------------------------------------------------*/
1333 /* genCpl - generate code for complement */
1334 /*-----------------------------------------------------------------*/
1342 /* assign asmOps to operand & result */
1343 aopOp (IC_LEFT (ic), ic, FALSE);
1344 aopOp (IC_RESULT (ic), ic, TRUE);
1346 /* if both are in bit space then
1348 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
1349 AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
1352 emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
1353 emitcode ("cpl", "c");
1354 emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
1358 size = AOP_SIZE (IC_RESULT (ic));
1361 char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE);
1363 emitcode ("cpl", "a");
1364 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
1369 /* release the aops */
1370 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
1371 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1374 /*-----------------------------------------------------------------*/
1375 /* genUminusFloat - unary minus for floating points */
1376 /*-----------------------------------------------------------------*/
1378 genUminusFloat (operand * op, operand * result)
1380 int size, offset = 0;
1382 /* for this we just need to flip the
1383 first it then copy the rest in place */
1384 size = AOP_SIZE (op) - 1;
1385 l = aopGet (AOP (op), 3, FALSE, FALSE);
1389 emitcode ("cpl", "acc.7");
1390 aopPut (AOP (result), "a", 3);
1394 aopPut (AOP (result),
1395 aopGet (AOP (op), offset, FALSE, FALSE),
1401 /*-----------------------------------------------------------------*/
1402 /* genUminus - unary minus code generation */
1403 /*-----------------------------------------------------------------*/
1405 genUminus (iCode * ic)
1408 sym_link *optype, *rtype;
1412 aopOp (IC_LEFT (ic), ic, FALSE);
1413 aopOp (IC_RESULT (ic), ic, TRUE);
1415 /* if both in bit space then special
1417 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
1418 AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
1421 emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
1422 emitcode ("cpl", "c");
1423 emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
1427 optype = operandType (IC_LEFT (ic));
1428 rtype = operandType (IC_RESULT (ic));
1430 /* if float then do float stuff */
1431 if (IS_FLOAT (optype))
1433 genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
1437 /* otherwise subtract from zero */
1438 size = AOP_SIZE (IC_LEFT (ic));
1443 char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE);
1444 if (!strcmp (l, "a"))
1448 emitcode ("cpl", "a");
1449 emitcode ("addc", "a,#0");
1455 emitcode ("clr", "a");
1456 emitcode ("subb", "a,%s", l);
1458 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
1461 /* if any remaining bytes in the result */
1462 /* we just need to propagate the sign */
1463 if ((size = (AOP_SIZE (IC_RESULT (ic)) - AOP_SIZE (IC_LEFT (ic)))))
1465 emitcode ("rlc", "a");
1466 emitcode ("subb", "a,acc");
1468 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
1472 /* release the aops */
1473 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
1474 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1477 /*-----------------------------------------------------------------*/
1478 /* saveRegisters - will look for a call and save the registers */
1479 /*-----------------------------------------------------------------*/
1481 saveRegisters (iCode * lic)
1489 for (ic = lic; ic; ic = ic->next)
1490 if (ic->op == CALL || ic->op == PCALL)
1495 fprintf (stderr, "found parameter push with no function call\n");
1499 /* if the registers have been saved already then
1501 if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave))
1504 /* find the registers in use at this time
1505 and push them away to safety */
1506 rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
1510 if (options.useXstack)
1512 if (bitVectBitValue (rsave, R0_IDX))
1513 emitcode ("mov", "b,r0");
1514 emitcode ("mov", "r0,%s", spname);
1515 for (i = 0; i < mcs51_nRegs; i++)
1517 if (bitVectBitValue (rsave, i))
1520 emitcode ("mov", "a,b");
1522 emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name);
1523 emitcode ("movx", "@r0,a");
1524 emitcode ("inc", "r0");
1527 emitcode ("mov", "%s,r0", spname);
1528 if (bitVectBitValue (rsave, R0_IDX))
1529 emitcode ("mov", "r0,b");
1532 for (i = 0; i < mcs51_nRegs; i++)
1534 if (bitVectBitValue (rsave, i))
1535 emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
1538 detype = getSpec (operandType (IC_LEFT (ic)));
1540 (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
1541 IS_ISR (currFunc->etype) &&
1544 saverbank (SPEC_BANK (detype), ic, TRUE);
1547 /*-----------------------------------------------------------------*/
1548 /* unsaveRegisters - pop the pushed registers */
1549 /*-----------------------------------------------------------------*/
1551 unsaveRegisters (iCode * ic)
1555 /* find the registers in use at this time
1556 and push them away to safety */
1557 rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
1560 if (options.useXstack)
1562 emitcode ("mov", "r0,%s", spname);
1563 for (i = mcs51_nRegs; i >= 0; i--)
1565 if (bitVectBitValue (rsave, i))
1567 emitcode ("dec", "r0");
1568 emitcode ("movx", "a,@r0");
1570 emitcode ("mov", "b,a");
1572 emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name);
1576 emitcode ("mov", "%s,r0", spname);
1577 if (bitVectBitValue (rsave, R0_IDX))
1578 emitcode ("mov", "r0,b");
1581 for (i = mcs51_nRegs; i >= 0; i--)
1583 if (bitVectBitValue (rsave, i))
1584 emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
1590 /*-----------------------------------------------------------------*/
1592 /*-----------------------------------------------------------------*/
1594 pushSide (operand * oper, int size)
1599 char *l = aopGet (AOP (oper), offset++, FALSE, TRUE);
1600 if (AOP_TYPE (oper) != AOP_REG &&
1601 AOP_TYPE (oper) != AOP_DIR &&
1604 emitcode ("mov", "a,%s", l);
1605 emitcode ("push", "acc");
1608 emitcode ("push", "%s", l);
1612 /*-----------------------------------------------------------------*/
1613 /* assignResultValue - */
1614 /*-----------------------------------------------------------------*/
1616 assignResultValue (operand * oper)
1619 int size = AOP_SIZE (oper);
1622 aopPut (AOP (oper), fReturn[offset], offset);
1628 /*-----------------------------------------------------------------*/
1629 /* genXpush - pushes onto the external stack */
1630 /*-----------------------------------------------------------------*/
1632 genXpush (iCode * ic)
1634 asmop *aop = newAsmop (0);
1636 int size, offset = 0;
1638 aopOp (IC_LEFT (ic), ic, FALSE);
1639 r = getFreePtr (ic, &aop, FALSE);
1642 emitcode ("mov", "%s,_spx", r->name);
1644 size = AOP_SIZE (IC_LEFT (ic));
1648 char *l = aopGet (AOP (IC_LEFT (ic)),
1649 offset++, FALSE, FALSE);
1651 emitcode ("movx", "@%s,a", r->name);
1652 emitcode ("inc", "%s", r->name);
1657 emitcode ("mov", "_spx,%s", r->name);
1659 freeAsmop (NULL, aop, ic, TRUE);
1660 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1663 /*-----------------------------------------------------------------*/
1664 /* genIpush - genrate code for pushing this gets a little complex */
1665 /*-----------------------------------------------------------------*/
1667 genIpush (iCode * ic)
1669 int size, offset = 0;
1673 /* if this is not a parm push : ie. it is spill push
1674 and spill push is always done on the local stack */
1678 /* and the item is spilt then do nothing */
1679 if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
1682 aopOp (IC_LEFT (ic), ic, FALSE);
1683 size = AOP_SIZE (IC_LEFT (ic));
1684 /* push it on the stack */
1687 l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE);
1693 emitcode ("push", "%s", l);
1698 /* this is a paramter push: in this case we call
1699 the routine to find the call and save those
1700 registers that need to be saved */
1703 /* if use external stack then call the external
1704 stack pushing routine */
1705 if (options.useXstack)
1711 /* then do the push */
1712 aopOp (IC_LEFT (ic), ic, FALSE);
1715 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1716 size = AOP_SIZE (IC_LEFT (ic));
1720 l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE);
1721 if (AOP_TYPE (IC_LEFT (ic)) != AOP_REG &&
1722 AOP_TYPE (IC_LEFT (ic)) != AOP_DIR &&
1725 emitcode ("mov", "a,%s", l);
1726 emitcode ("push", "acc");
1729 emitcode ("push", "%s", l);
1732 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1735 /*-----------------------------------------------------------------*/
1736 /* genIpop - recover the registers: can happen only for spilling */
1737 /*-----------------------------------------------------------------*/
1739 genIpop (iCode * ic)
1744 /* if the temp was not pushed then */
1745 if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
1748 aopOp (IC_LEFT (ic), ic, FALSE);
1749 size = AOP_SIZE (IC_LEFT (ic));
1750 offset = (size - 1);
1752 emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
1755 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1758 /*-----------------------------------------------------------------*/
1759 /* unsaverbank - restores the resgister bank from stack */
1760 /*-----------------------------------------------------------------*/
1762 unsaverbank (int bank, iCode * ic, bool popPsw)
1770 if (options.useXstack)
1773 r = getFreePtr (ic, &aop, FALSE);
1776 emitcode ("mov", "%s,_spx", r->name);
1777 emitcode ("movx", "a,@%s", r->name);
1778 emitcode ("mov", "psw,a");
1779 emitcode ("dec", "%s", r->name);
1783 emitcode ("pop", "psw");
1786 for (i = (mcs51_nRegs - 1); i >= 0; i--)
1788 if (options.useXstack)
1790 emitcode ("movx", "a,@%s", r->name);
1791 emitcode ("mov", "(%s+%d),a",
1792 regs8051[i].base, 8 * bank + regs8051[i].offset);
1793 emitcode ("dec", "%s", r->name);
1797 emitcode ("pop", "(%s+%d)",
1798 regs8051[i].base, 8 * bank + regs8051[i].offset);
1801 if (options.useXstack)
1804 emitcode ("mov", "_spx,%s", r->name);
1805 freeAsmop (NULL, aop, ic, TRUE);
1810 /*-----------------------------------------------------------------*/
1811 /* saverbank - saves an entire register bank on the stack */
1812 /*-----------------------------------------------------------------*/
1814 saverbank (int bank, iCode * ic, bool pushPsw)
1820 if (options.useXstack)
1824 r = getFreePtr (ic, &aop, FALSE);
1825 emitcode ("mov", "%s,_spx", r->name);
1829 for (i = 0; i < mcs51_nRegs; i++)
1831 if (options.useXstack)
1833 emitcode ("inc", "%s", r->name);
1834 emitcode ("mov", "a,(%s+%d)",
1835 regs8051[i].base, 8 * bank + regs8051[i].offset);
1836 emitcode ("movx", "@%s,a", r->name);
1839 emitcode ("push", "(%s+%d)",
1840 regs8051[i].base, 8 * bank + regs8051[i].offset);
1845 if (options.useXstack)
1847 emitcode ("mov", "a,psw");
1848 emitcode ("movx", "@%s,a", r->name);
1849 emitcode ("inc", "%s", r->name);
1850 emitcode ("mov", "_spx,%s", r->name);
1851 freeAsmop (NULL, aop, ic, TRUE);
1855 emitcode ("push", "psw");
1857 emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
1863 /*-----------------------------------------------------------------*/
1864 /* genCall - generates a call statement */
1865 /*-----------------------------------------------------------------*/
1867 genCall (iCode * ic)
1871 /* if caller saves & we have not saved then */
1875 /* if we are calling a function that is not using
1876 the same register bank then we need to save the
1877 destination registers on the stack */
1878 detype = getSpec (operandType (IC_LEFT (ic)));
1880 (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
1881 IS_ISR (currFunc->etype) &&
1884 saverbank (SPEC_BANK (detype), ic, TRUE);
1886 /* if send set is not empty the assign */
1891 for (sic = setFirstItem (_G.sendSet); sic;
1892 sic = setNextItem (_G.sendSet))
1894 int size, offset = 0;
1895 aopOp (IC_LEFT (sic), sic, FALSE);
1896 size = AOP_SIZE (IC_LEFT (sic));
1899 char *l = aopGet (AOP (IC_LEFT (sic)), offset,
1901 if (strcmp (l, fReturn[offset]))
1902 emitcode ("mov", "%s,%s",
1907 freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
1912 emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
1913 OP_SYMBOL (IC_LEFT (ic))->rname :
1914 OP_SYMBOL (IC_LEFT (ic))->name));
1916 /* if we need assign a result value */
1917 if ((IS_ITEMP (IC_RESULT (ic)) &&
1918 (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
1919 OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
1920 IS_TRUE_SYMOP (IC_RESULT (ic)))
1924 aopOp (IC_RESULT (ic), ic, FALSE);
1927 assignResultValue (IC_RESULT (ic));
1929 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
1932 /* adjust the stack for parameters if
1937 if (ic->parmBytes > 3)
1939 emitcode ("mov", "a,%s", spname);
1940 emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
1941 emitcode ("mov", "%s,a", spname);
1944 for (i = 0; i < ic->parmBytes; i++)
1945 emitcode ("dec", "%s", spname);
1949 /* if register bank was saved then pop them */
1951 unsaverbank (SPEC_BANK (detype), ic, TRUE);
1953 /* if we hade saved some registers then unsave them */
1954 if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
1955 unsaveRegisters (ic);
1960 /*-----------------------------------------------------------------*/
1961 /* genPcall - generates a call by pointer statement */
1962 /*-----------------------------------------------------------------*/
1964 genPcall (iCode * ic)
1967 symbol *rlbl = newiTempLabel (NULL);
1970 /* if caller saves & we have not saved then */
1974 /* if we are calling a function that is not using
1975 the same register bank then we need to save the
1976 destination registers on the stack */
1977 detype = getSpec (operandType (IC_LEFT (ic)));
1979 IS_ISR (currFunc->etype) &&
1980 (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
1981 saverbank (SPEC_BANK (detype), ic, TRUE);
1984 /* push the return address on to the stack */
1985 emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
1986 emitcode ("push", "acc");
1987 emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
1988 emitcode ("push", "acc");
1990 /* now push the calling address */
1991 aopOp (IC_LEFT (ic), ic, FALSE);
1993 pushSide (IC_LEFT (ic), FPTRSIZE);
1995 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
1997 /* if send set is not empty the assign */
2002 for (sic = setFirstItem (_G.sendSet); sic;
2003 sic = setNextItem (_G.sendSet))
2005 int size, offset = 0;
2006 aopOp (IC_LEFT (sic), sic, FALSE);
2007 size = AOP_SIZE (IC_LEFT (sic));
2010 char *l = aopGet (AOP (IC_LEFT (sic)), offset,
2012 if (strcmp (l, fReturn[offset]))
2013 emitcode ("mov", "%s,%s",
2018 freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
2023 emitcode ("ret", "");
2024 emitcode ("", "%05d$:", (rlbl->key + 100));
2027 /* if we need assign a result value */
2028 if ((IS_ITEMP (IC_RESULT (ic)) &&
2029 (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
2030 OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
2031 IS_TRUE_SYMOP (IC_RESULT (ic)))
2035 aopOp (IC_RESULT (ic), ic, FALSE);
2038 assignResultValue (IC_RESULT (ic));
2040 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
2043 /* adjust the stack for parameters if
2048 if (ic->parmBytes > 3)
2050 emitcode ("mov", "a,%s", spname);
2051 emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
2052 emitcode ("mov", "%s,a", spname);
2055 for (i = 0; i < ic->parmBytes; i++)
2056 emitcode ("dec", "%s", spname);
2060 /* if register bank was saved then unsave them */
2062 (SPEC_BANK (currFunc->etype) !=
2063 SPEC_BANK (detype)))
2064 unsaverbank (SPEC_BANK (detype), ic, TRUE);
2066 /* if we hade saved some registers then
2069 unsaveRegisters (ic);
2073 /*-----------------------------------------------------------------*/
2074 /* resultRemat - result is rematerializable */
2075 /*-----------------------------------------------------------------*/
2077 resultRemat (iCode * ic)
2079 if (SKIP_IC (ic) || ic->op == IFX)
2082 if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
2084 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2085 if (sym->remat && !POINTER_SET (ic))
2092 #if defined(__BORLANDC__) || defined(_MSC_VER)
2093 #define STRCASECMP stricmp
2095 #define STRCASECMP strcasecmp
2098 /*-----------------------------------------------------------------*/
2099 /* inExcludeList - return 1 if the string is in exclude Reg list */
2100 /*-----------------------------------------------------------------*/
2102 inExcludeList (char *s)
2106 if (options.excludeRegs[i] &&
2107 STRCASECMP (options.excludeRegs[i], "none") == 0)
2110 for (i = 0; options.excludeRegs[i]; i++)
2112 if (options.excludeRegs[i] &&
2113 STRCASECMP (s, options.excludeRegs[i]) == 0)
2119 /*-----------------------------------------------------------------*/
2120 /* genFunction - generated code for function entry */
2121 /*-----------------------------------------------------------------*/
2123 genFunction (iCode * ic)
2129 /* create the function header */
2130 emitcode (";", "-----------------------------------------");
2131 emitcode (";", " function %s", (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
2132 emitcode (";", "-----------------------------------------");
2134 emitcode ("", "%s:", sym->rname);
2135 fetype = getSpec (operandType (IC_LEFT (ic)));
2137 /* if critical function then turn interrupts off */
2138 if (SPEC_CRTCL (fetype))
2139 emitcode ("clr", "ea");
2141 /* here we need to generate the equates for the
2142 register bank if required */
2143 if (SPEC_BANK (fetype) != rbank)
2147 rbank = SPEC_BANK (fetype);
2148 for (i = 0; i < mcs51_nRegs; i++)
2150 if (strcmp (regs8051[i].base, "0") == 0)
2151 emitcode ("", "%s = 0x%02x",
2153 8 * rbank + regs8051[i].offset);
2155 emitcode ("", "%s = %s + 0x%02x",
2158 8 * rbank + regs8051[i].offset);
2162 /* if this is an interrupt service routine then
2163 save acc, b, dpl, dph */
2164 if (IS_ISR (sym->etype))
2167 if (!inExcludeList ("acc"))
2168 emitcode ("push", "acc");
2169 if (!inExcludeList ("b"))
2170 emitcode ("push", "b");
2171 if (!inExcludeList ("dpl"))
2172 emitcode ("push", "dpl");
2173 if (!inExcludeList ("dph"))
2174 emitcode ("push", "dph");
2175 /* if this isr has no bank i.e. is going to
2176 run with bank 0 , then we need to save more
2178 if (!SPEC_BANK (sym->etype))
2181 /* if this function does not call any other
2182 function then we can be economical and
2183 save only those registers that are used */
2188 /* if any registers used */
2191 /* save the registers used */
2192 for (i = 0; i < sym->regsUsed->size; i++)
2194 if (bitVectBitValue (sym->regsUsed, i) ||
2195 (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2196 emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
2203 /* this function has a function call cannot
2204 determines register usage so we will have the
2206 saverbank (0, ic, FALSE);
2212 /* if callee-save to be used for this function
2213 then save the registers being used in this function */
2214 if (sym->calleeSave)
2218 /* if any registers used */
2221 /* save the registers used */
2222 for (i = 0; i < sym->regsUsed->size; i++)
2224 if (bitVectBitValue (sym->regsUsed, i) ||
2225 (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2227 emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
2235 /* set the register bank to the desired value */
2236 if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
2238 emitcode ("push", "psw");
2239 emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
2242 if (IS_RENT (sym->etype) || options.stackAuto)
2245 if (options.useXstack)
2247 emitcode ("mov", "r0,%s", spname);
2248 emitcode ("mov", "a,_bp");
2249 emitcode ("movx", "@r0,a");
2250 emitcode ("inc", "%s", spname);
2254 /* set up the stack */
2255 emitcode ("push", "_bp"); /* save the callers stack */
2257 emitcode ("mov", "_bp,%s", spname);
2260 /* adjust the stack for the function */
2266 werror (W_STACK_OVERFLOW, sym->name);
2268 if (i > 3 && sym->recvSize < 4)
2271 emitcode ("mov", "a,sp");
2272 emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
2273 emitcode ("mov", "sp,a");
2278 emitcode ("inc", "sp");
2284 emitcode ("mov", "a,_spx");
2285 emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff));
2286 emitcode ("mov", "_spx,a");
2291 /*-----------------------------------------------------------------*/
2292 /* genEndFunction - generates epilogue for functions */
2293 /*-----------------------------------------------------------------*/
2295 genEndFunction (iCode * ic)
2297 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
2299 if (IS_RENT (sym->etype) || options.stackAuto)
2301 emitcode ("mov", "%s,_bp", spname);
2304 /* if use external stack but some variables were
2305 added to the local stack then decrement the
2307 if (options.useXstack && sym->stack)
2309 emitcode ("mov", "a,sp");
2310 emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
2311 emitcode ("mov", "sp,a");
2315 if ((IS_RENT (sym->etype) || options.stackAuto))
2317 if (options.useXstack)
2319 emitcode ("mov", "r0,%s", spname);
2320 emitcode ("movx", "a,@r0");
2321 emitcode ("mov", "_bp,a");
2322 emitcode ("dec", "%s", spname);
2326 emitcode ("pop", "_bp");
2330 /* restore the register bank */
2331 if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
2332 emitcode ("pop", "psw");
2334 if (IS_ISR (sym->etype))
2337 /* now we need to restore the registers */
2338 /* if this isr has no bank i.e. is going to
2339 run with bank 0 , then we need to save more
2341 if (!SPEC_BANK (sym->etype))
2344 /* if this function does not call any other
2345 function then we can be economical and
2346 save only those registers that are used */
2351 /* if any registers used */
2354 /* save the registers used */
2355 for (i = sym->regsUsed->size; i >= 0; i--)
2357 if (bitVectBitValue (sym->regsUsed, i) ||
2358 (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2359 emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
2366 /* this function has a function call cannot
2367 determines register usage so we will have the
2369 unsaverbank (0, ic, FALSE);
2373 if (!inExcludeList ("dph"))
2374 emitcode ("pop", "dph");
2375 if (!inExcludeList ("dpl"))
2376 emitcode ("pop", "dpl");
2377 if (!inExcludeList ("b"))
2378 emitcode ("pop", "b");
2379 if (!inExcludeList ("acc"))
2380 emitcode ("pop", "acc");
2382 if (SPEC_CRTCL (sym->etype))
2383 emitcode ("setb", "ea");
2385 /* if debug then send end of function */
2386 /* if (options.debug && currFunc) { */
2390 emitcode ("", "C$%s$%d$%d$%d ==.",
2391 FileBaseName (ic->filename), currFunc->lastLine,
2392 ic->level, ic->block);
2393 if (IS_STATIC (currFunc->etype))
2394 emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
2396 emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
2400 emitcode ("reti", "");
2404 if (SPEC_CRTCL (sym->etype))
2405 emitcode ("setb", "ea");
2407 if (sym->calleeSave)
2411 /* if any registers used */
2414 /* save the registers used */
2415 for (i = sym->regsUsed->size; i >= 0; i--)
2417 if (bitVectBitValue (sym->regsUsed, i) ||
2418 (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
2419 emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
2425 /* if debug then send end of function */
2429 emitcode ("", "C$%s$%d$%d$%d ==.",
2430 FileBaseName (ic->filename), currFunc->lastLine,
2431 ic->level, ic->block);
2432 if (IS_STATIC (currFunc->etype))
2433 emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
2435 emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
2439 emitcode ("ret", "");
2444 /*-----------------------------------------------------------------*/
2445 /* genRet - generate code for return statement */
2446 /*-----------------------------------------------------------------*/
2450 int size, offset = 0, pushed = 0;
2452 /* if we have no return value then
2453 just generate the "ret" */
2457 /* we have something to return then
2458 move the return value into place */
2459 aopOp (IC_LEFT (ic), ic, FALSE);
2460 size = AOP_SIZE (IC_LEFT (ic));
2465 if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
2468 l = aopGet (AOP (IC_LEFT (ic)), offset++,
2470 emitcode ("push", "%s", l);
2475 l = aopGet (AOP (IC_LEFT (ic)), offset,
2477 if (strcmp (fReturn[offset], l))
2478 emitcode ("mov", "%s,%s", fReturn[offset++], l);
2487 if (strcmp (fReturn[pushed], "a"))
2488 emitcode ("pop", fReturn[pushed]);
2490 emitcode ("pop", "acc");
2493 freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
2496 /* generate a jump to the return label
2497 if the next is not the return statement */
2498 if (!(ic->next && ic->next->op == LABEL &&
2499 IC_LABEL (ic->next) == returnLabel))
2501 emitcode ("ljmp", "%05d$", (returnLabel->key + 100));
2505 /*-----------------------------------------------------------------*/
2506 /* genLabel - generates a label */
2507 /*-----------------------------------------------------------------*/
2509 genLabel (iCode * ic)
2511 /* special case never generate */
2512 if (IC_LABEL (ic) == entryLabel)
2515 emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
2518 /*-----------------------------------------------------------------*/
2519 /* genGoto - generates a ljmp */
2520 /*-----------------------------------------------------------------*/
2522 genGoto (iCode * ic)
2524 emitcode ("ljmp", "%05d$", (IC_LABEL (ic)->key + 100));
2527 /*-----------------------------------------------------------------*/
2528 /* findLabelBackwards: walks back through the iCode chain looking */
2529 /* for the given label. Returns number of iCode instructions */
2530 /* between that label and given ic. */
2531 /* Returns zero if label not found. */
2532 /*-----------------------------------------------------------------*/
2534 findLabelBackwards (iCode * ic, int key)
2543 if (ic->op == LABEL && IC_LABEL (ic)->key == key)
2545 /* printf("findLabelBackwards = %d\n", count); */
2553 /*-----------------------------------------------------------------*/
2554 /* genPlusIncr :- does addition with increment if possible */
2555 /*-----------------------------------------------------------------*/
2557 genPlusIncr (iCode * ic)
2559 unsigned int icount;
2560 unsigned int size = getDataSize (IC_RESULT (ic));
2562 /* will try to generate an increment */
2563 /* if the right side is not a literal
2565 if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
2568 /* if the literal value of the right hand side
2569 is greater than 4 then it is not worth it */
2570 if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
2573 /* if increment 16 bits in register */
2574 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
2582 /* If the next instruction is a goto and the goto target
2583 * is < 10 instructions previous to this, we can generate
2584 * jumps straight to that target.
2586 if (ic->next && ic->next->op == GOTO
2587 && (labelRange = findLabelBackwards (ic, IC_LABEL (ic->next)->key)) != 0
2588 && labelRange <= 10)
2590 emitcode (";", "tail increment optimized");
2591 tlbl = IC_LABEL (ic->next);
2596 tlbl = newiTempLabel (NULL);
2599 emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE));
2600 if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
2601 IS_AOP_PREG (IC_RESULT (ic)))
2602 emitcode ("cjne", "%s,#0x00,%05d$"
2603 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE)
2607 emitcode ("clr", "a");
2608 emitcode ("cjne", "a,%s,%05d$"
2609 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE)
2613 emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE));
2616 if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
2617 IS_AOP_PREG (IC_RESULT (ic)))
2618 emitcode ("cjne", "%s,#0x00,%05d$"
2619 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE)
2622 emitcode ("cjne", "a,%s,%05d$"
2623 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE)
2626 emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE));
2630 if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
2631 IS_AOP_PREG (IC_RESULT (ic)))
2632 emitcode ("cjne", "%s,#0x00,%05d$"
2633 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE)
2637 emitcode ("cjne", "a,%s,%05d$"
2638 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE)
2641 emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE));
2646 emitcode ("", "%05d$:", tlbl->key + 100);
2651 /* if the sizes are greater than 1 then we cannot */
2652 if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
2653 AOP_SIZE (IC_LEFT (ic)) > 1)
2656 /* we can if the aops of the left & result match or
2657 if they are in registers and the registers are the
2659 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
2664 MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
2665 emitcode ("add", "a,#0x%02x", ((char) icount) & 0xff);
2666 aopPut (AOP (IC_RESULT (ic)), "a", 0);
2672 emitcode ("inc", "%s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE));
2681 /*-----------------------------------------------------------------*/
2682 /* outBitAcc - output a bit in acc */
2683 /*-----------------------------------------------------------------*/
2685 outBitAcc (operand * result)
2687 symbol *tlbl = newiTempLabel (NULL);
2688 /* if the result is a bit */
2689 if (AOP_TYPE (result) == AOP_CRY)
2691 aopPut (AOP (result), "a", 0);
2695 emitcode ("jz", "%05d$", tlbl->key + 100);
2696 emitcode ("mov", "a,%s", one);
2697 emitcode ("", "%05d$:", tlbl->key + 100);
2702 /*-----------------------------------------------------------------*/
2703 /* genPlusBits - generates code for addition of two bits */
2704 /*-----------------------------------------------------------------*/
2706 genPlusBits (iCode * ic)
2708 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
2710 symbol *lbl = newiTempLabel (NULL);
2711 emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
2712 emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
2713 emitcode ("cpl", "c");
2714 emitcode ("", "%05d$:", (lbl->key + 100));
2715 outBitC (IC_RESULT (ic));
2719 emitcode ("clr", "a");
2720 emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
2721 emitcode ("rlc", "a");
2722 emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
2723 emitcode ("addc", "a,#0x00");
2724 outAcc (IC_RESULT (ic));
2729 /* This is the original version of this code.
2731 * This is being kept around for reference,
2732 * because I am not entirely sure I got it right...
2735 adjustArithmeticResult (iCode * ic)
2737 if (AOP_SIZE (IC_RESULT (ic)) == 3 &&
2738 AOP_SIZE (IC_LEFT (ic)) == 3 &&
2739 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
2740 aopPut (AOP (IC_RESULT (ic)),
2741 aopGet (AOP (IC_LEFT (ic)), 2, FALSE, FALSE),
2744 if (AOP_SIZE (IC_RESULT (ic)) == 3 &&
2745 AOP_SIZE (IC_RIGHT (ic)) == 3 &&
2746 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
2747 aopPut (AOP (IC_RESULT (ic)),
2748 aopGet (AOP (IC_RIGHT (ic)), 2, FALSE, FALSE),
2751 if (AOP_SIZE (IC_RESULT (ic)) == 3 &&
2752 AOP_SIZE (IC_LEFT (ic)) < 3 &&
2753 AOP_SIZE (IC_RIGHT (ic)) < 3 &&
2754 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
2755 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
2758 sprintf (buffer, "#%d", pointerCode (getSpec (operandType (IC_LEFT (ic)))));
2759 aopPut (AOP (IC_RESULT (ic)), buffer, 2);
2763 /* This is the pure and virtuous version of this code.
2764 * I'm pretty certain it's right, but not enough to toss the old
2768 adjustArithmeticResult (iCode * ic)
2770 if (opIsGptr (IC_RESULT (ic)) &&
2771 opIsGptr (IC_LEFT (ic)) &&
2772 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
2774 aopPut (AOP (IC_RESULT (ic)),
2775 aopGet (AOP (IC_LEFT (ic)), GPTRSIZE - 1, FALSE, FALSE),
2779 if (opIsGptr (IC_RESULT (ic)) &&
2780 opIsGptr (IC_RIGHT (ic)) &&
2781 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
2783 aopPut (AOP (IC_RESULT (ic)),
2784 aopGet (AOP (IC_RIGHT (ic)), GPTRSIZE - 1, FALSE, FALSE),
2788 if (opIsGptr (IC_RESULT (ic)) &&
2789 AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
2790 AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
2791 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
2792 !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
2795 sprintf (buffer, "#%d", pointerCode (getSpec (operandType (IC_LEFT (ic)))));
2796 aopPut (AOP (IC_RESULT (ic)), buffer, GPTRSIZE - 1);
2801 /*-----------------------------------------------------------------*/
2802 /* genPlus - generates code for addition */
2803 /*-----------------------------------------------------------------*/
2805 genPlus (iCode * ic)
2807 int size, offset = 0;
2809 /* special cases :- */
2811 aopOp (IC_LEFT (ic), ic, FALSE);
2812 aopOp (IC_RIGHT (ic), ic, FALSE);
2813 aopOp (IC_RESULT (ic), ic, TRUE);
2815 /* if literal, literal on the right or
2816 if left requires ACC or right is already
2818 if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
2819 (AOP_NEEDSACC (IC_LEFT (ic))) ||
2820 AOP_TYPE (IC_RIGHT (ic)) == AOP_ACC)
2822 operand *t = IC_RIGHT (ic);
2823 IC_RIGHT (ic) = IC_LEFT (ic);
2827 /* if both left & right are in bit
2829 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
2830 AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
2836 /* if left in bit space & right literal */
2837 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
2838 AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT)
2840 emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
2841 /* if result in bit space */
2842 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
2844 if ((unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
2845 emitcode ("cpl", "c");
2846 outBitC (IC_RESULT (ic));
2850 size = getDataSize (IC_RESULT (ic));
2853 MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
2854 emitcode ("addc", "a,#00");
2855 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
2861 /* if I can do an increment instead
2862 of add then GOOD for ME */
2863 if (genPlusIncr (ic) == TRUE)
2866 size = getDataSize (IC_RESULT (ic));
2870 if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
2872 MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
2874 emitcode ("add", "a,%s",
2875 aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
2877 emitcode ("addc", "a,%s",
2878 aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
2882 MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
2884 emitcode ("add", "a,%s",
2885 aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
2887 emitcode ("addc", "a,%s",
2888 aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
2890 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
2893 adjustArithmeticResult (ic);
2896 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
2897 freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
2898 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
2901 /*-----------------------------------------------------------------*/
2902 /* genMinusDec :- does subtraction with deccrement if possible */
2903 /*-----------------------------------------------------------------*/
2905 genMinusDec (iCode * ic)
2907 unsigned int icount;
2908 unsigned int size = getDataSize (IC_RESULT (ic));
2910 /* will try to generate an increment */
2911 /* if the right side is not a literal
2913 if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
2916 /* if the literal value of the right hand side
2917 is greater than 4 then it is not worth it */
2918 if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
2921 /* if decrement 16 bits in register */
2922 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
2930 /* If the next instruction is a goto and the goto target
2931 * is <= 10 instructions previous to this, we can generate
2932 * jumps straight to that target.
2934 if (ic->next && ic->next->op == GOTO
2935 && (labelRange = findLabelBackwards (ic, IC_LABEL (ic->next)->key)) != 0
2936 && labelRange <= 10)
2938 emitcode (";", "tail decrement optimized");
2939 tlbl = IC_LABEL (ic->next);
2944 tlbl = newiTempLabel (NULL);
2948 emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE));
2949 if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
2950 IS_AOP_PREG (IC_RESULT (ic)))
2951 emitcode ("cjne", "%s,#0xff,%05d$"
2952 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE)
2956 emitcode ("mov", "a,#0xff");
2957 emitcode ("cjne", "a,%s,%05d$"
2958 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE)
2961 emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE));
2964 if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
2965 IS_AOP_PREG (IC_RESULT (ic)))
2966 emitcode ("cjne", "%s,#0xff,%05d$"
2967 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE)
2971 emitcode ("cjne", "a,%s,%05d$"
2972 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE)
2975 emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE));
2979 if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
2980 IS_AOP_PREG (IC_RESULT (ic)))
2981 emitcode ("cjne", "%s,#0xff,%05d$"
2982 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE)
2986 emitcode ("cjne", "a,%s,%05d$"
2987 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE)
2990 emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE));
2994 emitcode ("", "%05d$:", tlbl->key + 100);
2999 /* if the sizes are greater than 1 then we cannot */
3000 if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
3001 AOP_SIZE (IC_LEFT (ic)) > 1)
3004 /* we can if the aops of the left & result match or
3005 if they are in registers and the registers are the
3007 if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
3011 emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
3019 /*-----------------------------------------------------------------*/
3020 /* addSign - complete with sign */
3021 /*-----------------------------------------------------------------*/
3023 addSign (operand * result, int offset, int sign)
3025 int size = (getDataSize (result) - offset);
3030 emitcode ("rlc", "a");
3031 emitcode ("subb", "a,acc");
3033 aopPut (AOP (result), "a", offset++);
3037 aopPut (AOP (result), zero, offset++);
3041 /*-----------------------------------------------------------------*/
3042 /* genMinusBits - generates code for subtraction of two bits */
3043 /*-----------------------------------------------------------------*/
3045 genMinusBits (iCode * ic)
3047 symbol *lbl = newiTempLabel (NULL);
3048 if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
3050 emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
3051 emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
3052 emitcode ("cpl", "c");
3053 emitcode ("", "%05d$:", (lbl->key + 100));
3054 outBitC (IC_RESULT (ic));
3058 emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
3059 emitcode ("subb", "a,acc");
3060 emitcode ("jnb", "%s,%05d$", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100));
3061 emitcode ("inc", "a");
3062 emitcode ("", "%05d$:", (lbl->key + 100));
3063 aopPut (AOP (IC_RESULT (ic)), "a", 0);
3064 addSign (IC_RESULT (ic), MSB16, SPEC_USIGN (getSpec (operandType (IC_RESULT (ic)))));
3068 /*-----------------------------------------------------------------*/
3069 /* genMinus - generates code for subtraction */
3070 /*-----------------------------------------------------------------*/
3072 genMinus (iCode * ic)
3074 int size, offset = 0;
3075 unsigned long lit = 0L;
3077 aopOp (IC_LEFT (ic), ic, FALSE);
3078 aopOp (IC_RIGHT (ic), ic, FALSE);
3079 aopOp (IC_RESULT (ic), ic, TRUE);
3081 /* special cases :- */
3082 /* if both left & right are in bit space */
3083 if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
3084 AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
3090 /* if I can do an decrement instead
3091 of subtract then GOOD for ME */
3092 if (genMinusDec (ic) == TRUE)
3095 size = getDataSize (IC_RESULT (ic));
3097 if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
3103 lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3107 /* if literal, add a,#-lit, else normal subb */
3110 MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE));
3111 if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
3112 emitcode ("subb", "a,%s",
3113 aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE));
3116 /* first add without previous c */
3118 emitcode ("add", "a,#0x%02x",
3119 (unsigned int) (lit & 0x0FFL));
3121 emitcode ("addc", "a,#0x%02x",
3122 (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
3124 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
3127 adjustArithmeticResult (ic);
3130 freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3131 freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3132 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
3136 /*-----------------------------------------------------------------*/
3137 /* genMultbits :- multiplication of bits */
3138 /*-----------------------------------------------------------------*/
3140 genMultbits (operand * left,
3144 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3145 emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
3150 /*-----------------------------------------------------------------*/
3151 /* genMultOneByte : 8*8=8/16 bit multiplication */
3152 /*-----------------------------------------------------------------*/
3154 genMultOneByte (operand * left,
3158 sym_link *opetype = operandType (result);
3160 int size=AOP_SIZE(result);
3162 //emitcode (";",__FUNCTION__);
3163 if (size<1 || size>2) {
3164 // this should never happen
3165 fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
3166 AOP_SIZE(result), __FUNCTION__, lineno);
3170 /* (if two literals: the value is computed before) */
3171 /* if one literal, literal on the right */
3172 if (AOP_TYPE (left) == AOP_LIT)
3177 //emitcode (";", "swapped left and right");
3180 if (SPEC_USIGN(opetype)
3181 // ignore the sign of left and right, what else can we do?
3182 || (SPEC_USIGN(operandType(left)) &&
3183 SPEC_USIGN(operandType(right)))) {
3184 // just an unsigned 8*8=8/16 multiply
3185 //emitcode (";","unsigned");
3186 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3187 MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
3188 emitcode ("mul", "ab");
3189 aopPut (AOP (result), "a", 0);
3191 aopPut (AOP (result), "b", 1);
3196 // we have to do a signed multiply
3198 //emitcode (";", "signed");
3199 emitcode ("clr", "F0"); // reset sign flag
3200 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3201 MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
3203 lbl=newiTempLabel(NULL);
3204 emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
3205 // left side is negative, 8-bit two's complement, this fails for -128
3206 emitcode ("setb", "F0"); // set sign flag
3207 emitcode ("cpl", "a");
3208 emitcode ("inc", "a");
3210 emitcode ("", "%05d$:", lbl->key+100);
3211 emitcode ("xch", "a,b");
3214 if (AOP_TYPE(right)==AOP_LIT) {
3215 /* AND literal negative */
3216 if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) {
3217 // two's complement for literal<0
3218 emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
3219 emitcode ("cpl", "a");
3220 emitcode ("inc", "a");
3223 lbl=newiTempLabel(NULL);
3224 emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
3225 // right side is negative, 8-bit two's complement
3226 emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
3227 emitcode ("cpl", "a");
3228 emitcode ("inc", "a");
3229 emitcode ("", "%05d$:", lbl->key+100);
3231 emitcode ("mul", "ab");
3233 lbl=newiTempLabel(NULL);
3234 emitcode ("jnb", "F0,%05d$", lbl->key+100);
3235 // only ONE op was negative, we have to do a 8/16-bit two's complement
3236 emitcode ("cpl", "a"); // lsb
3238 emitcode ("inc", "a");
3240 emitcode ("add", "a,#1");
3241 emitcode ("xch", "a,b");
3242 emitcode ("cpl", "a"); // msb
3243 emitcode ("addc", "a,#0");
3244 emitcode ("xch", "a,b");
3247 emitcode ("", "%05d$:", lbl->key+100);
3248 aopPut (AOP (result), "a", 0);
3250 aopPut (AOP (result), "b", 1);
3254 /*-----------------------------------------------------------------*/
3255 /* genMult - generates code for multiplication */
3256 /*-----------------------------------------------------------------*/
3258 genMult (iCode * ic)
3260 operand *left = IC_LEFT (ic);
3261 operand *right = IC_RIGHT (ic);
3262 operand *result = IC_RESULT (ic);
3264 /* assign the amsops */
3265 aopOp (left, ic, FALSE);
3266 aopOp (right, ic, FALSE);
3267 aopOp (result, ic, TRUE);
3269 /* special cases first */
3271 if (AOP_TYPE (left) == AOP_CRY &&
3272 AOP_TYPE (right) == AOP_CRY)
3274 genMultbits (left, right, result);
3278 /* if both are of size == 1 */
3279 if (AOP_SIZE (left) == 1 &&
3280 AOP_SIZE (right) == 1)
3282 genMultOneByte (left, right, result);
3286 /* should have been converted to function call */
3290 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3291 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3292 freeAsmop (result, NULL, ic, TRUE);
3295 /*-----------------------------------------------------------------*/
3296 /* genDivbits :- division of bits */
3297 /*-----------------------------------------------------------------*/
3299 genDivbits (operand * left,
3306 /* the result must be bit */
3307 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3308 l = aopGet (AOP (left), 0, FALSE, FALSE);
3312 emitcode ("div", "ab");
3313 emitcode ("rrc", "a");
3314 aopPut (AOP (result), "c", 0);
3317 /*-----------------------------------------------------------------*/
3318 /* genDivOneByte : 8 bit division */
3319 /*-----------------------------------------------------------------*/
3321 genDivOneByte (operand * left,
3325 sym_link *opetype = operandType (result);
3330 size = AOP_SIZE (result) - 1;
3332 /* signed or unsigned */
3333 if (SPEC_USIGN (opetype))
3335 /* unsigned is easy */
3336 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3337 l = aopGet (AOP (left), 0, FALSE, FALSE);
3339 emitcode ("div", "ab");
3340 aopPut (AOP (result), "a", 0);
3342 aopPut (AOP (result), zero, offset++);
3346 /* signed is a little bit more difficult */
3348 /* save the signs of the operands */
3349 l = aopGet (AOP (left), 0, FALSE, FALSE);
3351 emitcode ("xrl", "a,%s", aopGet (AOP (right), 0, FALSE, TRUE));
3352 emitcode ("push", "acc"); /* save it on the stack */
3354 /* now sign adjust for both left & right */
3355 l = aopGet (AOP (right), 0, FALSE, FALSE);
3357 lbl = newiTempLabel (NULL);
3358 emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
3359 emitcode ("cpl", "a");
3360 emitcode ("inc", "a");
3361 emitcode ("", "%05d$:", (lbl->key + 100));
3362 emitcode ("mov", "b,a");
3364 /* sign adjust left side */
3365 l = aopGet (AOP (left), 0, FALSE, FALSE);
3368 lbl = newiTempLabel (NULL);
3369 emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
3370 emitcode ("cpl", "a");
3371 emitcode ("inc", "a");
3372 emitcode ("", "%05d$:", (lbl->key + 100));
3374 /* now the division */
3375 emitcode ("div", "ab");
3376 /* we are interested in the lower order
3378 emitcode ("mov", "b,a");
3379 lbl = newiTempLabel (NULL);
3380 emitcode ("pop", "acc");
3381 /* if there was an over flow we don't
3382 adjust the sign of the result */
3383 emitcode ("jb", "ov,%05d$", (lbl->key + 100));
3384 emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
3386 emitcode ("clr", "a");
3387 emitcode ("subb", "a,b");
3388 emitcode ("mov", "b,a");
3389 emitcode ("", "%05d$:", (lbl->key + 100));
3391 /* now we are done */
3392 aopPut (AOP (result), "b", 0);
3395 emitcode ("mov", "c,b.7");
3396 emitcode ("subb", "a,acc");
3399 aopPut (AOP (result), "a", offset++);
3403 /*-----------------------------------------------------------------*/
3404 /* genDiv - generates code for division */
3405 /*-----------------------------------------------------------------*/
3409 operand *left = IC_LEFT (ic);
3410 operand *right = IC_RIGHT (ic);
3411 operand *result = IC_RESULT (ic);
3413 /* assign the amsops */
3414 aopOp (left, ic, FALSE);
3415 aopOp (right, ic, FALSE);
3416 aopOp (result, ic, TRUE);
3418 /* special cases first */
3420 if (AOP_TYPE (left) == AOP_CRY &&
3421 AOP_TYPE (right) == AOP_CRY)
3423 genDivbits (left, right, result);
3427 /* if both are of size == 1 */
3428 if (AOP_SIZE (left) == 1 &&
3429 AOP_SIZE (right) == 1)
3431 genDivOneByte (left, right, result);
3435 /* should have been converted to function call */
3438 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3439 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3440 freeAsmop (result, NULL, ic, TRUE);
3443 /*-----------------------------------------------------------------*/
3444 /* genModbits :- modulus of bits */
3445 /*-----------------------------------------------------------------*/
3447 genModbits (operand * left,
3454 /* the result must be bit */
3455 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3456 l = aopGet (AOP (left), 0, FALSE, FALSE);
3460 emitcode ("div", "ab");
3461 emitcode ("mov", "a,b");
3462 emitcode ("rrc", "a");
3463 aopPut (AOP (result), "c", 0);
3466 /*-----------------------------------------------------------------*/
3467 /* genModOneByte : 8 bit modulus */
3468 /*-----------------------------------------------------------------*/
3470 genModOneByte (operand * left,
3474 sym_link *opetype = operandType (result);
3478 /* signed or unsigned */
3479 if (SPEC_USIGN (opetype))
3481 /* unsigned is easy */
3482 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3483 l = aopGet (AOP (left), 0, FALSE, FALSE);
3485 emitcode ("div", "ab");
3486 aopPut (AOP (result), "b", 0);
3490 /* signed is a little bit more difficult */
3492 /* save the signs of the operands */
3493 l = aopGet (AOP (left), 0, FALSE, FALSE);
3496 emitcode ("xrl", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE));
3497 emitcode ("push", "acc"); /* save it on the stack */
3499 /* now sign adjust for both left & right */
3500 l = aopGet (AOP (right), 0, FALSE, FALSE);
3503 lbl = newiTempLabel (NULL);
3504 emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
3505 emitcode ("cpl", "a");
3506 emitcode ("inc", "a");
3507 emitcode ("", "%05d$:", (lbl->key + 100));
3508 emitcode ("mov", "b,a");
3510 /* sign adjust left side */
3511 l = aopGet (AOP (left), 0, FALSE, FALSE);
3514 lbl = newiTempLabel (NULL);
3515 emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
3516 emitcode ("cpl", "a");
3517 emitcode ("inc", "a");
3518 emitcode ("", "%05d$:", (lbl->key + 100));
3520 /* now the multiplication */
3521 emitcode ("div", "ab");
3522 /* we are interested in the lower order
3524 lbl = newiTempLabel (NULL);
3525 emitcode ("pop", "acc");
3526 /* if there was an over flow we don't
3527 adjust the sign of the result */
3528 emitcode ("jb", "ov,%05d$", (lbl->key + 100));
3529 emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
3531 emitcode ("clr", "a");
3532 emitcode ("subb", "a,b");
3533 emitcode ("mov", "b,a");
3534 emitcode ("", "%05d$:", (lbl->key + 100));
3536 /* now we are done */
3537 aopPut (AOP (result), "b", 0);
3541 /*-----------------------------------------------------------------*/
3542 /* genMod - generates code for division */
3543 /*-----------------------------------------------------------------*/
3547 operand *left = IC_LEFT (ic);
3548 operand *right = IC_RIGHT (ic);
3549 operand *result = IC_RESULT (ic);
3551 /* assign the amsops */
3552 aopOp (left, ic, FALSE);
3553 aopOp (right, ic, FALSE);
3554 aopOp (result, ic, TRUE);
3556 /* special cases first */
3558 if (AOP_TYPE (left) == AOP_CRY &&
3559 AOP_TYPE (right) == AOP_CRY)
3561 genModbits (left, right, result);
3565 /* if both are of size == 1 */
3566 if (AOP_SIZE (left) == 1 &&
3567 AOP_SIZE (right) == 1)
3569 genModOneByte (left, right, result);
3573 /* should have been converted to function call */
3577 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3578 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3579 freeAsmop (result, NULL, ic, TRUE);
3582 /*-----------------------------------------------------------------*/
3583 /* genIfxJump :- will create a jump depending on the ifx */
3584 /*-----------------------------------------------------------------*/
3586 genIfxJump (iCode * ic, char *jval)
3589 symbol *tlbl = newiTempLabel (NULL);
3592 /* if true label then we jump if condition
3596 jlbl = IC_TRUE (ic);
3597 inst = ((strcmp (jval, "a") == 0 ? "jz" :
3598 (strcmp (jval, "c") == 0 ? "jnc" : "jnb")));
3602 /* false label is present */
3603 jlbl = IC_FALSE (ic);
3604 inst = ((strcmp (jval, "a") == 0 ? "jnz" :
3605 (strcmp (jval, "c") == 0 ? "jc" : "jb")));
3607 if (strcmp (inst, "jb") == 0 || strcmp (inst, "jnb") == 0)
3608 emitcode (inst, "%s,%05d$", jval, (tlbl->key + 100));
3610 emitcode (inst, "%05d$", tlbl->key + 100);
3611 emitcode ("ljmp", "%05d$", jlbl->key + 100);
3612 emitcode ("", "%05d$:", tlbl->key + 100);
3614 /* mark the icode as generated */
3618 /*-----------------------------------------------------------------*/
3619 /* genCmp :- greater or less than comparison */
3620 /*-----------------------------------------------------------------*/
3622 genCmp (operand * left, operand * right,
3623 operand * result, iCode * ifx, int sign, iCode *ic)
3625 int size, offset = 0;
3626 unsigned long lit = 0L;
3628 /* if left & right are bit variables */
3629 if (AOP_TYPE (left) == AOP_CRY &&
3630 AOP_TYPE (right) == AOP_CRY)
3632 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
3633 emitcode ("anl", "c,/%s", AOP (left)->aopu.aop_dir);
3637 /* subtract right from left if at the
3638 end the carry flag is set then we know that
3639 left is greater than right */
3640 size = max (AOP_SIZE (left), AOP_SIZE (right));
3642 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3643 if ((size == 1) && !sign &&
3644 (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
3646 symbol *lbl = newiTempLabel (NULL);
3647 emitcode ("cjne", "%s,%s,%05d$",
3648 aopGet (AOP (left), offset, FALSE, FALSE),
3649 aopGet (AOP (right), offset, FALSE, FALSE),
3651 emitcode ("", "%05d$:", lbl->key + 100);
3655 if (AOP_TYPE (right) == AOP_LIT)
3657 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
3658 /* optimize if(x < 0) or if(x >= 0) */
3667 MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE));
3668 if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
3670 genIfxJump (ifx, "acc.7");
3674 emitcode ("rlc", "a");
3682 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
3683 if (sign && size == 0)
3685 emitcode ("xrl", "a,#0x80");
3686 if (AOP_TYPE (right) == AOP_LIT)
3688 unsigned long lit = (unsigned long)
3689 floatFromVal (AOP (right)->aopu.aop_lit);
3690 emitcode ("subb", "a,#0x%02x",
3691 0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
3695 emitcode ("mov", "b,%s", aopGet (AOP (right), offset++, FALSE, FALSE));
3696 emitcode ("xrl", "b,#0x80");
3697 emitcode ("subb", "a,b");
3701 emitcode ("subb", "a,%s", aopGet (AOP (right), offset++, FALSE, FALSE));
3707 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3708 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3709 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
3715 /* if the result is used in the next
3716 ifx conditional branch then generate
3717 code a little differently */
3719 genIfxJump (ifx, "c");
3722 /* leave the result in acc */
3726 /*-----------------------------------------------------------------*/
3727 /* genCmpGt :- greater than comparison */
3728 /*-----------------------------------------------------------------*/
3730 genCmpGt (iCode * ic, iCode * ifx)
3732 operand *left, *right, *result;
3733 sym_link *letype, *retype;
3736 left = IC_LEFT (ic);
3737 right = IC_RIGHT (ic);
3738 result = IC_RESULT (ic);
3740 letype = getSpec (operandType (left));
3741 retype = getSpec (operandType (right));
3742 sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
3743 /* assign the amsops */
3744 aopOp (left, ic, FALSE);
3745 aopOp (right, ic, FALSE);
3746 aopOp (result, ic, TRUE);
3748 genCmp (right, left, result, ifx, sign,ic);
3750 freeAsmop (result, NULL, ic, TRUE);
3753 /*-----------------------------------------------------------------*/
3754 /* genCmpLt - less than comparisons */
3755 /*-----------------------------------------------------------------*/
3757 genCmpLt (iCode * ic, iCode * ifx)
3759 operand *left, *right, *result;
3760 sym_link *letype, *retype;
3763 left = IC_LEFT (ic);
3764 right = IC_RIGHT (ic);
3765 result = IC_RESULT (ic);
3767 letype = getSpec (operandType (left));
3768 retype = getSpec (operandType (right));
3769 sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
3771 /* assign the amsops */
3772 aopOp (left, ic, FALSE);
3773 aopOp (right, ic, FALSE);
3774 aopOp (result, ic, TRUE);
3776 genCmp (left, right, result, ifx, sign,ic);
3778 freeAsmop (result, NULL, ic, TRUE);
3781 /*-----------------------------------------------------------------*/
3782 /* gencjneshort - compare and jump if not equal */
3783 /*-----------------------------------------------------------------*/
3785 gencjneshort (operand * left, operand * right, symbol * lbl)
3787 int size = max (AOP_SIZE (left), AOP_SIZE (right));
3789 unsigned long lit = 0L;
3791 /* if the left side is a literal or
3792 if the right is in a pointer register and left
3794 if ((AOP_TYPE (left) == AOP_LIT) ||
3795 (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
3801 if (AOP_TYPE (right) == AOP_LIT)
3802 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
3804 /* if the right side is a literal then anything goes */
3805 if (AOP_TYPE (right) == AOP_LIT &&
3806 AOP_TYPE (left) != AOP_DIR)
3810 emitcode ("cjne", "%s,%s,%05d$",
3811 aopGet (AOP (left), offset, FALSE, FALSE),
3812 aopGet (AOP (right), offset, FALSE, FALSE),
3818 /* if the right side is in a register or in direct space or
3819 if the left is a pointer register & right is not */
3820 else if (AOP_TYPE (right) == AOP_REG ||
3821 AOP_TYPE (right) == AOP_DIR ||
3822 (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) ||
3823 (IS_AOP_PREG (left) && !IS_AOP_PREG (right)))
3827 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
3828 if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
3829 ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
3830 emitcode ("jnz", "%05d$", lbl->key + 100);
3832 emitcode ("cjne", "a,%s,%05d$",
3833 aopGet (AOP (right), offset, FALSE, TRUE),
3840 /* right is a pointer reg need both a & b */
3843 char *l = aopGet (AOP (left), offset, FALSE, FALSE);
3844 if (strcmp (l, "b"))
3845 emitcode ("mov", "b,%s", l);
3846 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
3847 emitcode ("cjne", "a,b,%05d$", lbl->key + 100);
3853 /*-----------------------------------------------------------------*/
3854 /* gencjne - compare and jump if not equal */
3855 /*-----------------------------------------------------------------*/
3857 gencjne (operand * left, operand * right, symbol * lbl)
3859 symbol *tlbl = newiTempLabel (NULL);
3861 gencjneshort (left, right, lbl);
3863 emitcode ("mov", "a,%s", one);
3864 emitcode ("sjmp", "%05d$", tlbl->key + 100);
3865 emitcode ("", "%05d$:", lbl->key + 100);
3866 emitcode ("clr", "a");
3867 emitcode ("", "%05d$:", tlbl->key + 100);
3870 /*-----------------------------------------------------------------*/
3871 /* genCmpEq - generates code for equal to */
3872 /*-----------------------------------------------------------------*/
3874 genCmpEq (iCode * ic, iCode * ifx)
3876 operand *left, *right, *result;
3878 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
3879 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
3880 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
3882 /* if literal, literal on the right or
3883 if the right is in a pointer register and left
3885 if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
3886 (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
3888 operand *t = IC_RIGHT (ic);
3889 IC_RIGHT (ic) = IC_LEFT (ic);
3893 if (ifx && !AOP_SIZE (result))
3896 /* if they are both bit variables */
3897 if (AOP_TYPE (left) == AOP_CRY &&
3898 ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
3900 if (AOP_TYPE (right) == AOP_LIT)
3902 unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3905 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3906 emitcode ("cpl", "c");
3910 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3914 emitcode ("clr", "c");
3916 /* AOP_TYPE(right) == AOP_CRY */
3920 symbol *lbl = newiTempLabel (NULL);
3921 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3922 emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
3923 emitcode ("cpl", "c");
3924 emitcode ("", "%05d$:", (lbl->key + 100));
3926 /* if true label then we jump if condition
3928 tlbl = newiTempLabel (NULL);
3931 emitcode ("jnc", "%05d$", tlbl->key + 100);
3932 emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
3936 emitcode ("jc", "%05d$", tlbl->key + 100);
3937 emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
3939 emitcode ("", "%05d$:", tlbl->key + 100);
3943 tlbl = newiTempLabel (NULL);
3944 gencjneshort (left, right, tlbl);
3947 emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
3948 emitcode ("", "%05d$:", tlbl->key + 100);
3952 symbol *lbl = newiTempLabel (NULL);
3953 emitcode ("sjmp", "%05d$", lbl->key + 100);
3954 emitcode ("", "%05d$:", tlbl->key + 100);
3955 emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
3956 emitcode ("", "%05d$:", lbl->key + 100);
3959 /* mark the icode as generated */
3964 /* if they are both bit variables */
3965 if (AOP_TYPE (left) == AOP_CRY &&
3966 ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
3968 if (AOP_TYPE (right) == AOP_LIT)
3970 unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3973 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3974 emitcode ("cpl", "c");
3978 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3982 emitcode ("clr", "c");
3984 /* AOP_TYPE(right) == AOP_CRY */
3988 symbol *lbl = newiTempLabel (NULL);
3989 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3990 emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
3991 emitcode ("cpl", "c");
3992 emitcode ("", "%05d$:", (lbl->key + 100));
3995 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4002 genIfxJump (ifx, "c");
4005 /* if the result is used in an arithmetic operation
4006 then put the result in place */
4011 gencjne (left, right, newiTempLabel (NULL));
4012 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4014 aopPut (AOP (result), "a", 0);
4019 genIfxJump (ifx, "a");
4022 /* if the result is used in an arithmetic operation
4023 then put the result in place */
4024 if (AOP_TYPE (result) != AOP_CRY)
4026 /* leave the result in acc */
4030 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4031 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4032 freeAsmop (result, NULL, ic, TRUE);
4035 /*-----------------------------------------------------------------*/
4036 /* ifxForOp - returns the icode containing the ifx for operand */
4037 /*-----------------------------------------------------------------*/
4039 ifxForOp (operand * op, iCode * ic)
4041 /* if true symbol then needs to be assigned */
4042 if (IS_TRUE_SYMOP (op))
4045 /* if this has register type condition and
4046 the next instruction is ifx with the same operand
4047 and live to of the operand is upto the ifx only then */
4049 ic->next->op == IFX &&
4050 IC_COND (ic->next)->key == op->key &&
4051 OP_SYMBOL (op)->liveTo <= ic->next->seq)
4057 /*-----------------------------------------------------------------*/
4058 /* hasInc - operand is incremented before any other use */
4059 /*-----------------------------------------------------------------*/
4061 hasInc (operand *op, iCode *ic)
4063 sym_link *type = operandType(op);
4064 sym_link *retype = getSpec (type);
4065 iCode *lic = ic->next;
4068 if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
4069 isize = getSize(type->next);
4071 /* if operand of the form op = op + <sizeof *op> */
4072 if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
4073 isOperandEqual(IC_RESULT(lic),op) &&
4074 isOperandLiteral(IC_RIGHT(lic)) &&
4075 operandLitValue(IC_RIGHT(lic)) == isize) {
4078 /* if the operand used or deffed */
4079 if (bitVectBitValue(ic->uses,op->key) || (unsigned) ic->defKey == op->key) {
4087 /*-----------------------------------------------------------------*/
4088 /* genAndOp - for && operation */
4089 /*-----------------------------------------------------------------*/
4091 genAndOp (iCode * ic)
4093 operand *left, *right, *result;
4096 /* note here that && operations that are in an
4097 if statement are taken away by backPatchLabels
4098 only those used in arthmetic operations remain */
4099 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4100 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4101 aopOp ((result = IC_RESULT (ic)), ic, FALSE);
4103 /* if both are bit variables */
4104 if (AOP_TYPE (left) == AOP_CRY &&
4105 AOP_TYPE (right) == AOP_CRY)
4107 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4108 emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
4113 tlbl = newiTempLabel (NULL);
4115 emitcode ("jz", "%05d$", tlbl->key + 100);
4117 emitcode ("", "%05d$:", tlbl->key + 100);
4121 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4122 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4123 freeAsmop (result, NULL, ic, TRUE);
4127 /*-----------------------------------------------------------------*/
4128 /* genOrOp - for || operation */
4129 /*-----------------------------------------------------------------*/
4131 genOrOp (iCode * ic)
4133 operand *left, *right, *result;
4136 /* note here that || operations that are in an
4137 if statement are taken away by backPatchLabels
4138 only those used in arthmetic operations remain */
4139 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4140 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4141 aopOp ((result = IC_RESULT (ic)), ic, FALSE);
4143 /* if both are bit variables */
4144 if (AOP_TYPE (left) == AOP_CRY &&
4145 AOP_TYPE (right) == AOP_CRY)
4147 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4148 emitcode ("orl", "c,%s", AOP (right)->aopu.aop_dir);
4153 tlbl = newiTempLabel (NULL);
4155 emitcode ("jnz", "%05d$", tlbl->key + 100);
4157 emitcode ("", "%05d$:", tlbl->key + 100);
4161 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4162 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4163 freeAsmop (result, NULL, ic, TRUE);
4166 /*-----------------------------------------------------------------*/
4167 /* isLiteralBit - test if lit == 2^n */
4168 /*-----------------------------------------------------------------*/
4170 isLiteralBit (unsigned long lit)
4172 unsigned long pw[32] =
4173 {1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
4174 0x100L, 0x200L, 0x400L, 0x800L,
4175 0x1000L, 0x2000L, 0x4000L, 0x8000L,
4176 0x10000L, 0x20000L, 0x40000L, 0x80000L,
4177 0x100000L, 0x200000L, 0x400000L, 0x800000L,
4178 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
4179 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L};
4182 for (idx = 0; idx < 32; idx++)
4188 /*-----------------------------------------------------------------*/
4189 /* continueIfTrue - */
4190 /*-----------------------------------------------------------------*/
4192 continueIfTrue (iCode * ic)
4195 emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
4199 /*-----------------------------------------------------------------*/
4201 /*-----------------------------------------------------------------*/
4203 jumpIfTrue (iCode * ic)
4206 emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
4210 /*-----------------------------------------------------------------*/
4211 /* jmpTrueOrFalse - */
4212 /*-----------------------------------------------------------------*/
4214 jmpTrueOrFalse (iCode * ic, symbol * tlbl)
4216 // ugly but optimized by peephole
4219 symbol *nlbl = newiTempLabel (NULL);
4220 emitcode ("sjmp", "%05d$", nlbl->key + 100);
4221 emitcode ("", "%05d$:", tlbl->key + 100);
4222 emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
4223 emitcode ("", "%05d$:", nlbl->key + 100);
4227 emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
4228 emitcode ("", "%05d$:", tlbl->key + 100);
4233 /*-----------------------------------------------------------------*/
4234 /* genAnd - code for and */
4235 /*-----------------------------------------------------------------*/
4237 genAnd (iCode * ic, iCode * ifx)
4239 operand *left, *right, *result;
4240 int size, offset = 0;
4241 unsigned long lit = 0L;
4245 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4246 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4247 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4250 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
4252 AOP_TYPE (left), AOP_TYPE (right));
4253 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
4255 AOP_SIZE (left), AOP_SIZE (right));
4258 /* if left is a literal & right is not then exchange them */
4259 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
4260 AOP_NEEDSACC (left))
4262 operand *tmp = right;
4267 /* if result = right then exchange them */
4268 if (sameRegs (AOP (result), AOP (right)))
4270 operand *tmp = right;
4275 /* if right is bit then exchange them */
4276 if (AOP_TYPE (right) == AOP_CRY &&
4277 AOP_TYPE (left) != AOP_CRY)
4279 operand *tmp = right;
4283 if (AOP_TYPE (right) == AOP_LIT)
4284 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4286 size = AOP_SIZE (result);
4289 // result = bit & yy;
4290 if (AOP_TYPE (left) == AOP_CRY)
4292 // c = bit & literal;
4293 if (AOP_TYPE (right) == AOP_LIT)
4297 if (size && sameRegs (AOP (result), AOP (left)))
4300 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4305 if (size && (AOP_TYPE (result) == AOP_CRY))
4307 emitcode ("clr", "%s", AOP (result)->aopu.aop_dir);
4310 if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4315 emitcode ("clr", "c");
4320 if (AOP_TYPE (right) == AOP_CRY)
4323 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4324 emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
4329 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
4331 emitcode ("rrc", "a");
4332 emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
4340 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4341 genIfxJump (ifx, "c");
4345 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4346 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4347 if ((AOP_TYPE (right) == AOP_LIT) &&
4348 (AOP_TYPE (result) == AOP_CRY) &&
4349 (AOP_TYPE (left) != AOP_CRY))
4351 int posbit = isLiteralBit (lit);
4356 MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE));
4359 emitcode ("mov", "c,acc.%d", posbit & 0x07);
4365 sprintf (buffer, "acc.%d", posbit & 0x07);
4366 genIfxJump (ifx, buffer);
4373 symbol *tlbl = newiTempLabel (NULL);
4374 int sizel = AOP_SIZE (left);
4376 emitcode ("setb", "c");
4379 if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
4381 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
4383 if ((posbit = isLiteralBit (bytelit)) != 0)
4384 emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
4387 if (bytelit != 0x0FFL)
4388 emitcode ("anl", "a,%s",
4389 aopGet (AOP (right), offset, FALSE, TRUE));
4390 emitcode ("jnz", "%05d$", tlbl->key + 100);
4395 // bit = left & literal
4398 emitcode ("clr", "c");
4399 emitcode ("", "%05d$:", tlbl->key + 100);
4401 // if(left & literal)
4405 jmpTrueOrFalse (ifx, tlbl);
4413 /* if left is same as result */
4414 if (sameRegs (AOP (result), AOP (left)))
4416 for (; size--; offset++)
4418 if (AOP_TYPE (right) == AOP_LIT)
4420 if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
4422 else if (bytelit == 0)
4423 aopPut (AOP (result), zero, offset);
4424 else if (IS_AOP_PREG (result))
4426 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4427 emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4428 aopPut (AOP (result), "a", offset);
4431 emitcode ("anl", "%s,%s",
4432 aopGet (AOP (left), offset, FALSE, TRUE),
4433 aopGet (AOP (right), offset, FALSE, FALSE));
4437 if (AOP_TYPE (left) == AOP_ACC)
4438 emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4441 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4442 if (IS_AOP_PREG (result))
4444 emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4445 aopPut (AOP (result), "a", offset);
4449 emitcode ("anl", "%s,a",
4450 aopGet (AOP (left), offset, FALSE, TRUE));
4457 // left & result in different registers
4458 if (AOP_TYPE (result) == AOP_CRY)
4461 // if(size), result in bit
4462 // if(!size && ifx), conditional oper: if(left & right)
4463 symbol *tlbl = newiTempLabel (NULL);
4464 int sizer = min (AOP_SIZE (left), AOP_SIZE (right));
4466 emitcode ("setb", "c");
4469 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4470 emitcode ("anl", "a,%s",
4471 aopGet (AOP (left), offset, FALSE, FALSE));
4472 emitcode ("jnz", "%05d$", tlbl->key + 100);
4478 emitcode ("", "%05d$:", tlbl->key + 100);
4482 jmpTrueOrFalse (ifx, tlbl);
4486 for (; (size--); offset++)
4489 // result = left & right
4490 if (AOP_TYPE (right) == AOP_LIT)
4492 if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
4494 aopPut (AOP (result),
4495 aopGet (AOP (left), offset, FALSE, FALSE),
4499 else if (bytelit == 0)
4501 aopPut (AOP (result), zero, offset);
4505 // faster than result <- left, anl result,right
4506 // and better if result is SFR
4507 if (AOP_TYPE (left) == AOP_ACC)
4508 emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4511 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4512 emitcode ("anl", "a,%s",
4513 aopGet (AOP (left), offset, FALSE, FALSE));
4515 aopPut (AOP (result), "a", offset);
4521 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4522 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4523 freeAsmop (result, NULL, ic, TRUE);
4526 /*-----------------------------------------------------------------*/
4527 /* genOr - code for or */
4528 /*-----------------------------------------------------------------*/
4530 genOr (iCode * ic, iCode * ifx)
4532 operand *left, *right, *result;
4533 int size, offset = 0;
4534 unsigned long lit = 0L;
4536 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4537 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4538 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4541 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
4543 AOP_TYPE (left), AOP_TYPE (right));
4544 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
4546 AOP_SIZE (left), AOP_SIZE (right));
4549 /* if left is a literal & right is not then exchange them */
4550 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
4551 AOP_NEEDSACC (left))
4553 operand *tmp = right;
4558 /* if result = right then exchange them */
4559 if (sameRegs (AOP (result), AOP (right)))
4561 operand *tmp = right;
4566 /* if right is bit then exchange them */
4567 if (AOP_TYPE (right) == AOP_CRY &&
4568 AOP_TYPE (left) != AOP_CRY)
4570 operand *tmp = right;
4574 if (AOP_TYPE (right) == AOP_LIT)
4575 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4577 size = AOP_SIZE (result);
4581 if (AOP_TYPE (left) == AOP_CRY)
4583 if (AOP_TYPE (right) == AOP_LIT)
4585 // c = bit & literal;
4588 // lit != 0 => result = 1
4589 if (AOP_TYPE (result) == AOP_CRY)
4592 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
4594 continueIfTrue (ifx);
4597 emitcode ("setb", "c");
4601 // lit == 0 => result = left
4602 if (size && sameRegs (AOP (result), AOP (left)))
4604 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4609 if (AOP_TYPE (right) == AOP_CRY)
4612 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4613 emitcode ("orl", "c,%s", AOP (left)->aopu.aop_dir);
4618 symbol *tlbl = newiTempLabel (NULL);
4619 if (!((AOP_TYPE (result) == AOP_CRY) && ifx))
4620 emitcode ("setb", "c");
4621 emitcode ("jb", "%s,%05d$",
4622 AOP (left)->aopu.aop_dir, tlbl->key + 100);
4624 emitcode ("jnz", "%05d$", tlbl->key + 100);
4625 if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4627 jmpTrueOrFalse (ifx, tlbl);
4633 emitcode ("", "%05d$:", tlbl->key + 100);
4642 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4643 genIfxJump (ifx, "c");
4647 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4648 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4649 if ((AOP_TYPE (right) == AOP_LIT) &&
4650 (AOP_TYPE (result) == AOP_CRY) &&
4651 (AOP_TYPE (left) != AOP_CRY))
4657 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
4659 continueIfTrue (ifx);
4664 // lit = 0, result = boolean(left)
4666 emitcode ("setb", "c");
4670 symbol *tlbl = newiTempLabel (NULL);
4671 emitcode ("jnz", "%05d$", tlbl->key + 100);
4673 emitcode ("", "%05d$:", tlbl->key + 100);
4677 genIfxJump (ifx, "a");
4685 /* if left is same as result */
4686 if (sameRegs (AOP (result), AOP (left)))
4688 for (; size--; offset++)
4690 if (AOP_TYPE (right) == AOP_LIT)
4692 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
4694 else if (IS_AOP_PREG (left))
4696 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4697 emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4698 aopPut (AOP (result), "a", offset);
4701 emitcode ("orl", "%s,%s",
4702 aopGet (AOP (left), offset, FALSE, TRUE),
4703 aopGet (AOP (right), offset, FALSE, FALSE));
4707 if (AOP_TYPE (left) == AOP_ACC)
4708 emitcode ("orl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4711 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4712 if (IS_AOP_PREG (left))
4714 emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4715 aopPut (AOP (result), "a", offset);
4718 emitcode ("orl", "%s,a",
4719 aopGet (AOP (left), offset, FALSE, TRUE));
4726 // left & result in different registers
4727 if (AOP_TYPE (result) == AOP_CRY)
4730 // if(size), result in bit
4731 // if(!size && ifx), conditional oper: if(left | right)
4732 symbol *tlbl = newiTempLabel (NULL);
4733 int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
4735 emitcode ("setb", "c");
4738 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4739 emitcode ("orl", "a,%s",
4740 aopGet (AOP (left), offset, FALSE, FALSE));
4741 emitcode ("jnz", "%05d$", tlbl->key + 100);
4747 emitcode ("", "%05d$:", tlbl->key + 100);
4751 jmpTrueOrFalse (ifx, tlbl);
4754 for (; (size--); offset++)
4757 // result = left & right
4758 if (AOP_TYPE (right) == AOP_LIT)
4760 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
4762 aopPut (AOP (result),
4763 aopGet (AOP (left), offset, FALSE, FALSE),
4768 // faster than result <- left, anl result,right
4769 // and better if result is SFR
4770 if (AOP_TYPE (left) == AOP_ACC)
4771 emitcode ("orl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4774 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4775 emitcode ("orl", "a,%s",
4776 aopGet (AOP (left), offset, FALSE, FALSE));
4778 aopPut (AOP (result), "a", offset);
4783 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4784 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4785 freeAsmop (result, NULL, ic, TRUE);
4788 /*-----------------------------------------------------------------*/
4789 /* genXor - code for xclusive or */
4790 /*-----------------------------------------------------------------*/
4792 genXor (iCode * ic, iCode * ifx)
4794 operand *left, *right, *result;
4795 int size, offset = 0;
4796 unsigned long lit = 0L;
4798 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4799 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4800 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4803 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
4805 AOP_TYPE (left), AOP_TYPE (right));
4806 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
4808 AOP_SIZE (left), AOP_SIZE (right));
4811 /* if left is a literal & right is not ||
4812 if left needs acc & right does not */
4813 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
4814 (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)))
4816 operand *tmp = right;
4821 /* if result = right then exchange them */
4822 if (sameRegs (AOP (result), AOP (right)))
4824 operand *tmp = right;
4829 /* if right is bit then exchange them */
4830 if (AOP_TYPE (right) == AOP_CRY &&
4831 AOP_TYPE (left) != AOP_CRY)
4833 operand *tmp = right;
4837 if (AOP_TYPE (right) == AOP_LIT)
4838 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4840 size = AOP_SIZE (result);
4844 if (AOP_TYPE (left) == AOP_CRY)
4846 if (AOP_TYPE (right) == AOP_LIT)
4848 // c = bit & literal;
4851 // lit>>1 != 0 => result = 1
4852 if (AOP_TYPE (result) == AOP_CRY)
4855 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
4857 continueIfTrue (ifx);
4860 emitcode ("setb", "c");
4867 // lit == 0, result = left
4868 if (size && sameRegs (AOP (result), AOP (left)))
4870 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4874 // lit == 1, result = not(left)
4875 if (size && sameRegs (AOP (result), AOP (left)))
4877 emitcode ("cpl", "%s", AOP (result)->aopu.aop_dir);
4882 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4883 emitcode ("cpl", "c");
4892 symbol *tlbl = newiTempLabel (NULL);
4893 if (AOP_TYPE (right) == AOP_CRY)
4896 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4900 int sizer = AOP_SIZE (right);
4902 // if val>>1 != 0, result = 1
4903 emitcode ("setb", "c");
4906 MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE));
4908 // test the msb of the lsb
4909 emitcode ("anl", "a,#0xfe");
4910 emitcode ("jnz", "%05d$", tlbl->key + 100);
4914 emitcode ("rrc", "a");
4916 emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
4917 emitcode ("cpl", "c");
4918 emitcode ("", "%05d$:", (tlbl->key + 100));
4925 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4926 genIfxJump (ifx, "c");
4930 if (sameRegs (AOP (result), AOP (left)))
4932 /* if left is same as result */
4933 for (; size--; offset++)
4935 if (AOP_TYPE (right) == AOP_LIT)
4937 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
4939 else if (IS_AOP_PREG (left))
4941 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4942 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4943 aopPut (AOP (result), "a", offset);
4946 emitcode ("xrl", "%s,%s",
4947 aopGet (AOP (left), offset, FALSE, TRUE),
4948 aopGet (AOP (right), offset, FALSE, FALSE));
4952 if (AOP_TYPE (left) == AOP_ACC)
4953 emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4956 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4957 if (IS_AOP_PREG (left))
4959 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4960 aopPut (AOP (result), "a", offset);
4963 emitcode ("xrl", "%s,a",
4964 aopGet (AOP (left), offset, FALSE, TRUE));
4971 // left & result in different registers
4972 if (AOP_TYPE (result) == AOP_CRY)
4975 // if(size), result in bit
4976 // if(!size && ifx), conditional oper: if(left ^ right)
4977 symbol *tlbl = newiTempLabel (NULL);
4978 int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
4980 emitcode ("setb", "c");
4983 if ((AOP_TYPE (right) == AOP_LIT) &&
4984 (((lit >> (offset * 8)) & 0x0FFL) == 0x00L))
4986 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
4990 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4991 emitcode ("xrl", "a,%s",
4992 aopGet (AOP (left), offset, FALSE, FALSE));
4994 emitcode ("jnz", "%05d$", tlbl->key + 100);
5000 emitcode ("", "%05d$:", tlbl->key + 100);
5004 jmpTrueOrFalse (ifx, tlbl);
5007 for (; (size--); offset++)
5010 // result = left & right
5011 if (AOP_TYPE (right) == AOP_LIT)
5013 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
5015 aopPut (AOP (result),
5016 aopGet (AOP (left), offset, FALSE, FALSE),
5021 // faster than result <- left, anl result,right
5022 // and better if result is SFR
5023 if (AOP_TYPE (left) == AOP_ACC)
5024 emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
5027 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5028 emitcode ("xrl", "a,%s",
5029 aopGet (AOP (left), offset, FALSE, TRUE));
5031 aopPut (AOP (result), "a", offset);
5036 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5037 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5038 freeAsmop (result, NULL, ic, TRUE);
5041 /*-----------------------------------------------------------------*/
5042 /* genInline - write the inline code out */
5043 /*-----------------------------------------------------------------*/
5045 genInline (iCode * ic)
5047 char buffer[MAX_INLINEASM];
5051 _G.inLine += (!options.asmpeep);
5052 strcpy (buffer, IC_INLINE (ic));
5054 /* emit each line as a code */
5079 /* emitcode("",buffer); */
5080 _G.inLine -= (!options.asmpeep);
5083 /*-----------------------------------------------------------------*/
5084 /* genRRC - rotate right with carry */
5085 /*-----------------------------------------------------------------*/
5089 operand *left, *result;
5090 int size, offset = 0;
5093 /* rotate right with carry */
5094 left = IC_LEFT (ic);
5095 result = IC_RESULT (ic);
5096 aopOp (left, ic, FALSE);
5097 aopOp (result, ic, FALSE);
5099 /* move it to the result */
5100 size = AOP_SIZE (result);
5105 l = aopGet (AOP (left), offset, FALSE, FALSE);
5107 emitcode ("rrc", "a");
5108 if (AOP_SIZE (result) > 1)
5109 aopPut (AOP (result), "a", offset--);
5111 /* now we need to put the carry into the
5112 highest order byte of the result */
5113 if (AOP_SIZE (result) > 1)
5115 l = aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE);
5118 emitcode ("mov", "acc.7,c");
5119 aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
5120 freeAsmop (left, NULL, ic, TRUE);
5121 freeAsmop (result, NULL, ic, TRUE);
5124 /*-----------------------------------------------------------------*/
5125 /* genRLC - generate code for rotate left with carry */
5126 /*-----------------------------------------------------------------*/
5130 operand *left, *result;
5131 int size, offset = 0;
5134 /* rotate right with carry */
5135 left = IC_LEFT (ic);
5136 result = IC_RESULT (ic);
5137 aopOp (left, ic, FALSE);
5138 aopOp (result, ic, FALSE);
5140 /* move it to the result */
5141 size = AOP_SIZE (result);
5145 l = aopGet (AOP (left), offset, FALSE, FALSE);
5147 emitcode ("add", "a,acc");
5148 if (AOP_SIZE (result) > 1)
5149 aopPut (AOP (result), "a", offset++);
5152 l = aopGet (AOP (left), offset, FALSE, FALSE);
5154 emitcode ("rlc", "a");
5155 if (AOP_SIZE (result) > 1)
5156 aopPut (AOP (result), "a", offset++);
5159 /* now we need to put the carry into the
5160 highest order byte of the result */
5161 if (AOP_SIZE (result) > 1)
5163 l = aopGet (AOP (result), 0, FALSE, FALSE);
5166 emitcode ("mov", "acc.0,c");
5167 aopPut (AOP (result), "a", 0);
5168 freeAsmop (left, NULL, ic, TRUE);
5169 freeAsmop (result, NULL, ic, TRUE);
5172 /*-----------------------------------------------------------------*/
5173 /* genGetHbit - generates code get highest order bit */
5174 /*-----------------------------------------------------------------*/
5176 genGetHbit (iCode * ic)
5178 operand *left, *result;
5179 left = IC_LEFT (ic);
5180 result = IC_RESULT (ic);
5181 aopOp (left, ic, FALSE);
5182 aopOp (result, ic, FALSE);
5184 /* get the highest order byte into a */
5185 MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE));
5186 if (AOP_TYPE (result) == AOP_CRY)
5188 emitcode ("rlc", "a");
5193 emitcode ("rl", "a");
5194 emitcode ("anl", "a,#0x01");
5199 freeAsmop (left, NULL, ic, TRUE);
5200 freeAsmop (result, NULL, ic, TRUE);
5203 /*-----------------------------------------------------------------*/
5204 /* AccRol - rotate left accumulator by known count */
5205 /*-----------------------------------------------------------------*/
5207 AccRol (int shCount)
5209 shCount &= 0x0007; // shCount : 0..7
5216 emitcode ("rl", "a");
5219 emitcode ("rl", "a");
5220 emitcode ("rl", "a");
5223 emitcode ("swap", "a");
5224 emitcode ("rr", "a");
5227 emitcode ("swap", "a");
5230 emitcode ("swap", "a");
5231 emitcode ("rl", "a");
5234 emitcode ("rr", "a");
5235 emitcode ("rr", "a");
5238 emitcode ("rr", "a");
5243 /*-----------------------------------------------------------------*/
5244 /* AccLsh - left shift accumulator by known count */
5245 /*-----------------------------------------------------------------*/
5247 AccLsh (int shCount)
5252 emitcode ("add", "a,acc");
5253 else if (shCount == 2)
5255 emitcode ("add", "a,acc");
5256 emitcode ("add", "a,acc");
5260 /* rotate left accumulator */
5262 /* and kill the lower order bits */
5263 emitcode ("anl", "a,#0x%02x", SLMask[shCount]);
5268 /*-----------------------------------------------------------------*/
5269 /* AccRsh - right shift accumulator by known count */
5270 /*-----------------------------------------------------------------*/
5272 AccRsh (int shCount)
5279 emitcode ("rrc", "a");
5283 /* rotate right accumulator */
5284 AccRol (8 - shCount);
5285 /* and kill the higher order bits */
5286 emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
5291 /*-----------------------------------------------------------------*/
5292 /* AccSRsh - signed right shift accumulator by known count */
5293 /*-----------------------------------------------------------------*/
5295 AccSRsh (int shCount)
5302 emitcode ("mov", "c,acc.7");
5303 emitcode ("rrc", "a");
5305 else if (shCount == 2)
5307 emitcode ("mov", "c,acc.7");
5308 emitcode ("rrc", "a");
5309 emitcode ("mov", "c,acc.7");
5310 emitcode ("rrc", "a");
5314 tlbl = newiTempLabel (NULL);
5315 /* rotate right accumulator */
5316 AccRol (8 - shCount);
5317 /* and kill the higher order bits */
5318 emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
5319 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5320 emitcode ("orl", "a,#0x%02x",
5321 (unsigned char) ~SRMask[shCount]);
5322 emitcode ("", "%05d$:", tlbl->key + 100);
5327 /*-----------------------------------------------------------------*/
5328 /* shiftR1Left2Result - shift right one byte from left to result */
5329 /*-----------------------------------------------------------------*/
5331 shiftR1Left2Result (operand * left, int offl,
5332 operand * result, int offr,
5333 int shCount, int sign)
5335 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5336 /* shift right accumulator */
5341 aopPut (AOP (result), "a", offr);
5344 /*-----------------------------------------------------------------*/
5345 /* shiftL1Left2Result - shift left one byte from left to result */
5346 /*-----------------------------------------------------------------*/
5348 shiftL1Left2Result (operand * left, int offl,
5349 operand * result, int offr, int shCount)
5352 l = aopGet (AOP (left), offl, FALSE, FALSE);
5354 /* shift left accumulator */
5356 aopPut (AOP (result), "a", offr);
5359 /*-----------------------------------------------------------------*/
5360 /* movLeft2Result - move byte from left to result */
5361 /*-----------------------------------------------------------------*/
5363 movLeft2Result (operand * left, int offl,
5364 operand * result, int offr, int sign)
5367 if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
5369 l = aopGet (AOP (left), offl, FALSE, FALSE);
5371 if (*l == '@' && (IS_AOP_PREG (result)))
5373 emitcode ("mov", "a,%s", l);
5374 aopPut (AOP (result), "a", offr);
5379 aopPut (AOP (result), l, offr);
5382 /* MSB sign in acc.7 ! */
5383 if (getDataSize (left) == offl + 1)
5385 emitcode ("mov", "a,%s", l);
5386 aopPut (AOP (result), "a", offr);
5393 /*-----------------------------------------------------------------*/
5394 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5395 /*-----------------------------------------------------------------*/
5399 emitcode ("rrc", "a");
5400 emitcode ("xch", "a,%s", x);
5401 emitcode ("rrc", "a");
5402 emitcode ("xch", "a,%s", x);
5405 /*-----------------------------------------------------------------*/
5406 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5407 /*-----------------------------------------------------------------*/
5411 emitcode ("xch", "a,%s", x);
5412 emitcode ("rlc", "a");
5413 emitcode ("xch", "a,%s", x);
5414 emitcode ("rlc", "a");
5417 /*-----------------------------------------------------------------*/
5418 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5419 /*-----------------------------------------------------------------*/
5423 emitcode ("xch", "a,%s", x);
5424 emitcode ("add", "a,acc");
5425 emitcode ("xch", "a,%s", x);
5426 emitcode ("rlc", "a");
5429 /*-----------------------------------------------------------------*/
5430 /* AccAXLsh - left shift a:x by known count (0..7) */
5431 /*-----------------------------------------------------------------*/
5433 AccAXLsh (char *x, int shCount)
5448 case 5: // AAAAABBB:CCCCCDDD
5450 AccRol (shCount); // BBBAAAAA:CCCCCDDD
5452 emitcode ("anl", "a,#0x%02x",
5453 SLMask[shCount]); // BBB00000:CCCCCDDD
5455 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBB00000
5457 AccRol (shCount); // DDDCCCCC:BBB00000
5459 emitcode ("xch", "a,%s", x); // BBB00000:DDDCCCCC
5461 emitcode ("xrl", "a,%s", x); // (BBB^DDD)CCCCC:DDDCCCCC
5463 emitcode ("xch", "a,%s", x); // DDDCCCCC:(BBB^DDD)CCCCC
5465 emitcode ("anl", "a,#0x%02x",
5466 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5468 emitcode ("xch", "a,%s", x); // (BBB^DDD)CCCCC:DDD00000
5470 emitcode ("xrl", "a,%s", x); // BBBCCCCC:DDD00000
5473 case 6: // AAAAAABB:CCCCCCDD
5474 emitcode ("anl", "a,#0x%02x",
5475 SRMask[shCount]); // 000000BB:CCCCCCDD
5476 emitcode ("mov", "c,acc.0"); // c = B
5477 emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB
5479 AccAXRrl1 (x); // BCCCCCCD:D000000B
5480 AccAXRrl1 (x); // BBCCCCCC:DD000000
5482 emitcode("rrc","a");
5483 emitcode("xch","a,%s", x);
5484 emitcode("rrc","a");
5485 emitcode("mov","c,acc.0"); //<< get correct bit
5486 emitcode("xch","a,%s", x);
5488 emitcode("rrc","a");
5489 emitcode("xch","a,%s", x);
5490 emitcode("rrc","a");
5491 emitcode("xch","a,%s", x);
5494 case 7: // a:x <<= 7
5496 emitcode ("anl", "a,#0x%02x",
5497 SRMask[shCount]); // 0000000B:CCCCCCCD
5499 emitcode ("mov", "c,acc.0"); // c = B
5501 emitcode ("xch", "a,%s", x); // CCCCCCCD:0000000B
5503 AccAXRrl1 (x); // BCCCCCCC:D0000000
5511 /*-----------------------------------------------------------------*/
5512 /* AccAXRsh - right shift a:x known count (0..7) */
5513 /*-----------------------------------------------------------------*/
5515 AccAXRsh (char *x, int shCount)
5523 AccAXRrl1 (x); // 0->a:x
5528 AccAXRrl1 (x); // 0->a:x
5531 AccAXRrl1 (x); // 0->a:x
5536 case 5: // AAAAABBB:CCCCCDDD = a:x
5538 AccRol (8 - shCount); // BBBAAAAA:DDDCCCCC
5540 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
5542 AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
5544 emitcode ("anl", "a,#0x%02x",
5545 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5547 emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA
5549 emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5551 emitcode ("anl", "a,#0x%02x",
5552 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5554 emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA
5556 emitcode ("xrl", "a,%s", x); // BBBCCCCC:000AAAAA
5558 emitcode ("xch", "a,%s", x); // 000AAAAA:BBBCCCCC
5561 case 6: // AABBBBBB:CCDDDDDD
5563 emitcode ("mov", "c,acc.7");
5564 AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
5566 AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
5568 emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
5570 emitcode ("anl", "a,#0x%02x",
5571 SRMask[shCount]); // 000000AA:BBBBBBCC
5574 case 7: // ABBBBBBB:CDDDDDDD
5576 emitcode ("mov", "c,acc.7"); // c = A
5578 AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
5580 emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
5582 emitcode ("anl", "a,#0x%02x",
5583 SRMask[shCount]); // 0000000A:BBBBBBBC
5591 /*-----------------------------------------------------------------*/
5592 /* AccAXRshS - right shift signed a:x known count (0..7) */
5593 /*-----------------------------------------------------------------*/
5595 AccAXRshS (char *x, int shCount)
5603 emitcode ("mov", "c,acc.7");
5604 AccAXRrl1 (x); // s->a:x
5608 emitcode ("mov", "c,acc.7");
5609 AccAXRrl1 (x); // s->a:x
5611 emitcode ("mov", "c,acc.7");
5612 AccAXRrl1 (x); // s->a:x
5617 case 5: // AAAAABBB:CCCCCDDD = a:x
5619 tlbl = newiTempLabel (NULL);
5620 AccRol (8 - shCount); // BBBAAAAA:CCCCCDDD
5622 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
5624 AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
5626 emitcode ("anl", "a,#0x%02x",
5627 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5629 emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA
5631 emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5633 emitcode ("anl", "a,#0x%02x",
5634 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5636 emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA
5638 emitcode ("xrl", "a,%s", x); // BBBCCCCC:000AAAAA
5640 emitcode ("xch", "a,%s", x); // 000SAAAA:BBBCCCCC
5642 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5643 emitcode ("orl", "a,#0x%02x",
5644 (unsigned char) ~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5646 emitcode ("", "%05d$:", tlbl->key + 100);
5647 break; // SSSSAAAA:BBBCCCCC
5649 case 6: // AABBBBBB:CCDDDDDD
5651 tlbl = newiTempLabel (NULL);
5652 emitcode ("mov", "c,acc.7");
5653 AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
5655 AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
5657 emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
5659 emitcode ("anl", "a,#0x%02x",
5660 SRMask[shCount]); // 000000AA:BBBBBBCC
5662 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5663 emitcode ("orl", "a,#0x%02x",
5664 (unsigned char) ~SRMask[shCount]); // 111111AA:BBBBBBCC
5666 emitcode ("", "%05d$:", tlbl->key + 100);
5668 case 7: // ABBBBBBB:CDDDDDDD
5670 tlbl = newiTempLabel (NULL);
5671 emitcode ("mov", "c,acc.7"); // c = A
5673 AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
5675 emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
5677 emitcode ("anl", "a,#0x%02x",
5678 SRMask[shCount]); // 0000000A:BBBBBBBC
5680 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5681 emitcode ("orl", "a,#0x%02x",
5682 (unsigned char) ~SRMask[shCount]); // 1111111A:BBBBBBBC
5684 emitcode ("", "%05d$:", tlbl->key + 100);
5691 /*-----------------------------------------------------------------*/
5692 /* shiftL2Left2Result - shift left two bytes from left to result */
5693 /*-----------------------------------------------------------------*/
5695 shiftL2Left2Result (operand * left, int offl,
5696 operand * result, int offr, int shCount)
5698 if (sameRegs (AOP (result), AOP (left)) &&
5699 ((offl + MSB16) == offr))
5701 /* don't crash result[offr] */
5702 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5703 emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5707 movLeft2Result (left, offl, result, offr, 0);
5708 MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5710 /* ax << shCount (x = lsb(result)) */
5711 AccAXLsh (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
5712 aopPut (AOP (result), "a", offr + MSB16);
5716 /*-----------------------------------------------------------------*/
5717 /* shiftR2Left2Result - shift right two bytes from left to result */
5718 /*-----------------------------------------------------------------*/
5720 shiftR2Left2Result (operand * left, int offl,
5721 operand * result, int offr,
5722 int shCount, int sign)
5724 if (sameRegs (AOP (result), AOP (left)) &&
5725 ((offl + MSB16) == offr))
5727 /* don't crash result[offr] */
5728 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5729 emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5733 movLeft2Result (left, offl, result, offr, 0);
5734 MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5736 /* a:x >> shCount (x = lsb(result)) */
5738 AccAXRshS (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
5740 AccAXRsh (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
5741 if (getDataSize (result) > 1)
5742 aopPut (AOP (result), "a", offr + MSB16);
5745 /*-----------------------------------------------------------------*/
5746 /* shiftLLeftOrResult - shift left one byte from left, or to result */
5747 /*-----------------------------------------------------------------*/
5749 shiftLLeftOrResult (operand * left, int offl,
5750 operand * result, int offr, int shCount)
5752 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5753 /* shift left accumulator */
5755 /* or with result */
5756 emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE));
5757 /* back to result */
5758 aopPut (AOP (result), "a", offr);
5761 /*-----------------------------------------------------------------*/
5762 /* shiftRLeftOrResult - shift right one byte from left,or to result */
5763 /*-----------------------------------------------------------------*/
5765 shiftRLeftOrResult (operand * left, int offl,
5766 operand * result, int offr, int shCount)
5768 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5769 /* shift right accumulator */
5771 /* or with result */
5772 emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE));
5773 /* back to result */
5774 aopPut (AOP (result), "a", offr);
5777 /*-----------------------------------------------------------------*/
5778 /* genlshOne - left shift a one byte quantity by known count */
5779 /*-----------------------------------------------------------------*/
5781 genlshOne (operand * result, operand * left, int shCount)
5783 shiftL1Left2Result (left, LSB, result, LSB, shCount);
5786 /*-----------------------------------------------------------------*/
5787 /* genlshTwo - left shift two bytes by known amount != 0 */
5788 /*-----------------------------------------------------------------*/
5790 genlshTwo (operand * result, operand * left, int shCount)
5794 size = getDataSize (result);
5796 /* if shCount >= 8 */
5804 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
5806 movLeft2Result (left, LSB, result, MSB16, 0);
5808 aopPut (AOP (result), zero, LSB);
5811 /* 1 <= shCount <= 7 */
5815 shiftL1Left2Result (left, LSB, result, LSB, shCount);
5817 shiftL2Left2Result (left, LSB, result, LSB, shCount);
5821 /*-----------------------------------------------------------------*/
5822 /* shiftLLong - shift left one long from left to result */
5823 /* offl = LSB or MSB16 */
5824 /*-----------------------------------------------------------------*/
5826 shiftLLong (operand * left, operand * result, int offr)
5829 int size = AOP_SIZE (result);
5831 if (size >= LSB + offr)
5833 l = aopGet (AOP (left), LSB, FALSE, FALSE);
5835 emitcode ("add", "a,acc");
5836 if (sameRegs (AOP (left), AOP (result)) &&
5837 size >= MSB16 + offr && offr != LSB)
5838 emitcode ("xch", "a,%s",
5839 aopGet (AOP (left), LSB + offr, FALSE, FALSE));
5841 aopPut (AOP (result), "a", LSB + offr);
5844 if (size >= MSB16 + offr)
5846 if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB16 + offr && offr != LSB))
5848 l = aopGet (AOP (left), MSB16, FALSE, FALSE);
5851 emitcode ("rlc", "a");
5852 if (sameRegs (AOP (left), AOP (result)) &&
5853 size >= MSB24 + offr && offr != LSB)
5854 emitcode ("xch", "a,%s",
5855 aopGet (AOP (left), MSB16 + offr, FALSE, FALSE));
5857 aopPut (AOP (result), "a", MSB16 + offr);
5860 if (size >= MSB24 + offr)
5862 if (!(sameRegs (AOP (left), AOP (left)) && size >= MSB24 + offr && offr != LSB))
5864 l = aopGet (AOP (left), MSB24, FALSE, FALSE);
5867 emitcode ("rlc", "a");
5868 if (sameRegs (AOP (left), AOP (result)) &&
5869 size >= MSB32 + offr && offr != LSB)
5870 emitcode ("xch", "a,%s",
5871 aopGet (AOP (left), MSB24 + offr, FALSE, FALSE));
5873 aopPut (AOP (result), "a", MSB24 + offr);
5876 if (size > MSB32 + offr)
5878 if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB32 + offr && offr != LSB))
5880 l = aopGet (AOP (left), MSB32, FALSE, FALSE);
5883 emitcode ("rlc", "a");
5884 aopPut (AOP (result), "a", MSB32 + offr);
5887 aopPut (AOP (result), zero, LSB);
5890 /*-----------------------------------------------------------------*/
5891 /* genlshFour - shift four byte by a known amount != 0 */
5892 /*-----------------------------------------------------------------*/
5894 genlshFour (operand * result, operand * left, int shCount)
5898 size = AOP_SIZE (result);
5900 /* if shifting more that 3 bytes */
5905 /* lowest order of left goes to the highest
5906 order of the destination */
5907 shiftL1Left2Result (left, LSB, result, MSB32, shCount);
5909 movLeft2Result (left, LSB, result, MSB32, 0);
5910 aopPut (AOP (result), zero, LSB);
5911 aopPut (AOP (result), zero, MSB16);
5912 aopPut (AOP (result), zero, MSB24);
5916 /* more than two bytes */
5917 else if (shCount >= 16)
5919 /* lower order two bytes goes to higher order two bytes */
5921 /* if some more remaining */
5923 shiftL2Left2Result (left, LSB, result, MSB24, shCount);
5926 movLeft2Result (left, MSB16, result, MSB32, 0);
5927 movLeft2Result (left, LSB, result, MSB24, 0);
5929 aopPut (AOP (result), zero, MSB16);
5930 aopPut (AOP (result), zero, LSB);
5934 /* if more than 1 byte */
5935 else if (shCount >= 8)
5937 /* lower order three bytes goes to higher order three bytes */
5942 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
5944 movLeft2Result (left, LSB, result, MSB16, 0);
5950 movLeft2Result (left, MSB24, result, MSB32, 0);
5951 movLeft2Result (left, MSB16, result, MSB24, 0);
5952 movLeft2Result (left, LSB, result, MSB16, 0);
5953 aopPut (AOP (result), zero, LSB);
5955 else if (shCount == 1)
5956 shiftLLong (left, result, MSB16);
5959 shiftL2Left2Result (left, MSB16, result, MSB24, shCount);
5960 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
5961 shiftRLeftOrResult (left, LSB, result, MSB24, 8 - shCount);
5962 aopPut (AOP (result), zero, LSB);
5967 /* 1 <= shCount <= 7 */
5968 else if (shCount <= 2)
5970 shiftLLong (left, result, LSB);
5972 shiftLLong (result, result, LSB);
5974 /* 3 <= shCount <= 7, optimize */
5977 shiftL2Left2Result (left, MSB24, result, MSB24, shCount);
5978 shiftRLeftOrResult (left, MSB16, result, MSB24, 8 - shCount);
5979 shiftL2Left2Result (left, LSB, result, LSB, shCount);
5983 /*-----------------------------------------------------------------*/
5984 /* genLeftShiftLiteral - left shifting by known count */
5985 /*-----------------------------------------------------------------*/
5987 genLeftShiftLiteral (operand * left,
5992 int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
5995 freeAsmop (right, NULL, ic, TRUE);
5997 aopOp (left, ic, FALSE);
5998 aopOp (result, ic, FALSE);
6000 size = getSize (operandType (result));
6003 emitcode ("; shift left ", "result %d, left %d", size,
6007 /* I suppose that the left size >= result size */
6012 movLeft2Result (left, size, result, size, 0);
6016 else if (shCount >= (size * 8))
6018 aopPut (AOP (result), zero, size);
6024 genlshOne (result, left, shCount);
6029 genlshTwo (result, left, shCount);
6033 genlshFour (result, left, shCount);
6037 freeAsmop (left, NULL, ic, TRUE);
6038 freeAsmop (result, NULL, ic, TRUE);
6041 /*-----------------------------------------------------------------*/
6042 /* genLeftShift - generates code for left shifting */
6043 /*-----------------------------------------------------------------*/
6045 genLeftShift (iCode * ic)
6047 operand *left, *right, *result;
6050 symbol *tlbl, *tlbl1;
6052 right = IC_RIGHT (ic);
6053 left = IC_LEFT (ic);
6054 result = IC_RESULT (ic);
6056 aopOp (right, ic, FALSE);
6058 /* if the shift count is known then do it
6059 as efficiently as possible */
6060 if (AOP_TYPE (right) == AOP_LIT)
6062 genLeftShiftLiteral (left, right, result, ic);
6066 /* shift count is unknown then we have to form
6067 a loop get the loop count in B : Note: we take
6068 only the lower order byte since shifting
6069 more that 32 bits make no sense anyway, ( the
6070 largest size of an object can be only 32 bits ) */
6072 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6073 emitcode ("inc", "b");
6074 freeAsmop (right, NULL, ic, TRUE);
6075 aopOp (left, ic, FALSE);
6076 aopOp (result, ic, FALSE);
6078 /* now move the left to the result if they are not the
6080 if (!sameRegs (AOP (left), AOP (result)) &&
6081 AOP_SIZE (result) > 1)
6084 size = AOP_SIZE (result);
6088 l = aopGet (AOP (left), offset, FALSE, TRUE);
6089 if (*l == '@' && (IS_AOP_PREG (result)))
6092 emitcode ("mov", "a,%s", l);
6093 aopPut (AOP (result), "a", offset);
6096 aopPut (AOP (result), l, offset);
6101 tlbl = newiTempLabel (NULL);
6102 size = AOP_SIZE (result);
6104 tlbl1 = newiTempLabel (NULL);
6106 /* if it is only one byte then */
6109 symbol *tlbl1 = newiTempLabel (NULL);
6111 l = aopGet (AOP (left), 0, FALSE, FALSE);
6113 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6114 emitcode ("", "%05d$:", tlbl->key + 100);
6115 emitcode ("add", "a,acc");
6116 emitcode ("", "%05d$:", tlbl1->key + 100);
6117 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6118 aopPut (AOP (result), "a", 0);
6122 reAdjustPreg (AOP (result));
6124 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6125 emitcode ("", "%05d$:", tlbl->key + 100);
6126 l = aopGet (AOP (result), offset, FALSE, FALSE);
6128 emitcode ("add", "a,acc");
6129 aopPut (AOP (result), "a", offset++);
6132 l = aopGet (AOP (result), offset, FALSE, FALSE);
6134 emitcode ("rlc", "a");
6135 aopPut (AOP (result), "a", offset++);
6137 reAdjustPreg (AOP (result));
6139 emitcode ("", "%05d$:", tlbl1->key + 100);
6140 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6142 freeAsmop (left, NULL, ic, TRUE);
6143 freeAsmop (result, NULL, ic, TRUE);
6146 /*-----------------------------------------------------------------*/
6147 /* genrshOne - right shift a one byte quantity by known count */
6148 /*-----------------------------------------------------------------*/
6150 genrshOne (operand * result, operand * left,
6151 int shCount, int sign)
6153 shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
6156 /*-----------------------------------------------------------------*/
6157 /* genrshTwo - right shift two bytes by known amount != 0 */
6158 /*-----------------------------------------------------------------*/
6160 genrshTwo (operand * result, operand * left,
6161 int shCount, int sign)
6163 /* if shCount >= 8 */
6168 shiftR1Left2Result (left, MSB16, result, LSB,
6171 movLeft2Result (left, MSB16, result, LSB, sign);
6172 addSign (result, MSB16, sign);
6175 /* 1 <= shCount <= 7 */
6177 shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
6180 /*-----------------------------------------------------------------*/
6181 /* shiftRLong - shift right one long from left to result */
6182 /* offl = LSB or MSB16 */
6183 /*-----------------------------------------------------------------*/
6185 shiftRLong (operand * left, int offl,
6186 operand * result, int sign)
6189 emitcode ("clr", "c");
6190 MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
6192 emitcode ("mov", "c,acc.7");
6193 emitcode ("rrc", "a");
6194 aopPut (AOP (result), "a", MSB32 - offl);
6196 /* add sign of "a" */
6197 addSign (result, MSB32, sign);
6199 MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
6200 emitcode ("rrc", "a");
6201 aopPut (AOP (result), "a", MSB24 - offl);
6203 MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
6204 emitcode ("rrc", "a");
6205 aopPut (AOP (result), "a", MSB16 - offl);
6209 MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
6210 emitcode ("rrc", "a");
6211 aopPut (AOP (result), "a", LSB);
6215 /*-----------------------------------------------------------------*/
6216 /* genrshFour - shift four byte by a known amount != 0 */
6217 /*-----------------------------------------------------------------*/
6219 genrshFour (operand * result, operand * left,
6220 int shCount, int sign)
6222 /* if shifting more that 3 bytes */
6227 shiftR1Left2Result (left, MSB32, result, LSB, shCount, sign);
6229 movLeft2Result (left, MSB32, result, LSB, sign);
6230 addSign (result, MSB16, sign);
6232 else if (shCount >= 16)
6236 shiftR2Left2Result (left, MSB24, result, LSB, shCount, sign);
6239 movLeft2Result (left, MSB24, result, LSB, 0);
6240 movLeft2Result (left, MSB32, result, MSB16, sign);
6242 addSign (result, MSB24, sign);
6244 else if (shCount >= 8)
6248 shiftRLong (left, MSB16, result, sign);
6249 else if (shCount == 0)
6251 movLeft2Result (left, MSB16, result, LSB, 0);
6252 movLeft2Result (left, MSB24, result, MSB16, 0);
6253 movLeft2Result (left, MSB32, result, MSB24, sign);
6254 addSign (result, MSB32, sign);
6258 shiftR2Left2Result (left, MSB16, result, LSB, shCount, 0);
6259 shiftLLeftOrResult (left, MSB32, result, MSB16, 8 - shCount);
6260 /* the last shift is signed */
6261 shiftR1Left2Result (left, MSB32, result, MSB24, shCount, sign);
6262 addSign (result, MSB32, sign);
6266 { /* 1 <= shCount <= 7 */
6269 shiftRLong (left, LSB, result, sign);
6271 shiftRLong (result, LSB, result, sign);
6275 shiftR2Left2Result (left, LSB, result, LSB, shCount, 0);
6276 shiftLLeftOrResult (left, MSB24, result, MSB16, 8 - shCount);
6277 shiftR2Left2Result (left, MSB24, result, MSB24, shCount, sign);
6282 /*-----------------------------------------------------------------*/
6283 /* genRightShiftLiteral - right shifting by known count */
6284 /*-----------------------------------------------------------------*/
6286 genRightShiftLiteral (operand * left,
6292 int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
6295 freeAsmop (right, NULL, ic, TRUE);
6297 aopOp (left, ic, FALSE);
6298 aopOp (result, ic, FALSE);
6301 emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
6305 size = getDataSize (left);
6306 /* test the LEFT size !!! */
6308 /* I suppose that the left size >= result size */
6311 size = getDataSize (result);
6313 movLeft2Result (left, size, result, size, 0);
6316 else if (shCount >= (size * 8))
6319 /* get sign in acc.7 */
6320 MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE));
6321 addSign (result, LSB, sign);
6328 genrshOne (result, left, shCount, sign);
6332 genrshTwo (result, left, shCount, sign);
6336 genrshFour (result, left, shCount, sign);
6342 freeAsmop (left, NULL, ic, TRUE);
6343 freeAsmop (result, NULL, ic, TRUE);
6347 /*-----------------------------------------------------------------*/
6348 /* genSignedRightShift - right shift of signed number */
6349 /*-----------------------------------------------------------------*/
6351 genSignedRightShift (iCode * ic)
6353 operand *right, *left, *result;
6356 symbol *tlbl, *tlbl1;
6358 /* we do it the hard way put the shift count in b
6359 and loop thru preserving the sign */
6361 right = IC_RIGHT (ic);
6362 left = IC_LEFT (ic);
6363 result = IC_RESULT (ic);
6365 aopOp (right, ic, FALSE);
6368 if (AOP_TYPE (right) == AOP_LIT)
6370 genRightShiftLiteral (left, right, result, ic, 1);
6373 /* shift count is unknown then we have to form
6374 a loop get the loop count in B : Note: we take
6375 only the lower order byte since shifting
6376 more that 32 bits make no sense anyway, ( the
6377 largest size of an object can be only 32 bits ) */
6379 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6380 emitcode ("inc", "b");
6381 freeAsmop (right, NULL, ic, TRUE);
6382 aopOp (left, ic, FALSE);
6383 aopOp (result, ic, FALSE);
6385 /* now move the left to the result if they are not the
6387 if (!sameRegs (AOP (left), AOP (result)) &&
6388 AOP_SIZE (result) > 1)
6391 size = AOP_SIZE (result);
6395 l = aopGet (AOP (left), offset, FALSE, TRUE);
6396 if (*l == '@' && IS_AOP_PREG (result))
6399 emitcode ("mov", "a,%s", l);
6400 aopPut (AOP (result), "a", offset);
6403 aopPut (AOP (result), l, offset);
6408 /* mov the highest order bit to OVR */
6409 tlbl = newiTempLabel (NULL);
6410 tlbl1 = newiTempLabel (NULL);
6412 size = AOP_SIZE (result);
6414 emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE));
6415 emitcode ("rlc", "a");
6416 emitcode ("mov", "ov,c");
6417 /* if it is only one byte then */
6420 l = aopGet (AOP (left), 0, FALSE, FALSE);
6422 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6423 emitcode ("", "%05d$:", tlbl->key + 100);
6424 emitcode ("mov", "c,ov");
6425 emitcode ("rrc", "a");
6426 emitcode ("", "%05d$:", tlbl1->key + 100);
6427 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6428 aopPut (AOP (result), "a", 0);
6432 reAdjustPreg (AOP (result));
6433 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6434 emitcode ("", "%05d$:", tlbl->key + 100);
6435 emitcode ("mov", "c,ov");
6438 l = aopGet (AOP (result), offset, FALSE, FALSE);
6440 emitcode ("rrc", "a");
6441 aopPut (AOP (result), "a", offset--);
6443 reAdjustPreg (AOP (result));
6444 emitcode ("", "%05d$:", tlbl1->key + 100);
6445 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6448 freeAsmop (left, NULL, ic, TRUE);
6449 freeAsmop (result, NULL, ic, TRUE);
6452 /*-----------------------------------------------------------------*/
6453 /* genRightShift - generate code for right shifting */
6454 /*-----------------------------------------------------------------*/
6456 genRightShift (iCode * ic)
6458 operand *right, *left, *result;
6462 symbol *tlbl, *tlbl1;
6464 /* if signed then we do it the hard way preserve the
6465 sign bit moving it inwards */
6466 retype = getSpec (operandType (IC_RESULT (ic)));
6468 if (!SPEC_USIGN (retype))
6470 genSignedRightShift (ic);
6474 /* signed & unsigned types are treated the same : i.e. the
6475 signed is NOT propagated inwards : quoting from the
6476 ANSI - standard : "for E1 >> E2, is equivalent to division
6477 by 2**E2 if unsigned or if it has a non-negative value,
6478 otherwise the result is implementation defined ", MY definition
6479 is that the sign does not get propagated */
6481 right = IC_RIGHT (ic);
6482 left = IC_LEFT (ic);
6483 result = IC_RESULT (ic);
6485 aopOp (right, ic, FALSE);
6487 /* if the shift count is known then do it
6488 as efficiently as possible */
6489 if (AOP_TYPE (right) == AOP_LIT)
6491 genRightShiftLiteral (left, right, result, ic, 0);
6495 /* shift count is unknown then we have to form
6496 a loop get the loop count in B : Note: we take
6497 only the lower order byte since shifting
6498 more that 32 bits make no sense anyway, ( the
6499 largest size of an object can be only 32 bits ) */
6501 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6502 emitcode ("inc", "b");
6503 freeAsmop (right, NULL, ic, TRUE);
6504 aopOp (left, ic, FALSE);
6505 aopOp (result, ic, FALSE);
6507 /* now move the left to the result if they are not the
6509 if (!sameRegs (AOP (left), AOP (result)) &&
6510 AOP_SIZE (result) > 1)
6513 size = AOP_SIZE (result);
6517 l = aopGet (AOP (left), offset, FALSE, TRUE);
6518 if (*l == '@' && IS_AOP_PREG (result))
6521 emitcode ("mov", "a,%s", l);
6522 aopPut (AOP (result), "a", offset);
6525 aopPut (AOP (result), l, offset);
6530 tlbl = newiTempLabel (NULL);
6531 tlbl1 = newiTempLabel (NULL);
6532 size = AOP_SIZE (result);
6535 /* if it is only one byte then */
6538 l = aopGet (AOP (left), 0, FALSE, FALSE);
6540 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6541 emitcode ("", "%05d$:", tlbl->key + 100);
6543 emitcode ("rrc", "a");
6544 emitcode ("", "%05d$:", tlbl1->key + 100);
6545 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6546 aopPut (AOP (result), "a", 0);
6550 reAdjustPreg (AOP (result));
6551 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6552 emitcode ("", "%05d$:", tlbl->key + 100);
6556 l = aopGet (AOP (result), offset, FALSE, FALSE);
6558 emitcode ("rrc", "a");
6559 aopPut (AOP (result), "a", offset--);
6561 reAdjustPreg (AOP (result));
6563 emitcode ("", "%05d$:", tlbl1->key + 100);
6564 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6567 freeAsmop (left, NULL, ic, TRUE);
6568 freeAsmop (result, NULL, ic, TRUE);
6571 /*-----------------------------------------------------------------*/
6572 /* genUnpackBits - generates code for unpacking bits */
6573 /*-----------------------------------------------------------------*/
6575 genUnpackBits (operand * result, char *rname, int ptype)
6583 etype = getSpec (operandType (result));
6584 rsize = getSize (operandType (result));
6585 /* read the first byte */
6591 emitcode ("mov", "a,@%s", rname);
6595 emitcode ("movx", "a,@%s", rname);
6599 emitcode ("movx", "a,@dptr");
6603 emitcode ("clr", "a");
6604 emitcode ("movc", "a,%s", "@a+dptr");
6608 emitcode ("lcall", "__gptrget");
6612 rlen = SPEC_BLEN (etype);
6614 /* if we have bitdisplacement then it fits */
6615 /* into this byte completely or if length is */
6616 /* less than a byte */
6617 if ((shCnt = SPEC_BSTR (etype)) ||
6618 (SPEC_BLEN (etype) <= 8))
6621 /* shift right acc */
6624 emitcode ("anl", "a,#0x%02x",
6625 ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
6626 aopPut (AOP (result), "a", offset++);
6630 /* bit field did not fit in a byte */
6631 aopPut (AOP (result), "a", offset++);
6640 emitcode ("inc", "%s", rname);
6641 emitcode ("mov", "a,@%s", rname);
6645 emitcode ("inc", "%s", rname);
6646 emitcode ("movx", "a,@%s", rname);
6650 emitcode ("inc", "dptr");
6651 emitcode ("movx", "a,@dptr");
6655 emitcode ("clr", "a");
6656 emitcode ("inc", "dptr");
6657 emitcode ("movc", "a", "@a+dptr");
6661 emitcode ("inc", "dptr");
6662 emitcode ("lcall", "__gptrget");
6667 /* if we are done */
6671 aopPut (AOP (result), "a", offset++);
6677 // emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(rlen));
6679 aopPut (AOP (result), "a", offset++);
6687 aopPut (AOP (result), zero, offset++);
6693 /*-----------------------------------------------------------------*/
6694 /* genDataPointerGet - generates code when ptr offset is known */
6695 /*-----------------------------------------------------------------*/
6697 genDataPointerGet (operand * left,
6703 int size, offset = 0;
6704 aopOp (result, ic, TRUE);
6706 /* get the string representation of the name */
6707 l = aopGet (AOP (left), 0, FALSE, TRUE);
6708 size = AOP_SIZE (result);
6712 sprintf (buffer, "(%s + %d)", l + 1, offset);
6714 sprintf (buffer, "%s", l + 1);
6715 aopPut (AOP (result), buffer, offset++);
6718 freeAsmop (left, NULL, ic, TRUE);
6719 freeAsmop (result, NULL, ic, TRUE);
6722 /*-----------------------------------------------------------------*/
6723 /* genNearPointerGet - emitcode for near pointer fetch */
6724 /*-----------------------------------------------------------------*/
6726 genNearPointerGet (operand * left,
6734 sym_link *rtype, *retype;
6735 sym_link *ltype = operandType (left);
6738 rtype = operandType (result);
6739 retype = getSpec (rtype);
6741 aopOp (left, ic, FALSE);
6743 /* if left is rematerialisable and
6744 result is not bit variable type and
6745 the left is pointer to data space i.e
6746 lower 128 bytes of space */
6747 if (AOP_TYPE (left) == AOP_IMMD &&
6748 !IS_BITVAR (retype) &&
6749 DCL_TYPE (ltype) == POINTER)
6751 genDataPointerGet (left, result, ic);
6755 /* if the value is already in a pointer register
6756 then don't need anything more */
6757 if (!AOP_INPREG (AOP (left)))
6759 /* otherwise get a free pointer register */
6761 preg = getFreePtr (ic, &aop, FALSE);
6762 emitcode ("mov", "%s,%s",
6764 aopGet (AOP (left), 0, FALSE, TRUE));
6768 rname = aopGet (AOP (left), 0, FALSE, FALSE);
6770 aopOp (result, ic, FALSE);
6772 /* if bitfield then unpack the bits */
6773 if (IS_BITVAR (retype))
6774 genUnpackBits (result, rname, POINTER);
6777 /* we have can just get the values */
6778 int size = AOP_SIZE (result);
6783 if (IS_AOP_PREG (result) || AOP_TYPE (result) == AOP_STK)
6786 emitcode ("mov", "a,@%s", rname);
6787 aopPut (AOP (result), "a", offset);
6791 sprintf (buffer, "@%s", rname);
6792 aopPut (AOP (result), buffer, offset);
6796 emitcode ("inc", "%s", rname);
6800 /* now some housekeeping stuff */
6801 if (aop) /* we had to allocate for this iCode */
6803 if (pi) { /* post increment present */
6804 aopPut(AOP ( left ),rname,0);
6806 freeAsmop (NULL, aop, ic, TRUE);
6810 /* we did not allocate which means left
6811 already in a pointer register, then
6812 if size > 0 && this could be used again
6813 we have to point it back to where it
6815 if ((AOP_SIZE (result) > 1 &&
6816 !OP_SYMBOL (left)->remat &&
6817 (OP_SYMBOL (left)->liveTo > ic->seq ||
6821 int size = AOP_SIZE (result) - 1;
6823 emitcode ("dec", "%s", rname);
6828 freeAsmop (left, NULL, ic, TRUE);
6829 freeAsmop (result, NULL, ic, TRUE);
6830 if (pi) pi->generated = 1;
6833 /*-----------------------------------------------------------------*/
6834 /* genPagedPointerGet - emitcode for paged pointer fetch */
6835 /*-----------------------------------------------------------------*/
6837 genPagedPointerGet (operand * left,
6845 sym_link *rtype, *retype;
6847 rtype = operandType (result);
6848 retype = getSpec (rtype);
6850 aopOp (left, ic, FALSE);
6852 /* if the value is already in a pointer register
6853 then don't need anything more */
6854 if (!AOP_INPREG (AOP (left)))
6856 /* otherwise get a free pointer register */
6858 preg = getFreePtr (ic, &aop, FALSE);
6859 emitcode ("mov", "%s,%s",
6861 aopGet (AOP (left), 0, FALSE, TRUE));
6865 rname = aopGet (AOP (left), 0, FALSE, FALSE);
6867 aopOp (result, ic, FALSE);
6869 /* if bitfield then unpack the bits */
6870 if (IS_BITVAR (retype))
6871 genUnpackBits (result, rname, PPOINTER);
6874 /* we have can just get the values */
6875 int size = AOP_SIZE (result);
6881 emitcode ("movx", "a,@%s", rname);
6882 aopPut (AOP (result), "a", offset);
6887 emitcode ("inc", "%s", rname);
6891 /* now some housekeeping stuff */
6892 if (aop) /* we had to allocate for this iCode */
6894 if (pi) aopPut ( AOP (left), rname, 0);
6895 freeAsmop (NULL, aop, ic, TRUE);
6899 /* we did not allocate which means left
6900 already in a pointer register, then
6901 if size > 0 && this could be used again
6902 we have to point it back to where it
6904 if ((AOP_SIZE (result) > 1 &&
6905 !OP_SYMBOL (left)->remat &&
6906 (OP_SYMBOL (left)->liveTo > ic->seq ||
6910 int size = AOP_SIZE (result) - 1;
6912 emitcode ("dec", "%s", rname);
6917 freeAsmop (left, NULL, ic, TRUE);
6918 freeAsmop (result, NULL, ic, TRUE);
6919 if (pi) pi->generated = 1;
6923 /*-----------------------------------------------------------------*/
6924 /* genFarPointerGet - gget value from far space */
6925 /*-----------------------------------------------------------------*/
6927 genFarPointerGet (operand * left,
6928 operand * result, iCode * ic, iCode * pi)
6931 sym_link *retype = getSpec (operandType (result));
6933 aopOp (left, ic, FALSE);
6935 /* if the operand is already in dptr
6936 then we do nothing else we move the value to dptr */
6937 if (AOP_TYPE (left) != AOP_STR)
6939 /* if this is remateriazable */
6940 if (AOP_TYPE (left) == AOP_IMMD)
6941 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
6943 { /* we need to get it byte by byte */
6944 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
6945 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
6948 /* so dptr know contains the address */
6949 aopOp (result, ic, FALSE);
6951 /* if bit then unpack */
6952 if (IS_BITVAR (retype))
6953 genUnpackBits (result, "dptr", FPOINTER);
6956 size = AOP_SIZE (result);
6961 emitcode ("movx", "a,@dptr");
6962 aopPut (AOP (result), "a", offset++);
6964 emitcode ("inc", "dptr");
6968 if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
6969 aopPut ( AOP (left), "dpl", 0);
6970 aopPut ( AOP (left), "dph", 1);
6973 freeAsmop (left, NULL, ic, TRUE);
6974 freeAsmop (result, NULL, ic, TRUE);
6977 /*-----------------------------------------------------------------*/
6978 /* genCodePointerGet - gget value from code space */
6979 /*-----------------------------------------------------------------*/
6981 genCodePointerGet (operand * left,
6982 operand * result, iCode * ic, iCode *pi)
6985 sym_link *retype = getSpec (operandType (result));
6987 aopOp (left, ic, FALSE);
6989 /* if the operand is already in dptr
6990 then we do nothing else we move the value to dptr */
6991 if (AOP_TYPE (left) != AOP_STR)
6993 /* if this is remateriazable */
6994 if (AOP_TYPE (left) == AOP_IMMD)
6995 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
6997 { /* we need to get it byte by byte */
6998 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
6999 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
7002 /* so dptr know contains the address */
7003 aopOp (result, ic, FALSE);
7005 /* if bit then unpack */
7006 if (IS_BITVAR (retype))
7007 genUnpackBits (result, "dptr", CPOINTER);
7010 size = AOP_SIZE (result);
7015 emitcode ("clr", "a");
7016 emitcode ("movc", "a,@a+dptr");
7017 aopPut (AOP (result), "a", offset++);
7019 emitcode ("inc", "dptr");
7023 if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
7024 aopPut ( AOP (left), "dpl", 0);
7025 aopPut ( AOP (left), "dph", 1);
7028 freeAsmop (left, NULL, ic, TRUE);
7029 freeAsmop (result, NULL, ic, TRUE);
7032 /*-----------------------------------------------------------------*/
7033 /* genGenPointerGet - gget value from generic pointer space */
7034 /*-----------------------------------------------------------------*/
7036 genGenPointerGet (operand * left,
7037 operand * result, iCode * ic, iCode *pi)
7040 sym_link *retype = getSpec (operandType (result));
7042 aopOp (left, ic, FALSE);
7044 /* if the operand is already in dptr
7045 then we do nothing else we move the value to dptr */
7046 if (AOP_TYPE (left) != AOP_STR)
7048 /* if this is remateriazable */
7049 if (AOP_TYPE (left) == AOP_IMMD)
7051 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
7052 emitcode ("mov", "b,#%d", pointerCode (retype));
7055 { /* we need to get it byte by byte */
7056 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
7057 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
7058 emitcode ("mov", "b,%s", aopGet (AOP (left), 2, FALSE, FALSE));
7061 /* so dptr know contains the address */
7062 aopOp (result, ic, FALSE);
7064 /* if bit then unpack */
7065 if (IS_BITVAR (retype))
7066 genUnpackBits (result, "dptr", GPOINTER);
7069 size = AOP_SIZE (result);
7074 emitcode ("lcall", "__gptrget");
7075 aopPut (AOP (result), "a", offset++);
7077 emitcode ("inc", "dptr");
7081 if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
7082 aopPut ( AOP (left), "dpl", 0);
7083 aopPut ( AOP (left), "dph", 1);
7086 freeAsmop (left, NULL, ic, TRUE);
7087 freeAsmop (result, NULL, ic, TRUE);
7090 /*-----------------------------------------------------------------*/
7091 /* genPointerGet - generate code for pointer get */
7092 /*-----------------------------------------------------------------*/
7094 genPointerGet (iCode * ic, iCode *pi)
7096 operand *left, *result;
7097 sym_link *type, *etype;
7100 left = IC_LEFT (ic);
7101 result = IC_RESULT (ic);
7103 /* depending on the type of pointer we need to
7104 move it to the correct pointer register */
7105 type = operandType (left);
7106 etype = getSpec (type);
7107 /* if left is of type of pointer then it is simple */
7108 if (IS_PTR (type) && !IS_FUNC (type->next))
7109 p_type = DCL_TYPE (type);
7112 /* we have to go by the storage class */
7113 p_type = PTR_TYPE (SPEC_OCLS (etype));
7116 /* now that we have the pointer type we assign
7117 the pointer values */
7123 genNearPointerGet (left, result, ic, pi);
7127 genPagedPointerGet (left, result, ic, pi);
7131 genFarPointerGet (left, result, ic, pi);
7135 genCodePointerGet (left, result, ic, pi);
7139 genGenPointerGet (left, result, ic, pi);
7145 /*-----------------------------------------------------------------*/
7146 /* genPackBits - generates code for packed bit storage */
7147 /*-----------------------------------------------------------------*/
7149 genPackBits (sym_link * etype,
7151 char *rname, int p_type)
7159 blen = SPEC_BLEN (etype);
7160 bstr = SPEC_BSTR (etype);
7162 l = aopGet (AOP (right), offset++, FALSE, FALSE);
7165 /* if the bit lenth is less than or */
7166 /* it exactly fits a byte then */
7167 if (SPEC_BLEN (etype) <= 8)
7169 shCount = SPEC_BSTR (etype);
7171 /* shift left acc */
7174 if (SPEC_BLEN (etype) < 8)
7175 { /* if smaller than a byte */
7181 emitcode ("mov", "b,a");
7182 emitcode ("mov", "a,@%s", rname);
7186 emitcode ("mov", "b,a");
7187 emitcode ("movx", "a,@dptr");
7191 emitcode ("push", "b");
7192 emitcode ("push", "acc");
7193 emitcode ("lcall", "__gptrget");
7194 emitcode ("pop", "b");
7198 emitcode ("anl", "a,#0x%02x", (unsigned char)
7199 ((unsigned char) (0xFF << (blen + bstr)) |
7200 (unsigned char) (0xFF >> (8 - bstr))));
7201 emitcode ("orl", "a,b");
7202 if (p_type == GPOINTER)
7203 emitcode ("pop", "b");
7210 emitcode ("mov", "@%s,a", rname);
7214 emitcode ("movx", "@dptr,a");
7218 emitcode ("lcall", "__gptrput");
7223 if (SPEC_BLEN (etype) <= 8)
7226 emitcode ("inc", "%s", rname);
7227 rLen = SPEC_BLEN (etype);
7229 /* now generate for lengths greater than one byte */
7233 l = aopGet (AOP (right), offset++, FALSE, TRUE);
7245 emitcode ("mov", "@%s,a", rname);
7248 emitcode ("mov", "@%s,%s", rname, l);
7253 emitcode ("movx", "@dptr,a");
7258 emitcode ("lcall", "__gptrput");
7261 emitcode ("inc", "%s", rname);
7266 /* last last was not complete */
7269 /* save the byte & read byte */
7273 emitcode ("mov", "b,a");
7274 emitcode ("mov", "a,@%s", rname);
7278 emitcode ("mov", "b,a");
7279 emitcode ("movx", "a,@dptr");
7283 emitcode ("push", "b");
7284 emitcode ("push", "acc");
7285 emitcode ("lcall", "__gptrget");
7286 emitcode ("pop", "b");
7290 emitcode ("anl", "a,#0x%02x", (((unsigned char) -1 << rLen) & 0xff));
7291 emitcode ("orl", "a,b");
7294 if (p_type == GPOINTER)
7295 emitcode ("pop", "b");
7301 emitcode ("mov", "@%s,a", rname);
7305 emitcode ("movx", "@dptr,a");
7309 emitcode ("lcall", "__gptrput");
7313 /*-----------------------------------------------------------------*/
7314 /* genDataPointerSet - remat pointer to data space */
7315 /*-----------------------------------------------------------------*/
7317 genDataPointerSet (operand * right,
7321 int size, offset = 0;
7322 char *l, buffer[256];
7324 aopOp (right, ic, FALSE);
7326 l = aopGet (AOP (result), 0, FALSE, TRUE);
7327 size = AOP_SIZE (right);
7331 sprintf (buffer, "(%s + %d)", l + 1, offset);
7333 sprintf (buffer, "%s", l + 1);
7334 emitcode ("mov", "%s,%s", buffer,
7335 aopGet (AOP (right), offset++, FALSE, FALSE));
7338 freeAsmop (right, NULL, ic, TRUE);
7339 freeAsmop (result, NULL, ic, TRUE);
7342 /*-----------------------------------------------------------------*/
7343 /* genNearPointerSet - emitcode for near pointer put */
7344 /*-----------------------------------------------------------------*/
7346 genNearPointerSet (operand * right,
7354 sym_link *retype, *letype;
7355 sym_link *ptype = operandType (result);
7357 retype = getSpec (operandType (right));
7358 letype = getSpec (ptype);
7359 aopOp (result, ic, FALSE);
7361 /* if the result is rematerializable &
7362 in data space & not a bit variable */
7363 if (AOP_TYPE (result) == AOP_IMMD &&
7364 DCL_TYPE (ptype) == POINTER &&
7365 !IS_BITVAR (retype) &&
7366 !IS_BITVAR (letype))
7368 genDataPointerSet (right, result, ic);
7372 /* if the value is already in a pointer register
7373 then don't need anything more */
7374 if (!AOP_INPREG (AOP (result)))
7376 /* otherwise get a free pointer register */
7378 preg = getFreePtr (ic, &aop, FALSE);
7379 emitcode ("mov", "%s,%s",
7381 aopGet (AOP (result), 0, FALSE, TRUE));
7385 rname = aopGet (AOP (result), 0, FALSE, FALSE);
7387 aopOp (right, ic, FALSE);
7389 /* if bitfield then unpack the bits */
7390 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7391 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER);
7394 /* we have can just get the values */
7395 int size = AOP_SIZE (right);
7400 l = aopGet (AOP (right), offset, FALSE, TRUE);
7404 emitcode ("mov", "@%s,a", rname);
7407 emitcode ("mov", "@%s,%s", rname, l);
7409 emitcode ("inc", "%s", rname);
7414 /* now some housekeeping stuff */
7415 if (aop) /* we had to allocate for this iCode */
7417 if (pi) aopPut (AOP (result),rname,0);
7418 freeAsmop (NULL, aop, ic, TRUE);
7422 /* we did not allocate which means left
7423 already in a pointer register, then
7424 if size > 0 && this could be used again
7425 we have to point it back to where it
7427 if ((AOP_SIZE (right) > 1 &&
7428 !OP_SYMBOL (result)->remat &&
7429 (OP_SYMBOL (result)->liveTo > ic->seq ||
7433 int size = AOP_SIZE (right) - 1;
7435 emitcode ("dec", "%s", rname);
7440 if (pi) pi->generated = 1;
7441 freeAsmop (result, NULL, ic, TRUE);
7442 freeAsmop (right, NULL, ic, TRUE);
7445 /*-----------------------------------------------------------------*/
7446 /* genPagedPointerSet - emitcode for Paged pointer put */
7447 /*-----------------------------------------------------------------*/
7449 genPagedPointerSet (operand * right,
7457 sym_link *retype, *letype;
7459 retype = getSpec (operandType (right));
7460 letype = getSpec (operandType (result));
7462 aopOp (result, ic, FALSE);
7464 /* if the value is already in a pointer register
7465 then don't need anything more */
7466 if (!AOP_INPREG (AOP (result)))
7468 /* otherwise get a free pointer register */
7470 preg = getFreePtr (ic, &aop, FALSE);
7471 emitcode ("mov", "%s,%s",
7473 aopGet (AOP (result), 0, FALSE, TRUE));
7477 rname = aopGet (AOP (result), 0, FALSE, FALSE);
7479 aopOp (right, ic, FALSE);
7481 /* if bitfield then unpack the bits */
7482 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7483 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, PPOINTER);
7486 /* we have can just get the values */
7487 int size = AOP_SIZE (right);
7492 l = aopGet (AOP (right), offset, FALSE, TRUE);
7495 emitcode ("movx", "@%s,a", rname);
7498 emitcode ("inc", "%s", rname);
7504 /* now some housekeeping stuff */
7505 if (aop) /* we had to allocate for this iCode */
7507 if (pi) aopPut (AOP (result),rname,0);
7508 freeAsmop (NULL, aop, ic, TRUE);
7512 /* we did not allocate which means left
7513 already in a pointer register, then
7514 if size > 0 && this could be used again
7515 we have to point it back to where it
7517 if (AOP_SIZE (right) > 1 &&
7518 !OP_SYMBOL (result)->remat &&
7519 (OP_SYMBOL (result)->liveTo > ic->seq ||
7522 int size = AOP_SIZE (right) - 1;
7524 emitcode ("dec", "%s", rname);
7529 if (pi) pi->generated = 1;
7530 freeAsmop (result, NULL, ic, TRUE);
7531 freeAsmop (right, NULL, ic, TRUE);
7536 /*-----------------------------------------------------------------*/
7537 /* genFarPointerSet - set value from far space */
7538 /*-----------------------------------------------------------------*/
7540 genFarPointerSet (operand * right,
7541 operand * result, iCode * ic, iCode * pi)
7544 sym_link *retype = getSpec (operandType (right));
7545 sym_link *letype = getSpec (operandType (result));
7546 aopOp (result, ic, FALSE);
7548 /* if the operand is already in dptr
7549 then we do nothing else we move the value to dptr */
7550 if (AOP_TYPE (result) != AOP_STR)
7552 /* if this is remateriazable */
7553 if (AOP_TYPE (result) == AOP_IMMD)
7554 emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
7556 { /* we need to get it byte by byte */
7557 emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
7558 emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
7561 /* so dptr know contains the address */
7562 aopOp (right, ic, FALSE);
7564 /* if bit then unpack */
7565 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7566 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
7569 size = AOP_SIZE (right);
7574 char *l = aopGet (AOP (right), offset++, FALSE, FALSE);
7576 emitcode ("movx", "@dptr,a");
7578 emitcode ("inc", "dptr");
7581 if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
7582 aopPut (AOP(result),"dpl",0);
7583 aopPut (AOP(result),"dph",1);
7586 freeAsmop (result, NULL, ic, TRUE);
7587 freeAsmop (right, NULL, ic, TRUE);
7590 /*-----------------------------------------------------------------*/
7591 /* genGenPointerSet - set value from generic pointer space */
7592 /*-----------------------------------------------------------------*/
7594 genGenPointerSet (operand * right,
7595 operand * result, iCode * ic, iCode * pi)
7598 sym_link *retype = getSpec (operandType (right));
7599 sym_link *letype = getSpec (operandType (result));
7601 aopOp (result, ic, FALSE);
7603 /* if the operand is already in dptr
7604 then we do nothing else we move the value to dptr */
7605 if (AOP_TYPE (result) != AOP_STR)
7607 /* if this is remateriazable */
7608 if (AOP_TYPE (result) == AOP_IMMD)
7610 emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
7611 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
7614 { /* we need to get it byte by byte */
7615 emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
7616 emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
7617 emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE));
7620 /* so dptr know contains the address */
7621 aopOp (right, ic, FALSE);
7623 /* if bit then unpack */
7624 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7625 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", GPOINTER);
7628 size = AOP_SIZE (right);
7633 char *l = aopGet (AOP (right), offset++, FALSE, FALSE);
7635 emitcode ("lcall", "__gptrput");
7637 emitcode ("inc", "dptr");
7641 if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
7642 aopPut (AOP(result),"dpl",0);
7643 aopPut (AOP(result),"dph",1);
7646 freeAsmop (result, NULL, ic, TRUE);
7647 freeAsmop (right, NULL, ic, TRUE);
7650 /*-----------------------------------------------------------------*/
7651 /* genPointerSet - stores the value into a pointer location */
7652 /*-----------------------------------------------------------------*/
7654 genPointerSet (iCode * ic, iCode *pi)
7656 operand *right, *result;
7657 sym_link *type, *etype;
7660 right = IC_RIGHT (ic);
7661 result = IC_RESULT (ic);
7663 /* depending on the type of pointer we need to
7664 move it to the correct pointer register */
7665 type = operandType (result);
7666 etype = getSpec (type);
7667 /* if left is of type of pointer then it is simple */
7668 if (IS_PTR (type) && !IS_FUNC (type->next))
7670 p_type = DCL_TYPE (type);
7674 /* we have to go by the storage class */
7675 p_type = PTR_TYPE (SPEC_OCLS (etype));
7678 /* now that we have the pointer type we assign
7679 the pointer values */
7685 genNearPointerSet (right, result, ic, pi);
7689 genPagedPointerSet (right, result, ic, pi);
7693 genFarPointerSet (right, result, ic, pi);
7697 genGenPointerSet (right, result, ic, pi);
7703 /*-----------------------------------------------------------------*/
7704 /* genIfx - generate code for Ifx statement */
7705 /*-----------------------------------------------------------------*/
7707 genIfx (iCode * ic, iCode * popIc)
7709 operand *cond = IC_COND (ic);
7712 aopOp (cond, ic, FALSE);
7714 /* get the value into acc */
7715 if (AOP_TYPE (cond) != AOP_CRY)
7719 /* the result is now in the accumulator */
7720 freeAsmop (cond, NULL, ic, TRUE);
7722 /* if there was something to be popped then do it */
7726 /* if the condition is a bit variable */
7727 if (isbit && IS_ITEMP (cond) &&
7729 genIfxJump (ic, SPIL_LOC (cond)->rname);
7730 else if (isbit && !IS_ITEMP (cond))
7731 genIfxJump (ic, OP_SYMBOL (cond)->rname);
7733 genIfxJump (ic, "a");
7738 /*-----------------------------------------------------------------*/
7739 /* genAddrOf - generates code for address of */
7740 /*-----------------------------------------------------------------*/
7742 genAddrOf (iCode * ic)
7744 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
7747 aopOp (IC_RESULT (ic), ic, FALSE);
7749 /* if the operand is on the stack then we
7750 need to get the stack offset of this
7754 /* if it has an offset then we need to compute
7758 emitcode ("mov", "a,_bp");
7759 emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
7760 aopPut (AOP (IC_RESULT (ic)), "a", 0);
7764 /* we can just move _bp */
7765 aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
7767 /* fill the result with zero */
7768 size = AOP_SIZE (IC_RESULT (ic)) - 1;
7773 aopPut (AOP (IC_RESULT (ic)), zero, offset++);
7779 /* object not on stack then we need the name */
7780 size = AOP_SIZE (IC_RESULT (ic));
7785 char s[SDCC_NAME_MAX];
7787 sprintf (s, "#(%s >> %d)",
7791 sprintf (s, "#%s", sym->rname);
7792 aopPut (AOP (IC_RESULT (ic)), s, offset++);
7796 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
7800 /*-----------------------------------------------------------------*/
7801 /* genFarFarAssign - assignment when both are in far space */
7802 /*-----------------------------------------------------------------*/
7804 genFarFarAssign (operand * result, operand * right, iCode * ic)
7806 int size = AOP_SIZE (right);
7809 /* first push the right side on to the stack */
7812 l = aopGet (AOP (right), offset++, FALSE, FALSE);
7814 emitcode ("push", "acc");
7817 freeAsmop (right, NULL, ic, FALSE);
7818 /* now assign DPTR to result */
7819 aopOp (result, ic, FALSE);
7820 size = AOP_SIZE (result);
7823 emitcode ("pop", "acc");
7824 aopPut (AOP (result), "a", --offset);
7826 freeAsmop (result, NULL, ic, FALSE);
7830 /*-----------------------------------------------------------------*/
7831 /* genAssign - generate code for assignment */
7832 /*-----------------------------------------------------------------*/
7834 genAssign (iCode * ic)
7836 operand *result, *right;
7838 unsigned long lit = 0L;
7840 result = IC_RESULT (ic);
7841 right = IC_RIGHT (ic);
7843 /* if they are the same */
7844 if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
7847 aopOp (right, ic, FALSE);
7849 /* special case both in far space */
7850 if ((AOP_TYPE (right) == AOP_DPTR ||
7851 AOP_TYPE (right) == AOP_DPTR2) &&
7852 IS_TRUE_SYMOP (result) &&
7853 isOperandInFarSpace (result))
7856 genFarFarAssign (result, right, ic);
7860 aopOp (result, ic, TRUE);
7862 /* if they are the same registers */
7863 if (sameRegs (AOP (right), AOP (result)))
7866 /* if the result is a bit */
7867 if (AOP_TYPE (result) == AOP_CRY)
7870 /* if the right size is a literal then
7871 we know what the value is */
7872 if (AOP_TYPE (right) == AOP_LIT)
7874 if (((int) operandLitValue (right)))
7875 aopPut (AOP (result), one, 0);
7877 aopPut (AOP (result), zero, 0);
7881 /* the right is also a bit variable */
7882 if (AOP_TYPE (right) == AOP_CRY)
7884 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
7885 aopPut (AOP (result), "c", 0);
7891 aopPut (AOP (result), "a", 0);
7895 /* bit variables done */
7897 size = AOP_SIZE (result);
7899 if (AOP_TYPE (right) == AOP_LIT)
7900 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
7902 (AOP_TYPE (result) != AOP_REG) &&
7903 (AOP_TYPE (right) == AOP_LIT) &&
7904 !IS_FLOAT (operandType (right)) &&
7907 emitcode ("clr", "a");
7910 if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) == 0)
7911 aopPut (AOP (result), "a", size);
7913 aopPut (AOP (result),
7914 aopGet (AOP (right), size, FALSE, FALSE),
7922 aopPut (AOP (result),
7923 aopGet (AOP (right), offset, FALSE, FALSE),
7930 freeAsmop (right, NULL, ic, TRUE);
7931 freeAsmop (result, NULL, ic, TRUE);
7934 /*-----------------------------------------------------------------*/
7935 /* genJumpTab - genrates code for jump table */
7936 /*-----------------------------------------------------------------*/
7938 genJumpTab (iCode * ic)
7943 aopOp (IC_JTCOND (ic), ic, FALSE);
7944 /* get the condition into accumulator */
7945 l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
7947 /* multiply by three */
7948 emitcode ("add", "a,acc");
7949 emitcode ("add", "a,%s", aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE));
7950 freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
7952 jtab = newiTempLabel (NULL);
7953 emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
7954 emitcode ("jmp", "@a+dptr");
7955 emitcode ("", "%05d$:", jtab->key + 100);
7956 /* now generate the jump labels */
7957 for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
7958 jtab = setNextItem (IC_JTLABELS (ic)))
7959 emitcode ("ljmp", "%05d$", jtab->key + 100);
7963 /*-----------------------------------------------------------------*/
7964 /* genCast - gen code for casting */
7965 /*-----------------------------------------------------------------*/
7967 genCast (iCode * ic)
7969 operand *result = IC_RESULT (ic);
7970 sym_link *ctype = operandType (IC_LEFT (ic));
7971 sym_link *rtype = operandType (IC_RIGHT (ic));
7972 operand *right = IC_RIGHT (ic);
7975 /* if they are equivalent then do nothing */
7976 if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
7979 aopOp (right, ic, FALSE);
7980 aopOp (result, ic, FALSE);
7982 /* if the result is a bit */
7983 if (AOP_TYPE (result) == AOP_CRY)
7985 /* if the right size is a literal then
7986 we know what the value is */
7987 if (AOP_TYPE (right) == AOP_LIT)
7989 if (((int) operandLitValue (right)))
7990 aopPut (AOP (result), one, 0);
7992 aopPut (AOP (result), zero, 0);
7997 /* the right is also a bit variable */
7998 if (AOP_TYPE (right) == AOP_CRY)
8000 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
8001 aopPut (AOP (result), "c", 0);
8007 aopPut (AOP (result), "a", 0);
8011 /* if they are the same size : or less */
8012 if (AOP_SIZE (result) <= AOP_SIZE (right))
8015 /* if they are in the same place */
8016 if (sameRegs (AOP (right), AOP (result)))
8019 /* if they in different places then copy */
8020 size = AOP_SIZE (result);
8024 aopPut (AOP (result),
8025 aopGet (AOP (right), offset, FALSE, FALSE),
8033 /* if the result is of type pointer */
8038 sym_link *type = operandType (right);
8039 sym_link *etype = getSpec (type);
8041 /* pointer to generic pointer */
8042 if (IS_GENPTR (ctype))
8047 p_type = DCL_TYPE (type);
8050 /* we have to go by the storage class */
8051 p_type = PTR_TYPE (SPEC_OCLS (etype));
8054 /* the first two bytes are known */
8055 size = GPTRSIZE - 1;
8059 aopPut (AOP (result),
8060 aopGet (AOP (right), offset, FALSE, FALSE),
8064 /* the last byte depending on type */
8082 /* this should never happen */
8083 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8084 "got unknown pointer type");
8087 aopPut (AOP (result), l, GPTRSIZE - 1);
8091 /* just copy the pointers */
8092 size = AOP_SIZE (result);
8096 aopPut (AOP (result),
8097 aopGet (AOP (right), offset, FALSE, FALSE),
8104 /* so we now know that the size of destination is greater
8105 than the size of the source */
8106 /* we move to result for the size of source */
8107 size = AOP_SIZE (right);
8111 aopPut (AOP (result),
8112 aopGet (AOP (right), offset, FALSE, FALSE),
8117 /* now depending on the sign of the source && destination */
8118 size = AOP_SIZE (result) - AOP_SIZE (right);
8119 /* if unsigned or not an integral type */
8120 if (SPEC_USIGN (rtype) || !IS_SPEC (rtype))
8123 aopPut (AOP (result), zero, offset++);
8127 /* we need to extend the sign :{ */
8128 char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
8131 emitcode ("rlc", "a");
8132 emitcode ("subb", "a,acc");
8134 aopPut (AOP (result), "a", offset++);
8137 /* we are done hurray !!!! */
8140 freeAsmop (right, NULL, ic, TRUE);
8141 freeAsmop (result, NULL, ic, TRUE);
8145 /*-----------------------------------------------------------------*/
8146 /* genDjnz - generate decrement & jump if not zero instrucion */
8147 /*-----------------------------------------------------------------*/
8149 genDjnz (iCode * ic, iCode * ifx)
8155 /* if the if condition has a false label
8156 then we cannot save */
8160 /* if the minus is not of the form
8162 if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
8163 !IS_OP_LITERAL (IC_RIGHT (ic)))
8166 if (operandLitValue (IC_RIGHT (ic)) != 1)
8169 /* if the size of this greater than one then no
8171 if (getSize (operandType (IC_RESULT (ic))) > 1)
8174 /* otherwise we can save BIG */
8175 lbl = newiTempLabel (NULL);
8176 lbl1 = newiTempLabel (NULL);
8178 aopOp (IC_RESULT (ic), ic, FALSE);
8180 if (IS_AOP_PREG (IC_RESULT (ic)))
8182 emitcode ("dec", "%s",
8183 aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
8184 emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
8185 emitcode ("jnz", "%05d$", lbl->key + 100);
8189 emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE),
8192 emitcode ("sjmp", "%05d$", lbl1->key + 100);
8193 emitcode ("", "%05d$:", lbl->key + 100);
8194 emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
8195 emitcode ("", "%05d$:", lbl1->key + 100);
8197 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
8202 /*-----------------------------------------------------------------*/
8203 /* genReceive - generate code for a receive iCode */
8204 /*-----------------------------------------------------------------*/
8206 genReceive (iCode * ic)
8208 if (isOperandInFarSpace (IC_RESULT (ic)) &&
8209 (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
8210 IS_TRUE_SYMOP (IC_RESULT (ic))))
8213 int size = getSize (operandType (IC_RESULT (ic)));
8214 int offset = fReturnSizeMCS51 - size;
8217 emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ?
8218 fReturn[fReturnSizeMCS51 - offset - 1] : "acc"));
8221 aopOp (IC_RESULT (ic), ic, FALSE);
8222 size = AOP_SIZE (IC_RESULT (ic));
8226 emitcode ("pop", "acc");
8227 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
8234 aopOp (IC_RESULT (ic), ic, FALSE);
8236 assignResultValue (IC_RESULT (ic));
8239 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
8242 /*-----------------------------------------------------------------*/
8243 /* gen51Code - generate code for 8051 based controllers */
8244 /*-----------------------------------------------------------------*/
8246 gen51Code (iCode * lic)
8251 lineHead = lineCurr = NULL;
8253 /* print the allocation information */
8255 printAllocInfo (currFunc, codeOutFile);
8256 /* if debug information required */
8257 /* if (options.debug && currFunc) { */
8260 cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
8262 if (IS_STATIC (currFunc->etype))
8263 emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
8265 emitcode ("", "G$%s$0$0 ==.", currFunc->name);
8268 /* stack pointer name */
8269 if (options.useXstack)
8275 for (ic = lic; ic; ic = ic->next)
8278 if (cln != ic->lineno)
8283 emitcode ("", "C$%s$%d$%d$%d ==.",
8284 FileBaseName (ic->filename), ic->lineno,
8285 ic->level, ic->block);
8288 emitcode (";", "%s %d", ic->filename, ic->lineno);
8291 /* if the result is marked as
8292 spilt and rematerializable or code for
8293 this has already been generated then
8295 if (resultRemat (ic) || ic->generated)
8298 /* depending on the operation */
8318 /* IPOP happens only when trying to restore a
8319 spilt live range, if there is an ifx statement
8320 following this pop then the if statement might
8321 be using some of the registers being popped which
8322 would destory the contents of the register so
8323 we need to check for this condition and handle it */
8325 ic->next->op == IFX &&
8326 regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
8327 genIfx (ic->next, ic);
8345 genEndFunction (ic);
8365 if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
8382 genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
8386 genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
8393 /* note these two are xlated by algebraic equivalence
8394 during parsing SDCC.y */
8395 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8396 "got '>=' or '<=' shouldn't have come here");
8400 genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
8412 genXor (ic, ifxForOp (IC_RESULT (ic), ic));
8416 genOr (ic, ifxForOp (IC_RESULT (ic), ic));
8420 genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
8447 case GET_VALUE_AT_ADDRESS:
8448 genPointerGet (ic, hasInc(IC_LEFT(ic),ic));
8452 if (POINTER_SET (ic))
8453 genPointerSet (ic, hasInc (IC_RESULT(ic),ic));
8479 addSet (&_G.sendSet, ic);
8488 /* now we are ready to call the
8489 peep hole optimizer */
8490 if (!options.nopeep)
8491 peepHole (&lineHead);
8493 /* now do the actual printing */
8494 printLine (lineHead, codeOutFile);