[a7de7182] | 1 |
|
---|
| 2 | /*
|
---|
| 3 | * Generate defines for the needed hardops.
|
---|
| 4 | */
|
---|
| 5 | #include "pass2.h"
|
---|
| 6 | #include <stdlib.h>
|
---|
| 7 |
|
---|
| 8 | #ifdef HAVE_STRING_H
|
---|
| 9 | #include <string.h>
|
---|
| 10 | #endif
|
---|
| 11 |
|
---|
| 12 | #ifdef HAVE_C99_FORMAT
|
---|
| 13 | #define FMTdPTR "%td"
|
---|
| 14 | #else
|
---|
| 15 | #if defined(_WIN64) || defined(LP64)
|
---|
| 16 | #define FMTdPTR "%ld"
|
---|
| 17 | #else
|
---|
| 18 | #define FMTdPTR "%d"
|
---|
| 19 | #endif
|
---|
| 20 | #endif
|
---|
| 21 |
|
---|
| 22 | int chkop[DSIZE];
|
---|
| 23 |
|
---|
| 24 | void mktables(void);
|
---|
| 25 |
|
---|
| 26 | char *ftitle;
|
---|
| 27 | char *cname = "external.c";
|
---|
| 28 | char *hname = "external.h";
|
---|
| 29 | FILE *fc, *fh;
|
---|
| 30 |
|
---|
| 31 | /*
|
---|
| 32 | * masks for matching dope with shapes
|
---|
| 33 | */
|
---|
| 34 | int mamask[] = {
|
---|
| 35 | SIMPFLG, /* OPSIMP */
|
---|
| 36 | SIMPFLG|ASGFLG, /* ASG OPSIMP */
|
---|
| 37 | COMMFLG, /* OPCOMM */
|
---|
| 38 | COMMFLG|ASGFLG, /* ASG OPCOMM */
|
---|
| 39 | MULFLG, /* OPMUL */
|
---|
| 40 | MULFLG|ASGFLG, /* ASG OPMUL */
|
---|
| 41 | DIVFLG, /* OPDIV */
|
---|
| 42 | DIVFLG|ASGFLG, /* ASG OPDIV */
|
---|
| 43 | UTYPE, /* OPUNARY */
|
---|
| 44 | TYFLG, /* ASG OPUNARY is senseless */
|
---|
| 45 | LTYPE, /* OPLEAF */
|
---|
| 46 | TYFLG, /* ASG OPLEAF is senseless */
|
---|
| 47 | 0, /* OPANY */
|
---|
| 48 | ASGOPFLG|ASGFLG, /* ASG OPANY */
|
---|
| 49 | LOGFLG, /* OPLOG */
|
---|
| 50 | TYFLG, /* ASG OPLOG is senseless */
|
---|
| 51 | FLOFLG, /* OPFLOAT */
|
---|
| 52 | FLOFLG|ASGFLG, /* ASG OPFLOAT */
|
---|
| 53 | SHFFLG, /* OPSHFT */
|
---|
| 54 | SHFFLG|ASGFLG, /* ASG OPSHIFT */
|
---|
| 55 | SPFLG, /* OPLTYPE */
|
---|
| 56 | TYFLG, /* ASG OPLTYPE is senseless */
|
---|
| 57 | };
|
---|
| 58 |
|
---|
| 59 |
|
---|
| 60 | struct checks {
|
---|
| 61 | int op, type;
|
---|
| 62 | char *name;
|
---|
| 63 | } checks[] = {
|
---|
| 64 | { MUL, TLONGLONG, "SMULLL", },
|
---|
| 65 | { DIV, TLONGLONG, "SDIVLL", },
|
---|
| 66 | { MOD, TLONGLONG, "SMODLL", },
|
---|
| 67 | { PLUS, TLONGLONG, "SPLUSLL", },
|
---|
| 68 | { MINUS, TLONGLONG, "SMINUSLL", },
|
---|
| 69 | { MUL, TULONGLONG, "UMULLL", },
|
---|
| 70 | { DIV, TULONGLONG, "UDIVLL", },
|
---|
| 71 | { MOD, TULONGLONG, "UMODLL", },
|
---|
| 72 | { PLUS, TULONGLONG, "UPLUSLL", },
|
---|
| 73 | { MINUS, TULONGLONG, "UMINUSLL", },
|
---|
| 74 | { 0, 0, 0, },
|
---|
| 75 | };
|
---|
| 76 |
|
---|
| 77 | int rstatus[] = { RSTATUS };
|
---|
| 78 | int roverlay[MAXREGS][MAXREGS] = { ROVERLAP };
|
---|
| 79 | int regclassmap[CLASSG][MAXREGS]; /* CLASSG is highest class */
|
---|
| 80 |
|
---|
| 81 | static void
|
---|
| 82 | compl(struct optab *q, char *str)
|
---|
| 83 | {
|
---|
| 84 | int op = q->op;
|
---|
| 85 | char *s;
|
---|
| 86 |
|
---|
| 87 | if (op < OPSIMP) {
|
---|
| 88 | s = opst[op];
|
---|
| 89 | } else
|
---|
| 90 | switch (op) {
|
---|
| 91 | default: s = "Special op"; break;
|
---|
| 92 | case OPSIMP: s = "OPLSIMP"; break;
|
---|
| 93 | case OPCOMM: s = "OPCOMM"; break;
|
---|
| 94 | case OPMUL: s = "OPMUL"; break;
|
---|
| 95 | case OPDIV: s = "OPDIV"; break;
|
---|
| 96 | case OPUNARY: s = "OPUNARY"; break;
|
---|
| 97 | case OPLEAF: s = "OPLEAF"; break;
|
---|
| 98 | case OPANY: s = "OPANY"; break;
|
---|
| 99 | case OPLOG: s = "OPLOG"; break;
|
---|
| 100 | case OPFLOAT: s = "OPFLOAT"; break;
|
---|
| 101 | case OPSHFT: s = "OPSHFT"; break;
|
---|
| 102 | case OPLTYPE: s = "OPLTYPE"; break;
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | printf("table entry " FMTdPTR ", op %s: %s\n", q - table, s, str);
|
---|
| 106 | }
|
---|
| 107 |
|
---|
| 108 | static int
|
---|
| 109 | getrcl(struct optab *q)
|
---|
| 110 | {
|
---|
| 111 | int v = q->needs &
|
---|
| 112 | (NACOUNT|NBCOUNT|NCCOUNT|NDCOUNT|NECOUNT|NFCOUNT|NGCOUNT);
|
---|
| 113 | int r = q->rewrite & RESC1 ? 1 : q->rewrite & RESC2 ? 2 : 3;
|
---|
| 114 | int i = 0;
|
---|
| 115 |
|
---|
| 116 | #define INCK(c) while (v & c##COUNT) { \
|
---|
| 117 | v -= c##REG, i++; if (i == r) return I##c##REG; }
|
---|
| 118 | INCK(NA)
|
---|
| 119 | INCK(NB)
|
---|
| 120 | INCK(NC)
|
---|
| 121 | INCK(ND)
|
---|
| 122 | INCK(NE)
|
---|
| 123 | INCK(NF)
|
---|
| 124 | INCK(NG)
|
---|
| 125 | return 0;
|
---|
| 126 | }
|
---|
| 127 |
|
---|
| 128 | int
|
---|
| 129 | main(int argc, char *argv[])
|
---|
| 130 | {
|
---|
| 131 | struct optab *q;
|
---|
| 132 | struct checks *ch;
|
---|
| 133 | int i, j, areg, breg, creg, dreg, mx, ereg, freg, greg;
|
---|
| 134 | char *bitary;
|
---|
| 135 | int bitsz, rval, nelem;
|
---|
| 136 |
|
---|
| 137 | if (argc == 2) {
|
---|
| 138 | i = atoi(argv[1]);
|
---|
| 139 | printf("Entry %d:\n%s\n", i, table[i].cstring);
|
---|
| 140 | return 0;
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | mkdope();
|
---|
| 144 |
|
---|
| 145 | for (q = table; q->op != FREE; q++) {
|
---|
| 146 | if (q->op >= OPSIMP)
|
---|
| 147 | continue;
|
---|
| 148 | if ((q->ltype & TLONGLONG) &&
|
---|
| 149 | (q->rtype & TLONGLONG))
|
---|
| 150 | chkop[q->op] |= TLONGLONG;
|
---|
| 151 | if ((q->ltype & TULONGLONG) &&
|
---|
| 152 | (q->rtype & TULONGLONG))
|
---|
| 153 | chkop[q->op] |= TULONGLONG;
|
---|
| 154 | }
|
---|
| 155 | if ((fc = fopen(cname, "w")) == NULL) {
|
---|
| 156 | perror("open cfile");
|
---|
| 157 | return(1);
|
---|
| 158 | }
|
---|
| 159 | if ((fh = fopen(hname, "w")) == NULL) {
|
---|
| 160 | perror("open hfile");
|
---|
| 161 | return(1);
|
---|
| 162 | }
|
---|
| 163 | fprintf(fh, "#ifndef _EXTERNAL_H_\n#define _EXTERNAL_H_\n");
|
---|
| 164 |
|
---|
| 165 | for (ch = checks; ch->op != 0; ch++) {
|
---|
| 166 | if ((chkop[ch->op] & ch->type) == 0)
|
---|
| 167 | fprintf(fh, "#define NEED_%s\n", ch->name);
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | fprintf(fc, "#include \"pass2.h\"\n");
|
---|
| 171 | /* create fast-lookup tables */
|
---|
| 172 | mktables();
|
---|
| 173 |
|
---|
| 174 | /* create efficient bitset sizes */
|
---|
| 175 | if (sizeof(long) == 8) { /* 64-bit arch */
|
---|
| 176 | bitary = "long";
|
---|
| 177 | bitsz = 64;
|
---|
| 178 | } else {
|
---|
| 179 | bitary = "int";
|
---|
| 180 | bitsz = sizeof(int) == 4 ? 32 : 16;
|
---|
| 181 | }
|
---|
| 182 | fprintf(fh, "#define NUMBITS %d\n", bitsz);
|
---|
| 183 | fprintf(fh, "#define BIT2BYTE(bits) "
|
---|
| 184 | "((((bits)+NUMBITS-1)/NUMBITS)*(NUMBITS/8))\n");
|
---|
| 185 | fprintf(fh, "#define BITSET(arr, bit) "
|
---|
| 186 | "(arr[bit/NUMBITS] |= ((%s)1 << (bit & (NUMBITS-1))))\n",
|
---|
| 187 | bitary);
|
---|
| 188 | fprintf(fh, "#define BITCLEAR(arr, bit) "
|
---|
| 189 | "(arr[bit/NUMBITS] &= ~((%s)1 << (bit & (NUMBITS-1))))\n",
|
---|
| 190 | bitary);
|
---|
| 191 | fprintf(fh, "#define TESTBIT(arr, bit) "
|
---|
| 192 | "(arr[bit/NUMBITS] & ((%s)1 << (bit & (NUMBITS-1))))\n",
|
---|
| 193 | bitary);
|
---|
| 194 | fprintf(fh, "typedef %s bittype;\n", bitary);
|
---|
| 195 |
|
---|
| 196 | /* register class definitions, used by graph-coloring */
|
---|
| 197 | /* TODO */
|
---|
| 198 |
|
---|
| 199 | /* Sanity-check the table */
|
---|
| 200 | rval = 0;
|
---|
| 201 | for (q = table; q->op != FREE; q++) {
|
---|
| 202 | switch (q->op) {
|
---|
| 203 | case ASSIGN:
|
---|
| 204 | #define F(x) (q->visit & x && q->rewrite & (RLEFT|RRIGHT) && \
|
---|
| 205 | q->lshape & ~x && q->rshape & ~x)
|
---|
| 206 | if (F(INAREG) || F(INBREG) || F(INCREG) || F(INDREG) ||
|
---|
| 207 | F(INEREG) || F(INFREG) || F(INGREG)) {
|
---|
| 208 | compl(q, "may match without result register");
|
---|
| 209 | rval++;
|
---|
| 210 | }
|
---|
| 211 | #undef F
|
---|
| 212 | /* FALLTHROUGH */
|
---|
| 213 | case STASG:
|
---|
| 214 | if ((q->visit & INREGS) && !(q->rewrite & RDEST)) {
|
---|
| 215 | compl(q, "ASSIGN/STASG reclaim must be RDEST");
|
---|
| 216 | rval++;
|
---|
| 217 | }
|
---|
| 218 | break;
|
---|
| 219 | }
|
---|
| 220 | /* check that reclaim is not the wrong class */
|
---|
| 221 | if ((q->rewrite & (RESC1|RESC2|RESC3)) &&
|
---|
| 222 | !(q->needs & REWRITE)) {
|
---|
| 223 | if ((q->visit & getrcl(q)) == 0) {
|
---|
| 224 | compl(q, "wrong RESCx class");
|
---|
| 225 | rval++;
|
---|
| 226 | }
|
---|
| 227 | }
|
---|
| 228 | if (q->rewrite & (RESC1|RESC2|RESC3) && q->visit & FOREFF)
|
---|
| 229 | compl(q, "FOREFF may cause reclaim of wrong class");
|
---|
| 230 | }
|
---|
| 231 |
|
---|
| 232 | /* print out list of scratched and permanent registers */
|
---|
| 233 | fprintf(fh, "extern int tempregs[], permregs[];\n");
|
---|
| 234 | fprintf(fc, "int tempregs[] = { ");
|
---|
| 235 | for (i = j = 0; i < MAXREGS; i++)
|
---|
| 236 | if (rstatus[i] & TEMPREG)
|
---|
| 237 | fprintf(fc, "%d, ", i), j++;
|
---|
| 238 | fprintf(fc, "-1 };\n");
|
---|
| 239 | fprintf(fh, "#define NTEMPREG %d\n", j+1);
|
---|
| 240 | fprintf(fh, "#define FREGS %d\n", j); /* XXX - to die */
|
---|
| 241 | fprintf(fc, "int permregs[] = { ");
|
---|
| 242 | for (i = j = 0; i < MAXREGS; i++)
|
---|
| 243 | if (rstatus[i] & PERMREG)
|
---|
| 244 | fprintf(fc, "%d, ", i), j++;
|
---|
| 245 | fprintf(fc, "-1 };\n");
|
---|
| 246 | fprintf(fh, "#define NPERMREG %d\n", j+1);
|
---|
| 247 | fprintf(fc, "bittype validregs[] = {\n");
|
---|
| 248 |
|
---|
| 249 | if (bitsz == 64) {
|
---|
| 250 | for (j = 0; j < MAXREGS; j += bitsz) {
|
---|
| 251 | long cbit = 0;
|
---|
| 252 | for (i = 0; i < bitsz; i++) {
|
---|
| 253 | if (i+j == MAXREGS)
|
---|
| 254 | break;
|
---|
| 255 | if (rstatus[i+j] & INREGS)
|
---|
| 256 | cbit |= ((long)1 << i);
|
---|
| 257 | }
|
---|
| 258 | fprintf(fc, "\t0x%lx,\n", cbit);
|
---|
| 259 | }
|
---|
| 260 | } else {
|
---|
| 261 | for (j = 0; j < MAXREGS; j += bitsz) {
|
---|
| 262 | int cbit = 0;
|
---|
| 263 | for (i = 0; i < bitsz; i++) {
|
---|
| 264 | if (i+j == MAXREGS)
|
---|
| 265 | break;
|
---|
| 266 | if (rstatus[i+j] & INREGS)
|
---|
| 267 | cbit |= (1 << i);
|
---|
| 268 | }
|
---|
| 269 | fprintf(fc, "\t0x%08x,\n", cbit);
|
---|
| 270 | }
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | fprintf(fc, "};\n");
|
---|
| 274 | fprintf(fh, "extern bittype validregs[];\n");
|
---|
| 275 |
|
---|
| 276 | /*
|
---|
| 277 | * The register allocator uses bitmasks of registers for each class.
|
---|
| 278 | */
|
---|
| 279 | areg = breg = creg = dreg = ereg = freg = greg = 0;
|
---|
| 280 | for (i = 0; i < MAXREGS; i++) {
|
---|
| 281 | for (j = 0; j < NUMCLASS; j++)
|
---|
| 282 | regclassmap[j][i] = -1;
|
---|
| 283 | if (rstatus[i] & SAREG) regclassmap[0][i] = areg++;
|
---|
| 284 | if (rstatus[i] & SBREG) regclassmap[1][i] = breg++;
|
---|
| 285 | if (rstatus[i] & SCREG) regclassmap[2][i] = creg++;
|
---|
| 286 | if (rstatus[i] & SDREG) regclassmap[3][i] = dreg++;
|
---|
| 287 | if (rstatus[i] & SEREG) regclassmap[4][i] = ereg++;
|
---|
| 288 | if (rstatus[i] & SFREG) regclassmap[5][i] = freg++;
|
---|
| 289 | if (rstatus[i] & SGREG) regclassmap[6][i] = greg++;
|
---|
| 290 | }
|
---|
| 291 | fprintf(fh, "#define AREGCNT %d\n", areg);
|
---|
| 292 | fprintf(fh, "#define BREGCNT %d\n", breg);
|
---|
| 293 | fprintf(fh, "#define CREGCNT %d\n", creg);
|
---|
| 294 | fprintf(fh, "#define DREGCNT %d\n", dreg);
|
---|
| 295 | fprintf(fh, "#define EREGCNT %d\n", ereg);
|
---|
| 296 | fprintf(fh, "#define FREGCNT %d\n", freg);
|
---|
| 297 | fprintf(fh, "#define GREGCNT %d\n", greg);
|
---|
| 298 | if (areg > bitsz)
|
---|
| 299 | printf("%d regs in class A (max %d)\n", areg, bitsz), rval++;
|
---|
| 300 | if (breg > bitsz)
|
---|
| 301 | printf("%d regs in class B (max %d)\n", breg, bitsz), rval++;
|
---|
| 302 | if (creg > bitsz)
|
---|
| 303 | printf("%d regs in class C (max %d)\n", creg, bitsz), rval++;
|
---|
| 304 | if (dreg > bitsz)
|
---|
| 305 | printf("%d regs in class D (max %d)\n", dreg, bitsz), rval++;
|
---|
| 306 | if (ereg > bitsz)
|
---|
| 307 | printf("%d regs in class E (max %d)\n", ereg, bitsz), rval++;
|
---|
| 308 | if (freg > bitsz)
|
---|
| 309 | printf("%d regs in class F (max %d)\n", freg, bitsz), rval++;
|
---|
| 310 | if (greg > bitsz)
|
---|
| 311 | printf("%d regs in class G (max %d)\n", greg, bitsz), rval++;
|
---|
| 312 |
|
---|
| 313 | fprintf(fc, "static int amap[MAXREGS][NUMCLASS] = {\n");
|
---|
| 314 | for (i = 0; i < MAXREGS; i++) {
|
---|
| 315 | int ba, bb, bc, bd, r, be, bf, bg;
|
---|
| 316 | ba = bb = bc = bd = be = bf = bg = 0;
|
---|
| 317 | if (rstatus[i] & SAREG) ba = (1 << regclassmap[0][i]);
|
---|
| 318 | if (rstatus[i] & SBREG) bb = (1 << regclassmap[1][i]);
|
---|
| 319 | if (rstatus[i] & SCREG) bc = (1 << regclassmap[2][i]);
|
---|
| 320 | if (rstatus[i] & SDREG) bd = (1 << regclassmap[3][i]);
|
---|
| 321 | if (rstatus[i] & SEREG) be = (1 << regclassmap[4][i]);
|
---|
| 322 | if (rstatus[i] & SFREG) bf = (1 << regclassmap[5][i]);
|
---|
| 323 | if (rstatus[i] & SGREG) bg = (1 << regclassmap[6][i]);
|
---|
| 324 | for (j = 0; roverlay[i][j] >= 0; j++) {
|
---|
| 325 | r = roverlay[i][j];
|
---|
| 326 | if (rstatus[r] & SAREG)
|
---|
| 327 | ba |= (1 << regclassmap[0][r]);
|
---|
| 328 | if (rstatus[r] & SBREG)
|
---|
| 329 | bb |= (1 << regclassmap[1][r]);
|
---|
| 330 | if (rstatus[r] & SCREG)
|
---|
| 331 | bc |= (1 << regclassmap[2][r]);
|
---|
| 332 | if (rstatus[r] & SDREG)
|
---|
| 333 | bd |= (1 << regclassmap[3][r]);
|
---|
| 334 | if (rstatus[r] & SEREG)
|
---|
| 335 | be |= (1 << regclassmap[4][r]);
|
---|
| 336 | if (rstatus[r] & SFREG)
|
---|
| 337 | bf |= (1 << regclassmap[5][r]);
|
---|
| 338 | if (rstatus[r] & SGREG)
|
---|
| 339 | bg |= (1 << regclassmap[6][r]);
|
---|
| 340 | }
|
---|
| 341 | fprintf(fc, "\t/* %d */{ 0x%x", i, ba);
|
---|
| 342 | if (NUMCLASS > 1) fprintf(fc, ",0x%x", bb);
|
---|
| 343 | if (NUMCLASS > 2) fprintf(fc, ",0x%x", bc);
|
---|
| 344 | if (NUMCLASS > 3) fprintf(fc, ",0x%x", bd);
|
---|
| 345 | if (NUMCLASS > 4) fprintf(fc, ",0x%x", be);
|
---|
| 346 | if (NUMCLASS > 5) fprintf(fc, ",0x%x", bf);
|
---|
| 347 | if (NUMCLASS > 6) fprintf(fc, ",0x%x", bg);
|
---|
| 348 | fprintf(fc, " },\n");
|
---|
| 349 | }
|
---|
| 350 | fprintf(fc, "};\n");
|
---|
| 351 |
|
---|
| 352 | fprintf(fh, "int aliasmap(int class, int regnum);\n");
|
---|
| 353 | fprintf(fc, "int\naliasmap(int class, int regnum)\n{\n");
|
---|
| 354 | fprintf(fc, " return amap[regnum][class-1];\n}\n");
|
---|
| 355 |
|
---|
| 356 | /* routines to convert back from color to regnum */
|
---|
| 357 | mx = areg;
|
---|
| 358 | if (breg > mx) mx = breg;
|
---|
| 359 | if (creg > mx) mx = creg;
|
---|
| 360 | if (dreg > mx) mx = dreg;
|
---|
| 361 | if (ereg > mx) mx = ereg;
|
---|
| 362 | if (freg > mx) mx = freg;
|
---|
| 363 | if (greg > mx) mx = greg;
|
---|
| 364 | if (mx > (int)(sizeof(int)*8)-1) {
|
---|
| 365 | printf("too many regs in a class, use two classes instead\n");
|
---|
| 366 | #ifdef HAVE_C99_FORMAT
|
---|
| 367 | printf("%d > %zu\n", mx, (sizeof(int)*8)-1);
|
---|
| 368 | #else
|
---|
| 369 | printf("%d > %d\n", mx, (int)(sizeof(int)*8)-1);
|
---|
| 370 | #endif
|
---|
| 371 | rval++;
|
---|
| 372 | }
|
---|
| 373 | fprintf(fc, "static int rmap[NUMCLASS][%d] = {\n", mx);
|
---|
| 374 | for (j = 0; j < NUMCLASS; j++) {
|
---|
| 375 | int cl = (1 << (j+1));
|
---|
| 376 | fprintf(fc, "\t{ ");
|
---|
| 377 | for (i = 0; i < MAXREGS; i++)
|
---|
| 378 | if (rstatus[i] & cl) fprintf(fc, "%d, ", i);
|
---|
| 379 | fprintf(fc, "},\n");
|
---|
| 380 | }
|
---|
| 381 | fprintf(fc, "};\n\n");
|
---|
| 382 |
|
---|
| 383 | fprintf(fh, "int color2reg(int color, int class);\n");
|
---|
| 384 | fprintf(fc, "int\ncolor2reg(int color, int class)\n{\n");
|
---|
| 385 | fprintf(fc, " return rmap[class-1][color];\n}\n");
|
---|
| 386 |
|
---|
| 387 | /* used by register allocator */
|
---|
| 388 | fprintf(fc, "int regK[] = { 0, %d, %d, %d, %d, %d, %d, %d };\n",
|
---|
| 389 | areg, breg, creg, dreg, ereg, freg, greg);
|
---|
| 390 | fprintf(fc, "int\nclassmask(int class)\n{\n");
|
---|
| 391 | fprintf(fc, "\tif(class == CLASSA) return 0x%x;\n", (1 << areg)-1);
|
---|
| 392 | fprintf(fc, "\tif(class == CLASSB) return 0x%x;\n", (1 << breg)-1);
|
---|
| 393 | fprintf(fc, "\tif(class == CLASSC) return 0x%x;\n", (1 << creg)-1);
|
---|
| 394 | fprintf(fc, "\tif(class == CLASSD) return 0x%x;\n", (1 << dreg)-1);
|
---|
| 395 | fprintf(fc, "\tif(class == CLASSE) return 0x%x;\n", (1 << ereg)-1);
|
---|
| 396 | fprintf(fc, "\tif(class == CLASSF) return 0x%x;\n", (1 << freg)-1);
|
---|
| 397 | fprintf(fc, "\treturn 0x%x;\n}\n", (1 << greg)-1);
|
---|
| 398 |
|
---|
| 399 | fprintf(fh, "int interferes(int reg1, int reg2);\n");
|
---|
| 400 | nelem = (MAXREGS+bitsz-1)/bitsz;
|
---|
| 401 | fprintf(fc, "static bittype ovlarr[MAXREGS][%d] = {\n", nelem);
|
---|
| 402 | for (i = 0; i < MAXREGS; i++) {
|
---|
| 403 | int el[10];
|
---|
| 404 | memset(el, 0, sizeof(el));
|
---|
| 405 | el[i/bitsz] = 1 << (i % bitsz);
|
---|
| 406 | for (j = 0; roverlay[i][j] >= 0; j++) {
|
---|
| 407 | int k = roverlay[i][j];
|
---|
| 408 | el[k/bitsz] |= (1 << (k % bitsz));
|
---|
| 409 | }
|
---|
| 410 | fprintf(fc, "{ ");
|
---|
| 411 | for (j = 0; j < MAXREGS; j += bitsz)
|
---|
| 412 | fprintf(fc, "0x%x, ", el[j/bitsz]);
|
---|
| 413 | fprintf(fc, " },\n");
|
---|
| 414 | }
|
---|
| 415 | fprintf(fc, "};\n");
|
---|
| 416 |
|
---|
| 417 | fprintf(fc, "int\ninterferes(int reg1, int reg2)\n{\n");
|
---|
| 418 | fprintf(fc, "return (TESTBIT(ovlarr[reg1], reg2)) != 0;\n}\n");
|
---|
| 419 | fclose(fc);
|
---|
| 420 | fprintf(fh, "#endif /* _EXTERNAL_H_ */\n");
|
---|
| 421 | fclose(fh);
|
---|
| 422 | return rval;
|
---|
| 423 | }
|
---|
| 424 |
|
---|
| 425 | #define P(x) fprintf x
|
---|
| 426 |
|
---|
| 427 | void
|
---|
| 428 | mktables()
|
---|
| 429 | {
|
---|
| 430 | struct optab *op;
|
---|
| 431 | int mxalen = 0, curalen;
|
---|
| 432 | int i;
|
---|
| 433 |
|
---|
| 434 | #if 0
|
---|
| 435 | P((fc, "#include \"pass2.h\"\n\n"));
|
---|
| 436 | #endif
|
---|
| 437 | for (i = 0; i <= MAXOP; i++) {
|
---|
| 438 | curalen = 0;
|
---|
| 439 | P((fc, "static int op%d[] = { ", i));
|
---|
| 440 | if (dope[i] != 0)
|
---|
| 441 | for (op = table; op->op != FREE; op++) {
|
---|
| 442 | if (op->op < OPSIMP) {
|
---|
| 443 | if (op->op == i) {
|
---|
| 444 | P((fc, FMTdPTR ", ", op - table));
|
---|
| 445 | curalen++;
|
---|
| 446 | }
|
---|
| 447 | } else {
|
---|
| 448 | int opmtemp;
|
---|
| 449 | if ((opmtemp=mamask[op->op - OPSIMP])&SPFLG) {
|
---|
| 450 | if (i==NAME || i==ICON || i==TEMP ||
|
---|
| 451 | i==OREG || i == REG || i == FCON) {
|
---|
| 452 | P((fc, FMTdPTR ", ",
|
---|
| 453 | op - table));
|
---|
| 454 | curalen++;
|
---|
| 455 | }
|
---|
| 456 | } else if ((dope[i]&(opmtemp|ASGFLG))==opmtemp){
|
---|
| 457 | P((fc, FMTdPTR ", ", op - table));
|
---|
| 458 | curalen++;
|
---|
| 459 | }
|
---|
| 460 | }
|
---|
| 461 | }
|
---|
| 462 | if (curalen > mxalen)
|
---|
| 463 | mxalen = curalen;
|
---|
| 464 | P((fc, "-1 };\n"));
|
---|
| 465 | }
|
---|
| 466 | P((fc, "\n"));
|
---|
| 467 |
|
---|
| 468 | P((fc, "int *qtable[] = { \n"));
|
---|
| 469 | for (i = 0; i <= MAXOP; i++) {
|
---|
| 470 | P((fc, " op%d,\n", i));
|
---|
| 471 | }
|
---|
| 472 | P((fc, "};\n"));
|
---|
| 473 | P((fh, "#define MAXOPLEN %d\n", mxalen+1));
|
---|
| 474 | }
|
---|