Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.51 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/mkext.c

Annotated File View

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