X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCpeeph.c;h=e052e3ea6b28ceca3a6e24b2a199c0318ab60840;hb=2de847a479c5a08a4e0dc8205a340809be8815f4;hp=0ae38500ffee4d56c6503cb49da3918c02c34eb7;hpb=9050c05f980b3f9d56ee80936b0bd4848e877ba1;p=fw%2Fsdcc diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index 0ae38500..e052e3ea 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -24,11 +24,9 @@ -------------------------------------------------------------------------*/ #include "common.h" -#include "SDCCpeeph.h" -#include "newalloc.h" -peepRule *rootRules = NULL; -peepRule *currRule = NULL; +static peepRule *rootRules = NULL; +static peepRule *currRule = NULL; #define HTAB_SIZE 53 typedef struct @@ -38,19 +36,138 @@ typedef struct } labelHashEntry; -hTab *labelHash = NULL; +static hTab *labelHash = NULL; + +static struct +{ + allocTrace values; + allocTrace labels; +} _G; static int hashSymbolName (const char *name); static void buildLabelRefCountHash (lineNode * head); static bool matchLine (char *, char *, hTab **); -#define FBYNAME(x) int x (hTab *vars, lineNode *currPl, lineNode *head, \ - const char *cmdLine) +#define FBYNAME(x) int x (hTab *vars, lineNode *currPl, lineNode *endPl, \ + lineNode *head, const char *cmdLine) + +#if !OPT_DISABLE_PIC +void peepRules2pCode(peepRule *); +#endif /*-----------------------------------------------------------------*/ /* pcDistance - afinds a label back ward or forward */ /*-----------------------------------------------------------------*/ +int +mcs51_instruction_size(const char *inst) +{ + char *op, op1[256], op2[256]; + int opsize; + const char *p; + + while (*inst && isspace(*inst)) inst++; + + #define ISINST(s) (strncmp(inst, (s), sizeof(s)-1) == 0) + if (ISINST("lcall")) return 3; + if (ISINST("ret")) return 1; + if (ISINST("ljmp")) return 3; + if (ISINST("sjmp")) return 2; + if (ISINST("rlc")) return 1; + if (ISINST("rrc")) return 1; + if (ISINST("rl")) return 1; + if (ISINST("rr")) return 1; + if (ISINST("swap")) return 1; + if (ISINST("movx")) return 1; + if (ISINST("movc")) return 1; + if (ISINST("push")) return 2; + if (ISINST("pop")) return 2; + if (ISINST("jc")) return 2; + if (ISINST("jnc")) return 2; + if (ISINST("jb")) return 3; + if (ISINST("jnb")) return 3; + if (ISINST("jbc")) return 3; + if (ISINST("jmp")) return 1; // always jmp @a+dptr + if (ISINST("jz")) return 2; + if (ISINST("jnz")) return 2; + if (ISINST("cjne")) return 3; + if (ISINST("mul")) return 1; + if (ISINST("div")) return 1; + if (ISINST("da")) return 1; + if (ISINST("xchd")) return 1; + if (ISINST("reti")) return 1; + if (ISINST("nop")) return 1; + if (ISINST("acall")) return 1; + if (ISINST("ajmp")) return 2; + + p = inst; + while (*p && isalnum(*p)) p++; + for (op = op1, opsize=0; *p && *p != ',' && opsize < sizeof(op1); p++) { + if (!isspace(*p)) *op++ = *p, opsize++; + } + *op = '\0'; + if (*p == ',') p++; + for (op = op2, opsize=0; *p && *p != ',' && opsize < sizeof(op2); p++) { + if (!isspace(*p)) *op++ = *p, opsize++; + } + *op = '\0'; + + #define IS_A(s) (*(s) == 'a' && *(s+1) == '\0') + #define IS_C(s) (*(s) == 'c' && *(s+1) == '\0') + #define IS_Rn(s) (*(s) == 'r' && *(s+1) >= '0' && *(s+1) <= '7') + #define IS_atRi(s) (*(s) == '@' && *(s+1) == 'r') + + if (ISINST("mov")) { + if (IS_C(op1) || IS_C(op2)) return 2; + if (IS_A(op1)) { + if (IS_Rn(op2) || IS_atRi(op2)) return 1; + return 2; + } + if (IS_Rn(op1) || IS_atRi(op1)) { + if (IS_A(op2)) return 1; + return 2; + } + if (strcmp(op1, "dptr") == 0) return 3; + if (IS_A(op2) || IS_Rn(op2) || IS_atRi(op2)) return 2; + return 3; + } + if (ISINST("add") || ISINST("addc") || ISINST("subb") || ISINST("xch")) { + if (IS_Rn(op2) || IS_atRi(op2)) return 1; + return 2; + } + if (ISINST("inc") || ISINST("dec")) { + if (IS_A(op1) || IS_Rn(op1) || IS_atRi(op1)) return 1; + if (strcmp(op1, "dptr") == 0) return 1; + return 2; + } + if (ISINST("anl") || ISINST("orl") || ISINST("xrl")) { + if (IS_C(op1)) return 2; + if (IS_A(op1)) { + if (IS_Rn(op2) || IS_atRi(op2)) return 1; + return 2; + } else { + if (IS_A(op2)) return 2; + return 3; + } + } + if (ISINST("clr") || ISINST("setb") || ISINST("cpl")) { + if (IS_A(op1) || IS_C(op1)) return 1; + return 2; + } + if (ISINST("djnz")) { + if (IS_Rn(op1)) return 2; + return 3; + } + + if (*inst == 'a' && *(inst+1) == 'r' && *(inst+2) >= '0' && *(inst+2) <= '7' && op1[0] == '=') { + /* ignore ar0 = 0x00 type definitions */ + return 0; + } + + fprintf(stderr, "Warning, peephole unrecognized instruction: %s\n", inst); + return 3; +} + int pcDistance (lineNode * cpos, char *lbl, bool back) { @@ -58,16 +175,20 @@ pcDistance (lineNode * cpos, char *lbl, bool back) char buff[MAX_PATTERN_LEN]; int dist = 0; - sprintf (buff, "%s:", lbl); + SNPRINTF (buff, sizeof(buff), "%s:", lbl); while (pl) { if (pl->line && *pl->line != ';' && pl->line[strlen (pl->line) - 1] != ':' && - !pl->isDebug) - - dist++; + !pl->isDebug) { + if (strcmp(port->target,"mcs51") == 0) { + dist += mcs51_instruction_size(pl->line); + } else { + dist += 3; + } + } if (strncmp (pl->line, buff, strlen (buff)) == 0) return dist; @@ -81,6 +202,23 @@ pcDistance (lineNode * cpos, char *lbl, bool back) return 0; } +/*-----------------------------------------------------------------*/ +/* flat24bitModeAndPortDS390 - */ +/*-----------------------------------------------------------------*/ +FBYNAME (flat24bitModeAndPortDS390) +{ + return ((strcmp(port->target,"ds390") == 0) && + (options.model == MODEL_FLAT24)); +} + +/*-----------------------------------------------------------------*/ +/* portIsDS390 - return true if port is DS390 */ +/*-----------------------------------------------------------------*/ +FBYNAME (portIsDS390) +{ + return (strcmp(port->target,"ds390") == 0); +} + /*-----------------------------------------------------------------*/ /* flat24bitMode - will check to see if we are in flat24 mode */ /*-----------------------------------------------------------------*/ @@ -89,6 +227,19 @@ FBYNAME (flat24bitMode) return (options.model == MODEL_FLAT24); } +/*-----------------------------------------------------------------*/ +/* xramMovcOption - check if using movc to read xram */ +/*-----------------------------------------------------------------*/ +FBYNAME (xramMovcOption) +{ + return (options.xram_movc && (strcmp(port->target,"mcs51") == 0)); +} + + + + + + /*-----------------------------------------------------------------*/ /* labelInRange - will check to see if label %5 is within range */ /*-----------------------------------------------------------------*/ @@ -101,7 +252,7 @@ FBYNAME (labelInRange) if (!lbl) return FALSE; - /* if the previous teo instructions are "ljmp"s then don't + /* if the previous two instructions are "ljmp"s then don't do it since it can be part of a jump table */ if (currPl->prev && currPl->prev->prev && strstr (currPl->prev->line, "ljmp") && @@ -117,17 +268,86 @@ FBYNAME (labelInRange) dist = (pcDistance (currPl, lbl, TRUE) + pcDistance (currPl, lbl, FALSE)); -/* if (!dist || dist > 45) has produced wrong sjmp */ - /* 07-Sep-2000 Michael Schmitt */ - /* FIX for Peephole 132 */ - /* switch with lots of case can lead to a sjmp with a distance */ - /* out of the range for sjmp */ - if (!dist || dist > 43) +/* changed to 127, now that pcDistance return actual number of bytes */ + if (!dist || dist > 127) return FALSE; return TRUE; } +/*-----------------------------------------------------------------*/ +/* labelIsReturnOnly - Check if label %5 is followed by RET */ +/*-----------------------------------------------------------------*/ +FBYNAME (labelIsReturnOnly) +{ + /* assumes that %5 pattern variable has the label name */ + const char *label, *p; + const lineNode *pl; + int len; + + label = hTabItemWithKey (vars, 5); + if (!label) return FALSE; + len = strlen(label); + + for(pl = currPl; pl; pl = pl->next) { + if (pl->line && !pl->isDebug && + pl->line[strlen(pl->line)-1] == ':') { + if (strncmp(pl->line, label, len) == 0) break; /* Found Label */ + if (strlen(pl->line) != 7 || !isdigit(*(pl->line)) || + !isdigit(*(pl->line+1)) || !isdigit(*(pl->line+2)) || + !isdigit(*(pl->line+3)) || !isdigit(*(pl->line+4)) || + *(pl->line+5) != '$') { + return FALSE; /* non-local label encountered */ + } + } + } + if (!pl) return FALSE; /* did not find the label */ + pl = pl->next; + if (!pl || !pl->line || pl->isDebug) return FALSE; /* next line not valid */ + p = pl->line; + for (p = pl->line; *p && isspace(*p); p++) + ; + if (strcmp(p, "ret") == 0) return TRUE; + return FALSE; +} + + +/*-----------------------------------------------------------------*/ +/* okToRemoveSLOC - Check if label %1 is a SLOC and not other */ +/* usage of it in the code depends on a value from this section */ +/*-----------------------------------------------------------------*/ +FBYNAME (okToRemoveSLOC) +{ + const lineNode *pl; + const char *sloc, *p; + int dummy1, dummy2, dummy3; + + /* assumes that %1 as the SLOC name */ + sloc = hTabItemWithKey (vars, 1); + if (sloc == NULL) return FALSE; + p = strstr(sloc, "sloc"); + if (p == NULL) return FALSE; + p += 4; + if (sscanf(p, "%d_%d_%d", &dummy1, &dummy2, &dummy3) != 3) return FALSE; + /*TODO: ultra-paranoid: get funtion name from "head" and check that */ + /* the sloc name begins with that. Probably not really necessary */ + + /* Look for any occurance of this SLOC before the peephole match */ + for (pl = currPl->prev; pl; pl = pl->prev) { + if (pl->line && !pl->isDebug && !pl->isComment + && *pl->line != ';' && strstr(pl->line, sloc)) + return FALSE; + } + /* Look for any occurance of this SLOC after the peephole match */ + for (pl = endPl->next; pl; pl = pl->next) { + if (pl->line && !pl->isDebug && !pl->isComment + && *pl->line != ';' && strstr(pl->line, sloc)) + return FALSE; + } + return TRUE; /* safe for a peephole to remove it :) */ +} + + /*-----------------------------------------------------------------*/ /* operandsNotSame - check if %1 & %2 are the same */ /*-----------------------------------------------------------------*/ @@ -142,6 +362,190 @@ FBYNAME (operandsNotSame) return TRUE; } +/*-----------------------------------------------------------------*/ +/* operandsNotSame3- check if any pair of %1,%2,%3 are the same */ +/*-----------------------------------------------------------------*/ +FBYNAME (operandsNotSame3) +{ + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); + char *op3 = hTabItemWithKey (vars, 3); + + if ( (strcmp (op1, op2) == 0) || + (strcmp (op1, op3) == 0) || + (strcmp (op2, op3) == 0) ) + return FALSE; + else + return TRUE; +} + +/*-----------------------------------------------------------------*/ +/* operandsNotSame4- check if any pair of %1,%2,%3,.. are the same */ +/*-----------------------------------------------------------------*/ +FBYNAME (operandsNotSame4) +{ + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); + char *op3 = hTabItemWithKey (vars, 3); + char *op4 = hTabItemWithKey (vars, 4); + + if ( (strcmp (op1, op2) == 0) || + (strcmp (op1, op3) == 0) || + (strcmp (op1, op4) == 0) || + (strcmp (op2, op3) == 0) || + (strcmp (op2, op4) == 0) || + (strcmp (op3, op4) == 0) ) + return FALSE; + else + return TRUE; +} + +/*-----------------------------------------------------------------*/ +/* operandsNotSame5- check if any pair of %1,%2,%3,.. are the same */ +/*-----------------------------------------------------------------*/ +FBYNAME (operandsNotSame5) +{ + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); + char *op3 = hTabItemWithKey (vars, 3); + char *op4 = hTabItemWithKey (vars, 4); + char *op5 = hTabItemWithKey (vars, 5); + + if ( (strcmp (op1, op2) == 0) || + (strcmp (op1, op3) == 0) || + (strcmp (op1, op4) == 0) || + (strcmp (op1, op5) == 0) || + (strcmp (op2, op3) == 0) || + (strcmp (op2, op4) == 0) || + (strcmp (op2, op5) == 0) || + (strcmp (op3, op4) == 0) || + (strcmp (op3, op5) == 0) || + (strcmp (op4, op5) == 0) ) + return FALSE; + else + return TRUE; +} + +/*-----------------------------------------------------------------*/ +/* operandsNotSame6- check if any pair of %1,%2,%3,.. are the same */ +/*-----------------------------------------------------------------*/ +FBYNAME (operandsNotSame6) +{ + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); + char *op3 = hTabItemWithKey (vars, 3); + char *op4 = hTabItemWithKey (vars, 4); + char *op5 = hTabItemWithKey (vars, 5); + char *op6 = hTabItemWithKey (vars, 6); + + if ( (strcmp (op1, op2) == 0) || + (strcmp (op1, op3) == 0) || + (strcmp (op1, op4) == 0) || + (strcmp (op1, op5) == 0) || + (strcmp (op1, op6) == 0) || + (strcmp (op2, op3) == 0) || + (strcmp (op2, op4) == 0) || + (strcmp (op2, op5) == 0) || + (strcmp (op2, op6) == 0) || + (strcmp (op3, op4) == 0) || + (strcmp (op3, op5) == 0) || + (strcmp (op3, op6) == 0) || + (strcmp (op4, op5) == 0) || + (strcmp (op4, op6) == 0) || + (strcmp (op5, op6) == 0) ) + return FALSE; + else + return TRUE; +} + + +/*-----------------------------------------------------------------*/ +/* operandsNotSame7- check if any pair of %1,%2,%3,.. are the same */ +/*-----------------------------------------------------------------*/ +FBYNAME (operandsNotSame7) +{ + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); + char *op3 = hTabItemWithKey (vars, 3); + char *op4 = hTabItemWithKey (vars, 4); + char *op5 = hTabItemWithKey (vars, 5); + char *op6 = hTabItemWithKey (vars, 6); + char *op7 = hTabItemWithKey (vars, 7); + + if ( (strcmp (op1, op2) == 0) || + (strcmp (op1, op3) == 0) || + (strcmp (op1, op4) == 0) || + (strcmp (op1, op5) == 0) || + (strcmp (op1, op6) == 0) || + (strcmp (op1, op7) == 0) || + (strcmp (op2, op3) == 0) || + (strcmp (op2, op4) == 0) || + (strcmp (op2, op5) == 0) || + (strcmp (op2, op6) == 0) || + (strcmp (op2, op7) == 0) || + (strcmp (op3, op4) == 0) || + (strcmp (op3, op5) == 0) || + (strcmp (op3, op6) == 0) || + (strcmp (op3, op7) == 0) || + (strcmp (op4, op5) == 0) || + (strcmp (op4, op6) == 0) || + (strcmp (op4, op7) == 0) || + (strcmp (op5, op6) == 0) || + (strcmp (op5, op7) == 0) || + (strcmp (op6, op7) == 0) ) + return FALSE; + else + return TRUE; +} + +/*-----------------------------------------------------------------*/ +/* operandsNotSame8- check if any pair of %1,%2,%3,.. are the same */ +/*-----------------------------------------------------------------*/ +FBYNAME (operandsNotSame8) +{ + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); + char *op3 = hTabItemWithKey (vars, 3); + char *op4 = hTabItemWithKey (vars, 4); + char *op5 = hTabItemWithKey (vars, 5); + char *op6 = hTabItemWithKey (vars, 6); + char *op7 = hTabItemWithKey (vars, 7); + char *op8 = hTabItemWithKey (vars, 8); + + if ( (strcmp (op1, op2) == 0) || + (strcmp (op1, op3) == 0) || + (strcmp (op1, op4) == 0) || + (strcmp (op1, op5) == 0) || + (strcmp (op1, op6) == 0) || + (strcmp (op1, op7) == 0) || + (strcmp (op1, op8) == 0) || + (strcmp (op2, op3) == 0) || + (strcmp (op2, op4) == 0) || + (strcmp (op2, op5) == 0) || + (strcmp (op2, op6) == 0) || + (strcmp (op2, op7) == 0) || + (strcmp (op2, op8) == 0) || + (strcmp (op3, op4) == 0) || + (strcmp (op3, op5) == 0) || + (strcmp (op3, op6) == 0) || + (strcmp (op3, op7) == 0) || + (strcmp (op3, op8) == 0) || + (strcmp (op4, op5) == 0) || + (strcmp (op4, op6) == 0) || + (strcmp (op4, op7) == 0) || + (strcmp (op4, op8) == 0) || + (strcmp (op5, op6) == 0) || + (strcmp (op5, op7) == 0) || + (strcmp (op5, op8) == 0) || + (strcmp (op6, op7) == 0) || + (strcmp (op6, op8) == 0) || + (strcmp (op7, op8) == 0) ) + return FALSE; + else + return TRUE; +} + + /* labelRefCount: * takes two parameters: a variable (bound to a label name) @@ -220,12 +624,13 @@ int callFuncByName (char *fname, hTab * vars, lineNode * currPl, + lineNode * endPl, lineNode * head) { struct ftab { char *fname; - int (*func) (hTab *, lineNode *, lineNode *, const char *); + int (*func) (hTab *, lineNode *, lineNode *, lineNode *, const char *); } ftab[] = { @@ -237,25 +642,89 @@ callFuncByName (char *fname, "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 + } }; - int i; + int i; + char *cmdCopy, *funcName, *funcArgs; + int rc = -1; + + /* Isolate the function name part (we are passed the full condition + * string including arguments) + */ + cmdCopy = Safe_strdup(fname); + funcName = strtok(cmdCopy, " \t"); + funcArgs = strtok(NULL, ""); - for (i = 0; i < ((sizeof (ftab)) / (sizeof (struct ftab))); i++) - if (strncmp (ftab[i].fname, fname, strlen (ftab[i].fname)) == 0) - { - return (*ftab[i].func) (vars, currPl, head, - fname + strlen (ftab[i].fname)); - } - fprintf (stderr, "could not find named function in function table\n"); - return TRUE; + for (i = 0; i < ((sizeof (ftab)) / (sizeof (struct ftab))); i++) + { + if (strcmp (ftab[i].fname, funcName) == 0) + { + rc = (*ftab[i].func) (vars, currPl, endPl, head, + funcArgs); + } + } + + Safe_free(cmdCopy); + + if (rc == -1) + { + fprintf (stderr, + "could not find named function \"%s\" in " + "peephole function table\n", + funcName); + // If the function couldn't be found, let's assume it's + // a bad rule and refuse it. + rc = FALSE; + } + + return rc; } /*-----------------------------------------------------------------*/ @@ -296,15 +765,14 @@ newPeepRule (lineNode * match, { peepRule *pr; - pr = Safe_calloc (1, sizeof (peepRule)); + pr = Safe_alloc ( sizeof (peepRule)); pr->match = match; pr->replace = replace; pr->restart = restart; if (cond && *cond) { - pr->cond = Safe_calloc (1, strlen (cond) + 1); - strcpy (pr->cond, cond); + pr->cond = Safe_strdup (cond); } else pr->cond = NULL; @@ -328,9 +796,8 @@ newLineNode (char *line) { lineNode *pl; - pl = Safe_calloc (1, sizeof (lineNode)); - pl->line = Safe_calloc (1, strlen (line) + 1); - strcpy (pl->line, line); + pl = Safe_alloc ( sizeof (lineNode)); + pl->line = Safe_strdup (line); return pl; } @@ -557,6 +1024,8 @@ bindVar (int key, char **s, hTab ** vtab) if (*vvx == ')') ubb--; } + // include the trailing ')' + *vv++ = *vvx++; } else *vv++ = *vvx++; @@ -564,10 +1033,9 @@ bindVar (int key, char **s, hTab ** vtab) *s = vvx; *vv = '\0'; /* got value */ - vvx = Safe_calloc (1, strlen (vval) + 1); - strcpy (vvx, vval); - hTabAddItem (vtab, key, vvx); + vvx = traceAlloc (&_G.values, Safe_strdup(vval)); + hTabAddItem (vtab, key, vvx); } /*-----------------------------------------------------------------*/ @@ -655,7 +1123,6 @@ matchRule (lineNode * pl, lineNode *spl; /* source pl */ lineNode *rpl; /* rule peep line */ - hTabClearAll (pr->vars); /* setToNull((void **) &pr->vars); */ /* pr->vars = newHashTable(100); */ @@ -689,7 +1156,7 @@ matchRule (lineNode * pl, /* if this rule has additional conditions */ if (pr->cond) { - if (callFuncByName (pr->cond, pr->vars, pl, head)) + if (callFuncByName (pr->cond, pr->vars, pl, spl, head)) { *mtail = spl; return TRUE; @@ -741,6 +1208,7 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr) lbp = lb; l = pl->line; + while (*l) { /* if the line contains a variable */ @@ -791,8 +1259,7 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr) (*shead)->prev->next = lhead; lhead->prev = (*shead)->prev; } - else - *shead = lhead; + *shead = lhead; /* now for the tail */ if (stail && stail->next) { @@ -887,7 +1354,7 @@ buildLabelRefCountHash (lineNode * head) { labelHashEntry *entry; - entry = Safe_calloc (1, sizeof (labelHashEntry)); + entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry))); memcpy (entry->name, label, labelLen); entry->name[labelLen] = 0; @@ -940,6 +1407,21 @@ buildLabelRefCountHash (lineNode * head) #endif } +/* How does this work? + peepHole + For each rule, + For each line, + Try to match + If it matches, + replace and restart. + + matchRule + matchLine + + Where is stuff allocated? + +*/ + /*-----------------------------------------------------------------*/ /* peepHole - matches & substitutes rules */ /*-----------------------------------------------------------------*/ @@ -949,43 +1431,69 @@ peepHole (lineNode ** pls) lineNode *spl; peepRule *pr; lineNode *mtail = NULL; + bool restart; + +#if !OPT_DISABLE_PIC + /* The PIC port uses a different peep hole optimizer based on "pCode" */ + if (TARGET_IS_PIC) + return; +#endif + + assert(labelHash == NULL); + + do + { + restart = FALSE; + + /* for all rules */ + for (pr = rootRules; pr; pr = pr->next) + { + for (spl = *pls; spl; spl = spl->next) + { + /* if inline assembler then no peep hole */ + if (spl->isInline) + continue; + + mtail = NULL; + + /* Tidy up any data stored in the hTab */ + + /* if it matches */ + if (matchRule (spl, &mtail, pr, *pls)) + { + + /* then replace */ + if (spl == *pls) + replaceRule (pls, mtail, pr); + else + replaceRule (&spl, mtail, pr); + + /* if restart rule type then + start at the top again */ + if (pr->restart) + { + restart = TRUE; + } + } + + if (pr->vars) + { + hTabDeleteAll (pr->vars); + Safe_free (pr->vars); + pr->vars = NULL; + } + + freeTrace (&_G.values); + } + } + } while (restart == TRUE); if (labelHash) { hTabDeleteAll (labelHash); + freeTrace (&_G.labels); } labelHash = NULL; - -top: - /* for all rules */ - for (pr = rootRules; pr; pr = pr->next) - { - - for (spl = *pls; spl; spl = spl->next) - { - /* if inline assembler then no peep hole */ - if (spl->isInline) - continue; - - mtail = NULL; - - /* if it matches */ - if (matchRule (spl, &mtail, pr, *pls)) - { - - /* then replace */ - if (spl == *pls) - replaceRule (pls, mtail, pr); - else - replaceRule (&spl, mtail, pr); - - /* if restart rule type then - start at the top again */ - if (pr->restart) - goto top; - } - } - } } @@ -1019,12 +1527,11 @@ readFileIntoBuffer (char *fname) if (rs) { rs = Safe_realloc (rs, strlen (rs) + strlen (lb) + 1); - strcat (rs, lb); + strncatz (rs, lb, strlen (rs) + strlen (lb) + 1); } else { - rs = Safe_calloc (1, strlen (lb) + 1); - strcpy (rs, lb); + rs = Safe_strdup (lb); } nch = 0; } @@ -1038,19 +1545,18 @@ readFileIntoBuffer (char *fname) if (rs) { rs = Safe_realloc (rs, strlen (rs) + strlen (lb) + 1); - strcat (rs, lb); + strncatz (rs, lb, strlen (rs) + strlen (lb) + 1); } else { - rs = Safe_calloc (1, strlen (lb) + 1); - strcpy (rs, lb); + rs = Safe_strdup (lb); } } return rs; } /*-----------------------------------------------------------------*/ -/* initPeepHole - initiaises the peep hole optimizer stuff */ +/* initPeepHole - initialises the peep hole optimizer stuff */ /*-----------------------------------------------------------------*/ void initPeepHole () @@ -1066,4 +1572,15 @@ initPeepHole () readRules (s = readFileIntoBuffer (options.peep_file)); setToNull ((void **) &s); } + + +#if !OPT_DISABLE_PIC + /* Convert the peep rules into pcode. + NOTE: this is only support in the PIC port (at the moment) + */ + if (TARGET_IS_PIC) { + peepRules2pCode(rootRules); + } +#endif + }