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, "r1l,[r0+2]");
278 sprintf (aop->name[1], "r1l");
279 emitcode (MOV, "r0,[r0]");
280 sprintf (aop->name[0], "r0");
283 emitcode (MOV, "r0,#%s", sym->rname);
284 emitcode (MOVC, "r1,[r0+2]");
285 sprintf (aop->name[1], "r1");
286 emitcode (MOVC, "r0,[r0]");
287 sprintf (aop->name[0], "r0");
293 emitcode ("mov", "r0,#%s ; aopForSym:code", sym->rname);
294 sprintf (aop->name[0], "[r0]");
296 sprintf (aop->name[1], "[r0+2]");
303 if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
304 if (!canUsePointer) {
309 emitcode (MOV, "r0,#%s", sym->rname);
310 emitcode (MOV, "r0l,[r0]");
311 sprintf (aop->name[0], "r0l");
314 emitcode (MOV, "r0,#%s", sym->rname);
315 emitcode (MOV, "r0,[r0]");
316 sprintf (aop->name[0], "r0");
319 emitcode (MOV, "r0,#%s", sym->rname);
320 emitcode (MOV, "r1l,[r0+2]");
321 sprintf (aop->name[1], "r1l");
322 emitcode (MOV, "r0,[r0]");
323 sprintf (aop->name[0], "r0");
326 emitcode (MOV, "r0,#%s", sym->rname);
327 emitcode (MOV, "r1,[r0+2]");
328 sprintf (aop->name[1], "r1");
329 emitcode (MOV, "r0,[r0]");
330 sprintf (aop->name[0], "r0");
335 emitcode ("mov.w", "r0,#%s ; aopForSym:far", sym->rname);
336 sprintf (aop->name[0], "[r0]");
338 sprintf (aop->name[1], "[r0+2]");
344 bailOut("aopForSym");
348 /*-----------------------------------------------------------------*/
349 /* aopForVal - for a value */
350 /*-----------------------------------------------------------------*/
351 static asmop *aopForVal(operand *op) {
354 if (IS_OP_LITERAL(op)) {
355 op->aop = aop = newAsmop (AOP_LIT);
356 switch ((aop->size=getSize(operandType(op))))
359 sprintf (aop->name[0], "#0x%02x",
360 SPEC_CVAL(operandType(op)).v_int & 0xff);
361 sprintf (aop->name[1], "#0");
364 sprintf (aop->name[0], "#0x%04x",
365 SPEC_CVAL(operandType(op)).v_int & 0xffff);
366 sprintf (aop->name[1], "#0");
369 // must be a generic pointer, can only be zero
370 // ?? if (v!=0) fprintf (stderr, "invalid val op for gptr\n"); exit(1);
371 sprintf (aop->name[0], "#0x%04x",
372 SPEC_CVAL(operandType(op)).v_uint & 0xffff);
373 sprintf (aop->name[1], "#0");
376 sprintf (aop->name[0], "#0x%04lx",
377 SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
378 sprintf (aop->name[1], "#0x%04lx",
379 SPEC_CVAL(operandType(op)).v_ulong >> 16);
382 bailOut("aopForVal");
389 op->aop = aop = newAsmop (AOP_IMMD);
390 switch ((aop->size=getSize(OP_SYMBOL(op)->type)))
394 sprintf (aop->name[0], "#%s", OP_SYMBOL(op)->rname);
396 case 3: // generic pointer
397 sprintf (aop->name[0], "#0x%02x", DCL_TYPE(operandType(op)));
398 sprintf (aop->name[1], "#%s", OP_SYMBOL(op)->rname);
403 bailOut ("aopForVal: unknown type");
407 static int aopOp(operand *op,
408 bool canUsePointer, bool canUseOffset) {
411 op->aop=aopForSym (OP_SYMBOL(op), canUsePointer, canUseOffset);
415 op->aop=aopForVal (op);
419 bailOut("aopOp: unexpected operand");
423 bool aopEqual(asmop *aop1, asmop *aop2, int offset) {
424 if (strcmp(aop1->name[offset], aop2->name[offset])) {
430 bool aopIsDir(operand *op) {
431 return AOP_TYPE(op)==AOP_DIR;
434 bool aopIsBit(operand *op) {
435 return AOP_TYPE(op)==AOP_BIT;
438 bool aopIsPtr(operand *op) {
439 if (AOP_TYPE(op)==AOP_STK ||
440 AOP_TYPE(op)==AOP_CODE ||
441 AOP_TYPE(op)==AOP_FAR) {
448 char *opRegName(operand *op, int offset, char *opName, bool decorate) {
451 if (OP_SYMBOL(op)->onStack) {
452 sprintf (opName, "[%s]", getStackOffset(OP_SYMBOL(op)->stack));
455 if (IS_TRUE_SYMOP(op))
456 return OP_SYMBOL(op)->rname;
457 else if (OP_SYMBOL(op)->regs[offset])
458 return OP_SYMBOL(op)->regs[offset]->name;
460 bailOut("opRegName: unknown regs");
464 switch (SPEC_NOUN(OP_VALUE(op)->type)) {
467 if (SPEC_CVAL(OP_VALUE(op)->type).v_int &&
468 SPEC_CVAL(OP_VALUE(op)->type).v_int != 1) {
469 bailOut("opRegName: invalid bit value");
473 sprintf (opName, "#%s0x%02x", decorate?"(char)":"",
474 SPEC_CVAL(OP_VALUE(op)->type).v_int);
477 if (SPEC_LONG(OP_VALUE(op)->type)) {
478 sprintf (opName, "#%s0x%02lx", decorate?"(long)":"",
479 SPEC_CVAL(OP_VALUE(op)->type).v_long);
481 sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
482 SPEC_CVAL(OP_VALUE(op)->type).v_int);
486 sprintf (opName, "#%s%f", decorate?"(float)":"",
487 SPEC_CVAL(OP_VALUE(op)->type).v_float);
490 bailOut("opRegName: unexpected noun");
494 bailOut("opRegName: unexpected operand type");
498 char * printOp (operand *op) {
499 static char line[132];
500 sym_link *optype=operandType(op);
501 bool isPtr = IS_PTR(optype);
504 symbol *sym=OP_SYMBOL(op);
505 if (!sym->regs[0] && SYM_SPIL_LOC(sym)) {
506 sym=SYM_SPIL_LOC(sym);
510 if (DCL_TYPE(optype)==FPOINTER)
511 strcat (line, "far * ");
512 else if (DCL_TYPE(optype)==CPOINTER)
513 strcat (line, "code * ");
514 else if (DCL_TYPE(optype)==GPOINTER)
515 strcat (line, "gen * ");
516 else if (DCL_TYPE(optype)==POINTER)
517 strcat (line, "near * ");
519 strcat (line, "unknown * ");
521 strcat (line, nounName(sym->etype));
523 strcat (line, sym->name);
526 sprintf (line, "(%s)%s:", nounName(sym->etype), sym->name);
529 strcat (line, sym->regs[0]->name);
532 strcat (line, sym->regs[1]->name);
537 sprintf (line+strlen(line), "stack%+d", sym->stack);
540 if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
541 strcat (line, "code");
544 if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
545 strcat (line, "far");
548 if (IN_BITSPACE(SPEC_OCLS(sym->etype))) {
549 strcat (line, "bit");
552 if (IN_DIRSPACE(SPEC_OCLS(sym->etype))) {
553 strcat (line, "dir");
556 strcat (line, "unknown");
558 } else if (IS_VALOP(op)) {
559 opRegName(op, 0, line, 1);
560 } else if (IS_TYPOP(op)) {
563 if (DCL_TYPE(optype)==FPOINTER)
564 strcat (line, "far * ");
565 else if (DCL_TYPE(optype)==CPOINTER)
566 strcat (line, "code * ");
567 else if (DCL_TYPE(optype)==GPOINTER)
568 strcat (line, "gen * ");
569 else if (DCL_TYPE(optype)==POINTER)
570 strcat (line, "near * ");
572 strcat (line, "unknown * ");
574 // forget about static, volatile, ... for now
575 if (SPEC_USIGN(operandType(op))) strcat (line, "unsigned ");
576 if (SPEC_LONG(operandType(op))) strcat (line, "long ");
577 strcat (line, nounName(operandType(op)));
580 bailOut("printOp: unexpected operand type");
585 void printIc (char *op, iCode * ic, bool result, bool left, bool right) {
588 sprintf (line, "%s(%d)", op, ic->lineno);
590 strcat (line, " result=");
591 strcat (line, printOp (IC_RESULT(ic)));
594 strcat (line, " left=");
595 strcat (line, printOp (IC_LEFT(ic)));
598 strcat (line, " right=");
599 strcat (line, printOp (IC_RIGHT(ic)));
601 emitcode (";", line);
604 /*-----------------------------------------------------------------*/
605 /* toBoolean - return carry for operand!=0 */
606 /*-----------------------------------------------------------------*/
607 static char *toBoolean (operand * op) {
608 symbol *tlbl=newiTempLabel(NULL);
610 switch (AOP_SIZE(op))
614 emitcode ("cjne", "%s,#1,%05d$; %s", AOP_NAME(op), tlbl->key+100,
615 "This needs a second thought");
617 emitcode ("", "%05d$:", tlbl->key+100);
621 bailOut("toBoolean: unknown size");
625 /*-----------------------------------------------------------------*/
626 /* regsInCommon - two operands have some registers in common */
627 /*-----------------------------------------------------------------*/
628 static bool regsInCommon (operand * op1, operand * op2) {
632 /* if they have registers in common */
633 if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
636 sym1 = OP_SYMBOL (op1);
637 sym2 = OP_SYMBOL (op2);
639 if (sym1->nRegs == 0 || sym2->nRegs == 0)
642 for (i = 0; i < sym1->nRegs; i++)
648 for (j = 0; j < sym2->nRegs; j++)
653 if (sym2->regs[j] == sym1->regs[i])
661 /*-----------------------------------------------------------------*/
662 /* resultRemat - result is rematerializable */
663 /*-----------------------------------------------------------------*/
664 static int resultRemat (iCode * ic) {
665 if (SKIP_IC (ic) || ic->op == IFX)
668 if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
670 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
671 if (sym->remat && !POINTER_SET (ic))
678 /*-----------------------------------------------------------------*/
679 /* genNot - generate code for ! operation */
680 /*-----------------------------------------------------------------*/
681 static void genNot (iCode * ic) {
682 printIc("genNot:", ic, 1,1,0);
685 /*-----------------------------------------------------------------*/
686 /* genCpl - generate code for complement */
687 /*-----------------------------------------------------------------*/
688 static void genCpl (iCode * ic) {
689 printIc("genCpl", ic, 1,1,0);
692 /*-----------------------------------------------------------------*/
693 /* genUminus - unary minus code generation */
694 /*-----------------------------------------------------------------*/
695 static void genUminus (iCode * ic) {
696 printIc("genUminus", ic, 1,1,0);
699 /*-----------------------------------------------------------------*/
700 /* genIpush - generate code for pushing */
701 /*-----------------------------------------------------------------*/
702 static void genIpush (iCode * ic) {
703 operand *left=IC_LEFT(ic);
705 printIc ("genIpush", ic, 0,1,0);
706 aopOp(left,FALSE,FALSE);
709 if (AOP_TYPE(left)==AOP_LIT) {
710 switch (AOP_SIZE(left))
713 emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
714 emitcode ("push", "r1l");
718 emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
719 emitcode ("push", "r1");
723 emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
724 emitcode ("push", "r1l");
725 emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
726 emitcode ("push", "r1");
730 emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
731 emitcode ("push", "r1");
732 emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
733 emitcode ("push", "r1");
738 if (AOP_SIZE(left)>2) {
739 emitcode ("push", "%s", AOP_NAME(left)[1]);
742 emitcode ("push", "%s", AOP_NAME(left)[0]);
747 /*-----------------------------------------------------------------*/
748 /* genIpop - recover the registers: can happen only for spilling */
749 /*-----------------------------------------------------------------*/
750 static void genIpop (iCode * ic) {
751 printIc ("genIpop", ic, 0,1,0);
754 /*-----------------------------------------------------------------*/
755 /* genCall - generates a call statement */
756 /*-----------------------------------------------------------------*/
757 static void genCall (iCode * ic) {
758 operand *result=IC_RESULT(ic);
760 emitcode (";", "genCall(%d) %s result=%s", ic->lineno,
761 OP_SYMBOL(IC_LEFT(ic))->name,
762 printOp (IC_RESULT(ic)));
763 emitcode ("call", "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
765 /* readjust the stack if we have pushed some parms */
766 if (_G.parmsPushed) {
767 emitcode ("add", "r7,#0x%02x", _G.parmsPushed*2);
771 /* if we need to assign a result value */
772 if (IS_ITEMP (IC_RESULT(ic)) &&
773 OP_SYMBOL (IC_RESULT (ic))->nRegs) {
774 aopOp(result,FALSE,FALSE);
775 switch (AOP_SIZE(result))
778 emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
781 emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
785 emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
786 emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
789 emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
790 emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
797 /*-----------------------------------------------------------------*/
798 /* genPcall - generates a call by pointer statement */
799 /*-----------------------------------------------------------------*/
801 genPcall (iCode * ic)
803 emitcode (";", "genPcall %s\n", OP_SYMBOL(IC_LEFT(ic))->name);
806 /*-----------------------------------------------------------------*/
807 /* genFunction - generated code for function entry */
808 /*-----------------------------------------------------------------*/
809 static void genFunction (iCode * ic) {
810 symbol *sym=OP_SYMBOL(IC_LEFT(ic));
811 sym_link *type=sym->type;
813 emitcode (";", "genFunction %s", sym->rname);
815 /* print the allocation information */
816 printAllocInfo (currFunc, codeOutFile);
818 emitcode ("", "%s:", sym->rname);
820 if (IFFUNC_ISNAKED(type))
822 emitcode(";", "naked function: no prologue.");
826 /* adjust the stack for locals used in this function */
828 emitcode ("sub", "r7,#%d\t; create stack space for locals", sym->stack);
832 /*-----------------------------------------------------------------*/
833 /* genEndFunction - generates epilogue for functions */
834 /*-----------------------------------------------------------------*/
836 genEndFunction (iCode * ic)
838 symbol *sym = OP_SYMBOL (IC_LEFT (ic));
840 printIc ("genEndFunction", ic, 0,0,0);
842 if (IFFUNC_ISNAKED(sym->type)) {
843 emitcode(";", "naked function: no epilogue.");
847 /* readjust the stock for locals used in this function */
849 emitcode ("add", "r7,#%d\t; release stack space for locals", sym->stack);
852 if (IFFUNC_ISISR(sym->type)) {
853 emitcode ("reti", "");
855 emitcode ("ret", "");
859 /*-----------------------------------------------------------------*/
860 /* genRet - generate code for return statement */
861 /*-----------------------------------------------------------------*/
862 static void genRet (iCode * ic) {
865 printIc ("genRet", ic, 0, 0, 0);
867 printIc ("genRet", ic, 0, 1, 0);
868 aopOp(IC_LEFT(ic), TRUE, TRUE);
869 switch (AOP_SIZE(IC_LEFT(ic)))
872 emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
873 emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
876 emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
879 emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
882 emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
889 emitcode ("jmp", "%05d$", returnLabel->key+100);
892 /*-----------------------------------------------------------------*/
893 /* genLabel - generates a label */
894 /*-----------------------------------------------------------------*/
895 static void genLabel (iCode * ic) {
896 /* special case never generate */
897 if (IC_LABEL (ic) == entryLabel)
900 emitcode (";", "genLabel(%d) %s", ic->lineno, IC_LABEL(ic)->name);
901 emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
904 /*-----------------------------------------------------------------*/
905 /* genGoto - generates a jmp */
906 /*-----------------------------------------------------------------*/
907 static void genGoto (iCode * ic) {
908 emitcode (";", "genGoto(%d) %s", ic->lineno, IC_LABEL(ic)->name);
909 emitcode ("jmp", "%05d$", (IC_LABEL (ic)->key + 100));
912 /*-----------------------------------------------------------------*/
913 /* genPlus - generates code for addition */
914 /*-----------------------------------------------------------------*/
915 static void genPlus (iCode * ic) {
916 operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
920 printIc ("genPlus", ic, 1,1,1);
922 size=aopOp(result, TRUE, TRUE);
924 /* if left is a literal, then exchange them */
925 if (IS_LITERAL(operandType(left))) {
926 operand *tmp = right;
931 if (aopIsBit(result)) {
932 if (IS_LITERAL(operandType(right))) {
933 if (operandLitValue(right)) {
934 emitcode ("setb", AOP_NAME(result)[0]);
937 aopOp(left, TRUE, TRUE);
938 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
941 bailOut("genPlus: unfinished genPlus bit");
944 aopOp(left, !aopIsPtr(result), !aopIsDir(result));
945 aopOp(right, !aopIsPtr(result), !aopIsDir(result));
947 // special case for * = * + char, needs a closer look
948 // heck, this shouldn't have come here but bug-223113 does
949 if (size==3 && AOP_SIZE(right)==1) {
950 emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
951 emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
952 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
953 emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
954 emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
958 // special case for (whatever)* = (whatever)** + char, needs a closer look
959 // heck, this shouldn't have come here but bug-441448 does
960 if (size==2 && AOP_SIZE(right)==1) {
961 emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
962 emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
963 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
964 emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
973 if (!aopEqual(result->aop, left->aop, 0)) {
974 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
976 emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
978 if (!aopEqual(result->aop, left->aop, 1)) {
979 emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
984 emitcode ("addc.w", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
990 /*-----------------------------------------------------------------*/
991 /* genMinus - generates code for subtraction */
992 /*-----------------------------------------------------------------*/
993 static void genMinus (iCode * ic) {
994 printIc ("genMinus", ic, 1,1,1);
998 /*-----------------------------------------------------------------*/
999 /* genMult - generates code for multiplication */
1000 /*-----------------------------------------------------------------*/
1001 static void genMult (iCode * ic) {
1002 printIc ("genMult", ic, 1,1,1);
1005 /*-----------------------------------------------------------------*/
1006 /* genDiv - generates code for division */
1007 /*-----------------------------------------------------------------*/
1008 static void genDiv (iCode * ic) {
1009 printIc ("genDiv", ic, 1,1,1);
1012 /*-----------------------------------------------------------------*/
1013 /* genMod - generates code for division */
1014 /*-----------------------------------------------------------------*/
1015 static void genMod (iCode * ic) {
1016 printIc ("genMod", ic, 1,1,1);
1019 /*-----------------------------------------------------------------*/
1020 /* genCmpGt :- greater than comparison */
1021 /*-----------------------------------------------------------------*/
1022 static void genCmpGt (iCode * ic) {
1023 printIc ("genCmpGt", ic, 1,1,1);
1025 /*-----------------------------------------------------------------*/
1026 /* genCmpGt :- greater than comparison */
1027 /*-----------------------------------------------------------------*/
1028 static void genCmpLe (iCode * ic) {
1029 printIc ("genCmpLe", ic, 1,1,1);
1031 /*-----------------------------------------------------------------*/
1032 /* genCmpGt :- greater than comparison */
1033 /*-----------------------------------------------------------------*/
1034 static void genCmpGe (iCode * ic) {
1035 printIc ("genCmpGe", ic, 1,1,1);
1037 /*-----------------------------------------------------------------*/
1038 /* genCmpGt :- greater than comparison */
1039 /*-----------------------------------------------------------------*/
1040 static void genCmpNe (iCode * ic) {
1041 printIc ("genCmpNe", ic, 1,1,1);
1043 /*-----------------------------------------------------------------*/
1044 /* genCmpLt - less than comparisons */
1045 /*-----------------------------------------------------------------*/
1046 static void genCmpLt (iCode * ic) {
1047 printIc ("genCmpLt", ic, 1,1,1);
1049 /*-----------------------------------------------------------------*/
1050 /* genCmpEq - generates code for equal to */
1051 /*-----------------------------------------------------------------*/
1052 static void genCmpEq (iCode * ic) {
1053 printIc ("genCmpEq", ic, 1,1,1);
1056 /*-----------------------------------------------------------------*/
1057 /* ifxForOp - returns the icode containing the ifx for operand */
1058 /*-----------------------------------------------------------------*/
1059 static iCode *ifxForOp (operand * op, iCode * ic) {
1060 /* if true symbol then needs to be assigned */
1061 if (IS_TRUE_SYMOP (op))
1064 /* if this has register type condition and
1065 the next instruction is ifx with the same operand
1066 and live to of the operand is upto the ifx only then */
1068 ic->next->op == IFX &&
1069 IC_COND (ic->next)->key == op->key &&
1070 OP_SYMBOL (op)->liveTo <= ic->next->seq)
1076 /*-----------------------------------------------------------------*/
1077 /* hasInc - operand is incremented before any other use */
1078 /*-----------------------------------------------------------------*/
1079 static iCode *hasInc (operand *op, iCode *ic, int osize) {
1080 sym_link *type = operandType(op);
1081 sym_link *retype = getSpec (type);
1082 iCode *lic = ic->next;
1085 /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
1086 if (!IS_SYMOP(op)) return NULL;
1088 if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
1089 if (IS_AGGREGATE(type->next)) return NULL;
1090 if (osize != (isize = getSize(type->next))) return NULL;
1093 /* if operand of the form op = op + <sizeof *op> */
1094 if (lic->op == '+') {
1095 if (isOperandEqual(IC_LEFT(lic),op) &&
1096 //isOperandEqual(IC_RESULT(lic),op) &&
1097 isOperandLiteral(IC_RIGHT(lic)) &&
1098 operandLitValue(IC_RIGHT(lic)) == isize) {
1099 emitcode (";", "Found hasInc");
1103 /* if the operand used or deffed */
1104 if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
1107 /* if GOTO or IFX */
1108 if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
1114 /*-----------------------------------------------------------------*/
1115 /* genAndOp - for && operation */
1116 /*-----------------------------------------------------------------*/
1117 static void genAndOp (iCode * ic) {
1118 printIc ("genAndOp(&&)", ic, 1,1,1);
1121 /*-----------------------------------------------------------------*/
1122 /* genOrOp - for || operation */
1123 /*-----------------------------------------------------------------*/
1124 static void genOrOp (iCode * ic) {
1125 printIc ("genOrOp(||)", ic, 1,1,1);
1128 /*-----------------------------------------------------------------*/
1129 /* genAnd - code for and */
1130 /*-----------------------------------------------------------------*/
1131 static void genAnd (iCode * ic, iCode * ifx) {
1132 printIc ("genAnd", ic, 1,1,1);
1135 /*-----------------------------------------------------------------*/
1136 /* genOr - code for or */
1137 /*-----------------------------------------------------------------*/
1138 static void genOr (iCode * ic, iCode * ifx) {
1139 operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
1143 printIc ("genOr", ic, 1,1,1);
1145 size=aopOp(result, TRUE, TRUE);
1147 /* if left is a literal, then exchange them */
1148 if (IS_LITERAL(operandType(left))) {
1149 operand *tmp = right;
1154 if (aopIsBit(result)) {
1155 if (IS_LITERAL(operandType(right))) {
1156 if (operandLitValue(right)) {
1157 emitcode ("setb", AOP_NAME(result)[0]);
1160 aopOp(left, TRUE, TRUE);
1161 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
1166 aopOp(left, !aopIsPtr(result), !aopIsDir(result));
1167 aopOp(right, !aopIsPtr(result), !aopIsDir(result));
1174 if (!aopEqual(result->aop, left->aop, 0)) {
1175 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1177 emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1179 if (!aopEqual(result->aop, left->aop, 1)) {
1180 emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
1182 emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
1187 /*-----------------------------------------------------------------*/
1188 /* genXor - code for xclusive or */
1189 /*-----------------------------------------------------------------*/
1190 static void genXor (iCode * ic, iCode * ifx) {
1191 printIc ("genXor", ic, 1,1,1);
1194 /*-----------------------------------------------------------------*/
1195 /* genInline - write the inline code out */
1196 /*-----------------------------------------------------------------*/
1197 static void genInline (iCode * ic) {
1199 printIc ("genInline", ic, 0,0,0);
1201 emitcode ("", IC_INLINE(ic));
1204 /*-----------------------------------------------------------------*/
1205 /* genRRC - rotate right with carry */
1206 /*-----------------------------------------------------------------*/
1207 static void genRRC (iCode * ic) {
1208 printIc ("genRRC", ic, 1,1,0);
1211 /*-----------------------------------------------------------------*/
1212 /* genRLC - generate code for rotate left with carry */
1213 /*-----------------------------------------------------------------*/
1214 static void genRLC (iCode * ic) {
1215 printIc ("genRLC", ic, 1,1,0);
1218 /*-----------------------------------------------------------------*/
1219 /* genGetHbit - generates code get highest order bit */
1220 /*-----------------------------------------------------------------*/
1221 static void genGetHbit (iCode * ic) {
1222 printIc ("genGetHbit", ic, 1,1,0);
1225 /*-----------------------------------------------------------------*/
1226 /* genLeftShift - generates code for left shifting */
1227 /*-----------------------------------------------------------------*/
1228 static void genLeftShift (iCode * ic) {
1229 printIc ("genLeftShift", ic, 1,1,1);
1232 /*-----------------------------------------------------------------*/
1233 /* genRightShift - generate code for right shifting */
1234 /*-----------------------------------------------------------------*/
1235 static void genRightShift (iCode * ic) {
1236 printIc ("genRightShift", ic, 1,1,1);
1239 /*-----------------------------------------------------------------*/
1240 /* genPointerGet - generate code for pointer get */
1241 /*-----------------------------------------------------------------*/
1242 static void genPointerGet (iCode * ic, iCode *pi) {
1243 char *instr, *scratchReg;
1244 operand *result=IC_RESULT(ic), *left=IC_LEFT(ic);
1245 bool codePointer=IS_CODEPTR(operandType(left));
1249 printIc ("genPointerGet pi", ic, 1,1,0);
1251 printIc ("genPointerGet", ic, 1,1,0);
1254 if (!IS_PTR(operandType(left))) {
1255 bailOut ("genPointerGet: pointer required");
1258 aopOp(left,FALSE,FALSE);
1259 size=aopOp(result,TRUE,aopIsDir(left));
1261 if (IS_GENPTR(operandType(left))) {
1262 symbol *tlbl1=newiTempLabel(NULL);
1263 symbol *tlbl2=newiTempLabel(NULL);
1264 emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
1265 emitcode ("beq", "%05d$", tlbl1->key+100);
1268 emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1271 emitcode ("mov", "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1275 emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
1277 emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
1280 emitcode ("br", "%05d$", tlbl2->key+100);
1281 emitcode ("", "%05d$:", tlbl1->key+100);
1284 emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
1287 emitcode ("mov", "r0,%s", AOP_NAME(left)[0]);
1288 emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[0]);
1292 emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
1294 emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1]);
1297 emitcode ("", "%05d$:", tlbl2->key+100);
1301 switch (AOP_TYPE(left))
1304 emitcode("mov","r1,%s", AOP_NAME(left)[0]);
1305 sprintf (AOP_NAME(left)[0], "r1");
1323 if (AOP_TYPE(result)==AOP_STK) {
1324 emitcode (MOV, "%s,[%s]", scratchReg, AOP_NAME(left)[0]);
1325 emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
1328 emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0],
1333 emitcode (MOV, "r1,%s", AOP_NAME(left)[0]);
1334 emitcode (instr, "%s,[r1+]", AOP_NAME(result)[0]);
1336 emitcode (instr, "%s,[%s]", AOP_NAME(result)[0],
1350 if (AOP_TYPE(result)==AOP_STK) {
1351 emitcode (MOV, "%s,[%s+2]", scratchReg, AOP_NAME(left)[0]);
1352 emitcode (MOV, "%s,%s", AOP_NAME(result)[1], scratchReg);
1355 emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1],
1359 emitcode (instr, "%s,[r1]", AOP_NAME(result)[1]);
1361 emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1],
1369 bailOut ("genPointerGet");
1372 /*-----------------------------------------------------------------*/
1373 /* genPointerSet - stores the value into a pointer location */
1374 /*-----------------------------------------------------------------*/
1375 static void genPointerSet (iCode * ic, iCode *pi) {
1377 operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
1380 printIc ("genPointerSet", ic, 1,0,1);
1382 if (!IS_PTR(operandType(result))) {
1383 bailOut ("genPointerSet: pointer required");
1386 aopOp(result,FALSE,FALSE);
1387 size=aopOp(right,FALSE, FALSE);
1389 if (IS_GENPTR(operandType(result))) {
1390 emitcode (";", "INLINE\t_gptrset ; [%s %s] = %s %s",
1391 AOP_NAME(result)[0], AOP_NAME(result)[1],
1392 AOP_NAME(right)[0], AOP_NAME(right)[1]);
1396 switch (AOP_TYPE(right))
1406 emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1409 emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1416 emitcode (instr, "[%s+],%s", AOP_NAME(result)[0],
1417 AOP_NAME(right)[1]);
1419 emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0],
1420 AOP_NAME(right)[1]);
1425 bailOut ("genPointerSet");
1428 /*-----------------------------------------------------------------*/
1429 /* genIfx - generate code for Ifx statement */
1430 /*-----------------------------------------------------------------*/
1431 static void genIfx (iCode * ic, iCode * popIc) {
1435 symbol *jlbl, *tlbl=newiTempLabel(NULL);
1436 operand *cond=IC_COND(ic);
1438 emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s",
1439 ic->lineno, printOp(cond),
1440 IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
1441 IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
1443 size=aopOp(cond,TRUE,TRUE);
1453 switch (AOP_TYPE(cond) )
1456 emitcode (trueOrFalse ? "jnb" : "jb", "%s,%05d$",
1457 AOP_NAME(cond)[0], tlbl->key+100);
1458 emitcode ("jmp", "%05d$", jlbl->key+100);
1459 emitcode ("", "%05d$:", tlbl->key+100);
1470 emitcode (instr, "%s,#0", AOP_NAME(cond)[0]);
1471 emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
1474 // generic pointer, forget the generic part
1476 emitcode (instr, "%s,#0", AOP_NAME(cond)[1]);
1477 emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
1480 emitcode ("jmp", "%05d$", jlbl->key+100);
1481 emitcode ("", "%05d$:", tlbl->key+100);
1487 /*-----------------------------------------------------------------*/
1488 /* genAddrOf - generates code for address of */
1489 /*-----------------------------------------------------------------*/
1490 static void genAddrOf (iCode * ic) {
1492 operand *left=IC_LEFT(ic);
1494 printIc ("genAddrOf", ic, 1,1,0);
1496 size=aopOp (IC_RESULT(ic), FALSE, TRUE);
1498 if (isOperandOnStack(left)) {
1499 emitcode ("lea", "%s,%s", AOP_NAME(IC_RESULT(ic))[0],
1500 getStackOffset(OP_SYMBOL(left)->stack));
1502 // this must be a generic pointer
1503 emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
1508 if (isOperandInDirSpace(left) ||
1509 isOperandInFarSpace(left) ||
1510 isOperandInCodeSpace(left)) {
1511 emitcode ("mov.w", "%s,#%s", AOP_NAME(IC_RESULT(ic))[0],
1512 OP_SYMBOL(left)->rname);
1514 // this must be a generic pointer
1515 int space=0; // dir space
1516 if (isOperandInFarSpace(left)) {
1518 } else if (isOperandInCodeSpace(left)) {
1521 emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], space);
1526 bailOut("genAddrOf");
1529 /*-----------------------------------------------------------------*/
1530 /* genAssign - generate code for assignment */
1531 /*-----------------------------------------------------------------*/
1532 static void genAssign (iCode * ic) {
1533 operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
1537 printIc ("genAssign", ic, 1,0,1);
1539 if (!IS_SYMOP(result)) {
1540 bailOut("genAssign: result is not a symbol");
1543 aopOp(result, TRUE, TRUE);
1544 aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
1545 size=AOP_SIZE(result);
1547 /* if result is a bit */
1548 if (AOP_TYPE(result) == AOP_BIT) {
1549 /* if right is literal, we know what the value is */
1550 if (AOP_TYPE(right) == AOP_LIT) {
1551 if (operandLitValue(right)) {
1552 emitcode ("setb", AOP_NAME(result)[0]);
1554 emitcode ("clr", AOP_NAME(result)[0]);
1558 /* if right is also a bit */
1559 if (AOP_TYPE(right) == AOP_BIT) {
1560 emitcode ("mov", "c,%s", AOP_NAME(right));
1561 emitcode ("mov", "%s,c", AOP_NAME(result));
1565 emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
1575 emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1582 emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
1587 /*-----------------------------------------------------------------*/
1588 /* genJumpTab - genrates code for jump table */
1589 /*-----------------------------------------------------------------*/
1590 static void genJumpTab (iCode * ic) {
1591 printIc ("genJumpTab", ic, 0,0,0);
1594 /*-----------------------------------------------------------------*/
1595 /* genCast - gen code for casting */
1596 /*-----------------------------------------------------------------*/
1597 static void genCast (iCode * ic) {
1599 operand *result=IC_RESULT(ic);
1600 operand *right=IC_RIGHT(ic);
1601 sym_link *ctype=operandType(IC_LEFT(ic));
1602 sym_link *rtype=operandType(IC_RIGHT(ic));
1603 sym_link *etype=getSpec(rtype);
1604 short ptrType, signedness;
1606 printIc ("genCast", ic, 1,1,1);
1608 aopOp(result, TRUE, TRUE);
1609 aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
1610 size=AOP_SIZE(result);
1612 /* if result is a bit */
1613 if (AOP_TYPE(result) == AOP_BIT) {
1614 /* if right is literal, we know what the value is */
1615 if (AOP_TYPE(right) == AOP_LIT) {
1616 if (operandLitValue(right)) {
1617 emitcode ("setb", AOP_NAME(result)[0]);
1619 emitcode ("clr", AOP_NAME(result)[0]);
1623 /* if right is also a bit */
1624 if (AOP_TYPE(right) == AOP_BIT) {
1625 emitcode ("mov", "c,%s", AOP_NAME(right));
1626 emitcode ("mov", "%s,c", AOP_NAME(result));
1630 emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
1634 /* if right is a bit */
1635 if (AOP_TYPE(right)==AOP_BIT) {
1636 emitcode ("mov", "c,%s", AOP_NAME(right));
1637 emitcode ("mov", "%s,#0", AOP_NAME(result)[0]);
1638 emitcode ("rlc", "%s,#1", AOP_NAME(result)[0]);
1640 emitcode ("mov", "%s,#0", AOP_NAME(result)[1]);
1645 /* if the result is of type pointer */
1646 if (IS_PTR (ctype)) {
1648 if (AOP_SIZE(right)>1) {
1649 emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1651 emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
1652 emitcode ("sext", "r1h");
1653 emitcode ("mov", "%s,r1", AOP_NAME(result)[0]);
1656 /* if pointer to generic pointer */
1657 if (IS_GENPTR (ctype)) {
1659 if (IS_GENPTR (rtype)) {
1660 bailOut("genCast: gptr -> gptr");
1663 if (IS_PTR (rtype)) {
1664 ptrType = DCL_TYPE (rtype);
1666 /* we have to go by the storage class */
1667 if (!SPEC_OCLS(etype)) {
1668 ptrType=0; // hush the compiler
1669 bailOut("genCast: unknown storage class");
1671 ptrType = PTR_TYPE (SPEC_OCLS (etype));
1675 /* the generic part depends on the type */
1679 emitcode ("mov.b", "%s,#0x00", AOP_NAME(result)[1]);
1682 emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
1685 emitcode ("mov.b", "%s,#0x02", AOP_NAME(result)[1]);
1688 bailOut("genCast: got unknown storage class");
1694 /* do we have to sign extend? */
1695 signedness = SPEC_USIGN(rtype);
1697 /* now depending on the size */
1698 switch ((AOP_SIZE(result)<<4) + AOP_SIZE(right))
1702 emitcode("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
1707 emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1710 emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
1712 emitcode("sext", "%s", AOP_NAME(result)[1]);
1714 emitcode("mov", "%s,#0", AOP_NAME(result)[1]);
1719 emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
1721 emitcode("sext", "r1h");
1723 emitcode("mov", "r1h,#0");
1725 emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
1728 // fall through: case 0x41
1730 emitcode("sext", "r1");
1732 emitcode("mov", "r1,#0");
1734 emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
1738 emitcode("mov", "r1,%s", AOP_NAME(right)[0]);
1739 emitcode("mov", "%s,r1l", AOP_NAME(result)[0]);
1742 fprintf(stderr, "genCast: unknown size: %d:%d\n",
1743 AOP_SIZE(result), AOP_SIZE(right));
1744 bailOut("genCast: unknown size");
1748 /*-----------------------------------------------------------------*/
1749 /* genDjnz - generate decrement & jump if not zero instrucion */
1750 /*-----------------------------------------------------------------*/
1751 static bool genDjnz (iCode * ic, iCode * ifx) {
1757 /* if the if condition has a false label
1758 then we cannot save */
1762 /* if the minus is not of the form
1764 if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
1765 !IS_OP_LITERAL (IC_RIGHT (ic)))
1768 if (operandLitValue (IC_RIGHT (ic)) != 1)
1771 /* if the size of this greater than two then no
1773 if (getSize (operandType (IC_RESULT (ic))) > 2)
1776 printIc ("genDjnz", ic, 1,1,1);
1778 /* otherwise we can save BIG */
1779 lbl = newiTempLabel (NULL);
1780 lbl1 = newiTempLabel (NULL);
1782 aopOp (IC_RESULT (ic), FALSE, TRUE);
1784 if (AOP_TYPE(IC_RESULT(ic))==AOP_REG || AOP_TYPE(IC_RESULT(ic))==AOP_DIR) {
1785 emitcode ("djnz", "%s,%05d$", AOP_NAME(IC_RESULT(ic)), lbl->key+100);
1786 emitcode ("br", "%05d$", lbl1->key + 100);
1787 emitcode ("", "%05d$:", lbl->key + 100);
1788 emitcode ("jmp", "%05d$", IC_TRUE (ifx)->key + 100);
1789 emitcode ("", "%05d$:", lbl1->key + 100);
1793 bailOut("genDjnz: aop type");
1797 /*-----------------------------------------------------------------*/
1798 /* genReceive - generate code for a receive iCode */
1799 /*-----------------------------------------------------------------*/
1800 static void genReceive (iCode * ic) {
1801 printIc ("genReceive", ic, 1,0,0);
1804 /*-----------------------------------------------------------------*/
1805 /* gen51Code - generate code for 8051 based controllers */
1806 /*-----------------------------------------------------------------*/
1807 void genXA51Code (iCode * lic) {
1811 lineHead = lineCurr = NULL;
1813 /* if debug information required */
1814 if (options.debug && currFunc)
1816 cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
1818 if (IS_STATIC (currFunc->etype))
1819 emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
1821 emitcode ("", "G$%s$0$0 ==.", currFunc->name);
1825 for (ic = lic; ic; ic = ic->next) {
1826 if (ic->lineno && cln != ic->lineno) {
1827 if (options.debug) {
1829 emitcode ("", "C$%s$%d$%d$%d ==.",
1830 FileBaseName (ic->filename), ic->lineno,
1831 ic->level, ic->block);
1834 emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
1835 printCLine(ic->filename, ic->lineno));
1838 /* if the result is marked as
1839 spilt and rematerializable or code for
1840 this has already been generated then
1842 if (resultRemat (ic) || ic->generated)
1845 /* depending on the operation */
1865 /* IPOP happens only when trying to restore a
1866 spilt live range, if there is an ifx statement
1867 following this pop then the if statement might
1868 be using some of the registers being popped which
1869 would destory the contents of the register so
1870 we need to check for this condition and handle it */
1872 ic->next->op == IFX &&
1873 regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
1874 genIfx (ic->next, ic);
1892 genEndFunction (ic);
1912 if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
1961 genXor (ic, ifxForOp (IC_RESULT (ic), ic));
1965 genOr (ic, ifxForOp (IC_RESULT (ic), ic));
1969 genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
1996 case GET_VALUE_AT_ADDRESS:
1997 genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_RESULT(ic)))));
2001 if (POINTER_SET (ic))
2002 genPointerSet (ic, hasInc(IC_RESULT(ic), ic, getSize(operandType(IC_RIGHT(ic)))));
2028 addSet (&_G.sendSet, ic);
2037 /* now we are ready to call the
2038 peep hole optimizer */
2039 if (!options.nopeep)
2040 peepHole (&lineHead);
2042 /* now do the actual printing */
2043 printLine (lineHead, codeOutFile);