OSDN Git Service

* Makefile.in (start.encap): Do not depend on LIBGCC1.
[pf3gnuchains/gcc-fork.git] / gcc / gensupport.c
1 /* Read machine descriptions, return top level rtx for use by the
2    various generation passes. 
3
4    Copyright (C) 2000 Free Software Foundation, Inc.
5
6    This file is part of GNU CC.
7
8    GNU CC is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GNU CC is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GNU CC; see the file COPYING.  If not, write to
20    the Free Software Foundation, 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23 #include "hconfig.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "errors.h"
27 #include "gensupport.h"
28
29 static FILE *input_file;
30
31 static int sequence_num;
32
33 struct queue_elem {
34     rtx data;
35     struct queue_elem *next;
36 };
37
38 static struct queue_elem *rtx_ready_queue;
39
40 /* Recursively remove constraints from an rtx.  */
41
42 static void
43 remove_constraints (part)
44      rtx part;
45 {
46   register int i, j;
47   register const char *format_ptr;
48
49   if (part == 0)
50     return;
51
52   if (GET_CODE (part) == MATCH_OPERAND)
53     XSTR (part, 2) = "";
54   else if (GET_CODE (part) == MATCH_SCRATCH)
55     XSTR (part, 1) = "";
56
57   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
58
59   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
60     switch (*format_ptr++)
61       {
62       case 'e':
63       case 'u':
64         remove_constraints (XEXP (part, i));
65         break;
66       case 'E':
67         if (XVEC (part, i) != NULL)
68           for (j = 0; j < XVECLEN (part, i); j++)
69             remove_constraints (XVECEXP (part, i, j));
70         break;
71       }
72 }
73
74 /* Handle any synthetic top level rtx, i.e. anything except:
75        DEFINE_INSN
76        DEFINE_EXPAND
77        DEFINE_SPLIT
78        DEFINE_PEEPHOLE
79        DEFINE_PEEPHOLE2
80        DEFINE_ATTRIBUTE
81        DEFINE_FUNCTION_UNIT
82        DEFINE_ASM_ATTRIBUTES */
83
84 static void
85 process_rtx (desc)
86     rtx* desc;
87 {
88   if (GET_CODE (*desc) == DEFINE_INSN_AND_SPLIT) 
89     {
90       struct queue_elem* elem = xmalloc (sizeof (struct queue_elem));
91       const char *split_cond;
92   
93       /* Create a split with values from the insn_and_split. */
94       rtx split = rtx_alloc (DEFINE_SPLIT);
95       XEXP (split, 0) = copy_rtx (XEXP (*desc, 1));
96       remove_constraints (XEXP (split, 0));
97       split_cond = XSTR (split, 1) = XSTR (*desc, 4);
98   
99       /* If the split condition starts with "&&", append it to the
100          insn condition to create the new split condition.  */
101       if (split_cond[0] == '&' && split_cond[1] == '&')
102         {
103         const char *insn_cond = XSTR (*desc, 2);
104         char *combined = 
105             xmalloc (strlen (insn_cond) + strlen (split_cond) + 1);
106         strcpy (combined, insn_cond);
107         strcat (combined, split_cond);
108         XSTR (split, 1) = combined;
109         }
110   
111       XVEC (split, 2) = XVEC (*desc, 5);
112       XSTR (split, 3) = XSTR (*desc, 6);
113   
114       /* Fix up the DEFINE_INSN.  */
115       PUT_CODE (*desc, DEFINE_INSN);
116       XVEC (*desc, 4) = XVEC (*desc, 7);
117   
118       /* Return the DEFINE_INSN part, and put the DEFINE_SPLIT
119          in the queue.  */
120       elem->next = rtx_ready_queue;
121       elem->data = split;       
122       rtx_ready_queue = elem;  
123     }
124 }
125
126 /* The entry point for initializing the reader.  */
127
128 int 
129 init_md_reader (filename)
130     const char *filename;
131 {
132
133   input_file = fopen (filename, "r");
134
135   if (input_file == 0)
136     {
137       perror (filename);
138       return FATAL_EXIT_CODE;
139     }
140
141   read_rtx_filename = filename;
142   sequence_num = 0;
143   rtx_ready_queue = NULL; 
144
145   return SUCCESS_EXIT_CODE;
146 }
147
148
149 /* The entry point for reading a single rtx from an md file.  */
150
151 rtx 
152 read_md_rtx (lineno, seqnr)
153     int *lineno;
154     int *seqnr;
155
156   rtx desc;
157
158   if (rtx_ready_queue != NULL) 
159     {
160       desc = rtx_ready_queue->data;
161       rtx_ready_queue = rtx_ready_queue->next;
162     }
163   else 
164     {
165       int c;
166       c = read_skip_spaces (input_file);
167       if (c == EOF)
168         return NULL;
169
170       ungetc (c, input_file);
171       desc = read_rtx (input_file);
172       process_rtx (&desc);
173     }
174   *lineno = read_rtx_lineno;
175   *seqnr = sequence_num;
176   switch (GET_CODE (desc))
177     {
178       case DEFINE_INSN:
179       case DEFINE_EXPAND:
180       case DEFINE_SPLIT:
181       case DEFINE_PEEPHOLE:
182       case DEFINE_PEEPHOLE2:
183         sequence_num++;
184         break;
185
186       default:
187         break;
188     }
189
190   return desc;
191 }