-------------------------------------------------------------------------*/
#include "common.h"
+#include "dbuf_string.h"
#define ISCHARDIGIT(c) isdigit((unsigned char)c)
#define ISCHARSPACE(c) isspace((unsigned char)c)
static peepRule *currRule = NULL;
#define HTAB_SIZE 53
-typedef struct
- {
- char name[SDCC_NAME_MAX + 1];
- int refCount;
- }
-labelHashEntry;
-static hTab *labelHash = NULL;
+hTab *labelHash = NULL;
static struct
{
static int hashSymbolName (const char *name);
static void buildLabelRefCountHash (lineNode * head);
+static void bindVar (int key, char **s, hTab ** vtab);
static bool matchLine (char *, char *, hTab **);
-bool isLabelDefinition (const char *line, const char **start, int *len);
-#define FBYNAME(x) int x (hTab *vars, lineNode *currPl, lineNode *endPl, \
+#define FBYNAME(x) static int x (hTab *vars, lineNode *currPl, lineNode *endPl, \
lineNode *head, char *cmdLine)
#if !OPT_DISABLE_PIC
#endif
/*-----------------------------------------------------------------*/
-/* pcDistance - afinds a label back ward or forward */
+/* pcDistance - finds a label backward or forward */
/*-----------------------------------------------------------------*/
-int
+static int
pcDistance (lineNode * cpos, char *lbl, bool back)
{
lineNode *pl = cpos;
SNPRINTF (buff, sizeof(buff), "%s:", lbl);
while (pl)
{
-
if (pl->line &&
- *pl->line != ';' &&
- pl->line[strlen (pl->line) - 1] != ':' &&
- !pl->isDebug) {
- if (port->peep.getSize) {
- dist += port->peep.getSize(pl);
- } else {
- dist += 3;
- }
+ !pl->isComment &&
+ !pl->isLabel &&
+ !pl->isDebug)
+ {
+ if (port->peep.getSize)
+ {
+ dist += port->peep.getSize(pl);
+ }
+ else
+ {
+ dist += 3;
+ }
}
if (strncmp (pl->line, buff, strlen (buff)) == 0)
return 0;
}
-/*-----------------------------------------------------------------*/
-/* flat24bitModeAndPortDS390 - */
-/*-----------------------------------------------------------------*/
-FBYNAME (flat24bitModeAndPortDS390)
-{
- return (((strcmp(port->target,"ds390") == 0) ||
- (strcmp(port->target,"ds400") == 0)) &&
- (options.model == MODEL_FLAT24));
-}
-
/*-----------------------------------------------------------------*/
/* portIsDS390 - return true if port is DS390 */
/*-----------------------------------------------------------------*/
return (options.xram_movc && (strcmp(port->target,"mcs51") == 0));
}
-
-
-
-
+/*-----------------------------------------------------------------*/
+/* useAcallAjmp - Enable replacement of lcall/ljmp with acall/ajmp */
+/*-----------------------------------------------------------------*/
+FBYNAME (useAcallAjmp)
+{
+ return (options.acall_ajmp && (strcmp(port->target,"mcs51") == 0));
+}
/*-----------------------------------------------------------------*/
/* labelInRange - will check to see if label %5 is within range */
return FALSE;
/* calculate the label distance : the jump for reladdr can be
- +/- 127 bytes, here Iam assuming that an average 8051
+ +/- 127 bytes, here I am assuming that an average 8051
instruction is 2 bytes long, so if the label is more than
63 intructions away, the label is considered out of range
for a relative jump. we could get more precise this will
return TRUE;
}
-
/*-----------------------------------------------------------------*/
/* labelJTInRange - will check to see if label %5 and up are */
/* within range. */
return TRUE;
}
-
/*-----------------------------------------------------------------*/
/* labelIsReturnOnly - Check if label %5 is followed by RET */
/*-----------------------------------------------------------------*/
int len;
char * retInst;
+ /* Don't optimize jumps in a jump table; a more generic test */
+ if (currPl->ic && currPl->ic->op == JUMPTABLE)
+ return FALSE;
+
label = hTabItemWithKey (vars, 5);
- if (!label) return FALSE;
+ if (!label)
+ return FALSE;
len = strlen(label);
- for(pl = currPl; pl; pl = pl->next) {
- if (pl->line && !pl->isDebug && !pl->isComment &&
- pl->line[strlen(pl->line)-1] == ':') {
- if (strncmp(pl->line, label, len) == 0) break; /* Found Label */
- if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) ||
- !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) ||
- !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) ||
- *(pl->line+5) != '$') {
- return FALSE; /* non-local label encountered */
- }
+ for(pl = currPl; pl; pl = pl->next)
+ {
+ if (pl->line && !pl->isDebug && !pl->isComment && pl->isLabel)
+ {
+ if (strncmp(pl->line, label, len) == 0)
+ break; /* Found Label */
+ if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) ||
+ !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) ||
+ !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) ||
+ *(pl->line+5) != '$')
+ {
+ return FALSE; /* non-local label encountered */
+ }
}
- }
- if (!pl) return FALSE; /* did not find the label */
+ }
+ if (!pl)
+ return FALSE; /* did not find the label */
pl = pl->next;
while (pl && (pl->isDebug || pl->isComment))
pl = pl->next;
- if (!pl || !pl->line || pl->isDebug) return FALSE; /* next line not valid */
+ if (!pl || !pl->line || pl->isDebug)
+ return FALSE; /* next line not valid */
p = pl->line;
for (p = pl->line; *p && ISCHARSPACE(*p); p++)
- ;
+ ;
retInst = "ret";
if (TARGET_IS_HC08)
retInst = "rts";
- if (strcmp(p, retInst) == 0) return TRUE;
+ if (strcmp(p, retInst) == 0)
+ return TRUE;
return FALSE;
}
+/*-----------------------------------------------------------------*/
+/* labelIsUncondJump - Check if label %5 is followed by an */
+/* unconditional jump and put the destination of that jump in %6 */
+/*-----------------------------------------------------------------*/
+FBYNAME (labelIsUncondJump)
+{
+ /* assumes that %5 pattern variable has the label name */
+ const char *label;
+ char *p, *q;
+ const lineNode *pl;
+ int len;
+ char * jpInst = NULL;
+
+ /* Don't optimize jumps in a jump table; a more generic test */
+ if (currPl->ic && currPl->ic->op == JUMPTABLE)
+ return FALSE;
+
+ label = hTabItemWithKey (vars, 5);
+ if (!label)
+ return FALSE;
+ len = strlen(label);
+
+ for (pl = currPl; pl; pl = pl->next)
+ {
+ if (pl->line && !pl->isDebug && !pl->isComment && pl->isLabel)
+ {
+ if (strncmp(pl->line, label, len) == 0)
+ break; /* Found Label */
+ if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) ||
+ !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) ||
+ !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) ||
+ *(pl->line+5) != '$')
+ {
+ return FALSE; /* non-local label encountered */
+ }
+ }
+ }
+ if (!pl)
+ return FALSE; /* did not find the label */
+ pl = pl->next;
+ while (pl && (pl->isDebug || pl->isComment))
+ pl = pl->next;
+ if (!pl || !pl->line)
+ return FALSE; /* next line not valid */
+ p = pl->line;
+ while (*p && ISCHARSPACE(*p))
+ p++;
+
+ if (TARGET_MCS51_LIKE)
+ jpInst = "ljmp";
+ if (TARGET_IS_HC08)
+ jpInst = "jmp";
+ if (TARGET_Z80_LIKE)
+ jpInst = "jp";
+ len = strlen(jpInst);
+ if (strncmp(p, jpInst, len) != 0)
+ return FALSE; /* next line is no jump */
+ p += len;
+ while (*p && ISCHARSPACE(*p))
+ p++;
+
+ q = p;
+ while (*q && *q!=';')
+ q++;
+ while (q>p && ISCHARSPACE(*q))
+ q--;
+ len = q-p;
+ if (len == 0)
+ return FALSE; /* no destination? */
+ if (TARGET_Z80_LIKE)
+ {
+ while (q>p && *q!=',')
+ q--;
+ if (*q==',')
+ return FALSE; /* conditional jump */
+ }
+ if (strcmp(p, q) == 0)
+ return FALSE; /* labels are equal */
+ /* now put the destination in %6 */
+ bindVar (6, &p, &vars);
+ return TRUE;
+}
/*-----------------------------------------------------------------*/
/* okToRemoveSLOC - Check if label %1 is a SLOC and not other */
return TRUE; /* safe for a peephole to remove it :) */
}
+/*-----------------------------------------------------------------*/
+/* deadMove - Check, if a pop/push pair can be removed */
+/*-----------------------------------------------------------------*/
+FBYNAME (deadMove)
+{
+ const char *reg = hTabItemWithKey (vars, 1);
+
+ if (port->peep.deadMove)
+ return port->peep.deadMove (reg, currPl, head);
+
+ fprintf (stderr, "Function deadMove not initialized in port structure\n");
+ return FALSE;
+}
/*-----------------------------------------------------------------*/
/* operandsNotSame - check if %1 & %2 are the same */
return TRUE;
}
-
/*-----------------------------------------------------------------*/
/* operandsNotSame7- check if any pair of %1,%2,%3,.. are the same */
/*-----------------------------------------------------------------*/
return TRUE;
}
+/*-----------------------------------------------------------------*/
+/* labelHashEntry- searches for a label in the list labelHash */
+/* Builds labelHash, if it does not yet exist. */
+/* Returns the labelHashEntry or NULL */
+/*-----------------------------------------------------------------*/
+labelHashEntry *
+getLabelRef (const char *label, lineNode *head)
+{
+ labelHashEntry *entry;
+
+ /* If we don't have the label hash table yet, build it. */
+ if (!labelHash)
+ {
+ buildLabelRefCountHash (head);
+ }
+
+ entry = hTabFirstItemWK (labelHash, hashSymbolName (label));
+
+ while (entry)
+ {
+ if (!strcmp (label, entry->name))
+ {
+ break;
+ }
+ entry = hTabNextItemWK (labelHash);
+ }
+ return entry;
+}
/* labelRefCount:
int varNumber, expectedRefCount;
bool rc = FALSE;
- /* If we don't have the label hash table yet, build it. */
- if (!labelHash)
- {
- buildLabelRefCountHash (head);
- }
-
if (sscanf (cmdLine, "%*[ \t%]%d %d", &varNumber, &expectedRefCount) == 2)
{
char *label = hTabItemWithKey (vars, varNumber);
if (label)
{
- labelHashEntry *entry;
+ labelHashEntry *entry = getLabelRef (label, head);
- entry = hTabFirstItemWK (labelHash, hashSymbolName (label));
-
- while (entry)
- {
- if (!strcmp (label, entry->name))
- {
- break;
- }
- entry = hTabNextItemWK (labelHash);
- }
if (entry)
{
#if 0
return rc;
}
-
/* labelRefCountChange:
* takes two parameters: a variable (bound to a label name)
* and a signed int for changing the reference count.
return rc;
}
-
/* Within the context of the lines currPl through endPl, determine
** if the variable var contains a symbol that is volatile. Returns
** TRUE only if it is certain that this was not volatile (the symbol
{
case IFX:
op = IC_COND (cl->ic);
- if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) )
- return !op->isvolatile;
+ if (IS_SYMOP (op) &&
+ ( !strcmp(OP_SYMBOL (op)->rname, symname) ||
+ (OP_SYMBOL (op)->isspilt &&
+ SPIL_LOC (op) &&
+ !strcmp(SPIL_LOC (op)->rname, symname)) ))
+ {
+ return !op->isvolatile;
+ }
case JUMPTABLE:
op = IC_JTCOND (cl->ic);
- if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) )
- return !op->isvolatile;
+ if (IS_SYMOP (op) &&
+ ( !strcmp(OP_SYMBOL (op)->rname, symname) ||
+ (OP_SYMBOL (op)->isspilt &&
+ SPIL_LOC (op) &&
+ !strcmp(SPIL_LOC (op)->rname, symname)) ))
+ {
+ return !op->isvolatile;
+ }
default:
op = IC_LEFT (cl->ic);
- if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) )
- return !op->isvolatile;
+ if (IS_SYMOP (op) &&
+ ( !strcmp(OP_SYMBOL (op)->rname, symname) ||
+ (OP_SYMBOL (op)->isspilt &&
+ SPIL_LOC (op) &&
+ !strcmp(SPIL_LOC (op)->rname, symname)) ))
+ {
+ return !op->isvolatile;
+ }
op = IC_RIGHT (cl->ic);
- if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) )
- return !op->isvolatile;
+ if (IS_SYMOP (op) &&
+ ( !strcmp(OP_SYMBOL (op)->rname, symname) ||
+ (OP_SYMBOL (op)->isspilt &&
+ SPIL_LOC (op) &&
+ !strcmp(SPIL_LOC (op)->rname, symname)) ))
+ {
+ return !op->isvolatile;
+ }
op = IC_RESULT (cl->ic);
- if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) )
- return !op->isvolatile;
+ if (IS_SYMOP (op) &&
+ ( !strcmp(OP_SYMBOL (op)->rname, symname) ||
+ (OP_SYMBOL (op)->isspilt &&
+ SPIL_LOC (op) &&
+ !strcmp(SPIL_LOC (op)->rname, symname)) ))
+ {
+ return !op->isvolatile;
+ }
}
}
}
return TRUE;
-
error:
fprintf (stderr,
"*** internal error: notVolatile peephole restriction"
return FALSE;
}
-
/*------------------------------------------------------------------*/
/* setFromConditionArgs - parse a peephole condition's arguments */
/* to produce a set of strings, one per argument. Variables %x will */
return "a";
if (!strncmp (op, "ar", 2) && ISCHARDIGIT(*(op+2)) && !*(op+3))
return op+1;
+ // bug 1739475, temp fix
+ if (op[0] == '@')
+ return operandBaseName(op+1);
}
return op;
}
-
/*-------------------------------------------------------------------*/
-/* operandsNotRelated - returns true of the condition's operands are */
+/* operandsNotRelated - returns true if the condition's operands are */
/* not related (taking into account register name aliases). N-way */
/* comparison performed between all operands. */
/*-------------------------------------------------------------------*/
return TRUE;
}
+/*-------------------------------------------------------------------*/
+/* operandsLiteral - returns true of the condition's operands are */
+/* literals. */
+/*-------------------------------------------------------------------*/
+FBYNAME (operandsLiteral)
+{
+ set *operands;
+ const char *op;
+
+ operands = setFromConditionArgs (cmdLine, vars);
+
+ if (!operands)
+ {
+ fprintf (stderr,
+ "*** internal error: operandsLiteral peephole restriction"
+ " malformed: %s\n", cmdLine);
+ return FALSE;
+ }
+
+ for (op = setFirstItem (operands); op; op = setNextItem (operands))
+ {
+ if (!isdigit(*op))
+ {
+ deleteSet (&operands);
+ return FALSE;
+ }
+ }
+
+ deleteSet (&operands);
+ return TRUE;
+}
+static const struct ftab
+{
+ char *fname;
+ int (*func) (hTab *, lineNode *, lineNode *, lineNode *, char *);
+}
+ftab[] = // sorted on the number of times used
+{ // in the peephole rules on 2007-10-29
+ {
+ "labelRefCount", labelRefCount //105
+ },
+ {
+ "notVolatile", notVolatile //85
+ },
+ {
+ "labelRefCountChange", labelRefCountChange //74
+ },
+ {
+ "labelInRange", labelInRange //37
+ },
+ {
+ "labelJTInRange", labelJTInRange //13
+ },
+ {
+ "operandsNotRelated", operandsNotRelated //9
+ },
+ {
+ "24bitMode", flat24bitMode //9
+ },
+ {
+ "operandsNotSame", operandsNotSame //8
+ },
+ {
+ "operandsNotSame3", operandsNotSame3
+ },
+ {
+ "operandsNotSame4", operandsNotSame4
+ },
+ {
+ "operandsNotSame5", operandsNotSame5
+ },
+ {
+ "operandsNotSame6", operandsNotSame6
+ },
+ {
+ "operandsNotSame7", operandsNotSame7
+ },
+ {
+ "operandsNotSame8", operandsNotSame8
+ },
+ {
+ "xramMovcOption", xramMovcOption
+ },
+ {
+ "portIsDS390", portIsDS390
+ },
+ {
+ "labelIsReturnOnly", labelIsReturnOnly
+ },
+ {
+ "labelIsUncondJump", labelIsUncondJump
+ },
+ {
+ "okToRemoveSLOC", okToRemoveSLOC
+ },
+ {
+ "deadMove", deadMove
+ },
+ {
+ "operandsLiteral", operandsLiteral
+ },
+ {
+ "useAcallAjmp", useAcallAjmp
+ }
+};
/*-----------------------------------------------------------------*/
/* callFuncByName - calls a function as defined in the table */
/*-----------------------------------------------------------------*/
-int
+static int
callFuncByName (char *fname,
hTab * vars,
- lineNode * currPl,
- lineNode * endPl,
+ lineNode * currPl, /* first source line matched */
+ lineNode * endPl, /* last source line matched */
lineNode * head)
{
- struct ftab
- {
- char *fname;
- int (*func) (hTab *, lineNode *, lineNode *, lineNode *, char *);
- }
- ftab[] =
- {
- {
- "labelInRange", labelInRange
- }
- ,
- {
- "labelJTInRange", labelJTInRange
- }
- ,
- {
- "operandsNotSame", operandsNotSame
- }
- ,
- {
- "operandsNotSame3", operandsNotSame3
- }
- ,
- {
- "operandsNotSame4", operandsNotSame4
- }
- ,
- {
- "operandsNotSame5", operandsNotSame5
- }
- ,
- {
- "operandsNotSame6", operandsNotSame6
- }
- ,
- {
- "operandsNotSame7", operandsNotSame7
- }
- ,
- {
- "operandsNotSame8", operandsNotSame8
- }
- ,
- {
- "24bitMode", flat24bitMode
- }
- ,
- {
- "xramMovcOption", xramMovcOption
- }
- ,
- {
- "labelRefCount", labelRefCount
- }
- ,
- {
- "portIsDS390", portIsDS390
- },
- {
- "labelIsReturnOnly", labelIsReturnOnly
- },
- {
- "okToRemoveSLOC", okToRemoveSLOC
- },
- {
- "24bitModeAndPortDS390", flat24bitModeAndPortDS390
- },
- {
- "notVolatile", notVolatile
- },
- {
- "operandsNotRelated", operandsNotRelated
- },
- {
- "labelRefCountChange", labelRefCountChange
- }
- };
int i;
char *cmdCopy, *funcName, *funcArgs, *cmdTerm;
char c;
{
if (strcmp (ftab[i].fname, funcName) == 0)
{
- rc = (*ftab[i].func) (vars, currPl, endPl, head,
- funcArgs);
+ rc = (*ftab[i].func) (vars, currPl, endPl, head, funcArgs);
break;
}
}
/* printLine - prints a line chain into a given file */
/*-----------------------------------------------------------------*/
void
-printLine (lineNode * head, FILE * of)
+printLine (lineNode * head, struct dbuf_s * oBuf)
{
iCode *last_ic = NULL;
bool debug_iCode_tracking = (getenv("DEBUG_ICODE_TRACKING")!=NULL);
- if (!of)
- of = stdout;
-
while (head)
{
if (head->ic!=last_ic)
if (debug_iCode_tracking)
{
if (head->ic)
- fprintf (of, "; block = %d, seq = %d\n",
+ dbuf_printf (oBuf, "; block = %d, seq = %d\n",
head->ic->block, head->ic->seq);
else
- fprintf (of, "; iCode lost\n");
+ dbuf_append_str (oBuf, "; iCode lost\n");
}
}
/* don't indent comments & labels */
if (head->line &&
- (*head->line == ';' ||
- head->line[strlen (head->line) - 1] == ':')) {
- fprintf (of, "%s\n", head->line);
+ (head->isComment || head->isLabel)) {
+ dbuf_printf (oBuf, "%s\n", head->line);
} else {
if (head->isInline && *head->line=='#') {
// comment out preprocessor directives in inline asm
- fprintf (of, ";");
+ dbuf_append_char (oBuf, ';');
}
- fprintf (of, "\t%s\n", head->line);
+ dbuf_printf (oBuf, "\t%s\n", head->line);
}
head = head->next;
}
/*-----------------------------------------------------------------*/
/* newPeepRule - creates a new peeprule and attach it to the root */
/*-----------------------------------------------------------------*/
-peepRule *
+static peepRule *
newPeepRule (lineNode * match,
lineNode * replace,
char *cond,
/* newLineNode - creates a new peep line */
/*-----------------------------------------------------------------*/
lineNode *
-newLineNode (char *line)
+newLineNode (const char *line)
{
lineNode *pl;
if (!isComment || (isComment && !options.noPeepComments))
{
+ const char *dummy1;
+ int dummy2;
+
if (!currL)
*head = currL = newLineNode (lines);
else
currL = connectLine (currL, newLineNode (lines));
currL->isComment = isComment;
+ currL->isLabel = isLabelDefinition (currL->line, &dummy1, &dummy2,
+ TRUE);
}
}
{
char restart = 0;
char lines[MAX_PATTERN_LEN];
- char *lp;
+ char *lp, *rp;
lineNode *match;
lineNode *replace;
lineNode *currL = NULL;
EXPECT_CHR (bp, '{', "expected '{'\n");
bp++;
+ /* save char position (needed for generating error msg) */
+ rp = bp;
+
SKIP_SPACE (bp, "unexpected end of rule\n");
getPeepLine (&replace, &bp);
newPeepRule (match, replace, lines, restart);
}
else
- newPeepRule (match, replace, NULL, restart);
+ {
+ if (*bp && strncmp (bp, "replace", 7))
+ {
+ /* not the start of a new peeprule, so "if" should be here */
+
+ char strbuff[1000];
+ char *cp;
+
+ /* go to the start of the line following "{" of the "by" token */
+ while (*rp && (*rp == '\n'))
+ rp++;
+
+ /* copy text of rule starting with line after "by {" */
+ cp = strbuff;
+ while (*rp && (rp < bp) && ((cp - strbuff) < sizeof(strbuff)))
+ *cp++ = *rp++;
+
+ /* and now the rest of the line */
+ while (*rp && (*rp != '\n') && ((cp - strbuff) < sizeof(strbuff)))
+ *cp++ = *rp++;
+
+ *cp = '\0';
+ fprintf (stderr, "%s\nexpected '} if ...'\n", strbuff);
+ return;
+ }
+ newPeepRule (match, replace, NULL, restart);
+ }
goto top;
}
return FALSE;
}
else
- /* variable not bound we need to
- bind it */
+ /* variable not bound we need to bind it */
bindVar (keyForVar (d + 1), &s, vars);
/* in either case go past the variable */
csl = shead;
while (1)
{
- const char *labelStart;
- int labelLength;
-
/* skip over any comments */
while (csl!=stail->next && csl->isComment)
csl = csl->next;
if (csl==stail->next)
break;
- if (isLabelDefinition(csl->line, &labelStart, &labelLength))
+ if (csl->isLabel)
{
/* found a source line label; look for it in the replacment lines */
crl = rhead;
else
lhead = cl = newLineNode (lb);
cl->isComment = pl->isComment;
+ cl->isLabel = pl->isLabel;
}
/* add the comments if any to the head of list */
* and len will be it's length.
*/
bool
-isLabelDefinition (const char *line, const char **start, int *len)
+isLabelDefinition (const char *line, const char **start, int *len,
+ bool isPeepRule)
{
const char *cp = line;
*start = cp;
- while (ISCHARALNUM (*cp) || (*cp == '$') || (*cp == '_'))
+ while (ISCHARALNUM (*cp) || (*cp == '$') || (*cp == '_') ||
+ (isPeepRule && (*cp == '%')))
{
cp++;
}
labelHash = newHashTable (HTAB_SIZE);
/* First pass: locate all the labels. */
- line = head;
-
- while (line)
+ for (line = head; line; line = line->next)
{
- if (isLabelDefinition (line->line, &label, &labelLen)
- && labelLen <= SDCC_NAME_MAX)
+ if (line->isLabel ||
+ line->isInline)
{
- labelHashEntry *entry;
+ /* run isLabelDefinition to:
+ - look for labels in inline assembler
+ - calculate labelLen
+ */
+ if (isLabelDefinition (line->line, &label, &labelLen, FALSE) &&
+ labelLen <= SDCC_NAME_MAX)
+ {
+ labelHashEntry *entry;
- entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry)));
+ entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry)));
- memcpy (entry->name, label, labelLen);
- entry->name[labelLen] = 0;
- entry->refCount = -1;
+ memcpy (entry->name, label, labelLen);
+ entry->name[labelLen] = 0;
+ entry->refCount = -1;
- /* Assume function entry points are referenced somewhere, */
- /* even if we can't find a reference (might be from outside */
- /* the function) */
- if (line->ic && (line->ic->op == FUNCTION))
- entry->refCount++;
+ /* Assume function entry points are referenced somewhere, */
+ /* even if we can't find a reference (might be from outside */
+ /* the function) */
+ if (line->ic && (line->ic->op == FUNCTION))
+ entry->refCount++;
- hTabAddItem (&labelHash, hashSymbolName (entry->name), entry);
+ hTabAddItem (&labelHash, hashSymbolName (entry->name), entry);
+ }
}
- line = line->next;
}
lineNode *spl;
peepRule *pr;
lineNode *mtail = NULL;
- bool restart;
+ bool restart, replaced;
#if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
/* The PIC port uses a different peep hole optimizer based on "pCode" */
/* for all rules */
for (pr = rootRules; pr; pr = pr->next)
{
- for (spl = *pls; spl; spl = spl->next)
+ for (spl = *pls; spl; spl = replaced ? spl : spl->next)
{
+ replaced = FALSE;
+
/* if inline assembler then no peep hole */
if (spl->isInline)
continue;
/* if it matches */
if (matchRule (spl, &mtail, pr, *pls))
{
+ /* restart at the replaced line */
+ replaced = TRUE;
/* then replace */
if (spl == *pls)
- replaceRule (pls, mtail, pr);
+ {
+ replaceRule (pls, mtail, pr);
+ spl = *pls;
+ }
else
replaceRule (&spl, mtail, pr);
char *s;
/* read in the default rules */
- readRules (port->peep.default_rules);
+ if (!options.nopeep)
+ {
+ readRules (port->peep.default_rules);
+ }
/* if we have any additional file read it too */
if (options.peep_file)
{
readRules (s = readFileIntoBuffer (options.peep_file));
setToNull ((void *) &s);
+ /* override nopeep setting, default rules have not been read */
+ options.nopeep = 0;
}