X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fgen.c;h=1cf40126b348e97bf7c6490a1f18184af97ec885;hb=df203a96d87ea3322e836e3dd980f64b80b234e7;hp=77bae8aaf24e441ecfdb34b5652603453148d53a;hpb=5041ceef1317fba40db00ddc5f57b74f7484220d;p=fw%2Fsdcc diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 77bae8aa..1cf40126 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -30,7 +30,7 @@ #include #include -#include +#include "common.h" #include "ralloc.h" #include "gen.h" #include "SDCCglobl.h" @@ -159,33 +159,47 @@ static unsigned char SRMask[] = static void emitcode (char *inst, char *fmt,...) { - va_list ap; - char lb[INITIAL_INLINEASM]; - char *lbp = lb; - - va_start (ap, fmt); - - if (inst && *inst) + va_list ap; + char lb[INITIAL_INLINEASM]; + char *lbp = lb; + + va_start (ap, fmt); + + if (inst && *inst) { - if (fmt && *fmt) - sprintf (lb, "%s\t", inst); - else - sprintf (lb, "%s", inst); - tvsprintf (lb + (strlen (lb)), fmt, ap); + if (fmt && *fmt) + { + SNPRINTF (lb, sizeof(lb), "%s\t", inst); + } + else + { + SNPRINTF (lb, sizeof(lb), "%s", inst); + } + + tvsprintf (lb + strlen(lb), sizeof(lb) - strlen(lb), + fmt, ap); } - else - tvsprintf (lb, fmt, ap); + else + { + tvsprintf (lb, sizeof(lb), fmt, ap); + } + - while (isspace (*lbp)) - lbp++; + while (isspace (*lbp)) + { + lbp++; + } - if (lbp && *lbp) - lineCurr = (lineCurr ? - connectLine (lineCurr, newLineNode (lb)) : - (lineHead = newLineNode (lb))); - lineCurr->isInline = _G.inLine; - lineCurr->isDebug = _G.debugLine; - va_end (ap); + if (lbp && *lbp) + { + lineCurr = (lineCurr ? + connectLine (lineCurr, newLineNode (lb)) : + (lineHead = newLineNode (lb))); + } + + lineCurr->isInline = _G.inLine; + lineCurr->isDebug = _G.debugLine; + va_end (ap); } /*-----------------------------------------------------------------*/ @@ -652,10 +666,10 @@ aopForRemat (symbol * sym) aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1); strcpy (aop->aopu.aop_immd.aop_immd1, buffer); /* set immd2 field if required */ - if (aop->aopu.aop_immd.from_cast_remat) { - tsprintf(buffer,"#!constbyte",ptr_type); - aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1); - strcpy (aop->aopu.aop_immd.aop_immd2, buffer); + if (aop->aopu.aop_immd.from_cast_remat) + { + tsprintf(buffer, sizeof(buffer), "#!constbyte",ptr_type); + aop->aopu.aop_immd.aop_immd2 = Safe_strdup(buffer); } return aop; @@ -1066,8 +1080,8 @@ aopGet (asmop * aop, bool dname, bool canClobberACC) { - char *s = buffer; - char *rs; + //char *s = buffer; + //char *rs; /* offset is greater than size then zero */ @@ -1100,10 +1114,8 @@ aopGet (asmop * aop, emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name); return (dname ? "acc" : "a"); } - sprintf (s, "@%s", aop->aopu.aop_ptr->name); - rs = Safe_calloc (1, strlen (s) + 1); - strcpy (rs, s); - return rs; + SNPRINTF (buffer, sizeof(buffer), "@%s", aop->aopu.aop_ptr->name); + return Safe_strdup(buffer); case AOP_DPTRn: assert(offset <= 3); @@ -1160,44 +1172,60 @@ aopGet (asmop * aop, return (dname ? "acc" : "a"); case AOP_IMMD: - if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) { - sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2); - } else if (bit16) - sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1); - else if (offset) { + if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) + { + SNPRINTF(buffer, sizeof(buffer), + "%s",aop->aopu.aop_immd.aop_immd2); + } + else if (bit16) + { + SNPRINTF(buffer, sizeof(buffer), + "#%s", aop->aopu.aop_immd.aop_immd1); + } + else if (offset) + { switch (offset) { case 1: - tsprintf(s,"#!his",aop->aopu.aop_immd.aop_immd1); + tsprintf(buffer, sizeof(buffer), + "#!his",aop->aopu.aop_immd.aop_immd1); break; case 2: - tsprintf(s,"#!hihis",aop->aopu.aop_immd.aop_immd1); + tsprintf(buffer, sizeof(buffer), + "#!hihis",aop->aopu.aop_immd.aop_immd1); break; case 3: - tsprintf(s,"#!hihihis",aop->aopu.aop_immd.aop_immd1); + tsprintf(buffer, sizeof(buffer), + "#!hihihis",aop->aopu.aop_immd.aop_immd1); break; default: /* should not need this (just in case) */ - sprintf (s, "#(%s >> %d)", + SNPRINTF (buffer, sizeof(buffer), + "#(%s >> %d)", aop->aopu.aop_immd.aop_immd1, offset * 8); } } else - sprintf (s, "#%s", - aop->aopu.aop_immd.aop_immd1); - rs = Safe_calloc (1, strlen (s) + 1); - strcpy (rs, s); - return rs; + { + SNPRINTF (buffer, sizeof(buffer), + "#%s", aop->aopu.aop_immd.aop_immd1); + } + return Safe_strdup(buffer); case AOP_DIR: if (offset) - sprintf (s, "(%s + %d)", + { + SNPRINTF (buffer, sizeof(buffer), + "(%s + %d)", aop->aopu.aop_dir, offset); + } else - sprintf (s, "%s", aop->aopu.aop_dir); - rs = Safe_calloc (1, strlen (s) + 1); - strcpy (rs, s); - return rs; + { + SNPRINTF(buffer, sizeof(buffer), + "%s", aop->aopu.aop_dir); + } + + return Safe_strdup(buffer); case AOP_REG: if (dname) @@ -3680,6 +3708,7 @@ adjustArithmeticResult (iCode * ic) } } +#ifdef KEVIN_SCREWED_UP // Macro to aopOp all three operands of an ic. If this cannot be done, // the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter // will be set TRUE. The caller must then handle the case specially, noting @@ -3713,6 +3742,88 @@ adjustArithmeticResult (iCode * ic) aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \ aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); +#else // Kevin didn't screw up... + +#define AOP_IS_STR(x) (IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) + +// The guts of AOP_OP_3_NOFATAL. Generates the left & right opcodes of an IC, +// generates the result if possible. If result is generated, returns TRUE; otherwise +// returns false and caller must deal with fact that result isn't aopOp'd. +bool aopOp3(iCode * ic) +{ + bool dp1InUse, dp2InUse; + + // First, generate the right opcode. DPTR may be used if neither left nor result are + // of type AOP_STR. + +// D(emitcode(";", "aopOp3: AOP_IS_STR left: %s right: %s result: %s", +// AOP_IS_STR(IC_LEFT(ic)) ? "true" : "false", +// AOP_IS_STR(IC_RIGHT(ic)) ? "true" : "false", +// AOP_IS_STR(IC_RESULT(ic)) ? "true" : "false"); +// ); + + aopOp (IC_RIGHT(ic),ic,FALSE, AOP_IS_STR(IC_LEFT(ic)) || AOP_IS_STR(IC_RESULT(ic))); + + // Now, the left opcode. This can use DPTR if the right didn't AND the result is not + // AOP_STR (however, if the result is the same operand as the left, then DPTR may be used). + aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic)) || + (AOP_IS_STR(IC_RESULT(ic)) && !isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)))); + + // We've op'd the left. So, if left & result are the same operand, we know aopOp + // will succeed, and we can just do it & bail. + if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic))) + { +// D(emitcode(";", "aopOp3: left & result equal");); + aopOp(IC_RESULT(ic),ic,TRUE, FALSE); + return TRUE; + } + + // Note which dptrs are currently in use. + dp1InUse = (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || + AOP_IS_STR(IC_RIGHT(ic)) || AOP_IS_STR(IC_LEFT(ic)); + dp2InUse = (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR2) || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2); + + // OK, now if either left or right uses DPTR and the result is an AOP_STR, we cannot generate it. + if (dp1InUse && AOP_IS_STR(IC_RESULT(ic))) + { + return FALSE; + } + + // or, if both dp1 & dp2 are in use and the result needs a dptr, we're out of luck + if (dp1InUse && dp2InUse && isOperandInFarSpace(IC_RESULT(ic))) + { + return FALSE; + } + + aopOp (IC_RESULT(ic),ic,TRUE, dp1InUse); + + // SOme sanity checking... + if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && + AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) + { + fprintf(stderr, + "Ack: got unexpected DP2! (%s:%d %s:%d)\n", + __FILE__, __LINE__, ic->filename, ic->lineno); + } + + return TRUE; +} + +// Macro to aopOp all three operands of an ic. If this cannot be done, +// the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter +// will be set TRUE. The caller must then handle the case specially, noting +// that the IC_RESULT operand is not aopOp'd. +// +#define AOP_OP_3_NOFATAL(ic, rc) \ + do { rc = !aopOp3(ic); } while (0) + +// aopOp the left & right operands of an ic. +#define AOP_OP_2(ic) \ + aopOp (IC_RIGHT(ic),ic,FALSE, AOP_IS_STR(IC_LEFT(ic))); \ + aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic))); + +#endif + // convienience macro. #define AOP_SET_LOCALS(ic) \ left = IC_LEFT(ic); \ @@ -8485,11 +8596,11 @@ genRightShiftLiteral (operand * left, default: break; } - - freeAsmop (left, NULL, ic, TRUE); - freeAsmop (result, NULL, ic, TRUE); } - return TRUE; + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); + + return TRUE; } #endif @@ -9382,7 +9493,8 @@ genGenPointerGet (operand * left, else { /* we need to get it byte by byte */ _startLazyDPSEvaluation (); -#if 1 // I see no point at all to this code and will likely yank it soon. +#if 0 // I see no point at all to this code. + // So I yanked it. Kill at some future date if no bugs rear their heads. if (AOP(left)->type==AOP_DPTR2) { char *l; l=aopGet(AOP(left),0,FALSE,FALSE,TRUE); @@ -9418,23 +9530,48 @@ genGenPointerGet (operand * left, _endLazyDPSEvaluation (); } } - /* so dptr know contains the address */ + + /* so dptr-b now contains the address */ + _G.bInUse++; aopOp (result, ic, FALSE, TRUE); + _G.bInUse--; /* if bit then unpack */ if (IS_BITVAR (retype) || IS_BITVAR (letype)) + { genUnpackBits (result, "dptr", GPOINTER); + } else { - size = AOP_SIZE (result); - offset = 0; + size = AOP_SIZE (result); + offset = 0; - while (size--) + while (size--) { - emitcode ("lcall", "__gptrget"); - aopPut (AOP (result), "a", offset++); - if (size || (pi && AOP_TYPE (left) != AOP_IMMD)) - emitcode ("inc", "dptr"); + if (size) + { + // Get two bytes at a time, results in _AP & A. + // dptr will be incremented ONCE by __gptrgetWord. + // + // Note: any change here must be coordinated + // with the implementation of __gptrgetWord + // in device/lib/_gptrget.c + emitcode ("lcall", "__gptrgetWord"); + aopPut (AOP (result), DP2_RESULT_REG, offset++); + aopPut (AOP (result), "a", offset++); + size--; + } + else + { + // Only one byte to get. + emitcode ("lcall", "__gptrget"); + aopPut (AOP (result), "a", offset++); + } + + if (size || (pi && AOP_TYPE (left) != AOP_IMMD)) + { + emitcode ("inc", "dptr"); + } } } @@ -10250,7 +10387,8 @@ genAddrOf (iCode * ic) /* if 10 bit stack */ if (options.stack10bit) { char buff[10]; - tsprintf(buff,"#!constbyte",(options.stack_loc >> 16) & 0xff); + tsprintf(buff, sizeof(buff), + "#!constbyte",(options.stack_loc >> 16) & 0xff); /* if it has an offset then we need to compute it */ /* emitcode ("subb", "a,#!constbyte", */ /* -((sym->stack < 0) ? */ @@ -10316,16 +10454,16 @@ genAddrOf (iCode * ic) if (offset) { switch (offset) { case 1: - tsprintf(s,"!his",sym->rname); + tsprintf(s, sizeof(s), "!his",sym->rname); break; case 2: - tsprintf(s,"!hihis",sym->rname); + tsprintf(s, sizeof(s), "!hihis",sym->rname); break; case 3: - tsprintf(s,"!hihihis",sym->rname); + tsprintf(s, sizeof(s), "!hihihis",sym->rname); break; default: /* should not need this (just in case) */ - sprintf (s, "#(%s >> %d)", + SNPRINTF (s, sizeof(s), "#(%s >> %d)", sym->rname, offset * 8); } @@ -12434,10 +12572,15 @@ gen390Code (iCode * lic) ic->level, ic->block); _G.debugLine = 0; } - emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, - printCLine(ic->filename, ic->lineno)); + if (!options.noCcodeInAsm) { + emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, + printCLine(ic->filename, ic->lineno)); + } cln = ic->lineno; } + if (options.iCodeInAsm) { + emitcode("", ";ic:%d: %s", ic->key, printILine(ic)); + } /* if the result is marked as spilt and rematerializable or code for this has already been generated then