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!
26 -------------------------------------------------------------------------*/
35 #include "SDCCglobl.h"
38 #ifdef HAVE_SYS_ISA_DEFS_H
39 #include <sys/isa_defs.h>
41 #ifdef HAVE_MACHINE_ENDIAN_H
42 #include <machine/endian.h>
47 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
48 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
49 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
56 #include "SDCCpeeph.h"
60 #if defined(__BORLANDC__) || defined(_MSC_VER)
61 #define STRCASECMP stricmp
63 #define STRCASECMP strcasecmp
68 /* this is the down and dirty file with all kinds of
69 kludgy & hacky stuff. This is what it is all about
70 CODE GENERATION for a specific MCU . some of the
71 routines may be reusable, will have to see */
84 extern int xa51_ptrRegReq;
85 extern int xa51_nRegs;
86 extern FILE *codeOutFile;
88 static lineNode *lineHead = NULL;
89 static lineNode *lineCurr = NULL;
96 static char *MOV="mov";
97 static char *MOVB="mov.b";
98 static char *MOVW="mov.w";
99 static char *MOVC="movc";
100 static char *MOVCB="movc.b";
101 static char *MOVCW="movc.w";
103 static char *R1L="r1l";
104 static char *R1="r1";
106 void bailOut (char *mesg) {
107 fprintf (stderr, "%s: bailing out\n", mesg);
111 /*-----------------------------------------------------------------*/
112 /* emitcode - writes the code into a file : for now it is simple */
113 /*-----------------------------------------------------------------*/
114 static void emitcode (char *inst, char *fmt,...) {
116 char lb[INITIAL_INLINEASM];
124 sprintf (lb, "%s\t", inst);
126 sprintf (lb, "%s", inst);
127 vsprintf (lb + (strlen (lb)), fmt, ap);
130 vsprintf (lb, fmt, ap);
132 while (isspace ((int)*lbp))
136 lineCurr = (lineCurr ?
137 connectLine (lineCurr, newLineNode (lb)) :
138 (lineHead = newLineNode (lb)));
139 lineCurr->isInline = _G.inLine;
140 lineCurr->isDebug = _G.debugLine;
144 char *getStackOffset(int stack) {
145 static char gsoBuf[1024];
146 sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
147 currFunc->stack, _G.nRegsSaved);
151 /*-----------------------------------------------------------------*/
152 /* newAsmop - creates a new asmOp */
153 /*-----------------------------------------------------------------*/
155 newAsmop (short type)
159 aop = Safe_calloc (1, sizeof (asmop));
164 char *aopTypeName(asmop *aop) {
167 case AOP_LIT: return "lit";
168 case AOP_REG: return "reg";
169 case AOP_DIR: return "dir";
170 case AOP_FAR: return "far";
171 case AOP_CODE: return "code";
172 case AOP_GPTR: return "gptr";
173 case AOP_STK: return "stack";
174 case AOP_IMMD: return "imm";
175 case AOP_BIT: return "bit";
180 /*-----------------------------------------------------------------*/
181 /* aopForSym - for a true symbol */
182 /*-----------------------------------------------------------------*/
183 static asmop *aopForSym(symbol *sym,
184 bool canUsePointer, bool canUseOffset) {
188 sym->aop = aop = newAsmop(0);
189 size=aop->size=getSize(sym->type);
191 // if the sym has registers
192 if (sym->nRegs && sym->regs[0]) {
194 sprintf (aop->name[0], sym->regs[0]->name);
196 sprintf (aop->name[1], sym->regs[1]->name);
203 if (!canUsePointer || !canUseOffset) {
208 emitcode ("mov.b", "r0l,[%s]", getStackOffset(sym->stack));
209 sprintf (aop->name[0], "r0l");
212 emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
213 sprintf (aop->name[0], "r0");
216 emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
217 sprintf (aop->name[0], "r0");
218 emitcode ("mov.b", "r1l,[%s]", getStackOffset(sym->stack+2));
219 sprintf (aop->name[1], "r1l");
222 emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
223 sprintf (aop->name[0], "r0");
224 emitcode ("mov.w", "r1,[%s]", getStackOffset(sym->stack+2));
225 sprintf (aop->name[1], "r1");
230 sprintf (aop->name[0], "[%s]", getStackOffset(sym->stack));
232 sprintf (aop->name[1], "[%s]", getStackOffset(sym->stack+2));
237 // if it has a spillLoc
238 if (sym->usl.spillLoc) {
239 return aopForSym (sym->usl.spillLoc, canUsePointer, canUseOffset);
243 if (IN_BITSPACE(SPEC_OCLS(sym->etype))) {
245 sprintf (aop->name[0], sym->rname);
249 // if in direct space
250 if (IN_DIRSPACE(SPEC_OCLS(sym->etype))) {
252 sprintf (aop->name[0], sym->rname);
254 sprintf (aop->name[1], "%s+2", sym->rname);
260 if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
261 if (!canUsePointer) {
266 emitcode (MOV, "r0,#%s", sym->rname);
267 emitcode (MOVC, "r0l,[r0+]");
268 sprintf (aop->name[0], "r0l");
271 emitcode (MOV, "r0,#%s", sym->rname);
272 emitcode (MOVC, "r0,[r0+]");
273 sprintf (aop->name[0], "r0");
276 emitcode (MOV, "r0,#%s", sym->rname);
277 emitcode (MOVC, "r0,[r0+]");
278 sprintf (aop->name[1], "r0");
279 emitcode (MOV, "r1l,[r0+]");
280 sprintf (aop->name[0], "r1l");
283 emitcode (MOV, "r0,#%s", sym->rname);
284 emitcode (MOVC, "r1,[r0+]");
285 emitcode (MOVC, "r0,[r0+]");
286 emitcode ("xch", "r0,r1");
287 sprintf (aop->name[0], "r0");
288 sprintf (aop->name[1], "r1");
294 emitcode ("mov", "r0,#%s ; aopForSym:code", sym->rname);
295 sprintf (aop->name[0], "[r0]");
297 sprintf (aop->name[1], "[r0+2]");
304 if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
305 if (!canUsePointer) {
310 emitcode (MOV, "r0,#%s", sym->rname);
311 emitcode (MOV, "r0l,[r0]");
312 sprintf (aop->name[0], "r0l");
315 emitcode (MOV, "r0,#%s", sym->rname);
316 emitcode (MOV, "r0,[r0]");
317 sprintf (aop->name[0], "r0");
320 emitcode (MOV, "r0,#%s", sym->rname);
321 emitcode (MOV, "r1l,[r0+2]");
322 sprintf (aop->name[1], "r1l");
323 emitcode (MOV, "r0,[r0]");
324 sprintf (aop->name[0], "r0");
327 emitcode (MOV, "r0,#%s", sym->rname);
328 emitcode (MOV, "r1,[r0+2]");
329 sprintf (aop->name[1], "r1");
330 emitcode (MOV, "r0,[r0]");
331 sprintf (aop->name[0], "r0");
336 emitcode ("mov.w", "r0,#%s ; aopForSym:far", sym->rname);
337 sprintf (aop->name[0], "[r0]");
339 sprintf (aop->name[1], "[r0+2]");
345 bailOut("aopForSym");
349 /*-----------------------------------------------------------------*/
350 /* aopForVal - for a value */
351 /*-----------------------------------------------------------------*/
352 static asmop *aopForVal(operand *op) {
355 if (IS_OP_LITERAL(op)) {
356 op->aop = aop = newAsmop (AOP_LIT);
357 switch ((aop->size=getSize(operandType(op))))
360 sprintf (aop->name[0], "#0x%02x",
361 SPEC_CVAL(operandType(op)).v_int & 0xff);
362 sprintf (aop->name[1], "#0");
365 sprintf (aop->name[0], "#0x%04x",
366 SPEC_CVAL(operandType(op)).v_int & 0xffff);
367 sprintf (aop->name[1], "#0");
370 // must be a generic pointer, can only be zero
371 // ?? if (v!=0) fprintf (stderr, "invalid val op for gptr\n"); exit(1);
372 sprintf (aop->name[0], "#0x%04x",
373 SPEC_CVAL(operandType(op)).v_uint & 0xffff);
374 sprintf (aop->name[1], "#0");
377 sprintf (aop->name[0], "#0x%04lx",
378 SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
379 sprintf (aop->name[1], "#0x%04lx",
380 SPEC_CVAL(operandType(op)).v_ulong >> 16);
383 bailOut("aopForVal");
390 op->aop = aop = newAsmop (AOP_IMMD);
391 switch ((aop->size=getSize(OP_SYMBOL(op)->type)))
395 sprintf (aop->name[0], "#%s", OP_SYMBOL(op)->rname);
397 case 3: // generic pointer
398 sprintf (aop->name[0], "#0x%02x", DCL_TYPE(operandType(op)));
399 sprintf (aop->name[1], "#%s", OP_SYMBOL(op)->rname);
404 bailOut ("aopForVal: unknown type");
408 static int aopOp(operand *op,
409 bool canUsePointer, bool canUseOffset) {
412 op->aop=aopForSym (OP_SYMBOL(op), canUsePointer, canUseOffset);
416 op->aop=aopForVal (op);
420 bailOut("aopOp: unexpected operand");
424 bool aopEqual(asmop *aop1, asmop *aop2, int offset) {
425 if (strcmp(aop1->name[offset], aop2->name[offset])) {
431 bool aopIsDir(operand *op) {
432 return AOP_TYPE(op)==AOP_DIR;
435 bool aopIsBit(operand *op) {
436 return AOP_TYPE(op)==AOP_BIT;
439 bool aopIsPtr(operand *op) {
440 if (AOP_TYPE(op)==AOP_STK ||
441 AOP_TYPE(op)==AOP_CODE ||
442 AOP_TYPE(op)==AOP_FAR) {
449 char *opRegName(operand *op, int offset, char *opName, bool decorate) {
452 if (OP_SYMBOL(op)->onStack) {
453 sprintf (opName, "[%s]", getStackOffset(OP_SYMBOL(op)->stack));
456 if (IS_TRUE_SYMOP(op))
457 return OP_SYMBOL(op)->rname;
458 else if (OP_SYMBOL(op)->regs[offset])
459 return OP_SYMBOL(op)->regs[offset]->name;
461 bailOut("opRegName: unknown regs");
465 switch (SPEC_NOUN(OP_VALUE(op)->type)) {
468 if (SPEC_CVAL(OP_VALUE(op)->type).v_int &&
469 SPEC_CVAL(OP_VALUE(op)->type).v_int != 1) {
470 bailOut("opRegName: invalid bit value");
474 sprintf (opName, "#%s0x%02x", decorate?"(char)":"",
475 SPEC_CVAL(OP_VALUE(op)->type).v_int);
478 if (SPEC_LONG(OP_VALUE(op)->type)) {
479 sprintf (opName, "#%s0x%02lx", decorate?"(long)":"",
480 SPEC_CVAL(OP_VALUE(op)->type).v_long);
482 sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
483 SPEC_CVAL(OP_VALUE(op)->type).v_int);
487 sprintf (opName, "#%s%f", decorate?"(float)":"",
488 SPEC_CVAL(OP_VALUE(op)->type).v_float);
491 bailOut("opRegName: unexpected noun");
495 bailOut("opRegName: unexpected operand type");
499 char * printOp (operand *op) {
500 static char line[132];
501 sym_link *optype=operandType(op);
502 bool isPtr = IS_PTR(optype);
505 symbol *sym=OP_SYMBOL(op);
506 if (!sym->regs[0] && SYM_SPIL_LOC(sym)) {
507 sym=SYM_SPIL_LOC(sym);
511 if (DCL_TYPE(optype)==FPOINTER)
512 strcat (line, "far * ");
513 else if (DCL_TYPE(optype)==CPOINTER)
514 strcat (line, "code * ");
515 else if (DCL_TYPE(optype)==GPOINTER)
516 strcat (line, "gen * ");
517 else if (DCL_TYPE(optype)==POINTER)
518 strcat (line, "near * ");
520 strcat (line, "unknown * ");
522 strcat (line, nounName(sym->etype));
524 strcat (line, sym->name);
527 sprintf (line, "(%s)%s:", nounName(sym->etype), sym->name);
530 strcat (line, sym->regs[0]->name);
533 strcat (line, sym->regs[1]->name);
538 sprintf (line+strlen(line), "stack%+d", sym->stack);
541 if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
542 strcat (line, "code");
545 if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
546 strcat (line, "far");
549 if (IN_BITSPACE(SPEC_OCLS(sym->etype))) {
550 strcat (line, "bit");
553 if (IN_DIRSPACE(SPEC_OCLS(sym->etype))) {
554 strcat (line, "dir");
557 strcat (line, "unknown");
559 } else if (IS_VALOP(op)) {
560 opRegName(op, 0, line, 1);
561 } else if (IS_TYPOP(op)) {
564 if (DCL_TYPE(optype)==FPOINTER)
565 strcat (line, "far * ");
566 else if (DCL_TYPE(optype)==CPOINTER)
567 strcat (line, "code * ");
568 else if (DCL_TYPE(optype)==GPOINTER)
569 strcat (line, "gen * ");
570 else if (DCL_TYPE(optype)==POINTER)
571 strcat (line, "near * ");
573 strcat (line, "unknown * ");
575 // forget about static, volatile, ... for now
576 if (SPEC_USIGN(operandType(op))) strcat (line, "unsigned ");
577 if (SPEC_LONG(operandType(op))) strcat (line, "long ");
578 strcat (line, nounName(operandType(op)));
581 bailOut("printOp: unexpected operand type");
586 void printIc (char *op, iCode * ic, bool result, bool left, bool right) {
589 sprintf (line, "%s(%d)", op, ic->lineno);
591 strcat (line, " result=");
592 strcat (line, printOp (IC_RESULT(ic)));
595 strcat (line, " left=");
596 strcat (line, printOp (IC_LEFT(ic)));
599 strcat (line, " right=");
600 strcat (line, printOp (IC_RIGHT(ic)));
602 emitcode (";", line);
605 /*-----------------------------------------------------------------*/
606 /* toBoolean - return carry for operand!=0 */
607 /*-----------------------------------------------------------------*/
608 static char *toBoolean (operand * op) {
609 symbol *tlbl=newiTempLabel(NULL);
611 switch (AOP_SIZE(op))
615 emitcode ("cjne", "%s,#1,%05d$; %s", AOP_NAME(op), tlbl->key+100,
616 "This needs a second thought");
618 emitcode ("", "%05d$:", tlbl->key+100);
622 bailOut("toBoolean: unknown size");
626 /*-----------------------------------------------------------------*/
627 /* regsInCommon - two operands have some registers in common */
628 /*-----------------------------------------------------------------*/
629 static bool regsInCommon (operand * op1, operand * op2) {
633 /* if they have registers in common */
634 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
637 sym1 = OP_SYMBOL (op1);
638 sym2 = OP_SYMBOL (op2);
640 if (sym1->nRegs == 0 || sym2->nRegs == 0)
643 for (i = 0; i < sym1->nRegs; i++)
649 for (j = 0; j < sym2->nRegs; j++)
654 if (sym2->regs[j] == sym1->regs[i])
662 /*-----------------------------------------------------------------*/
663 /* resultRemat - result is rematerializable */
664 /*-----------------------------------------------------------------*/
665 static int resultRemat (iCode * ic) {
666 if (SKIP_IC (ic) || ic->op == IFX)
669 if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
671 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
672 if (sym->remat && !POINTER_SET (ic))
679 /*-----------------------------------------------------------------*/
680 /* genNot - generate code for ! operation */
681 /*-----------------------------------------------------------------*/
682 static void genNot (iCode * ic) {
683 printIc("genNot:", ic, 1,1,0);
686 /*-----------------------------------------------------------------*/
687 /* genCpl - generate code for complement */
688 /*-----------------------------------------------------------------*/
689 static void genCpl (iCode * ic) {
690 printIc("genCpl", ic, 1,1,0);
693 /*-----------------------------------------------------------------*/
694 /* genUminus - unary minus code generation */
695 /*-----------------------------------------------------------------*/
696 static void genUminus (iCode * ic) {
697 printIc("genUminus", ic, 1,1,0);
700 /*-----------------------------------------------------------------*/
701 /* genIpush - generate code for pushing */
702 /*-----------------------------------------------------------------*/
703 static void genIpush (iCode * ic) {
704 operand *left=IC_LEFT(ic);
706 printIc ("genIpush", ic, 0,1,0);
707 aopOp(left,FALSE,FALSE);
710 if (AOP_TYPE(left)==AOP_LIT) {
711 switch (AOP_SIZE(left))
714 emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
715 emitcode ("push", "r1l");
719 emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
720 emitcode ("push", "r1");
724 emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
725 emitcode ("push", "r1l");
726 emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
727 emitcode ("push", "r1");
731 emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
732 emitcode ("push", "r1");
733 emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
734 emitcode ("push", "r1");
739 if (AOP_SIZE(left)>2) {
740 emitcode ("push", "%s", AOP_NAME(left)[1]);
743 emitcode ("push", "%s", AOP_NAME(left)[0]);
748 /*-----------------------------------------------------------------*/
749 /* genIpop - recover the registers: can happen only for spilling */
750 /*-----------------------------------------------------------------*/
751 static void genIpop (iCode * ic) {
752 printIc ("genIpop", ic, 0,1,0);
755 /*-----------------------------------------------------------------*/
756 /* genCall - generates a call statement */
757 /*-----------------------------------------------------------------*/
758 static void genCall (iCode * ic) {
759 operand *result=IC_RESULT(ic);
761 emitcode (";", "genCall(%d) %s result=%s", ic->lineno,
762 OP_SYMBOL(IC_LEFT(ic))->name,
763 printOp (IC_RESULT(ic)));
764 emitcode ("call", "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
766 /* readjust the stack if we have pushed some parms */
767 if (_G.parmsPushed) {
768 emitcode ("add", "r7,#0x%02x", _G.parmsPushed*2);
772 /* if we need to assign a result value */
773 if (IS_ITEMP (IC_RESULT(ic)) &&
774 OP_SYMBOL (IC_RESULT (ic))->nRegs) {
775 aopOp(result,FALSE,FALSE);
776 switch (AOP_SIZE(result))
779 emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
782 emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
786 emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
787 emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
790 emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
791 emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
798 /*-----------------------------------------------------------------*/
799 /* genPcall - generates a call by pointer statement */
800 /*-----------------------------------------------------------------*/
802 genPcall (iCode * ic)
804 emitcode (";", "genPcall %s\n", OP_SYMBOL(IC_LEFT(ic))->name);
807 /*-----------------------------------------------------------------*/
808 /* genFunction - generated code for function entry */
809 /*-----------------------------------------------------------------*/
810 static void genFunction (iCode * ic) {
811 symbol *sym=OP_SYMBOL(IC_LEFT(ic));
812 sym_link *type=sym->type;
814 emitcode (";", "genFunction %s", sym->rname);
816 /* print the allocation information */
817 printAllocInfo (currFunc, codeOutFile);
819 emitcode ("", "%s:", sym->rname);
821 if (IFFUNC_ISNAKED(type))
823 emitcode(";", "naked function: no prologue.");
827 /* adjust the stack for locals used in this function */
829 emitcode ("sub", "r7,#%d\t; create stack space for locals", sym->stack);
833 /*-----------------------------------------------------------------*/
834 /* genEndFunction - generates epilogue for functions */
835 /*-----------------------------------------------------------------*/
837 genEndFunction (iCode * ic)
839 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
841 printIc ("genEndFunction", ic, 0,0,0);
843 if (IFFUNC_ISNAKED(sym->type)) {
844 emitcode(";", "naked function: no epilogue.");
848 /* readjust the stock for locals used in this function */
850 emitcode ("add", "r7,#%d\t; release stack space for locals", sym->stack);
853 if (IFFUNC_ISISR(sym->type)) {
854 emitcode ("reti", "");
856 emitcode ("ret", "");
860 /*-----------------------------------------------------------------*/
861 /* genRet - generate code for return statement */
862 /*-----------------------------------------------------------------*/
863 static void genRet (iCode * ic) {
866 printIc ("genRet", ic, 0, 0, 0);
868 printIc ("genRet", ic, 0, 1, 0);
869 aopOp(IC_LEFT(ic), TRUE, TRUE);
870 switch (AOP_SIZE(IC_LEFT(ic)))
873 emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
874 emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
877 emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
880 emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
883 emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
890 emitcode ("jmp", "%05d$", returnLabel->key+100);
893 /*-----------------------------------------------------------------*/
894 /* genLabel - generates a label */
895 /*-----------------------------------------------------------------*/
896 static void genLabel (iCode * ic) {
897 /* special case never generate */
898 if (IC_LABEL (ic) == entryLabel)
901 emitcode (";", "genLabel(%d) %s", ic->lineno, IC_LABEL(ic)->name);
902 emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
905 /*-----------------------------------------------------------------*/
906 /* genGoto - generates a jmp */
907 /*-----------------------------------------------------------------*/
908 static void genGoto (iCode * ic) {
909 emitcode (";", "genGoto(%d) %s", ic->lineno, IC_LABEL(ic)->name);
910 emitcode ("jmp", "%05d$", (IC_LABEL (ic)->key + 100));
913 /*-----------------------------------------------------------------*/
914 /* genPlus - generates code for addition */
915 /*-----------------------------------------------------------------*/
916 static void genPlus (iCode * ic) {
917 operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
921 printIc ("genPlus", ic, 1,1,1);
923 size=aopOp(result, TRUE, TRUE);
925 /* if left is a literal, then exchange them */
926 if (IS_LITERAL(operandType(left))) {
927 operand *tmp = right;
932 if (aopIsBit(result)) {
933 if (IS_LITERAL(operandType(right))) {
934 if (operandLitValue(right)) {
935 emitcode ("setb", AOP_NAME(result)[0]);
938 aopOp(left, TRUE, TRUE);
939 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
942 bailOut("genPlus: unfinished genPlus bit");
945 aopOp(left, !aopIsPtr(result), !aopIsDir(result));
946 aopOp(right, !aopIsPtr(result), !aopIsDir(result));
948 // special case for * = * + char, needs a closer look
949 // heck, this shouldn't have come here but bug-223113 does
950 if (size==3 && AOP_SIZE(right)==1) {
951 emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
952 emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
953 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
954 emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
955 emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
959 // special case for (whatever)* = (whatever)** + char, needs a closer look
960 // heck, this shouldn't have come here but bug-441448 does
961 if (size==2 && AOP_SIZE(right)==1) {
962 emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
963 emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
964 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
965 emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
974 if (!aopEqual(result->aop, left->aop, 0)) {
975 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
977 emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
979 if (!aopEqual(result->aop, left->aop, 1)) {
980 emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
985 emitcode ("addc.w", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
991 /*-----------------------------------------------------------------*/
992 /* genMinus - generates code for subtraction */
993 /*-----------------------------------------------------------------*/
994 static void genMinus (iCode * ic) {
995 printIc ("genMinus", ic, 1,1,1);
999 /*-----------------------------------------------------------------*/
1000 /* genMult - generates code for multiplication */
1001 /*-----------------------------------------------------------------*/
1002 static void genMult (iCode * ic) {
1003 printIc ("genMult", ic, 1,1,1);
1006 /*-----------------------------------------------------------------*/
1007 /* genDiv - generates code for division */
1008 /*-----------------------------------------------------------------*/
1009 static void genDiv (iCode * ic) {
1010 printIc ("genDiv", ic, 1,1,1);
1013 /*-----------------------------------------------------------------*/
1014 /* genMod - generates code for division */
1015 /*-----------------------------------------------------------------*/
1016 static void genMod (iCode * ic) {
1017 printIc ("genMod", ic, 1,1,1);
1020 /*-----------------------------------------------------------------*/
1021 /* genCmpGt :- greater than comparison */
1022 /*-----------------------------------------------------------------*/
1023 static void genCmpGt (iCode * ic) {
1024 printIc ("genCmpGt", ic, 1,1,1);
1026 /*-----------------------------------------------------------------*/
1027 /* genCmpLt - less than comparisons */
1028 /*-----------------------------------------------------------------*/
1029 static void genCmpLt (iCode * ic) {
1030 printIc ("genCmpLt", ic, 1,1,1);
1032 /*-----------------------------------------------------------------*/
1033 /* genCmpEq - generates code for equal to */
1034 /*-----------------------------------------------------------------*/
1035 static void genCmpEq (iCode * ic) {
1036 printIc ("genCmpEq", ic, 1,1,1);
1039 /*-----------------------------------------------------------------*/
1040 /* ifxForOp - returns the icode containing the ifx for operand */
1041 /*-----------------------------------------------------------------*/
1042 static iCode *ifxForOp (operand * op, iCode * ic) {
1043 /* if true symbol then needs to be assigned */
1044 if (IS_TRUE_SYMOP (op))
1047 /* if this has register type condition and
1048 the next instruction is ifx with the same operand
1049 and live to of the operand is upto the ifx only then */
1051 ic->next->op == IFX &&
1052 IC_COND (ic->next)->key == op->key &&
1053 OP_SYMBOL (op)->liveTo <= ic->next->seq)
1059 /*-----------------------------------------------------------------*/
1060 /* hasInc - operand is incremented before any other use */
1061 /*-----------------------------------------------------------------*/
1062 static iCode *hasInc (operand *op, iCode *ic, int osize) {
1063 sym_link *type = operandType(op);
1064 sym_link *retype = getSpec (type);
1065 iCode *lic = ic->next;
1068 /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
1069 if (!IS_SYMOP(op)) return NULL;
1071 if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
1072 if (IS_AGGREGATE(type->next)) return NULL;
1073 if (osize != (isize = getSize(type->next))) return NULL;
1076 /* if operand of the form op = op + <sizeof *op> */
1077 if (lic->op == '+') {
1078 if (isOperandEqual(IC_LEFT(lic),op) &&
1079 //isOperandEqual(IC_RESULT(lic),op) &&
1080 isOperandLiteral(IC_RIGHT(lic)) &&
1081 operandLitValue(IC_RIGHT(lic)) == isize) {
1082 emitcode (";", "Found hasInc");
1086 /* if the operand used or deffed */
1087 if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
1090 /* if GOTO or IFX */
1091 if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
1097 /*-----------------------------------------------------------------*/
1098 /* genAndOp - for && operation */
1099 /*-----------------------------------------------------------------*/
1100 static void genAndOp (iCode * ic) {
1101 printIc ("genAndOp(&&)", ic, 1,1,1);
1104 /*-----------------------------------------------------------------*/
1105 /* genOrOp - for || operation */
1106 /*-----------------------------------------------------------------*/
1107 static void genOrOp (iCode * ic) {
1108 printIc ("genOrOp(||)", ic, 1,1,1);
1111 /*-----------------------------------------------------------------*/
1112 /* genAnd - code for and */
1113 /*-----------------------------------------------------------------*/
1114 static void genAnd (iCode * ic, iCode * ifx) {
1115 printIc ("genAnd", ic, 1,1,1);
1118 /*-----------------------------------------------------------------*/
1119 /* genOr - code for or */
1120 /*-----------------------------------------------------------------*/
1121 static void genOr (iCode * ic, iCode * ifx) {
1122 operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
1126 printIc ("genOr", ic, 1,1,1);
1128 size=aopOp(result, TRUE, TRUE);
1130 /* if left is a literal, then exchange them */
1131 if (IS_LITERAL(operandType(left))) {
1132 operand *tmp = right;
1137 if (aopIsBit(result)) {
1138 if (IS_LITERAL(operandType(right))) {
1139 if (operandLitValue(right)) {
1140 emitcode ("setb", AOP_NAME(result)[0]);
1143 aopOp(left, TRUE, TRUE);
1144 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
1149 aopOp(left, !aopIsPtr(result), !aopIsDir(result));
1150 aopOp(right, !aopIsPtr(result), !aopIsDir(result));
1157 if (!aopEqual(result->aop, left->aop, 0)) {
1158 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1160 emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1162 if (!aopEqual(result->aop, left->aop, 1)) {
1163 emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
1165 emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
1170 /*-----------------------------------------------------------------*/
1171 /* genXor - code for xclusive or */
1172 /*-----------------------------------------------------------------*/
1173 static void genXor (iCode * ic, iCode * ifx) {
1174 printIc ("genXor", ic, 1,1,1);
1177 /*-----------------------------------------------------------------*/
1178 /* genInline - write the inline code out */
1179 /*-----------------------------------------------------------------*/
1180 static void genInline (iCode * ic) {
1182 printIc ("genInline", ic, 0,0,0);
1184 emitcode ("", IC_INLINE(ic));
1187 /*-----------------------------------------------------------------*/
1188 /* genRRC - rotate right with carry */
1189 /*-----------------------------------------------------------------*/
1190 static void genRRC (iCode * ic) {
1191 printIc ("genRRC", ic, 1,1,0);
1194 /*-----------------------------------------------------------------*/
1195 /* genRLC - generate code for rotate left with carry */
1196 /*-----------------------------------------------------------------*/
1197 static void genRLC (iCode * ic) {
1198 printIc ("genRLC", ic, 1,1,0);
1201 /*-----------------------------------------------------------------*/
1202 /* genGetHbit - generates code get highest order bit */
1203 /*-----------------------------------------------------------------*/
1204 static void genGetHbit (iCode * ic) {
1205 printIc ("genGetHbit", ic, 1,1,0);
1208 /*-----------------------------------------------------------------*/
1209 /* genLeftShift - generates code for left shifting */
1210 /*-----------------------------------------------------------------*/
1211 static void genLeftShift (iCode * ic) {
1212 printIc ("genLeftShift", ic, 1,1,1);
1215 /*-----------------------------------------------------------------*/
1216 /* genRightShift - generate code for right shifting */
1217 /*-----------------------------------------------------------------*/
1218 static void genRightShift (iCode * ic) {
1219 printIc ("genRightShift", ic, 1,1,1);
1222 /*-----------------------------------------------------------------*/
1223 /* genPointerGet - generate code for pointer get */
1224 /*-----------------------------------------------------------------*/
1225 static void genPointerGet (iCode * ic, iCode *pi) {
1226 char *instr, *scratchReg;
1227 operand *result=IC_RESULT(ic), *left=IC_LEFT(ic);
1228 bool codePointer=IS_CODEPTR(operandType(left));
1232 printIc ("genPointerGet pi", ic, 1,1,0);
1234 printIc ("genPointerGet", ic, 1,1,0);
1237 if (!IS_PTR(operandType(left))) {
1238 bailOut ("genPointerGet: pointer required");
1241 aopOp(left,FALSE,FALSE);
1242 size=aopOp(result,TRUE,aopIsDir(left));
1244 if (IS_GENPTR(operandType(left))) {
1245 symbol *tlbl1=newiTempLabel(NULL);
1246 symbol *tlbl2=newiTempLabel(NULL);
1247 emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
1248 emitcode ("beq", "%05d$", tlbl1->key+100);
1251 emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1254 emitcode ("mov", "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1258 emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
1260 emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
1263 emitcode ("br", "%05d$", tlbl2->key+100);
1264 emitcode ("", "%05d$:", tlbl1->key+100);
1267 emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1270 emitcode ("mov", "r0,%s", AOP_NAME(left)[0]);
1271 emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[0]);
1275 emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
1277 emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1]);
1280 emitcode ("", "%05d$:", tlbl2->key+100);
1284 switch (AOP_TYPE(left))
1287 emitcode("mov","r1,%s", AOP_NAME(left)[0]);
1288 sprintf (AOP_NAME(left)[0], "r1");
1306 if (AOP_TYPE(result)==AOP_STK) {
1307 emitcode (MOV, "%s,[%s]", scratchReg, AOP_NAME(left)[0]);
1308 emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
1311 emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0],
1316 emitcode (MOV, "r1,%s", AOP_NAME(left)[0]);
1317 emitcode (instr, "%s,[r1+]", AOP_NAME(result)[0]);
1319 emitcode (instr, "%s,[%s]", AOP_NAME(result)[0],
1333 if (AOP_TYPE(result)==AOP_STK) {
1334 emitcode (MOV, "%s,[%s+2]", scratchReg, AOP_NAME(left)[0]);
1335 emitcode (MOV, "%s,%s", AOP_NAME(result)[1], scratchReg);
1338 emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1],
1342 emitcode (instr, "%s,[r1]", AOP_NAME(result)[1]);
1344 emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1],
1352 bailOut ("genPointerGet");
1355 /*-----------------------------------------------------------------*/
1356 /* genPointerSet - stores the value into a pointer location */
1357 /*-----------------------------------------------------------------*/
1358 static void genPointerSet (iCode * ic, iCode *pi) {
1360 operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
1363 printIc ("genPointerSet", ic, 1,0,1);
1365 if (!IS_PTR(operandType(result))) {
1366 bailOut ("genPointerSet: pointer required");
1369 aopOp(result,FALSE,FALSE);
1370 size=aopOp(right,FALSE, FALSE);
1372 if (IS_GENPTR(operandType(result))) {
1373 emitcode (";", "INLINE\t_gptrset ; [%s %s] = %s %s",
1374 AOP_NAME(result)[0], AOP_NAME(result)[1],
1375 AOP_NAME(right)[0], AOP_NAME(right)[1]);
1379 switch (AOP_TYPE(right))
1389 emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1392 emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1399 emitcode (instr, "[%s+],%s", AOP_NAME(result)[0],
1400 AOP_NAME(right)[1]);
1402 emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0],
1403 AOP_NAME(right)[1]);
1408 bailOut ("genPointerSet");
1411 /*-----------------------------------------------------------------*/
1412 /* genIfx - generate code for Ifx statement */
1413 /*-----------------------------------------------------------------*/
1414 static void genIfx (iCode * ic, iCode * popIc) {
1418 symbol *jlbl, *tlbl=newiTempLabel(NULL);
1419 operand *cond=IC_COND(ic);
1421 emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s",
1422 ic->lineno, printOp(cond),
1423 IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
1424 IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
1426 size=aopOp(cond,TRUE,TRUE);
1436 switch (AOP_TYPE(cond) )
1439 emitcode (trueOrFalse ? "jnb" : "jb", "%s,%05d$",
1440 AOP_NAME(cond)[0], tlbl->key+100);
1441 emitcode ("jmp", "%05d$", jlbl->key+100);
1442 emitcode ("", "%05d$:", tlbl->key+100);
1453 emitcode (instr, "%s,#0", AOP_NAME(cond)[0]);
1454 emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
1457 // generic pointer, forget the generic part
1459 emitcode (instr, "%s,#0", AOP_NAME(cond)[1]);
1460 emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
1463 emitcode ("jmp", "%05d$", jlbl->key+100);
1464 emitcode ("", "%05d$:", tlbl->key+100);
1470 /*-----------------------------------------------------------------*/
1471 /* genAddrOf - generates code for address of */
1472 /*-----------------------------------------------------------------*/
1473 static void genAddrOf (iCode * ic) {
1475 operand *left=IC_LEFT(ic);
1477 printIc ("genAddrOf", ic, 1,1,0);
1479 size=aopOp (IC_RESULT(ic), FALSE, TRUE);
1481 if (isOperandOnStack(left)) {
1482 emitcode ("lea", "%s,%s", AOP_NAME(IC_RESULT(ic))[0],
1483 getStackOffset(OP_SYMBOL(left)->stack));
1485 // this must be a generic pointer
1486 emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
1491 if (isOperandInDirSpace(left) ||
1492 isOperandInFarSpace(left) ||
1493 isOperandInCodeSpace(left)) {
1494 emitcode ("mov.w", "%s,#%s", AOP_NAME(IC_RESULT(ic))[0],
1495 OP_SYMBOL(left)->rname);
1497 // this must be a generic pointer
1498 int space=0; // dir space
1499 if (isOperandInFarSpace(left)) {
1501 } else if (isOperandInCodeSpace(left)) {
1504 emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], space);
1509 bailOut("genAddrOf");
1512 /*-----------------------------------------------------------------*/
1513 /* genAssign - generate code for assignment */
1514 /*-----------------------------------------------------------------*/
1515 static void genAssign (iCode * ic) {
1516 operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
1520 printIc ("genAssign", ic, 1,0,1);
1522 if (!IS_SYMOP(result)) {
1523 bailOut("genAssign: result is not a symbol");
1526 aopOp(result, TRUE, TRUE);
1527 aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
1528 size=AOP_SIZE(result);
1530 /* if result is a bit */
1531 if (AOP_TYPE(result) == AOP_BIT) {
1532 /* if right is literal, we know what the value is */
1533 if (AOP_TYPE(right) == AOP_LIT) {
1534 if (operandLitValue(right)) {
1535 emitcode ("setb", AOP_NAME(result)[0]);
1537 emitcode ("clr", AOP_NAME(result)[0]);
1541 /* if right is also a bit */
1542 if (AOP_TYPE(right) == AOP_BIT) {
1543 emitcode ("mov", "c,%s", AOP_NAME(right));
1544 emitcode ("mov", "%s,c", AOP_NAME(result));
1548 emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
1558 emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1565 emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
1570 /*-----------------------------------------------------------------*/
1571 /* genJumpTab - genrates code for jump table */
1572 /*-----------------------------------------------------------------*/
1573 static void genJumpTab (iCode * ic) {
1574 printIc ("genJumpTab", ic, 0,0,0);
1577 /*-----------------------------------------------------------------*/
1578 /* genCast - gen code for casting */
1579 /*-----------------------------------------------------------------*/
1580 static void genCast (iCode * ic) {
1582 operand *result=IC_RESULT(ic);
1583 operand *right=IC_RIGHT(ic);
1584 sym_link *ctype=operandType(IC_LEFT(ic));
1585 sym_link *rtype=operandType(IC_RIGHT(ic));
1586 sym_link *etype=getSpec(rtype);
1587 short ptrType, signedness;
1589 printIc ("genCast", ic, 1,1,1);
1591 aopOp(result, TRUE, TRUE);
1592 aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
1593 size=AOP_SIZE(result);
1595 /* if result is a bit */
1596 if (AOP_TYPE(result) == AOP_BIT) {
1597 /* if right is literal, we know what the value is */
1598 if (AOP_TYPE(right) == AOP_LIT) {
1599 if (operandLitValue(right)) {
1600 emitcode ("setb", AOP_NAME(result)[0]);
1602 emitcode ("clr", AOP_NAME(result)[0]);
1606 /* if right is also a bit */
1607 if (AOP_TYPE(right) == AOP_BIT) {
1608 emitcode ("mov", "c,%s", AOP_NAME(right));
1609 emitcode ("mov", "%s,c", AOP_NAME(result));
1613 emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
1617 /* if right is a bit */
1618 if (AOP_TYPE(right)==AOP_BIT) {
1619 emitcode ("mov", "c,%s", AOP_NAME(right));
1620 emitcode ("mov", "%s,#0", AOP_NAME(result)[0]);
1621 emitcode ("rlc", "%s,#1", AOP_NAME(result)[0]);
1623 emitcode ("mov", "%s,#0", AOP_NAME(result)[1]);
1628 /* if the result is of type pointer */
1629 if (IS_PTR (ctype)) {
1631 if (AOP_SIZE(right)>1) {
1632 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1634 emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
1635 emitcode ("sext", "r1h");
1636 emitcode ("mov", "%s,r1", AOP_NAME(result)[0]);
1639 /* if pointer to generic pointer */
1640 if (IS_GENPTR (ctype)) {
1642 if (IS_GENPTR (rtype)) {
1643 bailOut("genCast: gptr -> gptr");
1646 if (IS_PTR (rtype)) {
1647 ptrType = DCL_TYPE (rtype);
1649 /* we have to go by the storage class */
1650 if (!SPEC_OCLS(etype)) {
1651 ptrType=0; // hush the compiler
1652 bailOut("genCast: unknown storage class");
1654 ptrType = PTR_TYPE (SPEC_OCLS (etype));
1658 /* the generic part depends on the type */
1662 emitcode ("mov.b", "%s,#0x00", AOP_NAME(result)[1]);
1665 emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
1668 emitcode ("mov.b", "%s,#0x02", AOP_NAME(result)[1]);
1671 bailOut("genCast: got unknown storage class");
1677 /* do we have to sign extend? */
1678 signedness = SPEC_USIGN(rtype);
1680 /* now depending on the size */
1681 switch ((AOP_SIZE(result)<<4) + AOP_SIZE(right))
1685 emitcode("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
1690 emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1693 emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1695 emitcode("sext", "%s", AOP_NAME(result)[1]);
1697 emitcode("mov", "%s,#0", AOP_NAME(result)[1]);
1702 emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
1704 emitcode("sext", "r1h");
1706 emitcode("mov", "r1h,#0");
1708 emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
1711 // fall through: case 0x41
1713 emitcode("sext", "r1");
1715 emitcode("mov", "r1,#0");
1717 emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
1721 emitcode("mov", "r1,%s", AOP_NAME(right)[0]);
1722 emitcode("mov", "%s,r1l", AOP_NAME(result)[0]);
1725 fprintf(stderr, "genCast: unknown size: %d:%d\n",
1726 AOP_SIZE(result), AOP_SIZE(right));
1727 bailOut("genCast: unknown size");
1731 /*-----------------------------------------------------------------*/
1732 /* genDjnz - generate decrement & jump if not zero instrucion */
1733 /*-----------------------------------------------------------------*/
1734 static bool genDjnz (iCode * ic, iCode * ifx) {
1740 /* if the if condition has a false label
1741 then we cannot save */
1745 /* if the minus is not of the form
1747 if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
1748 !IS_OP_LITERAL (IC_RIGHT (ic)))
1751 if (operandLitValue (IC_RIGHT (ic)) != 1)
1754 /* if the size of this greater than two then no
1756 if (getSize (operandType (IC_RESULT (ic))) > 2)
1759 printIc ("genDjnz", ic, 1,1,1);
1761 /* otherwise we can save BIG */
1762 lbl = newiTempLabel (NULL);
1763 lbl1 = newiTempLabel (NULL);
1765 aopOp (IC_RESULT (ic), FALSE, TRUE);
1767 if (AOP_TYPE(IC_RESULT(ic))==AOP_REG || AOP_TYPE(IC_RESULT(ic))==AOP_DIR) {
1768 emitcode ("djnz", "%s,%05d$", AOP_NAME(IC_RESULT(ic)), lbl->key+100);
1769 emitcode ("br", "%05d$", lbl1->key + 100);
1770 emitcode ("", "%05d$:", lbl->key + 100);
1771 emitcode ("jmp", "%05d$", IC_TRUE (ifx)->key + 100);
1772 emitcode ("", "%05d$:", lbl1->key + 100);
1776 bailOut("genDjnz: aop type");
1780 /*-----------------------------------------------------------------*/
1781 /* genReceive - generate code for a receive iCode */
1782 /*-----------------------------------------------------------------*/
1783 static void genReceive (iCode * ic) {
1784 printIc ("genReceive", ic, 1,0,0);
1787 /*-----------------------------------------------------------------*/
1788 /* gen51Code - generate code for 8051 based controllers */
1789 /*-----------------------------------------------------------------*/
1790 void genXA51Code (iCode * lic) {
1794 lineHead = lineCurr = NULL;
1796 /* if debug information required */
1797 if (options.debug && currFunc)
1799 cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
1801 if (IS_STATIC (currFunc->etype))
1802 emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
1804 emitcode ("", "G$%s$0$0 ==.", currFunc->name);
1808 for (ic = lic; ic; ic = ic->next) {
1809 if (ic->lineno && cln != ic->lineno) {
1810 if (options.debug) {
1812 emitcode ("", "C$%s$%d$%d$%d ==.",
1813 FileBaseName (ic->filename), ic->lineno,
1814 ic->level, ic->block);
1817 emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
1818 printCLine(ic->filename, ic->lineno));
1821 /* if the result is marked as
1822 spilt and rematerializable or code for
1823 this has already been generated then
1825 if (resultRemat (ic) || ic->generated)
1828 /* depending on the operation */
1848 /* IPOP happens only when trying to restore a
1849 spilt live range, if there is an ifx statement
1850 following this pop then the if statement might
1851 be using some of the registers being popped which
1852 would destory the contents of the register so
1853 we need to check for this condition and handle it */
1855 ic->next->op == IFX &&
1856 regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
1857 genIfx (ic->next, ic);
1875 genEndFunction (ic);
1895 if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
1923 /* note these two are xlated by algebraic equivalence
1924 during parsing SDCC.y */
1925 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1926 "got '>=' or '<=' shouldn't have come here");
1942 genXor (ic, ifxForOp (IC_RESULT (ic), ic));
1946 genOr (ic, ifxForOp (IC_RESULT (ic), ic));
1950 genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
1977 case GET_VALUE_AT_ADDRESS:
1978 genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_RESULT(ic)))));
1982 if (POINTER_SET (ic))
1983 genPointerSet (ic, hasInc(IC_RESULT(ic), ic, getSize(operandType(IC_RIGHT(ic)))));
2009 addSet (&_G.sendSet, ic);
2018 /* now we are ready to call the
2019 peep hole optimizer */
2020 if (!options.nopeep)
2021 peepHole (&lineHead);
2023 /* now do the actual printing */
2024 printLine (lineHead, codeOutFile);