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)
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 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
3713 /* if the result is used in the next
3714 ifx conditional branch then generate
3715 code a little differently */
3717 genIfxJump (ifx, "c");
3720 /* leave the result in acc */
3724 /*-----------------------------------------------------------------*/
3725 /* genCmpGt :- greater than comparison */
3726 /*-----------------------------------------------------------------*/
3728 genCmpGt (iCode * ic, iCode * ifx)
3730 operand *left, *right, *result;
3731 sym_link *letype, *retype;
3734 left = IC_LEFT (ic);
3735 right = IC_RIGHT (ic);
3736 result = IC_RESULT (ic);
3738 letype = getSpec (operandType (left));
3739 retype = getSpec (operandType (right));
3740 sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
3741 /* assign the amsops */
3742 aopOp (left, ic, FALSE);
3743 aopOp (right, ic, FALSE);
3744 aopOp (result, ic, TRUE);
3746 genCmp (right, left, result, ifx, sign);
3748 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3749 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
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);
3778 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3779 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
3780 freeAsmop (result, NULL, ic, TRUE);
3783 /*-----------------------------------------------------------------*/
3784 /* gencjneshort - compare and jump if not equal */
3785 /*-----------------------------------------------------------------*/
3787 gencjneshort (operand * left, operand * right, symbol * lbl)
3789 int size = max (AOP_SIZE (left), AOP_SIZE (right));
3791 unsigned long lit = 0L;
3793 /* if the left side is a literal or
3794 if the right is in a pointer register and left
3796 if ((AOP_TYPE (left) == AOP_LIT) ||
3797 (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
3803 if (AOP_TYPE (right) == AOP_LIT)
3804 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
3806 /* if the right side is a literal then anything goes */
3807 if (AOP_TYPE (right) == AOP_LIT &&
3808 AOP_TYPE (left) != AOP_DIR)
3812 emitcode ("cjne", "%s,%s,%05d$",
3813 aopGet (AOP (left), offset, FALSE, FALSE),
3814 aopGet (AOP (right), offset, FALSE, FALSE),
3820 /* if the right side is in a register or in direct space or
3821 if the left is a pointer register & right is not */
3822 else if (AOP_TYPE (right) == AOP_REG ||
3823 AOP_TYPE (right) == AOP_DIR ||
3824 (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) ||
3825 (IS_AOP_PREG (left) && !IS_AOP_PREG (right)))
3829 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
3830 if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
3831 ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
3832 emitcode ("jnz", "%05d$", lbl->key + 100);
3834 emitcode ("cjne", "a,%s,%05d$",
3835 aopGet (AOP (right), offset, FALSE, TRUE),
3842 /* right is a pointer reg need both a & b */
3845 char *l = aopGet (AOP (left), offset, FALSE, FALSE);
3846 if (strcmp (l, "b"))
3847 emitcode ("mov", "b,%s", l);
3848 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
3849 emitcode ("cjne", "a,b,%05d$", lbl->key + 100);
3855 /*-----------------------------------------------------------------*/
3856 /* gencjne - compare and jump if not equal */
3857 /*-----------------------------------------------------------------*/
3859 gencjne (operand * left, operand * right, symbol * lbl)
3861 symbol *tlbl = newiTempLabel (NULL);
3863 gencjneshort (left, right, lbl);
3865 emitcode ("mov", "a,%s", one);
3866 emitcode ("sjmp", "%05d$", tlbl->key + 100);
3867 emitcode ("", "%05d$:", lbl->key + 100);
3868 emitcode ("clr", "a");
3869 emitcode ("", "%05d$:", tlbl->key + 100);
3872 /*-----------------------------------------------------------------*/
3873 /* genCmpEq - generates code for equal to */
3874 /*-----------------------------------------------------------------*/
3876 genCmpEq (iCode * ic, iCode * ifx)
3878 operand *left, *right, *result;
3880 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
3881 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
3882 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
3884 /* if literal, literal on the right or
3885 if the right is in a pointer register and left
3887 if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
3888 (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
3890 operand *t = IC_RIGHT (ic);
3891 IC_RIGHT (ic) = IC_LEFT (ic);
3895 if (ifx && !AOP_SIZE (result))
3898 /* if they are both bit variables */
3899 if (AOP_TYPE (left) == AOP_CRY &&
3900 ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
3902 if (AOP_TYPE (right) == AOP_LIT)
3904 unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3907 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3908 emitcode ("cpl", "c");
3912 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3916 emitcode ("clr", "c");
3918 /* AOP_TYPE(right) == AOP_CRY */
3922 symbol *lbl = newiTempLabel (NULL);
3923 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3924 emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
3925 emitcode ("cpl", "c");
3926 emitcode ("", "%05d$:", (lbl->key + 100));
3928 /* if true label then we jump if condition
3930 tlbl = newiTempLabel (NULL);
3933 emitcode ("jnc", "%05d$", tlbl->key + 100);
3934 emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
3938 emitcode ("jc", "%05d$", tlbl->key + 100);
3939 emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
3941 emitcode ("", "%05d$:", tlbl->key + 100);
3945 tlbl = newiTempLabel (NULL);
3946 gencjneshort (left, right, tlbl);
3949 emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
3950 emitcode ("", "%05d$:", tlbl->key + 100);
3954 symbol *lbl = newiTempLabel (NULL);
3955 emitcode ("sjmp", "%05d$", lbl->key + 100);
3956 emitcode ("", "%05d$:", tlbl->key + 100);
3957 emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
3958 emitcode ("", "%05d$:", lbl->key + 100);
3961 /* mark the icode as generated */
3966 /* if they are both bit variables */
3967 if (AOP_TYPE (left) == AOP_CRY &&
3968 ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
3970 if (AOP_TYPE (right) == AOP_LIT)
3972 unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
3975 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3976 emitcode ("cpl", "c");
3980 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3984 emitcode ("clr", "c");
3986 /* AOP_TYPE(right) == AOP_CRY */
3990 symbol *lbl = newiTempLabel (NULL);
3991 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
3992 emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
3993 emitcode ("cpl", "c");
3994 emitcode ("", "%05d$:", (lbl->key + 100));
3997 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4004 genIfxJump (ifx, "c");
4007 /* if the result is used in an arithmetic operation
4008 then put the result in place */
4013 gencjne (left, right, newiTempLabel (NULL));
4014 if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
4016 aopPut (AOP (result), "a", 0);
4021 genIfxJump (ifx, "a");
4024 /* if the result is used in an arithmetic operation
4025 then put the result in place */
4026 if (AOP_TYPE (result) != AOP_CRY)
4028 /* leave the result in acc */
4032 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4033 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4034 freeAsmop (result, NULL, ic, TRUE);
4037 /*-----------------------------------------------------------------*/
4038 /* ifxForOp - returns the icode containing the ifx for operand */
4039 /*-----------------------------------------------------------------*/
4041 ifxForOp (operand * op, iCode * ic)
4043 /* if true symbol then needs to be assigned */
4044 if (IS_TRUE_SYMOP (op))
4047 /* if this has register type condition and
4048 the next instruction is ifx with the same operand
4049 and live to of the operand is upto the ifx only then */
4051 ic->next->op == IFX &&
4052 IC_COND (ic->next)->key == op->key &&
4053 OP_SYMBOL (op)->liveTo <= ic->next->seq)
4059 /*-----------------------------------------------------------------*/
4060 /* hasInc - operand is incremented before any other use */
4061 /*-----------------------------------------------------------------*/
4063 hasInc (operand *op, iCode *ic)
4065 sym_link *type = operandType(op);
4066 sym_link *retype = getSpec (type);
4067 iCode *lic = ic->next;
4070 if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
4071 isize = getSize(type->next);
4073 /* if operand of the form op = op + <sizeof *op> */
4074 if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
4075 isOperandEqual(IC_RESULT(lic),op) &&
4076 isOperandLiteral(IC_RIGHT(lic)) &&
4077 operandLitValue(IC_RIGHT(lic)) == isize) {
4080 /* if the operand used or deffed */
4081 if (bitVectBitValue(ic->uses,op->key) || (unsigned) ic->defKey == op->key) {
4089 /*-----------------------------------------------------------------*/
4090 /* genAndOp - for && operation */
4091 /*-----------------------------------------------------------------*/
4093 genAndOp (iCode * ic)
4095 operand *left, *right, *result;
4098 /* note here that && operations that are in an
4099 if statement are taken away by backPatchLabels
4100 only those used in arthmetic operations remain */
4101 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4102 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4103 aopOp ((result = IC_RESULT (ic)), ic, FALSE);
4105 /* if both are bit variables */
4106 if (AOP_TYPE (left) == AOP_CRY &&
4107 AOP_TYPE (right) == AOP_CRY)
4109 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4110 emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
4115 tlbl = newiTempLabel (NULL);
4117 emitcode ("jz", "%05d$", tlbl->key + 100);
4119 emitcode ("", "%05d$:", tlbl->key + 100);
4123 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4124 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4125 freeAsmop (result, NULL, ic, TRUE);
4129 /*-----------------------------------------------------------------*/
4130 /* genOrOp - for || operation */
4131 /*-----------------------------------------------------------------*/
4133 genOrOp (iCode * ic)
4135 operand *left, *right, *result;
4138 /* note here that || operations that are in an
4139 if statement are taken away by backPatchLabels
4140 only those used in arthmetic operations remain */
4141 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4142 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4143 aopOp ((result = IC_RESULT (ic)), ic, FALSE);
4145 /* if both are bit variables */
4146 if (AOP_TYPE (left) == AOP_CRY &&
4147 AOP_TYPE (right) == AOP_CRY)
4149 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4150 emitcode ("orl", "c,%s", AOP (right)->aopu.aop_dir);
4155 tlbl = newiTempLabel (NULL);
4157 emitcode ("jnz", "%05d$", tlbl->key + 100);
4159 emitcode ("", "%05d$:", tlbl->key + 100);
4163 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4164 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4165 freeAsmop (result, NULL, ic, TRUE);
4168 /*-----------------------------------------------------------------*/
4169 /* isLiteralBit - test if lit == 2^n */
4170 /*-----------------------------------------------------------------*/
4172 isLiteralBit (unsigned long lit)
4174 unsigned long pw[32] =
4175 {1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
4176 0x100L, 0x200L, 0x400L, 0x800L,
4177 0x1000L, 0x2000L, 0x4000L, 0x8000L,
4178 0x10000L, 0x20000L, 0x40000L, 0x80000L,
4179 0x100000L, 0x200000L, 0x400000L, 0x800000L,
4180 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
4181 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L};
4184 for (idx = 0; idx < 32; idx++)
4190 /*-----------------------------------------------------------------*/
4191 /* continueIfTrue - */
4192 /*-----------------------------------------------------------------*/
4194 continueIfTrue (iCode * ic)
4197 emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
4201 /*-----------------------------------------------------------------*/
4203 /*-----------------------------------------------------------------*/
4205 jumpIfTrue (iCode * ic)
4208 emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
4212 /*-----------------------------------------------------------------*/
4213 /* jmpTrueOrFalse - */
4214 /*-----------------------------------------------------------------*/
4216 jmpTrueOrFalse (iCode * ic, symbol * tlbl)
4218 // ugly but optimized by peephole
4221 symbol *nlbl = newiTempLabel (NULL);
4222 emitcode ("sjmp", "%05d$", nlbl->key + 100);
4223 emitcode ("", "%05d$:", tlbl->key + 100);
4224 emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
4225 emitcode ("", "%05d$:", nlbl->key + 100);
4229 emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
4230 emitcode ("", "%05d$:", tlbl->key + 100);
4235 /*-----------------------------------------------------------------*/
4236 /* genAnd - code for and */
4237 /*-----------------------------------------------------------------*/
4239 genAnd (iCode * ic, iCode * ifx)
4241 operand *left, *right, *result;
4242 int size, offset = 0;
4243 unsigned long lit = 0L;
4247 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4248 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4249 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4252 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
4254 AOP_TYPE (left), AOP_TYPE (right));
4255 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
4257 AOP_SIZE (left), AOP_SIZE (right));
4260 /* if left is a literal & right is not then exchange them */
4261 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
4262 AOP_NEEDSACC (left))
4264 operand *tmp = right;
4269 /* if result = right then exchange them */
4270 if (sameRegs (AOP (result), AOP (right)))
4272 operand *tmp = right;
4277 /* if right is bit then exchange them */
4278 if (AOP_TYPE (right) == AOP_CRY &&
4279 AOP_TYPE (left) != AOP_CRY)
4281 operand *tmp = right;
4285 if (AOP_TYPE (right) == AOP_LIT)
4286 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4288 size = AOP_SIZE (result);
4291 // result = bit & yy;
4292 if (AOP_TYPE (left) == AOP_CRY)
4294 // c = bit & literal;
4295 if (AOP_TYPE (right) == AOP_LIT)
4299 if (size && sameRegs (AOP (result), AOP (left)))
4302 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4307 if (size && (AOP_TYPE (result) == AOP_CRY))
4309 emitcode ("clr", "%s", AOP (result)->aopu.aop_dir);
4312 if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4317 emitcode ("clr", "c");
4322 if (AOP_TYPE (right) == AOP_CRY)
4325 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4326 emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
4331 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
4333 emitcode ("rrc", "a");
4334 emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
4342 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4343 genIfxJump (ifx, "c");
4347 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4348 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4349 if ((AOP_TYPE (right) == AOP_LIT) &&
4350 (AOP_TYPE (result) == AOP_CRY) &&
4351 (AOP_TYPE (left) != AOP_CRY))
4353 int posbit = isLiteralBit (lit);
4358 MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE));
4361 emitcode ("mov", "c,acc.%d", posbit & 0x07);
4367 sprintf (buffer, "acc.%d", posbit & 0x07);
4368 genIfxJump (ifx, buffer);
4375 symbol *tlbl = newiTempLabel (NULL);
4376 int sizel = AOP_SIZE (left);
4378 emitcode ("setb", "c");
4381 if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
4383 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
4385 if ((posbit = isLiteralBit (bytelit)) != 0)
4386 emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
4389 if (bytelit != 0x0FFL)
4390 emitcode ("anl", "a,%s",
4391 aopGet (AOP (right), offset, FALSE, TRUE));
4392 emitcode ("jnz", "%05d$", tlbl->key + 100);
4397 // bit = left & literal
4400 emitcode ("clr", "c");
4401 emitcode ("", "%05d$:", tlbl->key + 100);
4403 // if(left & literal)
4407 jmpTrueOrFalse (ifx, tlbl);
4415 /* if left is same as result */
4416 if (sameRegs (AOP (result), AOP (left)))
4418 for (; size--; offset++)
4420 if (AOP_TYPE (right) == AOP_LIT)
4422 if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
4424 else if (bytelit == 0)
4425 aopPut (AOP (result), zero, offset);
4426 else if (IS_AOP_PREG (result))
4428 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4429 emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4430 aopPut (AOP (result), "a", offset);
4433 emitcode ("anl", "%s,%s",
4434 aopGet (AOP (left), offset, FALSE, TRUE),
4435 aopGet (AOP (right), offset, FALSE, FALSE));
4439 if (AOP_TYPE (left) == AOP_ACC)
4440 emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4443 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4444 if (IS_AOP_PREG (result))
4446 emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4447 aopPut (AOP (result), "a", offset);
4451 emitcode ("anl", "%s,a",
4452 aopGet (AOP (left), offset, FALSE, TRUE));
4459 // left & result in different registers
4460 if (AOP_TYPE (result) == AOP_CRY)
4463 // if(size), result in bit
4464 // if(!size && ifx), conditional oper: if(left & right)
4465 symbol *tlbl = newiTempLabel (NULL);
4466 int sizer = min (AOP_SIZE (left), AOP_SIZE (right));
4468 emitcode ("setb", "c");
4471 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4472 emitcode ("anl", "a,%s",
4473 aopGet (AOP (left), offset, FALSE, FALSE));
4474 emitcode ("jnz", "%05d$", tlbl->key + 100);
4480 emitcode ("", "%05d$:", tlbl->key + 100);
4484 jmpTrueOrFalse (ifx, tlbl);
4488 for (; (size--); offset++)
4491 // result = left & right
4492 if (AOP_TYPE (right) == AOP_LIT)
4494 if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
4496 aopPut (AOP (result),
4497 aopGet (AOP (left), offset, FALSE, FALSE),
4501 else if (bytelit == 0)
4503 aopPut (AOP (result), zero, offset);
4507 // faster than result <- left, anl result,right
4508 // and better if result is SFR
4509 if (AOP_TYPE (left) == AOP_ACC)
4510 emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4513 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4514 emitcode ("anl", "a,%s",
4515 aopGet (AOP (left), offset, FALSE, FALSE));
4517 aopPut (AOP (result), "a", offset);
4523 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4524 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4525 freeAsmop (result, NULL, ic, TRUE);
4528 /*-----------------------------------------------------------------*/
4529 /* genOr - code for or */
4530 /*-----------------------------------------------------------------*/
4532 genOr (iCode * ic, iCode * ifx)
4534 operand *left, *right, *result;
4535 int size, offset = 0;
4536 unsigned long lit = 0L;
4538 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4539 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4540 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4543 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
4545 AOP_TYPE (left), AOP_TYPE (right));
4546 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
4548 AOP_SIZE (left), AOP_SIZE (right));
4551 /* if left is a literal & right is not then exchange them */
4552 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
4553 AOP_NEEDSACC (left))
4555 operand *tmp = right;
4560 /* if result = right then exchange them */
4561 if (sameRegs (AOP (result), AOP (right)))
4563 operand *tmp = right;
4568 /* if right is bit then exchange them */
4569 if (AOP_TYPE (right) == AOP_CRY &&
4570 AOP_TYPE (left) != AOP_CRY)
4572 operand *tmp = right;
4576 if (AOP_TYPE (right) == AOP_LIT)
4577 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4579 size = AOP_SIZE (result);
4583 if (AOP_TYPE (left) == AOP_CRY)
4585 if (AOP_TYPE (right) == AOP_LIT)
4587 // c = bit & literal;
4590 // lit != 0 => result = 1
4591 if (AOP_TYPE (result) == AOP_CRY)
4594 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
4596 continueIfTrue (ifx);
4599 emitcode ("setb", "c");
4603 // lit == 0 => result = left
4604 if (size && sameRegs (AOP (result), AOP (left)))
4606 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4611 if (AOP_TYPE (right) == AOP_CRY)
4614 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4615 emitcode ("orl", "c,%s", AOP (left)->aopu.aop_dir);
4620 symbol *tlbl = newiTempLabel (NULL);
4621 if (!((AOP_TYPE (result) == AOP_CRY) && ifx))
4622 emitcode ("setb", "c");
4623 emitcode ("jb", "%s,%05d$",
4624 AOP (left)->aopu.aop_dir, tlbl->key + 100);
4626 emitcode ("jnz", "%05d$", tlbl->key + 100);
4627 if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4629 jmpTrueOrFalse (ifx, tlbl);
4635 emitcode ("", "%05d$:", tlbl->key + 100);
4644 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4645 genIfxJump (ifx, "c");
4649 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4650 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4651 if ((AOP_TYPE (right) == AOP_LIT) &&
4652 (AOP_TYPE (result) == AOP_CRY) &&
4653 (AOP_TYPE (left) != AOP_CRY))
4659 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
4661 continueIfTrue (ifx);
4666 // lit = 0, result = boolean(left)
4668 emitcode ("setb", "c");
4672 symbol *tlbl = newiTempLabel (NULL);
4673 emitcode ("jnz", "%05d$", tlbl->key + 100);
4675 emitcode ("", "%05d$:", tlbl->key + 100);
4679 genIfxJump (ifx, "a");
4687 /* if left is same as result */
4688 if (sameRegs (AOP (result), AOP (left)))
4690 for (; size--; offset++)
4692 if (AOP_TYPE (right) == AOP_LIT)
4694 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
4696 else if (IS_AOP_PREG (left))
4698 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4699 emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4700 aopPut (AOP (result), "a", offset);
4703 emitcode ("orl", "%s,%s",
4704 aopGet (AOP (left), offset, FALSE, TRUE),
4705 aopGet (AOP (right), offset, FALSE, FALSE));
4709 if (AOP_TYPE (left) == AOP_ACC)
4710 emitcode ("orl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4713 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4714 if (IS_AOP_PREG (left))
4716 emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4717 aopPut (AOP (result), "a", offset);
4720 emitcode ("orl", "%s,a",
4721 aopGet (AOP (left), offset, FALSE, TRUE));
4728 // left & result in different registers
4729 if (AOP_TYPE (result) == AOP_CRY)
4732 // if(size), result in bit
4733 // if(!size && ifx), conditional oper: if(left | right)
4734 symbol *tlbl = newiTempLabel (NULL);
4735 int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
4737 emitcode ("setb", "c");
4740 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4741 emitcode ("orl", "a,%s",
4742 aopGet (AOP (left), offset, FALSE, FALSE));
4743 emitcode ("jnz", "%05d$", tlbl->key + 100);
4749 emitcode ("", "%05d$:", tlbl->key + 100);
4753 jmpTrueOrFalse (ifx, tlbl);
4756 for (; (size--); offset++)
4759 // result = left & right
4760 if (AOP_TYPE (right) == AOP_LIT)
4762 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
4764 aopPut (AOP (result),
4765 aopGet (AOP (left), offset, FALSE, FALSE),
4770 // faster than result <- left, anl result,right
4771 // and better if result is SFR
4772 if (AOP_TYPE (left) == AOP_ACC)
4773 emitcode ("orl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4776 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4777 emitcode ("orl", "a,%s",
4778 aopGet (AOP (left), offset, FALSE, FALSE));
4780 aopPut (AOP (result), "a", offset);
4785 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4786 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
4787 freeAsmop (result, NULL, ic, TRUE);
4790 /*-----------------------------------------------------------------*/
4791 /* genXor - code for xclusive or */
4792 /*-----------------------------------------------------------------*/
4794 genXor (iCode * ic, iCode * ifx)
4796 operand *left, *right, *result;
4797 int size, offset = 0;
4798 unsigned long lit = 0L;
4800 aopOp ((left = IC_LEFT (ic)), ic, FALSE);
4801 aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
4802 aopOp ((result = IC_RESULT (ic)), ic, TRUE);
4805 emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
4807 AOP_TYPE (left), AOP_TYPE (right));
4808 emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
4810 AOP_SIZE (left), AOP_SIZE (right));
4813 /* if left is a literal & right is not ||
4814 if left needs acc & right does not */
4815 if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
4816 (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)))
4818 operand *tmp = right;
4823 /* if result = right then exchange them */
4824 if (sameRegs (AOP (result), AOP (right)))
4826 operand *tmp = right;
4831 /* if right is bit then exchange them */
4832 if (AOP_TYPE (right) == AOP_CRY &&
4833 AOP_TYPE (left) != AOP_CRY)
4835 operand *tmp = right;
4839 if (AOP_TYPE (right) == AOP_LIT)
4840 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
4842 size = AOP_SIZE (result);
4846 if (AOP_TYPE (left) == AOP_CRY)
4848 if (AOP_TYPE (right) == AOP_LIT)
4850 // c = bit & literal;
4853 // lit>>1 != 0 => result = 1
4854 if (AOP_TYPE (result) == AOP_CRY)
4857 emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
4859 continueIfTrue (ifx);
4862 emitcode ("setb", "c");
4869 // lit == 0, result = left
4870 if (size && sameRegs (AOP (result), AOP (left)))
4872 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4876 // lit == 1, result = not(left)
4877 if (size && sameRegs (AOP (result), AOP (left)))
4879 emitcode ("cpl", "%s", AOP (result)->aopu.aop_dir);
4884 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
4885 emitcode ("cpl", "c");
4894 symbol *tlbl = newiTempLabel (NULL);
4895 if (AOP_TYPE (right) == AOP_CRY)
4898 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
4902 int sizer = AOP_SIZE (right);
4904 // if val>>1 != 0, result = 1
4905 emitcode ("setb", "c");
4908 MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE));
4910 // test the msb of the lsb
4911 emitcode ("anl", "a,#0xfe");
4912 emitcode ("jnz", "%05d$", tlbl->key + 100);
4916 emitcode ("rrc", "a");
4918 emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
4919 emitcode ("cpl", "c");
4920 emitcode ("", "%05d$:", (tlbl->key + 100));
4927 else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
4928 genIfxJump (ifx, "c");
4932 if (sameRegs (AOP (result), AOP (left)))
4934 /* if left is same as result */
4935 for (; size--; offset++)
4937 if (AOP_TYPE (right) == AOP_LIT)
4939 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
4941 else if (IS_AOP_PREG (left))
4943 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4944 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4945 aopPut (AOP (result), "a", offset);
4948 emitcode ("xrl", "%s,%s",
4949 aopGet (AOP (left), offset, FALSE, TRUE),
4950 aopGet (AOP (right), offset, FALSE, FALSE));
4954 if (AOP_TYPE (left) == AOP_ACC)
4955 emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
4958 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4959 if (IS_AOP_PREG (left))
4961 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
4962 aopPut (AOP (result), "a", offset);
4965 emitcode ("xrl", "%s,a",
4966 aopGet (AOP (left), offset, FALSE, TRUE));
4973 // left & result in different registers
4974 if (AOP_TYPE (result) == AOP_CRY)
4977 // if(size), result in bit
4978 // if(!size && ifx), conditional oper: if(left ^ right)
4979 symbol *tlbl = newiTempLabel (NULL);
4980 int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
4982 emitcode ("setb", "c");
4985 if ((AOP_TYPE (right) == AOP_LIT) &&
4986 (((lit >> (offset * 8)) & 0x0FFL) == 0x00L))
4988 MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
4992 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
4993 emitcode ("xrl", "a,%s",
4994 aopGet (AOP (left), offset, FALSE, FALSE));
4996 emitcode ("jnz", "%05d$", tlbl->key + 100);
5002 emitcode ("", "%05d$:", tlbl->key + 100);
5006 jmpTrueOrFalse (ifx, tlbl);
5009 for (; (size--); offset++)
5012 // result = left & right
5013 if (AOP_TYPE (right) == AOP_LIT)
5015 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
5017 aopPut (AOP (result),
5018 aopGet (AOP (left), offset, FALSE, FALSE),
5023 // faster than result <- left, anl result,right
5024 // and better if result is SFR
5025 if (AOP_TYPE (left) == AOP_ACC)
5026 emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
5029 MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
5030 emitcode ("xrl", "a,%s",
5031 aopGet (AOP (left), offset, FALSE, TRUE));
5033 aopPut (AOP (result), "a", offset);
5038 freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5039 freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
5040 freeAsmop (result, NULL, ic, TRUE);
5043 /*-----------------------------------------------------------------*/
5044 /* genInline - write the inline code out */
5045 /*-----------------------------------------------------------------*/
5047 genInline (iCode * ic)
5049 char buffer[MAX_INLINEASM];
5053 _G.inLine += (!options.asmpeep);
5054 strcpy (buffer, IC_INLINE (ic));
5056 /* emit each line as a code */
5081 /* emitcode("",buffer); */
5082 _G.inLine -= (!options.asmpeep);
5085 /*-----------------------------------------------------------------*/
5086 /* genRRC - rotate right with carry */
5087 /*-----------------------------------------------------------------*/
5091 operand *left, *result;
5092 int size, offset = 0;
5095 /* rotate right with carry */
5096 left = IC_LEFT (ic);
5097 result = IC_RESULT (ic);
5098 aopOp (left, ic, FALSE);
5099 aopOp (result, ic, FALSE);
5101 /* move it to the result */
5102 size = AOP_SIZE (result);
5107 l = aopGet (AOP (left), offset, FALSE, FALSE);
5109 emitcode ("rrc", "a");
5110 if (AOP_SIZE (result) > 1)
5111 aopPut (AOP (result), "a", offset--);
5113 /* now we need to put the carry into the
5114 highest order byte of the result */
5115 if (AOP_SIZE (result) > 1)
5117 l = aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE);
5120 emitcode ("mov", "acc.7,c");
5121 aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
5122 freeAsmop (left, NULL, ic, TRUE);
5123 freeAsmop (result, NULL, ic, TRUE);
5126 /*-----------------------------------------------------------------*/
5127 /* genRLC - generate code for rotate left with carry */
5128 /*-----------------------------------------------------------------*/
5132 operand *left, *result;
5133 int size, offset = 0;
5136 /* rotate right with carry */
5137 left = IC_LEFT (ic);
5138 result = IC_RESULT (ic);
5139 aopOp (left, ic, FALSE);
5140 aopOp (result, ic, FALSE);
5142 /* move it to the result */
5143 size = AOP_SIZE (result);
5147 l = aopGet (AOP (left), offset, FALSE, FALSE);
5149 emitcode ("add", "a,acc");
5150 if (AOP_SIZE (result) > 1)
5151 aopPut (AOP (result), "a", offset++);
5154 l = aopGet (AOP (left), offset, FALSE, FALSE);
5156 emitcode ("rlc", "a");
5157 if (AOP_SIZE (result) > 1)
5158 aopPut (AOP (result), "a", offset++);
5161 /* now we need to put the carry into the
5162 highest order byte of the result */
5163 if (AOP_SIZE (result) > 1)
5165 l = aopGet (AOP (result), 0, FALSE, FALSE);
5168 emitcode ("mov", "acc.0,c");
5169 aopPut (AOP (result), "a", 0);
5170 freeAsmop (left, NULL, ic, TRUE);
5171 freeAsmop (result, NULL, ic, TRUE);
5174 /*-----------------------------------------------------------------*/
5175 /* genGetHbit - generates code get highest order bit */
5176 /*-----------------------------------------------------------------*/
5178 genGetHbit (iCode * ic)
5180 operand *left, *result;
5181 left = IC_LEFT (ic);
5182 result = IC_RESULT (ic);
5183 aopOp (left, ic, FALSE);
5184 aopOp (result, ic, FALSE);
5186 /* get the highest order byte into a */
5187 MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE));
5188 if (AOP_TYPE (result) == AOP_CRY)
5190 emitcode ("rlc", "a");
5195 emitcode ("rl", "a");
5196 emitcode ("anl", "a,#0x01");
5201 freeAsmop (left, NULL, ic, TRUE);
5202 freeAsmop (result, NULL, ic, TRUE);
5205 /*-----------------------------------------------------------------*/
5206 /* AccRol - rotate left accumulator by known count */
5207 /*-----------------------------------------------------------------*/
5209 AccRol (int shCount)
5211 shCount &= 0x0007; // shCount : 0..7
5218 emitcode ("rl", "a");
5221 emitcode ("rl", "a");
5222 emitcode ("rl", "a");
5225 emitcode ("swap", "a");
5226 emitcode ("rr", "a");
5229 emitcode ("swap", "a");
5232 emitcode ("swap", "a");
5233 emitcode ("rl", "a");
5236 emitcode ("rr", "a");
5237 emitcode ("rr", "a");
5240 emitcode ("rr", "a");
5245 /*-----------------------------------------------------------------*/
5246 /* AccLsh - left shift accumulator by known count */
5247 /*-----------------------------------------------------------------*/
5249 AccLsh (int shCount)
5254 emitcode ("add", "a,acc");
5255 else if (shCount == 2)
5257 emitcode ("add", "a,acc");
5258 emitcode ("add", "a,acc");
5262 /* rotate left accumulator */
5264 /* and kill the lower order bits */
5265 emitcode ("anl", "a,#0x%02x", SLMask[shCount]);
5270 /*-----------------------------------------------------------------*/
5271 /* AccRsh - right shift accumulator by known count */
5272 /*-----------------------------------------------------------------*/
5274 AccRsh (int shCount)
5281 emitcode ("rrc", "a");
5285 /* rotate right accumulator */
5286 AccRol (8 - shCount);
5287 /* and kill the higher order bits */
5288 emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
5293 /*-----------------------------------------------------------------*/
5294 /* AccSRsh - signed right shift accumulator by known count */
5295 /*-----------------------------------------------------------------*/
5297 AccSRsh (int shCount)
5304 emitcode ("mov", "c,acc.7");
5305 emitcode ("rrc", "a");
5307 else if (shCount == 2)
5309 emitcode ("mov", "c,acc.7");
5310 emitcode ("rrc", "a");
5311 emitcode ("mov", "c,acc.7");
5312 emitcode ("rrc", "a");
5316 tlbl = newiTempLabel (NULL);
5317 /* rotate right accumulator */
5318 AccRol (8 - shCount);
5319 /* and kill the higher order bits */
5320 emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
5321 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5322 emitcode ("orl", "a,#0x%02x",
5323 (unsigned char) ~SRMask[shCount]);
5324 emitcode ("", "%05d$:", tlbl->key + 100);
5329 /*-----------------------------------------------------------------*/
5330 /* shiftR1Left2Result - shift right one byte from left to result */
5331 /*-----------------------------------------------------------------*/
5333 shiftR1Left2Result (operand * left, int offl,
5334 operand * result, int offr,
5335 int shCount, int sign)
5337 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5338 /* shift right accumulator */
5343 aopPut (AOP (result), "a", offr);
5346 /*-----------------------------------------------------------------*/
5347 /* shiftL1Left2Result - shift left one byte from left to result */
5348 /*-----------------------------------------------------------------*/
5350 shiftL1Left2Result (operand * left, int offl,
5351 operand * result, int offr, int shCount)
5354 l = aopGet (AOP (left), offl, FALSE, FALSE);
5356 /* shift left accumulator */
5358 aopPut (AOP (result), "a", offr);
5361 /*-----------------------------------------------------------------*/
5362 /* movLeft2Result - move byte from left to result */
5363 /*-----------------------------------------------------------------*/
5365 movLeft2Result (operand * left, int offl,
5366 operand * result, int offr, int sign)
5369 if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
5371 l = aopGet (AOP (left), offl, FALSE, FALSE);
5373 if (*l == '@' && (IS_AOP_PREG (result)))
5375 emitcode ("mov", "a,%s", l);
5376 aopPut (AOP (result), "a", offr);
5381 aopPut (AOP (result), l, offr);
5384 /* MSB sign in acc.7 ! */
5385 if (getDataSize (left) == offl + 1)
5387 emitcode ("mov", "a,%s", l);
5388 aopPut (AOP (result), "a", offr);
5395 /*-----------------------------------------------------------------*/
5396 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5397 /*-----------------------------------------------------------------*/
5401 emitcode ("rrc", "a");
5402 emitcode ("xch", "a,%s", x);
5403 emitcode ("rrc", "a");
5404 emitcode ("xch", "a,%s", x);
5407 /*-----------------------------------------------------------------*/
5408 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5409 /*-----------------------------------------------------------------*/
5413 emitcode ("xch", "a,%s", x);
5414 emitcode ("rlc", "a");
5415 emitcode ("xch", "a,%s", x);
5416 emitcode ("rlc", "a");
5419 /*-----------------------------------------------------------------*/
5420 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5421 /*-----------------------------------------------------------------*/
5425 emitcode ("xch", "a,%s", x);
5426 emitcode ("add", "a,acc");
5427 emitcode ("xch", "a,%s", x);
5428 emitcode ("rlc", "a");
5431 /*-----------------------------------------------------------------*/
5432 /* AccAXLsh - left shift a:x by known count (0..7) */
5433 /*-----------------------------------------------------------------*/
5435 AccAXLsh (char *x, int shCount)
5450 case 5: // AAAAABBB:CCCCCDDD
5452 AccRol (shCount); // BBBAAAAA:CCCCCDDD
5454 emitcode ("anl", "a,#0x%02x",
5455 SLMask[shCount]); // BBB00000:CCCCCDDD
5457 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBB00000
5459 AccRol (shCount); // DDDCCCCC:BBB00000
5461 emitcode ("xch", "a,%s", x); // BBB00000:DDDCCCCC
5463 emitcode ("xrl", "a,%s", x); // (BBB^DDD)CCCCC:DDDCCCCC
5465 emitcode ("xch", "a,%s", x); // DDDCCCCC:(BBB^DDD)CCCCC
5467 emitcode ("anl", "a,#0x%02x",
5468 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5470 emitcode ("xch", "a,%s", x); // (BBB^DDD)CCCCC:DDD00000
5472 emitcode ("xrl", "a,%s", x); // BBBCCCCC:DDD00000
5475 case 6: // AAAAAABB:CCCCCCDD
5476 emitcode ("anl", "a,#0x%02x",
5477 SRMask[shCount]); // 000000BB:CCCCCCDD
5478 emitcode ("mov", "c,acc.0"); // c = B
5479 emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB
5481 AccAXRrl1 (x); // BCCCCCCD:D000000B
5482 AccAXRrl1 (x); // BBCCCCCC:DD000000
5484 emitcode("rrc","a");
5485 emitcode("xch","a,%s", x);
5486 emitcode("rrc","a");
5487 emitcode("mov","c,acc.0"); //<< get correct bit
5488 emitcode("xch","a,%s", x);
5490 emitcode("rrc","a");
5491 emitcode("xch","a,%s", x);
5492 emitcode("rrc","a");
5493 emitcode("xch","a,%s", x);
5496 case 7: // a:x <<= 7
5498 emitcode ("anl", "a,#0x%02x",
5499 SRMask[shCount]); // 0000000B:CCCCCCCD
5501 emitcode ("mov", "c,acc.0"); // c = B
5503 emitcode ("xch", "a,%s", x); // CCCCCCCD:0000000B
5505 AccAXRrl1 (x); // BCCCCCCC:D0000000
5513 /*-----------------------------------------------------------------*/
5514 /* AccAXRsh - right shift a:x known count (0..7) */
5515 /*-----------------------------------------------------------------*/
5517 AccAXRsh (char *x, int shCount)
5525 AccAXRrl1 (x); // 0->a:x
5530 AccAXRrl1 (x); // 0->a:x
5533 AccAXRrl1 (x); // 0->a:x
5538 case 5: // AAAAABBB:CCCCCDDD = a:x
5540 AccRol (8 - shCount); // BBBAAAAA:DDDCCCCC
5542 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
5544 AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
5546 emitcode ("anl", "a,#0x%02x",
5547 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5549 emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA
5551 emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5553 emitcode ("anl", "a,#0x%02x",
5554 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5556 emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA
5558 emitcode ("xrl", "a,%s", x); // BBBCCCCC:000AAAAA
5560 emitcode ("xch", "a,%s", x); // 000AAAAA:BBBCCCCC
5563 case 6: // AABBBBBB:CCDDDDDD
5565 emitcode ("mov", "c,acc.7");
5566 AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
5568 AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
5570 emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
5572 emitcode ("anl", "a,#0x%02x",
5573 SRMask[shCount]); // 000000AA:BBBBBBCC
5576 case 7: // ABBBBBBB:CDDDDDDD
5578 emitcode ("mov", "c,acc.7"); // c = A
5580 AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
5582 emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
5584 emitcode ("anl", "a,#0x%02x",
5585 SRMask[shCount]); // 0000000A:BBBBBBBC
5593 /*-----------------------------------------------------------------*/
5594 /* AccAXRshS - right shift signed a:x known count (0..7) */
5595 /*-----------------------------------------------------------------*/
5597 AccAXRshS (char *x, int shCount)
5605 emitcode ("mov", "c,acc.7");
5606 AccAXRrl1 (x); // s->a:x
5610 emitcode ("mov", "c,acc.7");
5611 AccAXRrl1 (x); // s->a:x
5613 emitcode ("mov", "c,acc.7");
5614 AccAXRrl1 (x); // s->a:x
5619 case 5: // AAAAABBB:CCCCCDDD = a:x
5621 tlbl = newiTempLabel (NULL);
5622 AccRol (8 - shCount); // BBBAAAAA:CCCCCDDD
5624 emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
5626 AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
5628 emitcode ("anl", "a,#0x%02x",
5629 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5631 emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA
5633 emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5635 emitcode ("anl", "a,#0x%02x",
5636 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5638 emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA
5640 emitcode ("xrl", "a,%s", x); // BBBCCCCC:000AAAAA
5642 emitcode ("xch", "a,%s", x); // 000SAAAA:BBBCCCCC
5644 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5645 emitcode ("orl", "a,#0x%02x",
5646 (unsigned char) ~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5648 emitcode ("", "%05d$:", tlbl->key + 100);
5649 break; // SSSSAAAA:BBBCCCCC
5651 case 6: // AABBBBBB:CCDDDDDD
5653 tlbl = newiTempLabel (NULL);
5654 emitcode ("mov", "c,acc.7");
5655 AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
5657 AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
5659 emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
5661 emitcode ("anl", "a,#0x%02x",
5662 SRMask[shCount]); // 000000AA:BBBBBBCC
5664 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5665 emitcode ("orl", "a,#0x%02x",
5666 (unsigned char) ~SRMask[shCount]); // 111111AA:BBBBBBCC
5668 emitcode ("", "%05d$:", tlbl->key + 100);
5670 case 7: // ABBBBBBB:CDDDDDDD
5672 tlbl = newiTempLabel (NULL);
5673 emitcode ("mov", "c,acc.7"); // c = A
5675 AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
5677 emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
5679 emitcode ("anl", "a,#0x%02x",
5680 SRMask[shCount]); // 0000000A:BBBBBBBC
5682 emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
5683 emitcode ("orl", "a,#0x%02x",
5684 (unsigned char) ~SRMask[shCount]); // 1111111A:BBBBBBBC
5686 emitcode ("", "%05d$:", tlbl->key + 100);
5693 /*-----------------------------------------------------------------*/
5694 /* shiftL2Left2Result - shift left two bytes from left to result */
5695 /*-----------------------------------------------------------------*/
5697 shiftL2Left2Result (operand * left, int offl,
5698 operand * result, int offr, int shCount)
5700 if (sameRegs (AOP (result), AOP (left)) &&
5701 ((offl + MSB16) == offr))
5703 /* don't crash result[offr] */
5704 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5705 emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5709 movLeft2Result (left, offl, result, offr, 0);
5710 MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5712 /* ax << shCount (x = lsb(result)) */
5713 AccAXLsh (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
5714 aopPut (AOP (result), "a", offr + MSB16);
5718 /*-----------------------------------------------------------------*/
5719 /* shiftR2Left2Result - shift right two bytes from left to result */
5720 /*-----------------------------------------------------------------*/
5722 shiftR2Left2Result (operand * left, int offl,
5723 operand * result, int offr,
5724 int shCount, int sign)
5726 if (sameRegs (AOP (result), AOP (left)) &&
5727 ((offl + MSB16) == offr))
5729 /* don't crash result[offr] */
5730 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5731 emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5735 movLeft2Result (left, offl, result, offr, 0);
5736 MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE));
5738 /* a:x >> shCount (x = lsb(result)) */
5740 AccAXRshS (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
5742 AccAXRsh (aopGet (AOP (result), offr, FALSE, FALSE), shCount);
5743 if (getDataSize (result) > 1)
5744 aopPut (AOP (result), "a", offr + MSB16);
5747 /*-----------------------------------------------------------------*/
5748 /* shiftLLeftOrResult - shift left one byte from left, or to result */
5749 /*-----------------------------------------------------------------*/
5751 shiftLLeftOrResult (operand * left, int offl,
5752 operand * result, int offr, int shCount)
5754 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5755 /* shift left accumulator */
5757 /* or with result */
5758 emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE));
5759 /* back to result */
5760 aopPut (AOP (result), "a", offr);
5763 /*-----------------------------------------------------------------*/
5764 /* shiftRLeftOrResult - shift right one byte from left,or to result */
5765 /*-----------------------------------------------------------------*/
5767 shiftRLeftOrResult (operand * left, int offl,
5768 operand * result, int offr, int shCount)
5770 MOVA (aopGet (AOP (left), offl, FALSE, FALSE));
5771 /* shift right accumulator */
5773 /* or with result */
5774 emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE));
5775 /* back to result */
5776 aopPut (AOP (result), "a", offr);
5779 /*-----------------------------------------------------------------*/
5780 /* genlshOne - left shift a one byte quantity by known count */
5781 /*-----------------------------------------------------------------*/
5783 genlshOne (operand * result, operand * left, int shCount)
5785 shiftL1Left2Result (left, LSB, result, LSB, shCount);
5788 /*-----------------------------------------------------------------*/
5789 /* genlshTwo - left shift two bytes by known amount != 0 */
5790 /*-----------------------------------------------------------------*/
5792 genlshTwo (operand * result, operand * left, int shCount)
5796 size = getDataSize (result);
5798 /* if shCount >= 8 */
5806 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
5808 movLeft2Result (left, LSB, result, MSB16, 0);
5810 aopPut (AOP (result), zero, LSB);
5813 /* 1 <= shCount <= 7 */
5817 shiftL1Left2Result (left, LSB, result, LSB, shCount);
5819 shiftL2Left2Result (left, LSB, result, LSB, shCount);
5823 /*-----------------------------------------------------------------*/
5824 /* shiftLLong - shift left one long from left to result */
5825 /* offl = LSB or MSB16 */
5826 /*-----------------------------------------------------------------*/
5828 shiftLLong (operand * left, operand * result, int offr)
5831 int size = AOP_SIZE (result);
5833 if (size >= LSB + offr)
5835 l = aopGet (AOP (left), LSB, FALSE, FALSE);
5837 emitcode ("add", "a,acc");
5838 if (sameRegs (AOP (left), AOP (result)) &&
5839 size >= MSB16 + offr && offr != LSB)
5840 emitcode ("xch", "a,%s",
5841 aopGet (AOP (left), LSB + offr, FALSE, FALSE));
5843 aopPut (AOP (result), "a", LSB + offr);
5846 if (size >= MSB16 + offr)
5848 if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB16 + offr && offr != LSB))
5850 l = aopGet (AOP (left), MSB16, FALSE, FALSE);
5853 emitcode ("rlc", "a");
5854 if (sameRegs (AOP (left), AOP (result)) &&
5855 size >= MSB24 + offr && offr != LSB)
5856 emitcode ("xch", "a,%s",
5857 aopGet (AOP (left), MSB16 + offr, FALSE, FALSE));
5859 aopPut (AOP (result), "a", MSB16 + offr);
5862 if (size >= MSB24 + offr)
5864 if (!(sameRegs (AOP (left), AOP (left)) && size >= MSB24 + offr && offr != LSB))
5866 l = aopGet (AOP (left), MSB24, FALSE, FALSE);
5869 emitcode ("rlc", "a");
5870 if (sameRegs (AOP (left), AOP (result)) &&
5871 size >= MSB32 + offr && offr != LSB)
5872 emitcode ("xch", "a,%s",
5873 aopGet (AOP (left), MSB24 + offr, FALSE, FALSE));
5875 aopPut (AOP (result), "a", MSB24 + offr);
5878 if (size > MSB32 + offr)
5880 if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB32 + offr && offr != LSB))
5882 l = aopGet (AOP (left), MSB32, FALSE, FALSE);
5885 emitcode ("rlc", "a");
5886 aopPut (AOP (result), "a", MSB32 + offr);
5889 aopPut (AOP (result), zero, LSB);
5892 /*-----------------------------------------------------------------*/
5893 /* genlshFour - shift four byte by a known amount != 0 */
5894 /*-----------------------------------------------------------------*/
5896 genlshFour (operand * result, operand * left, int shCount)
5900 size = AOP_SIZE (result);
5902 /* if shifting more that 3 bytes */
5907 /* lowest order of left goes to the highest
5908 order of the destination */
5909 shiftL1Left2Result (left, LSB, result, MSB32, shCount);
5911 movLeft2Result (left, LSB, result, MSB32, 0);
5912 aopPut (AOP (result), zero, LSB);
5913 aopPut (AOP (result), zero, MSB16);
5914 aopPut (AOP (result), zero, MSB24);
5918 /* more than two bytes */
5919 else if (shCount >= 16)
5921 /* lower order two bytes goes to higher order two bytes */
5923 /* if some more remaining */
5925 shiftL2Left2Result (left, LSB, result, MSB24, shCount);
5928 movLeft2Result (left, MSB16, result, MSB32, 0);
5929 movLeft2Result (left, LSB, result, MSB24, 0);
5931 aopPut (AOP (result), zero, MSB16);
5932 aopPut (AOP (result), zero, LSB);
5936 /* if more than 1 byte */
5937 else if (shCount >= 8)
5939 /* lower order three bytes goes to higher order three bytes */
5944 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
5946 movLeft2Result (left, LSB, result, MSB16, 0);
5952 movLeft2Result (left, MSB24, result, MSB32, 0);
5953 movLeft2Result (left, MSB16, result, MSB24, 0);
5954 movLeft2Result (left, LSB, result, MSB16, 0);
5955 aopPut (AOP (result), zero, LSB);
5957 else if (shCount == 1)
5958 shiftLLong (left, result, MSB16);
5961 shiftL2Left2Result (left, MSB16, result, MSB24, shCount);
5962 shiftL1Left2Result (left, LSB, result, MSB16, shCount);
5963 shiftRLeftOrResult (left, LSB, result, MSB24, 8 - shCount);
5964 aopPut (AOP (result), zero, LSB);
5969 /* 1 <= shCount <= 7 */
5970 else if (shCount <= 2)
5972 shiftLLong (left, result, LSB);
5974 shiftLLong (result, result, LSB);
5976 /* 3 <= shCount <= 7, optimize */
5979 shiftL2Left2Result (left, MSB24, result, MSB24, shCount);
5980 shiftRLeftOrResult (left, MSB16, result, MSB24, 8 - shCount);
5981 shiftL2Left2Result (left, LSB, result, LSB, shCount);
5985 /*-----------------------------------------------------------------*/
5986 /* genLeftShiftLiteral - left shifting by known count */
5987 /*-----------------------------------------------------------------*/
5989 genLeftShiftLiteral (operand * left,
5994 int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
5997 freeAsmop (right, NULL, ic, TRUE);
5999 aopOp (left, ic, FALSE);
6000 aopOp (result, ic, FALSE);
6002 size = getSize (operandType (result));
6005 emitcode ("; shift left ", "result %d, left %d", size,
6009 /* I suppose that the left size >= result size */
6014 movLeft2Result (left, size, result, size, 0);
6018 else if (shCount >= (size * 8))
6020 aopPut (AOP (result), zero, size);
6026 genlshOne (result, left, shCount);
6031 genlshTwo (result, left, shCount);
6035 genlshFour (result, left, shCount);
6039 freeAsmop (left, NULL, ic, TRUE);
6040 freeAsmop (result, NULL, ic, TRUE);
6043 /*-----------------------------------------------------------------*/
6044 /* genLeftShift - generates code for left shifting */
6045 /*-----------------------------------------------------------------*/
6047 genLeftShift (iCode * ic)
6049 operand *left, *right, *result;
6052 symbol *tlbl, *tlbl1;
6054 right = IC_RIGHT (ic);
6055 left = IC_LEFT (ic);
6056 result = IC_RESULT (ic);
6058 aopOp (right, ic, FALSE);
6060 /* if the shift count is known then do it
6061 as efficiently as possible */
6062 if (AOP_TYPE (right) == AOP_LIT)
6064 genLeftShiftLiteral (left, right, result, ic);
6068 /* shift count is unknown then we have to form
6069 a loop get the loop count in B : Note: we take
6070 only the lower order byte since shifting
6071 more that 32 bits make no sense anyway, ( the
6072 largest size of an object can be only 32 bits ) */
6074 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6075 emitcode ("inc", "b");
6076 freeAsmop (right, NULL, ic, TRUE);
6077 aopOp (left, ic, FALSE);
6078 aopOp (result, ic, FALSE);
6080 /* now move the left to the result if they are not the
6082 if (!sameRegs (AOP (left), AOP (result)) &&
6083 AOP_SIZE (result) > 1)
6086 size = AOP_SIZE (result);
6090 l = aopGet (AOP (left), offset, FALSE, TRUE);
6091 if (*l == '@' && (IS_AOP_PREG (result)))
6094 emitcode ("mov", "a,%s", l);
6095 aopPut (AOP (result), "a", offset);
6098 aopPut (AOP (result), l, offset);
6103 tlbl = newiTempLabel (NULL);
6104 size = AOP_SIZE (result);
6106 tlbl1 = newiTempLabel (NULL);
6108 /* if it is only one byte then */
6111 symbol *tlbl1 = newiTempLabel (NULL);
6113 l = aopGet (AOP (left), 0, FALSE, FALSE);
6115 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6116 emitcode ("", "%05d$:", tlbl->key + 100);
6117 emitcode ("add", "a,acc");
6118 emitcode ("", "%05d$:", tlbl1->key + 100);
6119 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6120 aopPut (AOP (result), "a", 0);
6124 reAdjustPreg (AOP (result));
6126 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6127 emitcode ("", "%05d$:", tlbl->key + 100);
6128 l = aopGet (AOP (result), offset, FALSE, FALSE);
6130 emitcode ("add", "a,acc");
6131 aopPut (AOP (result), "a", offset++);
6134 l = aopGet (AOP (result), offset, FALSE, FALSE);
6136 emitcode ("rlc", "a");
6137 aopPut (AOP (result), "a", offset++);
6139 reAdjustPreg (AOP (result));
6141 emitcode ("", "%05d$:", tlbl1->key + 100);
6142 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6144 freeAsmop (left, NULL, ic, TRUE);
6145 freeAsmop (result, NULL, ic, TRUE);
6148 /*-----------------------------------------------------------------*/
6149 /* genrshOne - right shift a one byte quantity by known count */
6150 /*-----------------------------------------------------------------*/
6152 genrshOne (operand * result, operand * left,
6153 int shCount, int sign)
6155 shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
6158 /*-----------------------------------------------------------------*/
6159 /* genrshTwo - right shift two bytes by known amount != 0 */
6160 /*-----------------------------------------------------------------*/
6162 genrshTwo (operand * result, operand * left,
6163 int shCount, int sign)
6165 /* if shCount >= 8 */
6170 shiftR1Left2Result (left, MSB16, result, LSB,
6173 movLeft2Result (left, MSB16, result, LSB, sign);
6174 addSign (result, MSB16, sign);
6177 /* 1 <= shCount <= 7 */
6179 shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
6182 /*-----------------------------------------------------------------*/
6183 /* shiftRLong - shift right one long from left to result */
6184 /* offl = LSB or MSB16 */
6185 /*-----------------------------------------------------------------*/
6187 shiftRLong (operand * left, int offl,
6188 operand * result, int sign)
6191 emitcode ("clr", "c");
6192 MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
6194 emitcode ("mov", "c,acc.7");
6195 emitcode ("rrc", "a");
6196 aopPut (AOP (result), "a", MSB32 - offl);
6198 /* add sign of "a" */
6199 addSign (result, MSB32, sign);
6201 MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
6202 emitcode ("rrc", "a");
6203 aopPut (AOP (result), "a", MSB24 - offl);
6205 MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
6206 emitcode ("rrc", "a");
6207 aopPut (AOP (result), "a", MSB16 - offl);
6211 MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
6212 emitcode ("rrc", "a");
6213 aopPut (AOP (result), "a", LSB);
6217 /*-----------------------------------------------------------------*/
6218 /* genrshFour - shift four byte by a known amount != 0 */
6219 /*-----------------------------------------------------------------*/
6221 genrshFour (operand * result, operand * left,
6222 int shCount, int sign)
6224 /* if shifting more that 3 bytes */
6229 shiftR1Left2Result (left, MSB32, result, LSB, shCount, sign);
6231 movLeft2Result (left, MSB32, result, LSB, sign);
6232 addSign (result, MSB16, sign);
6234 else if (shCount >= 16)
6238 shiftR2Left2Result (left, MSB24, result, LSB, shCount, sign);
6241 movLeft2Result (left, MSB24, result, LSB, 0);
6242 movLeft2Result (left, MSB32, result, MSB16, sign);
6244 addSign (result, MSB24, sign);
6246 else if (shCount >= 8)
6250 shiftRLong (left, MSB16, result, sign);
6251 else if (shCount == 0)
6253 movLeft2Result (left, MSB16, result, LSB, 0);
6254 movLeft2Result (left, MSB24, result, MSB16, 0);
6255 movLeft2Result (left, MSB32, result, MSB24, sign);
6256 addSign (result, MSB32, sign);
6260 shiftR2Left2Result (left, MSB16, result, LSB, shCount, 0);
6261 shiftLLeftOrResult (left, MSB32, result, MSB16, 8 - shCount);
6262 /* the last shift is signed */
6263 shiftR1Left2Result (left, MSB32, result, MSB24, shCount, sign);
6264 addSign (result, MSB32, sign);
6268 { /* 1 <= shCount <= 7 */
6271 shiftRLong (left, LSB, result, sign);
6273 shiftRLong (result, LSB, result, sign);
6277 shiftR2Left2Result (left, LSB, result, LSB, shCount, 0);
6278 shiftLLeftOrResult (left, MSB24, result, MSB16, 8 - shCount);
6279 shiftR2Left2Result (left, MSB24, result, MSB24, shCount, sign);
6284 /*-----------------------------------------------------------------*/
6285 /* genRightShiftLiteral - right shifting by known count */
6286 /*-----------------------------------------------------------------*/
6288 genRightShiftLiteral (operand * left,
6294 int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
6297 freeAsmop (right, NULL, ic, TRUE);
6299 aopOp (left, ic, FALSE);
6300 aopOp (result, ic, FALSE);
6303 emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
6307 size = getDataSize (left);
6308 /* test the LEFT size !!! */
6310 /* I suppose that the left size >= result size */
6313 size = getDataSize (result);
6315 movLeft2Result (left, size, result, size, 0);
6318 else if (shCount >= (size * 8))
6321 /* get sign in acc.7 */
6322 MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE));
6323 addSign (result, LSB, sign);
6330 genrshOne (result, left, shCount, sign);
6334 genrshTwo (result, left, shCount, sign);
6338 genrshFour (result, left, shCount, sign);
6344 freeAsmop (left, NULL, ic, TRUE);
6345 freeAsmop (result, NULL, ic, TRUE);
6349 /*-----------------------------------------------------------------*/
6350 /* genSignedRightShift - right shift of signed number */
6351 /*-----------------------------------------------------------------*/
6353 genSignedRightShift (iCode * ic)
6355 operand *right, *left, *result;
6358 symbol *tlbl, *tlbl1;
6360 /* we do it the hard way put the shift count in b
6361 and loop thru preserving the sign */
6363 right = IC_RIGHT (ic);
6364 left = IC_LEFT (ic);
6365 result = IC_RESULT (ic);
6367 aopOp (right, ic, FALSE);
6370 if (AOP_TYPE (right) == AOP_LIT)
6372 genRightShiftLiteral (left, right, result, ic, 1);
6375 /* shift count is unknown then we have to form
6376 a loop get the loop count in B : Note: we take
6377 only the lower order byte since shifting
6378 more that 32 bits make no sense anyway, ( the
6379 largest size of an object can be only 32 bits ) */
6381 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6382 emitcode ("inc", "b");
6383 freeAsmop (right, NULL, ic, TRUE);
6384 aopOp (left, ic, FALSE);
6385 aopOp (result, ic, FALSE);
6387 /* now move the left to the result if they are not the
6389 if (!sameRegs (AOP (left), AOP (result)) &&
6390 AOP_SIZE (result) > 1)
6393 size = AOP_SIZE (result);
6397 l = aopGet (AOP (left), offset, FALSE, TRUE);
6398 if (*l == '@' && IS_AOP_PREG (result))
6401 emitcode ("mov", "a,%s", l);
6402 aopPut (AOP (result), "a", offset);
6405 aopPut (AOP (result), l, offset);
6410 /* mov the highest order bit to OVR */
6411 tlbl = newiTempLabel (NULL);
6412 tlbl1 = newiTempLabel (NULL);
6414 size = AOP_SIZE (result);
6416 emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE));
6417 emitcode ("rlc", "a");
6418 emitcode ("mov", "ov,c");
6419 /* if it is only one byte then */
6422 l = aopGet (AOP (left), 0, FALSE, FALSE);
6424 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6425 emitcode ("", "%05d$:", tlbl->key + 100);
6426 emitcode ("mov", "c,ov");
6427 emitcode ("rrc", "a");
6428 emitcode ("", "%05d$:", tlbl1->key + 100);
6429 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6430 aopPut (AOP (result), "a", 0);
6434 reAdjustPreg (AOP (result));
6435 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6436 emitcode ("", "%05d$:", tlbl->key + 100);
6437 emitcode ("mov", "c,ov");
6440 l = aopGet (AOP (result), offset, FALSE, FALSE);
6442 emitcode ("rrc", "a");
6443 aopPut (AOP (result), "a", offset--);
6445 reAdjustPreg (AOP (result));
6446 emitcode ("", "%05d$:", tlbl1->key + 100);
6447 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6450 freeAsmop (left, NULL, ic, TRUE);
6451 freeAsmop (result, NULL, ic, TRUE);
6454 /*-----------------------------------------------------------------*/
6455 /* genRightShift - generate code for right shifting */
6456 /*-----------------------------------------------------------------*/
6458 genRightShift (iCode * ic)
6460 operand *right, *left, *result;
6464 symbol *tlbl, *tlbl1;
6466 /* if signed then we do it the hard way preserve the
6467 sign bit moving it inwards */
6468 retype = getSpec (operandType (IC_RESULT (ic)));
6470 if (!SPEC_USIGN (retype))
6472 genSignedRightShift (ic);
6476 /* signed & unsigned types are treated the same : i.e. the
6477 signed is NOT propagated inwards : quoting from the
6478 ANSI - standard : "for E1 >> E2, is equivalent to division
6479 by 2**E2 if unsigned or if it has a non-negative value,
6480 otherwise the result is implementation defined ", MY definition
6481 is that the sign does not get propagated */
6483 right = IC_RIGHT (ic);
6484 left = IC_LEFT (ic);
6485 result = IC_RESULT (ic);
6487 aopOp (right, ic, FALSE);
6489 /* if the shift count is known then do it
6490 as efficiently as possible */
6491 if (AOP_TYPE (right) == AOP_LIT)
6493 genRightShiftLiteral (left, right, result, ic, 0);
6497 /* shift count is unknown then we have to form
6498 a loop get the loop count in B : Note: we take
6499 only the lower order byte since shifting
6500 more that 32 bits make no sense anyway, ( the
6501 largest size of an object can be only 32 bits ) */
6503 emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
6504 emitcode ("inc", "b");
6505 freeAsmop (right, NULL, ic, TRUE);
6506 aopOp (left, ic, FALSE);
6507 aopOp (result, ic, FALSE);
6509 /* now move the left to the result if they are not the
6511 if (!sameRegs (AOP (left), AOP (result)) &&
6512 AOP_SIZE (result) > 1)
6515 size = AOP_SIZE (result);
6519 l = aopGet (AOP (left), offset, FALSE, TRUE);
6520 if (*l == '@' && IS_AOP_PREG (result))
6523 emitcode ("mov", "a,%s", l);
6524 aopPut (AOP (result), "a", offset);
6527 aopPut (AOP (result), l, offset);
6532 tlbl = newiTempLabel (NULL);
6533 tlbl1 = newiTempLabel (NULL);
6534 size = AOP_SIZE (result);
6537 /* if it is only one byte then */
6540 l = aopGet (AOP (left), 0, FALSE, FALSE);
6542 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6543 emitcode ("", "%05d$:", tlbl->key + 100);
6545 emitcode ("rrc", "a");
6546 emitcode ("", "%05d$:", tlbl1->key + 100);
6547 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6548 aopPut (AOP (result), "a", 0);
6552 reAdjustPreg (AOP (result));
6553 emitcode ("sjmp", "%05d$", tlbl1->key + 100);
6554 emitcode ("", "%05d$:", tlbl->key + 100);
6558 l = aopGet (AOP (result), offset, FALSE, FALSE);
6560 emitcode ("rrc", "a");
6561 aopPut (AOP (result), "a", offset--);
6563 reAdjustPreg (AOP (result));
6565 emitcode ("", "%05d$:", tlbl1->key + 100);
6566 emitcode ("djnz", "b,%05d$", tlbl->key + 100);
6569 freeAsmop (left, NULL, ic, TRUE);
6570 freeAsmop (result, NULL, ic, TRUE);
6573 /*-----------------------------------------------------------------*/
6574 /* genUnpackBits - generates code for unpacking bits */
6575 /*-----------------------------------------------------------------*/
6577 genUnpackBits (operand * result, char *rname, int ptype)
6585 etype = getSpec (operandType (result));
6586 rsize = getSize (operandType (result));
6587 /* read the first byte */
6593 emitcode ("mov", "a,@%s", rname);
6597 emitcode ("movx", "a,@%s", rname);
6601 emitcode ("movx", "a,@dptr");
6605 emitcode ("clr", "a");
6606 emitcode ("movc", "a,%s", "@a+dptr");
6610 emitcode ("lcall", "__gptrget");
6614 rlen = SPEC_BLEN (etype);
6616 /* if we have bitdisplacement then it fits */
6617 /* into this byte completely or if length is */
6618 /* less than a byte */
6619 if ((shCnt = SPEC_BSTR (etype)) ||
6620 (SPEC_BLEN (etype) <= 8))
6623 /* shift right acc */
6626 emitcode ("anl", "a,#0x%02x",
6627 ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
6628 aopPut (AOP (result), "a", offset++);
6632 /* bit field did not fit in a byte */
6633 aopPut (AOP (result), "a", offset++);
6642 emitcode ("inc", "%s", rname);
6643 emitcode ("mov", "a,@%s", rname);
6647 emitcode ("inc", "%s", rname);
6648 emitcode ("movx", "a,@%s", rname);
6652 emitcode ("inc", "dptr");
6653 emitcode ("movx", "a,@dptr");
6657 emitcode ("clr", "a");
6658 emitcode ("inc", "dptr");
6659 emitcode ("movc", "a", "@a+dptr");
6663 emitcode ("inc", "dptr");
6664 emitcode ("lcall", "__gptrget");
6669 /* if we are done */
6673 aopPut (AOP (result), "a", offset++);
6679 // emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(rlen));
6681 aopPut (AOP (result), "a", offset++);
6689 aopPut (AOP (result), zero, offset++);
6695 /*-----------------------------------------------------------------*/
6696 /* genDataPointerGet - generates code when ptr offset is known */
6697 /*-----------------------------------------------------------------*/
6699 genDataPointerGet (operand * left,
6705 int size, offset = 0;
6706 aopOp (result, ic, TRUE);
6708 /* get the string representation of the name */
6709 l = aopGet (AOP (left), 0, FALSE, TRUE);
6710 size = AOP_SIZE (result);
6714 sprintf (buffer, "(%s + %d)", l + 1, offset);
6716 sprintf (buffer, "%s", l + 1);
6717 aopPut (AOP (result), buffer, offset++);
6720 freeAsmop (left, NULL, ic, TRUE);
6721 freeAsmop (result, NULL, ic, TRUE);
6724 /*-----------------------------------------------------------------*/
6725 /* genNearPointerGet - emitcode for near pointer fetch */
6726 /*-----------------------------------------------------------------*/
6728 genNearPointerGet (operand * left,
6736 sym_link *rtype, *retype;
6737 sym_link *ltype = operandType (left);
6740 rtype = operandType (result);
6741 retype = getSpec (rtype);
6743 aopOp (left, ic, FALSE);
6745 /* if left is rematerialisable and
6746 result is not bit variable type and
6747 the left is pointer to data space i.e
6748 lower 128 bytes of space */
6749 if (AOP_TYPE (left) == AOP_IMMD &&
6750 !IS_BITVAR (retype) &&
6751 DCL_TYPE (ltype) == POINTER)
6753 genDataPointerGet (left, result, ic);
6757 /* if the value is already in a pointer register
6758 then don't need anything more */
6759 if (!AOP_INPREG (AOP (left)))
6761 /* otherwise get a free pointer register */
6763 preg = getFreePtr (ic, &aop, FALSE);
6764 emitcode ("mov", "%s,%s",
6766 aopGet (AOP (left), 0, FALSE, TRUE));
6770 rname = aopGet (AOP (left), 0, FALSE, FALSE);
6772 aopOp (result, ic, FALSE);
6774 /* if bitfield then unpack the bits */
6775 if (IS_BITVAR (retype))
6776 genUnpackBits (result, rname, POINTER);
6779 /* we have can just get the values */
6780 int size = AOP_SIZE (result);
6785 if (IS_AOP_PREG (result) || AOP_TYPE (result) == AOP_STK)
6788 emitcode ("mov", "a,@%s", rname);
6789 aopPut (AOP (result), "a", offset);
6793 sprintf (buffer, "@%s", rname);
6794 aopPut (AOP (result), buffer, offset);
6798 emitcode ("inc", "%s", rname);
6802 /* now some housekeeping stuff */
6803 if (aop) /* we had to allocate for this iCode */
6805 if (pi) { /* post increment present */
6806 aopPut(AOP ( left ),rname,0);
6808 freeAsmop (NULL, aop, ic, TRUE);
6812 /* we did not allocate which means left
6813 already in a pointer register, then
6814 if size > 0 && this could be used again
6815 we have to point it back to where it
6817 if ((AOP_SIZE (result) > 1 &&
6818 !OP_SYMBOL (left)->remat &&
6819 (OP_SYMBOL (left)->liveTo > ic->seq ||
6823 int size = AOP_SIZE (result) - 1;
6825 emitcode ("dec", "%s", rname);
6830 freeAsmop (left, NULL, ic, TRUE);
6831 freeAsmop (result, NULL, ic, TRUE);
6832 if (pi) pi->generated = 1;
6835 /*-----------------------------------------------------------------*/
6836 /* genPagedPointerGet - emitcode for paged pointer fetch */
6837 /*-----------------------------------------------------------------*/
6839 genPagedPointerGet (operand * left,
6847 sym_link *rtype, *retype;
6849 rtype = operandType (result);
6850 retype = getSpec (rtype);
6852 aopOp (left, ic, FALSE);
6854 /* if the value is already in a pointer register
6855 then don't need anything more */
6856 if (!AOP_INPREG (AOP (left)))
6858 /* otherwise get a free pointer register */
6860 preg = getFreePtr (ic, &aop, FALSE);
6861 emitcode ("mov", "%s,%s",
6863 aopGet (AOP (left), 0, FALSE, TRUE));
6867 rname = aopGet (AOP (left), 0, FALSE, FALSE);
6869 aopOp (result, ic, FALSE);
6871 /* if bitfield then unpack the bits */
6872 if (IS_BITVAR (retype))
6873 genUnpackBits (result, rname, PPOINTER);
6876 /* we have can just get the values */
6877 int size = AOP_SIZE (result);
6883 emitcode ("movx", "a,@%s", rname);
6884 aopPut (AOP (result), "a", offset);
6889 emitcode ("inc", "%s", rname);
6893 /* now some housekeeping stuff */
6894 if (aop) /* we had to allocate for this iCode */
6896 if (pi) aopPut ( AOP (left), rname, 0);
6897 freeAsmop (NULL, aop, ic, TRUE);
6901 /* we did not allocate which means left
6902 already in a pointer register, then
6903 if size > 0 && this could be used again
6904 we have to point it back to where it
6906 if ((AOP_SIZE (result) > 1 &&
6907 !OP_SYMBOL (left)->remat &&
6908 (OP_SYMBOL (left)->liveTo > ic->seq ||
6912 int size = AOP_SIZE (result) - 1;
6914 emitcode ("dec", "%s", rname);
6919 freeAsmop (left, NULL, ic, TRUE);
6920 freeAsmop (result, NULL, ic, TRUE);
6921 if (pi) pi->generated = 1;
6925 /*-----------------------------------------------------------------*/
6926 /* genFarPointerGet - gget value from far space */
6927 /*-----------------------------------------------------------------*/
6929 genFarPointerGet (operand * left,
6930 operand * result, iCode * ic, iCode * pi)
6933 sym_link *retype = getSpec (operandType (result));
6935 aopOp (left, ic, FALSE);
6937 /* if the operand is already in dptr
6938 then we do nothing else we move the value to dptr */
6939 if (AOP_TYPE (left) != AOP_STR)
6941 /* if this is remateriazable */
6942 if (AOP_TYPE (left) == AOP_IMMD)
6943 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
6945 { /* we need to get it byte by byte */
6946 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
6947 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
6950 /* so dptr know contains the address */
6951 aopOp (result, ic, FALSE);
6953 /* if bit then unpack */
6954 if (IS_BITVAR (retype))
6955 genUnpackBits (result, "dptr", FPOINTER);
6958 size = AOP_SIZE (result);
6963 emitcode ("movx", "a,@dptr");
6964 aopPut (AOP (result), "a", offset++);
6966 emitcode ("inc", "dptr");
6970 if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
6971 aopPut ( AOP (left), "dpl", 0);
6972 aopPut ( AOP (left), "dph", 1);
6975 freeAsmop (left, NULL, ic, TRUE);
6976 freeAsmop (result, NULL, ic, TRUE);
6979 /*-----------------------------------------------------------------*/
6980 /* genCodePointerGet - gget value from code space */
6981 /*-----------------------------------------------------------------*/
6983 genCodePointerGet (operand * left,
6984 operand * result, iCode * ic, iCode *pi)
6987 sym_link *retype = getSpec (operandType (result));
6989 aopOp (left, ic, FALSE);
6991 /* if the operand is already in dptr
6992 then we do nothing else we move the value to dptr */
6993 if (AOP_TYPE (left) != AOP_STR)
6995 /* if this is remateriazable */
6996 if (AOP_TYPE (left) == AOP_IMMD)
6997 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
6999 { /* we need to get it byte by byte */
7000 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
7001 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
7004 /* so dptr know contains the address */
7005 aopOp (result, ic, FALSE);
7007 /* if bit then unpack */
7008 if (IS_BITVAR (retype))
7009 genUnpackBits (result, "dptr", CPOINTER);
7012 size = AOP_SIZE (result);
7017 emitcode ("clr", "a");
7018 emitcode ("movc", "a,@a+dptr");
7019 aopPut (AOP (result), "a", offset++);
7021 emitcode ("inc", "dptr");
7025 if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
7026 aopPut ( AOP (left), "dpl", 0);
7027 aopPut ( AOP (left), "dph", 1);
7030 freeAsmop (left, NULL, ic, TRUE);
7031 freeAsmop (result, NULL, ic, TRUE);
7034 /*-----------------------------------------------------------------*/
7035 /* genGenPointerGet - gget value from generic pointer space */
7036 /*-----------------------------------------------------------------*/
7038 genGenPointerGet (operand * left,
7039 operand * result, iCode * ic, iCode *pi)
7042 sym_link *retype = getSpec (operandType (result));
7044 aopOp (left, ic, FALSE);
7046 /* if the operand is already in dptr
7047 then we do nothing else we move the value to dptr */
7048 if (AOP_TYPE (left) != AOP_STR)
7050 /* if this is remateriazable */
7051 if (AOP_TYPE (left) == AOP_IMMD)
7053 emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
7054 emitcode ("mov", "b,#%d", pointerCode (retype));
7057 { /* we need to get it byte by byte */
7058 emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
7059 emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
7060 emitcode ("mov", "b,%s", aopGet (AOP (left), 2, FALSE, FALSE));
7063 /* so dptr know contains the address */
7064 aopOp (result, ic, FALSE);
7066 /* if bit then unpack */
7067 if (IS_BITVAR (retype))
7068 genUnpackBits (result, "dptr", GPOINTER);
7071 size = AOP_SIZE (result);
7076 emitcode ("lcall", "__gptrget");
7077 aopPut (AOP (result), "a", offset++);
7079 emitcode ("inc", "dptr");
7083 if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
7084 aopPut ( AOP (left), "dpl", 0);
7085 aopPut ( AOP (left), "dph", 1);
7088 freeAsmop (left, NULL, ic, TRUE);
7089 freeAsmop (result, NULL, ic, TRUE);
7092 /*-----------------------------------------------------------------*/
7093 /* genPointerGet - generate code for pointer get */
7094 /*-----------------------------------------------------------------*/
7096 genPointerGet (iCode * ic, iCode *pi)
7098 operand *left, *result;
7099 sym_link *type, *etype;
7102 left = IC_LEFT (ic);
7103 result = IC_RESULT (ic);
7105 /* depending on the type of pointer we need to
7106 move it to the correct pointer register */
7107 type = operandType (left);
7108 etype = getSpec (type);
7109 /* if left is of type of pointer then it is simple */
7110 if (IS_PTR (type) && !IS_FUNC (type->next))
7111 p_type = DCL_TYPE (type);
7114 /* we have to go by the storage class */
7115 p_type = PTR_TYPE (SPEC_OCLS (etype));
7118 /* now that we have the pointer type we assign
7119 the pointer values */
7125 genNearPointerGet (left, result, ic, pi);
7129 genPagedPointerGet (left, result, ic, pi);
7133 genFarPointerGet (left, result, ic, pi);
7137 genCodePointerGet (left, result, ic, pi);
7141 genGenPointerGet (left, result, ic, pi);
7147 /*-----------------------------------------------------------------*/
7148 /* genPackBits - generates code for packed bit storage */
7149 /*-----------------------------------------------------------------*/
7151 genPackBits (sym_link * etype,
7153 char *rname, int p_type)
7161 blen = SPEC_BLEN (etype);
7162 bstr = SPEC_BSTR (etype);
7164 l = aopGet (AOP (right), offset++, FALSE, FALSE);
7167 /* if the bit lenth is less than or */
7168 /* it exactly fits a byte then */
7169 if (SPEC_BLEN (etype) <= 8)
7171 shCount = SPEC_BSTR (etype);
7173 /* shift left acc */
7176 if (SPEC_BLEN (etype) < 8)
7177 { /* if smaller than a byte */
7183 emitcode ("mov", "b,a");
7184 emitcode ("mov", "a,@%s", rname);
7188 emitcode ("mov", "b,a");
7189 emitcode ("movx", "a,@dptr");
7193 emitcode ("push", "b");
7194 emitcode ("push", "acc");
7195 emitcode ("lcall", "__gptrget");
7196 emitcode ("pop", "b");
7200 emitcode ("anl", "a,#0x%02x", (unsigned char)
7201 ((unsigned char) (0xFF << (blen + bstr)) |
7202 (unsigned char) (0xFF >> (8 - bstr))));
7203 emitcode ("orl", "a,b");
7204 if (p_type == GPOINTER)
7205 emitcode ("pop", "b");
7212 emitcode ("mov", "@%s,a", rname);
7216 emitcode ("movx", "@dptr,a");
7220 emitcode ("lcall", "__gptrput");
7225 if (SPEC_BLEN (etype) <= 8)
7228 emitcode ("inc", "%s", rname);
7229 rLen = SPEC_BLEN (etype);
7231 /* now generate for lengths greater than one byte */
7235 l = aopGet (AOP (right), offset++, FALSE, TRUE);
7247 emitcode ("mov", "@%s,a", rname);
7250 emitcode ("mov", "@%s,%s", rname, l);
7255 emitcode ("movx", "@dptr,a");
7260 emitcode ("lcall", "__gptrput");
7263 emitcode ("inc", "%s", rname);
7268 /* last last was not complete */
7271 /* save the byte & read byte */
7275 emitcode ("mov", "b,a");
7276 emitcode ("mov", "a,@%s", rname);
7280 emitcode ("mov", "b,a");
7281 emitcode ("movx", "a,@dptr");
7285 emitcode ("push", "b");
7286 emitcode ("push", "acc");
7287 emitcode ("lcall", "__gptrget");
7288 emitcode ("pop", "b");
7292 emitcode ("anl", "a,#0x%02x", (((unsigned char) -1 << rLen) & 0xff));
7293 emitcode ("orl", "a,b");
7296 if (p_type == GPOINTER)
7297 emitcode ("pop", "b");
7303 emitcode ("mov", "@%s,a", rname);
7307 emitcode ("movx", "@dptr,a");
7311 emitcode ("lcall", "__gptrput");
7315 /*-----------------------------------------------------------------*/
7316 /* genDataPointerSet - remat pointer to data space */
7317 /*-----------------------------------------------------------------*/
7319 genDataPointerSet (operand * right,
7323 int size, offset = 0;
7324 char *l, buffer[256];
7326 aopOp (right, ic, FALSE);
7328 l = aopGet (AOP (result), 0, FALSE, TRUE);
7329 size = AOP_SIZE (right);
7333 sprintf (buffer, "(%s + %d)", l + 1, offset);
7335 sprintf (buffer, "%s", l + 1);
7336 emitcode ("mov", "%s,%s", buffer,
7337 aopGet (AOP (right), offset++, FALSE, FALSE));
7340 freeAsmop (right, NULL, ic, TRUE);
7341 freeAsmop (result, NULL, ic, TRUE);
7344 /*-----------------------------------------------------------------*/
7345 /* genNearPointerSet - emitcode for near pointer put */
7346 /*-----------------------------------------------------------------*/
7348 genNearPointerSet (operand * right,
7356 sym_link *retype, *letype;
7357 sym_link *ptype = operandType (result);
7359 retype = getSpec (operandType (right));
7360 letype = getSpec (ptype);
7361 aopOp (result, ic, FALSE);
7363 /* if the result is rematerializable &
7364 in data space & not a bit variable */
7365 if (AOP_TYPE (result) == AOP_IMMD &&
7366 DCL_TYPE (ptype) == POINTER &&
7367 !IS_BITVAR (retype) &&
7368 !IS_BITVAR (letype))
7370 genDataPointerSet (right, result, ic);
7374 /* if the value is already in a pointer register
7375 then don't need anything more */
7376 if (!AOP_INPREG (AOP (result)))
7378 /* otherwise get a free pointer register */
7380 preg = getFreePtr (ic, &aop, FALSE);
7381 emitcode ("mov", "%s,%s",
7383 aopGet (AOP (result), 0, FALSE, TRUE));
7387 rname = aopGet (AOP (result), 0, FALSE, FALSE);
7389 aopOp (right, ic, FALSE);
7391 /* if bitfield then unpack the bits */
7392 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7393 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER);
7396 /* we have can just get the values */
7397 int size = AOP_SIZE (right);
7402 l = aopGet (AOP (right), offset, FALSE, TRUE);
7406 emitcode ("mov", "@%s,a", rname);
7409 emitcode ("mov", "@%s,%s", rname, l);
7411 emitcode ("inc", "%s", rname);
7416 /* now some housekeeping stuff */
7417 if (aop) /* we had to allocate for this iCode */
7419 if (pi) aopPut (AOP (result),rname,0);
7420 freeAsmop (NULL, aop, ic, TRUE);
7424 /* we did not allocate which means left
7425 already in a pointer register, then
7426 if size > 0 && this could be used again
7427 we have to point it back to where it
7429 if ((AOP_SIZE (right) > 1 &&
7430 !OP_SYMBOL (result)->remat &&
7431 (OP_SYMBOL (result)->liveTo > ic->seq ||
7435 int size = AOP_SIZE (right) - 1;
7437 emitcode ("dec", "%s", rname);
7442 if (pi) pi->generated = 1;
7443 freeAsmop (result, NULL, ic, TRUE);
7444 freeAsmop (right, NULL, ic, TRUE);
7447 /*-----------------------------------------------------------------*/
7448 /* genPagedPointerSet - emitcode for Paged pointer put */
7449 /*-----------------------------------------------------------------*/
7451 genPagedPointerSet (operand * right,
7459 sym_link *retype, *letype;
7461 retype = getSpec (operandType (right));
7462 letype = getSpec (operandType (result));
7464 aopOp (result, ic, FALSE);
7466 /* if the value is already in a pointer register
7467 then don't need anything more */
7468 if (!AOP_INPREG (AOP (result)))
7470 /* otherwise get a free pointer register */
7472 preg = getFreePtr (ic, &aop, FALSE);
7473 emitcode ("mov", "%s,%s",
7475 aopGet (AOP (result), 0, FALSE, TRUE));
7479 rname = aopGet (AOP (result), 0, FALSE, FALSE);
7481 aopOp (right, ic, FALSE);
7483 /* if bitfield then unpack the bits */
7484 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7485 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, PPOINTER);
7488 /* we have can just get the values */
7489 int size = AOP_SIZE (right);
7494 l = aopGet (AOP (right), offset, FALSE, TRUE);
7497 emitcode ("movx", "@%s,a", rname);
7500 emitcode ("inc", "%s", rname);
7506 /* now some housekeeping stuff */
7507 if (aop) /* we had to allocate for this iCode */
7509 if (pi) aopPut (AOP (result),rname,0);
7510 freeAsmop (NULL, aop, ic, TRUE);
7514 /* we did not allocate which means left
7515 already in a pointer register, then
7516 if size > 0 && this could be used again
7517 we have to point it back to where it
7519 if (AOP_SIZE (right) > 1 &&
7520 !OP_SYMBOL (result)->remat &&
7521 (OP_SYMBOL (result)->liveTo > ic->seq ||
7524 int size = AOP_SIZE (right) - 1;
7526 emitcode ("dec", "%s", rname);
7531 if (pi) pi->generated = 1;
7532 freeAsmop (result, NULL, ic, TRUE);
7533 freeAsmop (right, NULL, ic, TRUE);
7538 /*-----------------------------------------------------------------*/
7539 /* genFarPointerSet - set value from far space */
7540 /*-----------------------------------------------------------------*/
7542 genFarPointerSet (operand * right,
7543 operand * result, iCode * ic, iCode * pi)
7546 sym_link *retype = getSpec (operandType (right));
7547 sym_link *letype = getSpec (operandType (result));
7548 aopOp (result, ic, FALSE);
7550 /* if the operand is already in dptr
7551 then we do nothing else we move the value to dptr */
7552 if (AOP_TYPE (result) != AOP_STR)
7554 /* if this is remateriazable */
7555 if (AOP_TYPE (result) == AOP_IMMD)
7556 emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
7558 { /* we need to get it byte by byte */
7559 emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
7560 emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
7563 /* so dptr know contains the address */
7564 aopOp (right, ic, FALSE);
7566 /* if bit then unpack */
7567 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7568 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
7571 size = AOP_SIZE (right);
7576 char *l = aopGet (AOP (right), offset++, FALSE, FALSE);
7578 emitcode ("movx", "@dptr,a");
7580 emitcode ("inc", "dptr");
7583 if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
7584 aopPut (AOP(result),"dpl",0);
7585 aopPut (AOP(result),"dph",1);
7588 freeAsmop (result, NULL, ic, TRUE);
7589 freeAsmop (right, NULL, ic, TRUE);
7592 /*-----------------------------------------------------------------*/
7593 /* genGenPointerSet - set value from generic pointer space */
7594 /*-----------------------------------------------------------------*/
7596 genGenPointerSet (operand * right,
7597 operand * result, iCode * ic, iCode * pi)
7600 sym_link *retype = getSpec (operandType (right));
7601 sym_link *letype = getSpec (operandType (result));
7603 aopOp (result, ic, FALSE);
7605 /* if the operand is already in dptr
7606 then we do nothing else we move the value to dptr */
7607 if (AOP_TYPE (result) != AOP_STR)
7609 /* if this is remateriazable */
7610 if (AOP_TYPE (result) == AOP_IMMD)
7612 emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
7613 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
7616 { /* we need to get it byte by byte */
7617 emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
7618 emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
7619 emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE));
7622 /* so dptr know contains the address */
7623 aopOp (right, ic, FALSE);
7625 /* if bit then unpack */
7626 if (IS_BITVAR (retype) || IS_BITVAR (letype))
7627 genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", GPOINTER);
7630 size = AOP_SIZE (right);
7635 char *l = aopGet (AOP (right), offset++, FALSE, FALSE);
7637 emitcode ("lcall", "__gptrput");
7639 emitcode ("inc", "dptr");
7643 if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
7644 aopPut (AOP(result),"dpl",0);
7645 aopPut (AOP(result),"dph",1);
7648 freeAsmop (result, NULL, ic, TRUE);
7649 freeAsmop (right, NULL, ic, TRUE);
7652 /*-----------------------------------------------------------------*/
7653 /* genPointerSet - stores the value into a pointer location */
7654 /*-----------------------------------------------------------------*/
7656 genPointerSet (iCode * ic, iCode *pi)
7658 operand *right, *result;
7659 sym_link *type, *etype;
7662 right = IC_RIGHT (ic);
7663 result = IC_RESULT (ic);
7665 /* depending on the type of pointer we need to
7666 move it to the correct pointer register */
7667 type = operandType (result);
7668 etype = getSpec (type);
7669 /* if left is of type of pointer then it is simple */
7670 if (IS_PTR (type) && !IS_FUNC (type->next))
7672 p_type = DCL_TYPE (type);
7676 /* we have to go by the storage class */
7677 p_type = PTR_TYPE (SPEC_OCLS (etype));
7680 /* now that we have the pointer type we assign
7681 the pointer values */
7687 genNearPointerSet (right, result, ic, pi);
7691 genPagedPointerSet (right, result, ic, pi);
7695 genFarPointerSet (right, result, ic, pi);
7699 genGenPointerSet (right, result, ic, pi);
7705 /*-----------------------------------------------------------------*/
7706 /* genIfx - generate code for Ifx statement */
7707 /*-----------------------------------------------------------------*/
7709 genIfx (iCode * ic, iCode * popIc)
7711 operand *cond = IC_COND (ic);
7714 aopOp (cond, ic, FALSE);
7716 /* get the value into acc */
7717 if (AOP_TYPE (cond) != AOP_CRY)
7721 /* the result is now in the accumulator */
7722 freeAsmop (cond, NULL, ic, TRUE);
7724 /* if there was something to be popped then do it */
7728 /* if the condition is a bit variable */
7729 if (isbit && IS_ITEMP (cond) &&
7731 genIfxJump (ic, SPIL_LOC (cond)->rname);
7732 else if (isbit && !IS_ITEMP (cond))
7733 genIfxJump (ic, OP_SYMBOL (cond)->rname);
7735 genIfxJump (ic, "a");
7740 /*-----------------------------------------------------------------*/
7741 /* genAddrOf - generates code for address of */
7742 /*-----------------------------------------------------------------*/
7744 genAddrOf (iCode * ic)
7746 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
7749 aopOp (IC_RESULT (ic), ic, FALSE);
7751 /* if the operand is on the stack then we
7752 need to get the stack offset of this
7756 /* if it has an offset then we need to compute
7760 emitcode ("mov", "a,_bp");
7761 emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
7762 aopPut (AOP (IC_RESULT (ic)), "a", 0);
7766 /* we can just move _bp */
7767 aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
7769 /* fill the result with zero */
7770 size = AOP_SIZE (IC_RESULT (ic)) - 1;
7775 aopPut (AOP (IC_RESULT (ic)), zero, offset++);
7781 /* object not on stack then we need the name */
7782 size = AOP_SIZE (IC_RESULT (ic));
7787 char s[SDCC_NAME_MAX];
7789 sprintf (s, "#(%s >> %d)",
7793 sprintf (s, "#%s", sym->rname);
7794 aopPut (AOP (IC_RESULT (ic)), s, offset++);
7798 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
7802 /*-----------------------------------------------------------------*/
7803 /* genFarFarAssign - assignment when both are in far space */
7804 /*-----------------------------------------------------------------*/
7806 genFarFarAssign (operand * result, operand * right, iCode * ic)
7808 int size = AOP_SIZE (right);
7811 /* first push the right side on to the stack */
7814 l = aopGet (AOP (right), offset++, FALSE, FALSE);
7816 emitcode ("push", "acc");
7819 freeAsmop (right, NULL, ic, FALSE);
7820 /* now assign DPTR to result */
7821 aopOp (result, ic, FALSE);
7822 size = AOP_SIZE (result);
7825 emitcode ("pop", "acc");
7826 aopPut (AOP (result), "a", --offset);
7828 freeAsmop (result, NULL, ic, FALSE);
7832 /*-----------------------------------------------------------------*/
7833 /* genAssign - generate code for assignment */
7834 /*-----------------------------------------------------------------*/
7836 genAssign (iCode * ic)
7838 operand *result, *right;
7840 unsigned long lit = 0L;
7842 result = IC_RESULT (ic);
7843 right = IC_RIGHT (ic);
7845 /* if they are the same */
7846 if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
7849 aopOp (right, ic, FALSE);
7851 /* special case both in far space */
7852 if ((AOP_TYPE (right) == AOP_DPTR ||
7853 AOP_TYPE (right) == AOP_DPTR2) &&
7854 IS_TRUE_SYMOP (result) &&
7855 isOperandInFarSpace (result))
7858 genFarFarAssign (result, right, ic);
7862 aopOp (result, ic, TRUE);
7864 /* if they are the same registers */
7865 if (sameRegs (AOP (right), AOP (result)))
7868 /* if the result is a bit */
7869 if (AOP_TYPE (result) == AOP_CRY)
7872 /* if the right size is a literal then
7873 we know what the value is */
7874 if (AOP_TYPE (right) == AOP_LIT)
7876 if (((int) operandLitValue (right)))
7877 aopPut (AOP (result), one, 0);
7879 aopPut (AOP (result), zero, 0);
7883 /* the right is also a bit variable */
7884 if (AOP_TYPE (right) == AOP_CRY)
7886 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
7887 aopPut (AOP (result), "c", 0);
7893 aopPut (AOP (result), "a", 0);
7897 /* bit variables done */
7899 size = AOP_SIZE (result);
7901 if (AOP_TYPE (right) == AOP_LIT)
7902 lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
7904 (AOP_TYPE (result) != AOP_REG) &&
7905 (AOP_TYPE (right) == AOP_LIT) &&
7906 !IS_FLOAT (operandType (right)) &&
7909 emitcode ("clr", "a");
7912 if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) == 0)
7913 aopPut (AOP (result), "a", size);
7915 aopPut (AOP (result),
7916 aopGet (AOP (right), size, FALSE, FALSE),
7924 aopPut (AOP (result),
7925 aopGet (AOP (right), offset, FALSE, FALSE),
7932 freeAsmop (right, NULL, ic, TRUE);
7933 freeAsmop (result, NULL, ic, TRUE);
7936 /*-----------------------------------------------------------------*/
7937 /* genJumpTab - genrates code for jump table */
7938 /*-----------------------------------------------------------------*/
7940 genJumpTab (iCode * ic)
7945 aopOp (IC_JTCOND (ic), ic, FALSE);
7946 /* get the condition into accumulator */
7947 l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
7949 /* multiply by three */
7950 emitcode ("add", "a,acc");
7951 emitcode ("add", "a,%s", aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE));
7952 freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
7954 jtab = newiTempLabel (NULL);
7955 emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
7956 emitcode ("jmp", "@a+dptr");
7957 emitcode ("", "%05d$:", jtab->key + 100);
7958 /* now generate the jump labels */
7959 for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
7960 jtab = setNextItem (IC_JTLABELS (ic)))
7961 emitcode ("ljmp", "%05d$", jtab->key + 100);
7965 /*-----------------------------------------------------------------*/
7966 /* genCast - gen code for casting */
7967 /*-----------------------------------------------------------------*/
7969 genCast (iCode * ic)
7971 operand *result = IC_RESULT (ic);
7972 sym_link *ctype = operandType (IC_LEFT (ic));
7973 sym_link *rtype = operandType (IC_RIGHT (ic));
7974 operand *right = IC_RIGHT (ic);
7977 /* if they are equivalent then do nothing */
7978 if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
7981 aopOp (right, ic, FALSE);
7982 aopOp (result, ic, FALSE);
7984 /* if the result is a bit */
7985 if (AOP_TYPE (result) == AOP_CRY)
7987 /* if the right size is a literal then
7988 we know what the value is */
7989 if (AOP_TYPE (right) == AOP_LIT)
7991 if (((int) operandLitValue (right)))
7992 aopPut (AOP (result), one, 0);
7994 aopPut (AOP (result), zero, 0);
7999 /* the right is also a bit variable */
8000 if (AOP_TYPE (right) == AOP_CRY)
8002 emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
8003 aopPut (AOP (result), "c", 0);
8009 aopPut (AOP (result), "a", 0);
8013 /* if they are the same size : or less */
8014 if (AOP_SIZE (result) <= AOP_SIZE (right))
8017 /* if they are in the same place */
8018 if (sameRegs (AOP (right), AOP (result)))
8021 /* if they in different places then copy */
8022 size = AOP_SIZE (result);
8026 aopPut (AOP (result),
8027 aopGet (AOP (right), offset, FALSE, FALSE),
8035 /* if the result is of type pointer */
8040 sym_link *type = operandType (right);
8041 sym_link *etype = getSpec (type);
8043 /* pointer to generic pointer */
8044 if (IS_GENPTR (ctype))
8049 p_type = DCL_TYPE (type);
8052 /* we have to go by the storage class */
8053 p_type = PTR_TYPE (SPEC_OCLS (etype));
8056 /* the first two bytes are known */
8057 size = GPTRSIZE - 1;
8061 aopPut (AOP (result),
8062 aopGet (AOP (right), offset, FALSE, FALSE),
8066 /* the last byte depending on type */
8084 /* this should never happen */
8085 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8086 "got unknown pointer type");
8089 aopPut (AOP (result), l, GPTRSIZE - 1);
8093 /* just copy the pointers */
8094 size = AOP_SIZE (result);
8098 aopPut (AOP (result),
8099 aopGet (AOP (right), offset, FALSE, FALSE),
8106 /* so we now know that the size of destination is greater
8107 than the size of the source */
8108 /* we move to result for the size of source */
8109 size = AOP_SIZE (right);
8113 aopPut (AOP (result),
8114 aopGet (AOP (right), offset, FALSE, FALSE),
8119 /* now depending on the sign of the source && destination */
8120 size = AOP_SIZE (result) - AOP_SIZE (right);
8121 /* if unsigned or not an integral type */
8122 if (SPEC_USIGN (rtype) || !IS_SPEC (rtype))
8125 aopPut (AOP (result), zero, offset++);
8129 /* we need to extend the sign :{ */
8130 char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
8133 emitcode ("rlc", "a");
8134 emitcode ("subb", "a,acc");
8136 aopPut (AOP (result), "a", offset++);
8139 /* we are done hurray !!!! */
8142 freeAsmop (right, NULL, ic, TRUE);
8143 freeAsmop (result, NULL, ic, TRUE);
8147 /*-----------------------------------------------------------------*/
8148 /* genDjnz - generate decrement & jump if not zero instrucion */
8149 /*-----------------------------------------------------------------*/
8151 genDjnz (iCode * ic, iCode * ifx)
8157 /* if the if condition has a false label
8158 then we cannot save */
8162 /* if the minus is not of the form
8164 if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
8165 !IS_OP_LITERAL (IC_RIGHT (ic)))
8168 if (operandLitValue (IC_RIGHT (ic)) != 1)
8171 /* if the size of this greater than one then no
8173 if (getSize (operandType (IC_RESULT (ic))) > 1)
8176 /* otherwise we can save BIG */
8177 lbl = newiTempLabel (NULL);
8178 lbl1 = newiTempLabel (NULL);
8180 aopOp (IC_RESULT (ic), ic, FALSE);
8182 if (IS_AOP_PREG (IC_RESULT (ic)))
8184 emitcode ("dec", "%s",
8185 aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
8186 emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
8187 emitcode ("jnz", "%05d$", lbl->key + 100);
8191 emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE),
8194 emitcode ("sjmp", "%05d$", lbl1->key + 100);
8195 emitcode ("", "%05d$:", lbl->key + 100);
8196 emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
8197 emitcode ("", "%05d$:", lbl1->key + 100);
8199 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
8204 /*-----------------------------------------------------------------*/
8205 /* genReceive - generate code for a receive iCode */
8206 /*-----------------------------------------------------------------*/
8208 genReceive (iCode * ic)
8210 if (isOperandInFarSpace (IC_RESULT (ic)) &&
8211 (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
8212 IS_TRUE_SYMOP (IC_RESULT (ic))))
8215 int size = getSize (operandType (IC_RESULT (ic)));
8216 int offset = fReturnSizeMCS51 - size;
8219 emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ?
8220 fReturn[fReturnSizeMCS51 - offset - 1] : "acc"));
8223 aopOp (IC_RESULT (ic), ic, FALSE);
8224 size = AOP_SIZE (IC_RESULT (ic));
8228 emitcode ("pop", "acc");
8229 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
8236 aopOp (IC_RESULT (ic), ic, FALSE);
8238 assignResultValue (IC_RESULT (ic));
8241 freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
8244 /*-----------------------------------------------------------------*/
8245 /* gen51Code - generate code for 8051 based controllers */
8246 /*-----------------------------------------------------------------*/
8248 gen51Code (iCode * lic)
8253 lineHead = lineCurr = NULL;
8255 /* print the allocation information */
8257 printAllocInfo (currFunc, codeOutFile);
8258 /* if debug information required */
8259 /* if (options.debug && currFunc) { */
8262 cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
8264 if (IS_STATIC (currFunc->etype))
8265 emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
8267 emitcode ("", "G$%s$0$0 ==.", currFunc->name);
8270 /* stack pointer name */
8271 if (options.useXstack)
8277 for (ic = lic; ic; ic = ic->next)
8280 if (cln != ic->lineno)
8285 emitcode ("", "C$%s$%d$%d$%d ==.",
8286 FileBaseName (ic->filename), ic->lineno,
8287 ic->level, ic->block);
8290 emitcode (";", "%s %d", ic->filename, ic->lineno);
8293 /* if the result is marked as
8294 spilt and rematerializable or code for
8295 this has already been generated then
8297 if (resultRemat (ic) || ic->generated)
8300 /* depending on the operation */
8320 /* IPOP happens only when trying to restore a
8321 spilt live range, if there is an ifx statement
8322 following this pop then the if statement might
8323 be using some of the registers being popped which
8324 would destory the contents of the register so
8325 we need to check for this condition and handle it */
8327 ic->next->op == IFX &&
8328 regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
8329 genIfx (ic->next, ic);
8347 genEndFunction (ic);
8367 if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
8384 genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
8388 genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
8395 /* note these two are xlated by algebraic equivalence
8396 during parsing SDCC.y */
8397 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8398 "got '>=' or '<=' shouldn't have come here");
8402 genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
8414 genXor (ic, ifxForOp (IC_RESULT (ic), ic));
8418 genOr (ic, ifxForOp (IC_RESULT (ic), ic));
8422 genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
8449 case GET_VALUE_AT_ADDRESS:
8450 genPointerGet (ic, hasInc(IC_LEFT(ic),ic));
8454 if (POINTER_SET (ic))
8455 genPointerSet (ic, hasInc (IC_RESULT(ic),ic));
8481 addSet (&_G.sendSet, ic);
8490 /* now we are ready to call the
8491 peep hole optimizer */
8492 if (!options.nopeep)
8493 peepHole (&lineHead);
8495 /* now do the actual printing */
8496 printLine (lineHead, codeOutFile);