OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [genpeep.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Generate code from machine description to perform peephole optimizations.
2
   Copyright (C) 1987, 1989, 1992, 1997, 1998,
3
   1999, 2000, 2003, 2004 Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
 
23
#include "bconfig.h"
24
#include "system.h"
25
#include "coretypes.h"
26
#include "tm.h"
27
#include "rtl.h"
28
#include "errors.h"
29
#include "gensupport.h"
30
 
31
 
32
/* While tree-walking an instruction pattern, we keep a chain
33
   of these `struct link's to record how to get down to the
34
   current position.  In each one, POS is the operand number,
35
   and if the operand is a vector VEC is the element number.
36
   VEC is -1 if the operand is not a vector.  */
37
 
38
struct link
39
{
40
  struct link *next;
41
  int pos;
42
  int vecelt;
43
};
44
 
45
static int max_opno;
46
 
47
/* Number of operands used in current peephole definition.  */
48
 
49
static int n_operands;
50
 
51
/* Peephole optimizations get insn codes just like insn patterns.
52
   Count them so we know the code of the define_peephole we are handling.  */
53
 
54
static int insn_code_number = 0;
55
 
56
static void gen_peephole (rtx);
57
static void match_rtx (rtx, struct link *, int);
58
static void print_path (struct link *);
59
static void print_code (RTX_CODE);
60
 
61
static void
62
gen_peephole (rtx peep)
63
{
64
  int ninsns = XVECLEN (peep, 0);
65
  int i;
66
 
67
  n_operands = 0;
68
 
69
  printf ("  insn = ins1;\n");
70
 
71
  for (i = 0; i < ninsns; i++)
72
    {
73
      if (i > 0)
74
        {
75
          printf ("  do { insn = NEXT_INSN (insn);\n");
76
          printf ("       if (insn == 0) goto L%d; }\n",
77
                  insn_code_number);
78
          printf ("  while (NOTE_P (insn)\n");
79
          printf ("\t || (NONJUMP_INSN_P (insn)\n");
80
          printf ("\t     && (GET_CODE (PATTERN (insn)) == USE\n");
81
          printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n");
82
 
83
          printf ("  if (LABEL_P (insn)\n\
84
      || BARRIER_P (insn))\n    goto L%d;\n",
85
                  insn_code_number);
86
        }
87
 
88
      printf ("  pat = PATTERN (insn);\n");
89
 
90
      /* Walk the insn's pattern, remembering at all times the path
91
         down to the walking point.  */
92
 
93
      match_rtx (XVECEXP (peep, 0, i), NULL, insn_code_number);
94
    }
95
 
96
  /* We get this far if the pattern matches.
97
     Now test the extra condition.  */
98
 
99
  if (XSTR (peep, 1) && XSTR (peep, 1)[0])
100
    printf ("  if (! (%s)) goto L%d;\n",
101
            XSTR (peep, 1), insn_code_number);
102
 
103
  /* If that matches, construct new pattern and put it in the first insn.
104
     This new pattern will never be matched.
105
     It exists only so that insn-extract can get the operands back.
106
     So use a simple regular form: a PARALLEL containing a vector
107
     of all the operands.  */
108
 
109
  printf ("  PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands);
110
 
111
  /* Record this define_peephole's insn code in the insn,
112
     as if it had been recognized to match this.  */
113
  printf ("  INSN_CODE (ins1) = %d;\n",
114
          insn_code_number);
115
 
116
  /* Delete the remaining insns.  */
117
  if (ninsns > 1)
118
    printf ("  delete_for_peephole (NEXT_INSN (ins1), insn);\n");
119
 
120
  /* See reload1.c for insertion of NOTE which guarantees that this
121
     cannot be zero.  */
122
  printf ("  return NEXT_INSN (insn);\n");
123
 
124
  printf (" L%d:\n\n", insn_code_number);
125
}
126
 
127
static void
128
match_rtx (rtx x, struct link *path, int fail_label)
129
{
130
  RTX_CODE code;
131
  int i;
132
  int len;
133
  const char *fmt;
134
  struct link link;
135
 
136
  if (x == 0)
137
    return;
138
 
139
 
140
  code = GET_CODE (x);
141
 
142
  switch (code)
143
    {
144
    case MATCH_OPERAND:
145
      if (XINT (x, 0) > max_opno)
146
        max_opno = XINT (x, 0);
147
      if (XINT (x, 0) >= n_operands)
148
        n_operands = 1 + XINT (x, 0);
149
 
150
      printf ("  x = ");
151
      print_path (path);
152
      printf (";\n");
153
 
154
      printf ("  operands[%d] = x;\n", XINT (x, 0));
155
      if (XSTR (x, 1) && XSTR (x, 1)[0])
156
        printf ("  if (! %s (x, %smode)) goto L%d;\n",
157
                XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
158
      return;
159
 
160
    case MATCH_DUP:
161
    case MATCH_PAR_DUP:
162
      printf ("  x = ");
163
      print_path (path);
164
      printf (";\n");
165
 
166
      printf ("  if (!rtx_equal_p (operands[%d], x)) goto L%d;\n",
167
              XINT (x, 0), fail_label);
168
      return;
169
 
170
    case MATCH_OP_DUP:
171
      printf ("  x = ");
172
      print_path (path);
173
      printf (";\n");
174
 
175
      printf ("  if (GET_CODE (operands[%d]) != GET_CODE (x)\n", XINT (x, 0));
176
      printf ("      || GET_MODE (operands[%d]) != GET_MODE (x)) goto L%d;\n",
177
              XINT (x, 0), fail_label);
178
      printf ("  operands[%d] = x;\n", XINT (x, 0));
179
      link.next = path;
180
      link.vecelt = -1;
181
      for (i = 0; i < XVECLEN (x, 1); i++)
182
        {
183
          link.pos = i;
184
          match_rtx (XVECEXP (x, 1, i), &link, fail_label);
185
        }
186
      return;
187
 
188
    case MATCH_OPERATOR:
189
      if (XINT (x, 0) > max_opno)
190
        max_opno = XINT (x, 0);
191
      if (XINT (x, 0) >= n_operands)
192
        n_operands = 1 + XINT (x, 0);
193
 
194
      printf ("  x = ");
195
      print_path (path);
196
      printf (";\n");
197
 
198
      printf ("  operands[%d] = x;\n", XINT (x, 0));
199
      if (XSTR (x, 1) && XSTR (x, 1)[0])
200
        printf ("  if (! %s (x, %smode)) goto L%d;\n",
201
                XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
202
      link.next = path;
203
      link.vecelt = -1;
204
      for (i = 0; i < XVECLEN (x, 2); i++)
205
        {
206
          link.pos = i;
207
          match_rtx (XVECEXP (x, 2, i), &link, fail_label);
208
        }
209
      return;
210
 
211
    case MATCH_PARALLEL:
212
      if (XINT (x, 0) > max_opno)
213
        max_opno = XINT (x, 0);
214
      if (XINT (x, 0) >= n_operands)
215
        n_operands = 1 + XINT (x, 0);
216
 
217
      printf ("  x = ");
218
      print_path (path);
219
      printf (";\n");
220
 
221
      printf ("  if (GET_CODE (x) != PARALLEL) goto L%d;\n", fail_label);
222
      printf ("  operands[%d] = x;\n", XINT (x, 0));
223
      if (XSTR (x, 1) && XSTR (x, 1)[0])
224
        printf ("  if (! %s (x, %smode)) goto L%d;\n",
225
                XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
226
      link.next = path;
227
      link.pos = 0;
228
      for (i = 0; i < XVECLEN (x, 2); i++)
229
        {
230
          link.vecelt = i;
231
          match_rtx (XVECEXP (x, 2, i), &link, fail_label);
232
        }
233
      return;
234
 
235
    case ADDRESS:
236
      match_rtx (XEXP (x, 0), path, fail_label);
237
      return;
238
 
239
    default:
240
      break;
241
    }
242
 
243
  printf ("  x = ");
244
  print_path (path);
245
  printf (";\n");
246
 
247
  printf ("  if (GET_CODE (x) != ");
248
  print_code (code);
249
  printf (") goto L%d;\n", fail_label);
250
 
251
  if (GET_MODE (x) != VOIDmode)
252
    {
253
      printf ("  if (GET_MODE (x) != %smode) goto L%d;\n",
254
              GET_MODE_NAME (GET_MODE (x)), fail_label);
255
    }
256
 
257
  link.next = path;
258
  link.vecelt = -1;
259
  fmt = GET_RTX_FORMAT (code);
260
  len = GET_RTX_LENGTH (code);
261
  for (i = 0; i < len; i++)
262
    {
263
      link.pos = i;
264
      if (fmt[i] == 'e' || fmt[i] == 'u')
265
        match_rtx (XEXP (x, i), &link, fail_label);
266
      else if (fmt[i] == 'E')
267
        {
268
          int j;
269
          printf ("  if (XVECLEN (x, %d) != %d) goto L%d;\n",
270
                  i, XVECLEN (x, i), fail_label);
271
          for (j = 0; j < XVECLEN (x, i); j++)
272
            {
273
              link.vecelt = j;
274
              match_rtx (XVECEXP (x, i, j), &link, fail_label);
275
            }
276
        }
277
      else if (fmt[i] == 'i')
278
        {
279
          /* Make sure that at run time `x' is the RTX we want to test.  */
280
          if (i != 0)
281
            {
282
              printf ("  x = ");
283
              print_path (path);
284
              printf (";\n");
285
            }
286
 
287
          printf ("  if (XINT (x, %d) != %d) goto L%d;\n",
288
                  i, XINT (x, i), fail_label);
289
        }
290
      else if (fmt[i] == 'w')
291
        {
292
          /* Make sure that at run time `x' is the RTX we want to test.  */
293
          if (i != 0)
294
            {
295
              printf ("  x = ");
296
              print_path (path);
297
              printf (";\n");
298
            }
299
 
300
          printf ("  if (XWINT (x, %d) != ", i);
301
          printf (HOST_WIDE_INT_PRINT_DEC, XWINT (x, i));
302
          printf (") goto L%d;\n", fail_label);
303
        }
304
      else if (fmt[i] == 's')
305
        {
306
          /* Make sure that at run time `x' is the RTX we want to test.  */
307
          if (i != 0)
308
            {
309
              printf ("  x = ");
310
              print_path (path);
311
              printf (";\n");
312
            }
313
 
314
          printf ("  if (strcmp (XSTR (x, %d), \"%s\")) goto L%d;\n",
315
                  i, XSTR (x, i), fail_label);
316
        }
317
    }
318
}
319
 
320
/* Given a PATH, representing a path down the instruction's
321
   pattern from the root to a certain point, output code to
322
   evaluate to the rtx at that point.  */
323
 
324
static void
325
print_path (struct link *path)
326
{
327
  if (path == 0)
328
    printf ("pat");
329
  else if (path->vecelt >= 0)
330
    {
331
      printf ("XVECEXP (");
332
      print_path (path->next);
333
      printf (", %d, %d)", path->pos, path->vecelt);
334
    }
335
  else
336
    {
337
      printf ("XEXP (");
338
      print_path (path->next);
339
      printf (", %d)", path->pos);
340
    }
341
}
342
 
343
static void
344
print_code (RTX_CODE code)
345
{
346
  const char *p1;
347
  for (p1 = GET_RTX_NAME (code); *p1; p1++)
348
    putchar (TOUPPER(*p1));
349
}
350
 
351
extern int main (int, char **);
352
 
353
int
354
main (int argc, char **argv)
355
{
356
  rtx desc;
357
 
358
  max_opno = -1;
359
 
360
  progname = "genpeep";
361
 
362
  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
363
    return (FATAL_EXIT_CODE);
364
 
365
  printf ("/* Generated automatically by the program `genpeep'\n\
366
from the machine description file `md'.  */\n\n");
367
 
368
  printf ("#include \"config.h\"\n");
369
  printf ("#include \"system.h\"\n");
370
  printf ("#include \"coretypes.h\"\n");
371
  printf ("#include \"tm.h\"\n");
372
  printf ("#include \"insn-config.h\"\n");
373
  printf ("#include \"rtl.h\"\n");
374
  printf ("#include \"tm_p.h\"\n");
375
  printf ("#include \"regs.h\"\n");
376
  printf ("#include \"output.h\"\n");
377
  printf ("#include \"real.h\"\n");
378
  printf ("#include \"recog.h\"\n");
379
  printf ("#include \"except.h\"\n\n");
380
  printf ("#include \"function.h\"\n\n");
381
 
382
  printf ("#ifdef HAVE_peephole\n");
383
  printf ("extern rtx peep_operand[];\n\n");
384
  printf ("#define operands peep_operand\n\n");
385
 
386
  printf ("rtx\npeephole (rtx ins1)\n{\n");
387
  printf ("  rtx insn ATTRIBUTE_UNUSED, x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n");
388
 
389
  /* Early out: no peepholes for insns followed by barriers.  */
390
  printf ("  if (NEXT_INSN (ins1)\n");
391
  printf ("      && BARRIER_P (NEXT_INSN (ins1)))\n");
392
  printf ("    return 0;\n\n");
393
 
394
  /* Read the machine description.  */
395
 
396
  while (1)
397
    {
398
      int line_no, rtx_number = 0;
399
 
400
      desc = read_md_rtx (&line_no, &rtx_number);
401
      if (desc == NULL)
402
        break;
403
 
404
       if (GET_CODE (desc) == DEFINE_PEEPHOLE)
405
        {
406
          gen_peephole (desc);
407
          insn_code_number++;
408
        }
409
      if (GET_CODE (desc) == DEFINE_INSN
410
          || GET_CODE (desc) == DEFINE_EXPAND
411
          || GET_CODE (desc) == DEFINE_SPLIT
412
          || GET_CODE (desc) == DEFINE_PEEPHOLE2)
413
        {
414
          insn_code_number++;
415
        }
416
    }
417
 
418
  printf ("  return 0;\n}\n\n");
419
 
420
  if (max_opno == -1)
421
    max_opno = 1;
422
 
423
  printf ("rtx peep_operand[%d];\n", max_opno + 1);
424
  printf ("#endif\n");
425
 
426
  fflush (stdout);
427
  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
428
}
429
 
430
/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
431
const char *
432
get_insn_name (int code ATTRIBUTE_UNUSED)
433
{
434
  return NULL;
435
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.