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 -------------------------------------------------------------------------*/
38 #include "SDCCglobl.h"
41 #ifdef HAVE_SYS_ISA_DEFS_H
42 #include <sys/isa_defs.h>
44 #ifdef HAVE_MACHINE_ENDIAN_H
45 #include <machine/endian.h>
50 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
51 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
52 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
59 #include "SDCCpeeph.h"
63 #if defined(__BORLANDC__) || defined(_MSC_VER)
64 #define STRCASECMP stricmp
66 #define STRCASECMP strcasecmp
71 /* this is the down and dirty file with all kinds of
72 kludgy & hacky stuff. This is what it is all about
73 CODE GENERATION for a specific MCU . some of the
74 routines may be reusable, will have to see */
85 extern int xa51_ptrRegReq;
86 extern int xa51_nRegs;
87 extern FILE *codeOutFile;
89 static lineNode *lineHead = NULL;
90 static lineNode *lineCurr = NULL;
97 /*-----------------------------------------------------------------*/
98 /* emitcode - writes the code into a file : for now it is simple */
99 /*-----------------------------------------------------------------*/
100 static void emitcode (char *inst, char *fmt,...) {
102 char lb[INITIAL_INLINEASM];
110 sprintf (lb, "%s\t", inst);
112 sprintf (lb, "%s", inst);
113 vsprintf (lb + (strlen (lb)), fmt, ap);
116 vsprintf (lb, fmt, ap);
118 while (isspace ((int)*lbp))
122 lineCurr = (lineCurr ?
123 connectLine (lineCurr, newLineNode (lb)) :
124 (lineHead = newLineNode (lb)));
125 lineCurr->isInline = _G.inLine;
126 lineCurr->isDebug = _G.debugLine;
130 /*-----------------------------------------------------------------*/
131 /* newAsmop - creates a new asmOp */
132 /*-----------------------------------------------------------------*/
134 newAsmop (short type)
138 aop = Safe_calloc (1, sizeof (asmop));
143 char *aopTypeName(asmop *aop) {
146 case AOP_LIT: return "lit";
147 case AOP_REG: return "reg";
148 case AOP_DIR: return "dir";
149 case AOP_FAR: return "far";
150 case AOP_CODE: return "code";
151 case AOP_STK: return "stack";
152 case AOP_IMMD: return "imm";
153 case AOP_CRY: return "bit";
158 /*-----------------------------------------------------------------*/
159 /* aopForSym - for a true symbol */
160 /*-----------------------------------------------------------------*/
161 static asmop *aopForSym(symbol *sym, bool result) {
164 sym->aop = aop = newAsmop(0);
165 aop->size=getSize(sym->type);
167 // if it is in registers
168 if (sym->nRegs && sym->regs[0]) {
171 sprintf (aop->name[1], sym->regs[1]->name);
173 sprintf (aop->name[0], sym->regs[0]->name);
180 sprintf (aop->name[0], "[r7+%d+0+%d+%d]", sym->stack,
181 FUNC_ISISR(currFunc->type) ? 6 : 4, _G.nRegsSaved);
182 sprintf (aop->name[1], "[r7+%d+2+%d+%d]", sym->stack,
183 FUNC_ISISR(currFunc->type) ? 6 : 4, _G.nRegsSaved);
187 // if it has a spillLoc
188 if (sym->usl.spillLoc) {
189 return aopForSym (sym->usl.spillLoc, result);
193 if (IN_BITSPACE(SPEC_OCLS(sym->etype))) {
195 sprintf (aop->name[0], sym->rname);
199 // if in direct space
200 if (IN_DIRSPACE(SPEC_OCLS(sym->etype))) {
202 sprintf (aop->name[0], sym->rname);
203 sprintf (aop->name[1], "#0x%02x", POINTER);
208 if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
210 fprintf (stderr, "aopForSym: result can not be in code space\n");
214 emitcode ("mov", "r0,#%s", sym->rname);
215 sprintf (aop->name[0], "r0");
216 sprintf (aop->name[1], "#0x%02x", CPOINTER);
221 if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
223 emitcode ("mov", "r0,#%s", sym->rname);
224 sprintf (aop->name[0], "[r0]");
226 sprintf (aop->name[1], "[r0+2]");
228 sprintf (aop->name[1], "#0x%02x", FPOINTER);
233 // special case for a function
234 if (IS_FUNC (sym->type)) {
236 sprintf (aop->name[0], sym->rname);
240 fprintf (stderr, "aopForSym (%s): What's up?\n", sym->name);
244 /*-----------------------------------------------------------------*/
245 /* aopForVal - for a value */
246 /*-----------------------------------------------------------------*/
247 static asmop *aopForVal(operand *op) {
249 long v=floatFromVal(OP_VALUE(op));
251 if (IS_OP_LITERAL(op)) {
252 op->aop = aop = newAsmop (AOP_LIT);
253 switch ((aop->size=getSize(operandType(op))))
256 sprintf (aop->name[0], "#0x%02lx", v);
259 sprintf (aop->name[0], "#0x%04lx", v);
262 sprintf (aop->name[0], "#(0x%08lx >> 16)", v);
263 sprintf (aop->name[1], "#(0x%08lx & 0xffff)", v);
266 fprintf (stderr, "aopForVal (lit): unknown size\n");
274 op->aop = aop = newAsmop (AOP_IMMD);
275 switch ((aop->size=getSize(OP_SYMBOL(op)->type)))
279 sprintf (aop->name[0], "#%s", OP_SYMBOL(op)->rname);
281 case 3: // generic pointer
282 sprintf (aop->name[0], "#0x%02x", DCL_TYPE(operandType(op)));
283 sprintf (aop->name[1], "#%s", OP_SYMBOL(op)->rname);
287 fprintf (stderr, "aopForVal: unknown type\n");
292 static void aopOp(operand *op, bool result) {
295 op->aop=aopForSym (OP_SYMBOL(op), result);
300 fprintf (stderr, "aopOp: result can not be a value\n");
307 fprintf (stderr, "aopOp: unexpected operand\n");
311 char *opRegName(operand *op, int offset, char *opName) {
314 if (OP_SYMBOL(op)->onStack) {
315 sprintf (aop->name[0], "[r7+%d+0+%d+%d]", sym->stack,
316 FUNC_ISISR(currFunc->type) ? 6 : 4, _G.nRegsSaved);
319 if (IS_TRUE_SYMOP(op))
320 return OP_SYMBOL(op)->rname;
321 else if (OP_SYMBOL(op)->regs[offset])
322 return OP_SYMBOL(op)->regs[offset]->name;
328 switch (SPEC_NOUN(OP_VALUE(op)->type)) {
330 if (SPEC_CVAL(OP_VALUE(op)->type).v_int &&
331 SPEC_CVAL(OP_VALUE(op)->type).v_int != 1) {
332 fprintf (stderr, "opRegName: invalid bit value (%d)\n",
333 SPEC_CVAL(OP_VALUE(op)->type).v_int);
338 sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
341 if (SPEC_LONG(OP_VALUE(op)->type)) {
342 sprintf (opName, "#0x%02lx", SPEC_CVAL(OP_VALUE(op)->type).v_long);
344 sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
348 sprintf (opName, "#0x%02lx", SPEC_CVAL(OP_VALUE(op)->type).v_long);
351 fprintf (stderr, "opRegName: unexpected noun\n");
356 fprintf (stderr, "opRegName: unexpected operand type\n");
358 return NULL; // to keep the compiler happy
361 char * printOp (operand *op) {
362 static char line[132];
363 bool isPtr = op->isPtr | op->isGptr;
366 symbol *sym=OP_SYMBOL(op);
367 if (!sym->regs[0] && SYM_SPIL_LOC(sym)) {
368 sym=SYM_SPIL_LOC(sym);
371 sprintf (line, "[%s]:", sym->name);
373 sprintf (line, "%s:", sym->name);
376 strcat (line, sym->regs[0]->name);
379 strcat (line, sym->regs[1]->name);
384 sprintf (line+strlen(line), "stack+%d", sym->stack);
387 if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
388 strcat (line, "far");
391 if (IN_BITSPACE(SPEC_OCLS(sym->etype))) {
392 strcat (line, "bit");
395 if (IN_DIRSPACE(SPEC_OCLS(sym->etype))) {
396 strcat (line, "dir");
399 strcat (line, "unknown");
401 } else if (IS_VALOP(op)) {
402 opRegName(op, 0, line);
403 } else if (IS_TYPOP(op)) {
405 // forget about static, volatile, ... for now
406 if (SPEC_USIGN(operandType(op))) strcat (line, "unsigned ");
407 if (SPEC_LONG(operandType(op))) strcat (line, "long ");
408 strcat (line, nounName(operandType(op)));
411 fprintf (stderr, "printOp: unexpected operand type\n");
417 void printIc (char *op, iCode * ic, bool result, bool left, bool right) {
420 sprintf (line, "%s", op);
422 strcat (line, " result=");
423 strcat (line, printOp (IC_RESULT(ic)));
426 strcat (line, " left=");
427 strcat (line, printOp (IC_LEFT(ic)));
430 strcat (line, " right=");
431 strcat (line, printOp (IC_RIGHT(ic)));
433 emitcode (";", line);
436 /*-----------------------------------------------------------------*/
437 /* toBoolean - return bit for operand!=0 */
438 /*-----------------------------------------------------------------*/
439 static char *toBoolean (operand * op) {
440 switch (AOP_SIZE(op))
444 emitcode ("cmp", "%s,#0", AOP_NAME(op));
448 fprintf (stderr, "toBoolean: unknown size %d\n", AOP_SIZE(op));
453 /*-----------------------------------------------------------------*/
454 /* regsInCommon - two operands have some registers in common */
455 /*-----------------------------------------------------------------*/
456 static bool regsInCommon (operand * op1, operand * op2) {
460 /* if they have registers in common */
461 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
464 sym1 = OP_SYMBOL (op1);
465 sym2 = OP_SYMBOL (op2);
467 if (sym1->nRegs == 0 || sym2->nRegs == 0)
470 for (i = 0; i < sym1->nRegs; i++)
476 for (j = 0; j < sym2->nRegs; j++)
481 if (sym2->regs[j] == sym1->regs[i])
489 /*-----------------------------------------------------------------*/
490 /* resultRemat - result is rematerializable */
491 /*-----------------------------------------------------------------*/
492 static int resultRemat (iCode * ic) {
493 if (SKIP_IC (ic) || ic->op == IFX)
496 if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
498 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
499 if (sym->remat && !POINTER_SET (ic))
506 /*-----------------------------------------------------------------*/
507 /* genNot - generate code for ! operation */
508 /*-----------------------------------------------------------------*/
509 static void genNot (iCode * ic) {
510 printIc("genNot:", ic, 1,1,0);
513 /*-----------------------------------------------------------------*/
514 /* genCpl - generate code for complement */
515 /*-----------------------------------------------------------------*/
516 static void genCpl (iCode * ic) {
517 printIc("genCpl", ic, 1,1,0);
520 /*-----------------------------------------------------------------*/
521 /* genUminus - unary minus code generation */
522 /*-----------------------------------------------------------------*/
523 static void genUminus (iCode * ic) {
524 printIc("genUminus", ic, 1,1,0);
527 /*-----------------------------------------------------------------*/
528 /* genIpush - genrate code for pushing this gets a little complex */
529 /*-----------------------------------------------------------------*/
530 static void genIpush (iCode * ic) {
531 printIc ("genIpush", ic, 0,1,0);
534 /*-----------------------------------------------------------------*/
535 /* genIpop - recover the registers: can happen only for spilling */
536 /*-----------------------------------------------------------------*/
537 static void genIpop (iCode * ic) {
538 printIc ("genIpop", ic, 0,1,0);
541 /*-----------------------------------------------------------------*/
542 /* genCall - generates a call statement */
543 /*-----------------------------------------------------------------*/
544 static void genCall (iCode * ic) {
545 emitcode (";", "genCall %s", OP_SYMBOL(IC_LEFT(ic))->name);
548 /*-----------------------------------------------------------------*/
549 /* genPcall - generates a call by pointer statement */
550 /*-----------------------------------------------------------------*/
552 genPcall (iCode * ic)
554 emitcode (";", "genPcall %s\n", OP_SYMBOL(IC_LEFT(ic))->name);
557 /*-----------------------------------------------------------------*/
558 /* genFunction - generated code for function entry */
559 /*-----------------------------------------------------------------*/
560 static void genFunction (iCode * ic) {
561 symbol *sym=OP_SYMBOL(IC_LEFT(ic));
562 sym_link *type=sym->type;
564 emitcode (";", "-----------------------------------------");
565 emitcode (";", " function %s", sym->name);
566 emitcode (";", "-----------------------------------------");
568 emitcode ("", "%s:", sym->rname);
570 if (IFFUNC_ISNAKED(type))
572 emitcode(";", "naked function: no prologue.");
576 /* if critical function then turn interrupts off */
577 if (IFFUNC_ISCRITICAL (type))
578 emitcode ("clr", "ea");
582 /*-----------------------------------------------------------------*/
583 /* genEndFunction - generates epilogue for functions */
584 /*-----------------------------------------------------------------*/
586 genEndFunction (iCode * ic)
588 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
590 if (IFFUNC_ISNAKED(sym->type))
592 emitcode(";", "naked function: no epilogue.");
596 printIc ("genEndFunction", ic, 0,0,0);
599 /*-----------------------------------------------------------------*/
600 /* genRet - generate code for return statement */
601 /*-----------------------------------------------------------------*/
602 static void genRet (iCode * ic) {
603 emitcode (";", "genRet");
606 /*-----------------------------------------------------------------*/
607 /* genLabel - generates a label */
608 /*-----------------------------------------------------------------*/
609 static void genLabel (iCode * ic) {
610 /* special case never generate */
611 if (IC_LABEL (ic) == entryLabel)
614 emitcode (";", "genLabel %s", IC_LABEL(ic)->name);
615 emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
618 /*-----------------------------------------------------------------*/
619 /* genGoto - generates a ljmp */
620 /*-----------------------------------------------------------------*/
621 static void genGoto (iCode * ic) {
622 emitcode (";", "genGoto %s", IC_LABEL(ic)->name);
623 emitcode ("ljmp", "%05d$", (IC_LABEL (ic)->key + 100));
626 /*-----------------------------------------------------------------*/
627 /* genPlus - generates code for addition */
628 /*-----------------------------------------------------------------*/
629 static void genPlus (iCode * ic) {
630 printIc ("genPlus", ic, 1,1,1);
633 /*-----------------------------------------------------------------*/
634 /* genMinus - generates code for subtraction */
635 /*-----------------------------------------------------------------*/
636 static void genMinus (iCode * ic) {
637 printIc ("genMinus", ic, 1,1,1);
641 /*-----------------------------------------------------------------*/
642 /* genMult - generates code for multiplication */
643 /*-----------------------------------------------------------------*/
644 static void genMult (iCode * ic) {
645 printIc ("genMult", ic, 1,1,1);
648 /*-----------------------------------------------------------------*/
649 /* genDiv - generates code for division */
650 /*-----------------------------------------------------------------*/
651 static void genDiv (iCode * ic) {
652 printIc ("genDiv", ic, 1,1,1);
655 /*-----------------------------------------------------------------*/
656 /* genMod - generates code for division */
657 /*-----------------------------------------------------------------*/
658 static void genMod (iCode * ic) {
659 printIc ("genMod", ic, 1,1,1);
662 /*-----------------------------------------------------------------*/
663 /* genCmpGt :- greater than comparison */
664 /*-----------------------------------------------------------------*/
665 static void genCmpGt (iCode * ic, iCode * ifx) {
666 printIc ("genCmpGt", ic, 1,1,1);
668 /*-----------------------------------------------------------------*/
669 /* genCmpLt - less than comparisons */
670 /*-----------------------------------------------------------------*/
671 static void genCmpLt (iCode * ic, iCode * ifx) {
672 printIc ("genCmpLt", ic, 1,1,1);
674 /*-----------------------------------------------------------------*/
675 /* genCmpEq - generates code for equal to */
676 /*-----------------------------------------------------------------*/
677 static void genCmpEq (iCode * ic, iCode * ifx) {
678 printIc ("genCmpEq", ic, 1,1,1);
681 /*-----------------------------------------------------------------*/
682 /* ifxForOp - returns the icode containing the ifx for operand */
683 /*-----------------------------------------------------------------*/
684 static iCode *ifxForOp (operand * op, iCode * ic) {
685 /* if true symbol then needs to be assigned */
686 if (IS_TRUE_SYMOP (op))
689 /* if this has register type condition and
690 the next instruction is ifx with the same operand
691 and live to of the operand is upto the ifx only then */
693 ic->next->op == IFX &&
694 IC_COND (ic->next)->key == op->key &&
695 OP_SYMBOL (op)->liveTo <= ic->next->seq)
701 /*-----------------------------------------------------------------*/
702 /* hasInc - operand is incremented before any other use */
703 /*-----------------------------------------------------------------*/
704 static iCode *hasInc (operand *op, iCode *ic, int osize) {
705 sym_link *type = operandType(op);
706 sym_link *retype = getSpec (type);
707 iCode *lic = ic->next;
710 /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
711 if (!IS_SYMOP(op)) return NULL;
713 if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
714 if (IS_AGGREGATE(type->next)) return NULL;
715 if (osize != (isize = getSize(type->next))) return NULL;
718 /* if operand of the form op = op + <sizeof *op> */
719 if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
720 isOperandEqual(IC_RESULT(lic),op) &&
721 isOperandLiteral(IC_RIGHT(lic)) &&
722 operandLitValue(IC_RIGHT(lic)) == isize) {
725 /* if the operand used or deffed */
726 if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
730 if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
736 /*-----------------------------------------------------------------*/
737 /* genAndOp - for && operation */
738 /*-----------------------------------------------------------------*/
739 static void genAndOp (iCode * ic) {
740 printIc ("genAndOp(&&)", ic, 1,1,1);
743 /*-----------------------------------------------------------------*/
744 /* genOrOp - for || operation */
745 /*-----------------------------------------------------------------*/
746 static void genOrOp (iCode * ic) {
747 printIc ("genOrOp(||)", ic, 1,1,1);
750 /*-----------------------------------------------------------------*/
751 /* genAnd - code for and */
752 /*-----------------------------------------------------------------*/
753 static void genAnd (iCode * ic, iCode * ifx) {
754 printIc ("genAnd", ic, 1,1,1);
757 /*-----------------------------------------------------------------*/
758 /* genOr - code for or */
759 /*-----------------------------------------------------------------*/
760 static void genOr (iCode * ic, iCode * ifx) {
761 printIc ("genOr", ic, 1,1,1);
764 /*-----------------------------------------------------------------*/
765 /* genXor - code for xclusive or */
766 /*-----------------------------------------------------------------*/
767 static void genXor (iCode * ic, iCode * ifx) {
768 printIc ("genXor", ic, 1,1,1);
771 /*-----------------------------------------------------------------*/
772 /* genInline - write the inline code out */
773 /*-----------------------------------------------------------------*/
774 static void genInline (iCode * ic) {
775 printIc ("genInline", ic, 0,0,0);
778 /*-----------------------------------------------------------------*/
779 /* genRRC - rotate right with carry */
780 /*-----------------------------------------------------------------*/
781 static void genRRC (iCode * ic) {
782 printIc ("genRRC", ic, 1,1,0);
785 /*-----------------------------------------------------------------*/
786 /* genRLC - generate code for rotate left with carry */
787 /*-----------------------------------------------------------------*/
788 static void genRLC (iCode * ic) {
789 printIc ("genRLC", ic, 1,1,0);
792 /*-----------------------------------------------------------------*/
793 /* genGetHbit - generates code get highest order bit */
794 /*-----------------------------------------------------------------*/
795 static void genGetHbit (iCode * ic) {
796 printIc ("genGetHbit", ic, 1,1,0);
799 /*-----------------------------------------------------------------*/
800 /* genLeftShift - generates code for left shifting */
801 /*-----------------------------------------------------------------*/
802 static void genLeftShift (iCode * ic) {
803 printIc ("genLeftShift", ic, 1,1,1);
806 /*-----------------------------------------------------------------*/
807 /* genRightShift - generate code for right shifting */
808 /*-----------------------------------------------------------------*/
809 static void genRightShift (iCode * ic) {
810 printIc ("genRightShift", ic, 1,1,1);
813 /*-----------------------------------------------------------------*/
814 /* genPointerGet - generate code for pointer get */
815 /*-----------------------------------------------------------------*/
816 static void genPointerGet (iCode * ic, iCode *pi) {
817 printIc ("genPointerGet", ic, 1,1,0);
820 /*-----------------------------------------------------------------*/
821 /* genPointerSet - stores the value into a pointer location */
822 /*-----------------------------------------------------------------*/
823 static void genPointerSet (iCode * ic, iCode *pi) {
824 printIc ("genPointerSet", ic, 1,0,1);
827 /*-----------------------------------------------------------------*/
828 /* genIfx - generate code for Ifx statement */
829 /*-----------------------------------------------------------------*/
830 static void genIfx (iCode * ic, iCode * popIc) {
833 operand *cond=IC_COND(ic);
835 emitcode (";", "genIfx cond=%s trueLabel:%s falseLabel:%s",
837 IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
838 IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
850 switch (AOP_TYPE(cond) )
853 emitcode (trueOrFalse ? "jb" : "jbc", "%s,%05d$",
854 AOP_NAME(cond)[0], jlbl->key+100);
859 tlbl=newiTempLabel(NULL);
860 emitcode ("cmp", "%s,#0", AOP_NAME(cond)[0]);
861 emitcode (trueOrFalse ? "bne" : "beq", "%05d$", tlbl->key+100);
862 if (*AOP_NAME(cond)[1]) {
863 emitcode ("cmp", "%s,#0", AOP_NAME(cond)[1]);
864 emitcode (trueOrFalse ? "bne" : "beq", "%05d$", tlbl->key+100);
866 emitcode ("jmp", "%05d$", jlbl->key+100);
867 emitcode ("", "%05d$:", tlbl->key+100);
872 /*-----------------------------------------------------------------*/
873 /* genAddrOf - generates code for address of */
874 /*-----------------------------------------------------------------*/
875 static void genAddrOf (iCode * ic) {
876 printIc ("genAddrOf", ic, 1,1,0);
879 /*-----------------------------------------------------------------*/
880 /* genAssign - generate code for assignment */
881 /*-----------------------------------------------------------------*/
882 static void genAssign (iCode * ic) {
883 operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
885 printIc ("genAssign", ic, 1,0,1);
887 if (!IS_SYMOP(result)) {
888 fprintf (stderr, "genAssign: result is not a symbol\n");
895 if (result->aop->type==AOP_REG ||
896 right->aop->type==AOP_REG ||
897 right->aop->type==AOP_LIT ||
898 right->aop->type==AOP_IMMD) {
899 // everything will do
901 // they have to match
902 if (result->aop->type != right->aop->type) {
903 fprintf (stderr, "genAssign: types don't match (%s!=%s)\n",
904 aopTypeName(result->aop), aopTypeName(right->aop));
909 /* if result is a bit */
910 if (AOP_TYPE(result) == AOP_CRY) {
911 /* if right is literal, we know what the value is */
912 if (AOP_TYPE(right) == AOP_LIT) {
913 if (operandLitValue(right)) {
914 emitcode ("setb", AOP_NAME(result)[0]);
916 emitcode ("clr", AOP_NAME(result)[0]);
920 /* if right is also a bit */
921 if (AOP_TYPE(right) == AOP_CRY) {
922 emitcode ("mov", "c,%s", AOP_NAME(right));
923 emitcode ("mov", "%s,c", AOP_NAME(result));
927 emitcode ("mov", "%s,%s", AOP_NAME(result), toBoolean(right));
932 emitcode ("mov", "%s,%s",
933 result->aop->name[0], right->aop->name[0]);
934 if (IS_GENPTR(operandType(result))) {
935 emitcode ("mov", "%s,%s",
936 result->aop->name[1], right->aop->name[1]);
941 /*-----------------------------------------------------------------*/
942 /* genJumpTab - genrates code for jump table */
943 /*-----------------------------------------------------------------*/
944 static void genJumpTab (iCode * ic) {
945 printIc ("genJumpTab", ic, 0,0,0);
948 /*-----------------------------------------------------------------*/
949 /* genCast - gen code for casting */
950 /*-----------------------------------------------------------------*/
951 static void genCast (iCode * ic) {
952 printIc ("genCast", ic, 1,1,1);
955 /*-----------------------------------------------------------------*/
956 /* genDjnz - generate decrement & jump if not zero instrucion */
957 /*-----------------------------------------------------------------*/
958 static bool genDjnz (iCode * ic, iCode * ifx) {
959 printIc ("genDjnz", ic, 0,0,0);
963 /*-----------------------------------------------------------------*/
964 /* genReceive - generate code for a receive iCode */
965 /*-----------------------------------------------------------------*/
966 static void genReceive (iCode * ic) {
967 printIc ("genReceive", ic, 1,0,0);
970 /*-----------------------------------------------------------------*/
971 /* gen51Code - generate code for 8051 based controllers */
972 /*-----------------------------------------------------------------*/
973 void genXA51Code (iCode * lic) {
977 fprintf (stderr, "genXA51Code\n");
978 lineHead = lineCurr = NULL;
980 /* print the allocation information */
982 printAllocInfo (currFunc, codeOutFile);
984 /* if debug information required */
985 if (options.debug && currFunc)
987 cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
989 if (IS_STATIC (currFunc->etype))
990 emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
992 emitcode ("", "G$%s$0$0 ==.", currFunc->name);
996 for (ic = lic; ic; ic = ic->next) {
997 if (cln != ic->lineno) {
1000 emitcode ("", "C$%s$%d$%d$%d ==.",
1001 FileBaseName (ic->filename), ic->lineno,
1002 ic->level, ic->block);
1005 emitcode (";", "%s %d", ic->filename, ic->lineno);
1008 /* if the result is marked as
1009 spilt and rematerializable or code for
1010 this has already been generated then
1012 if (resultRemat (ic) || ic->generated)
1015 /* depending on the operation */
1035 /* IPOP happens only when trying to restore a
1036 spilt live range, if there is an ifx statement
1037 following this pop then the if statement might
1038 be using some of the registers being popped which
1039 would destory the contents of the register so
1040 we need to check for this condition and handle it */
1042 ic->next->op == IFX &&
1043 regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
1044 genIfx (ic->next, ic);
1062 genEndFunction (ic);
1082 if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
1099 genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
1103 genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
1110 /* note these two are xlated by algebraic equivalence
1111 during parsing SDCC.y */
1112 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1113 "got '>=' or '<=' shouldn't have come here");
1117 genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
1129 genXor (ic, ifxForOp (IC_RESULT (ic), ic));
1133 genOr (ic, ifxForOp (IC_RESULT (ic), ic));
1137 genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
1164 case GET_VALUE_AT_ADDRESS:
1165 genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_LEFT(ic)))));
1169 if (POINTER_SET (ic))
1170 genPointerSet (ic, hasInc(IC_RESULT(ic), ic, getSize(operandType(IC_RIGHT(ic)))));
1196 addSet (&_G.sendSet, ic);
1205 /* now we are ready to call the
1206 peep hole optimizer */
1207 if (!options.nopeep)
1208 peepHole (&lineHead);
1210 /* now do the actual printing */
1211 printLine (lineHead, codeOutFile);