OSDN Git Service

* bb-reorder.c (get_next_bb_note, get_prev_bb_note): Prototype.
[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 static void remove_constraints PARAMS ((rtx));
41 static void process_rtx PARAMS ((rtx *));
42
43 /* Recursively remove constraints from an rtx.  */
44
45 static void
46 remove_constraints (part)
47      rtx part;
48 {
49   register int i, j;
50   register const char *format_ptr;
51
52   if (part == 0)
53     return;
54
55   if (GET_CODE (part) == MATCH_OPERAND)
56     XSTR (part, 2) = "";
57   else if (GET_CODE (part) == MATCH_SCRATCH)
58     XSTR (part, 1) = "";
59
60   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
61
62   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
63     switch (*format_ptr++)
64       {
65       case 'e':
66       case 'u':
67         remove_constraints (XEXP (part, i));
68         break;
69       case 'E':
70         if (XVEC (part, i) != NULL)
71           for (j = 0; j < XVECLEN (part, i); j++)
72             remove_constraints (XVECEXP (part, i, j));
73         break;
74       }
75 }
76
77 /* Handle any synthetic top level rtx, i.e. anything except:
78        DEFINE_INSN
79        DEFINE_EXPAND
80        DEFINE_SPLIT
81        DEFINE_PEEPHOLE
82        DEFINE_PEEPHOLE2
83        DEFINE_ATTRIBUTE
84        DEFINE_FUNCTION_UNIT
85        DEFINE_ASM_ATTRIBUTES */
86
87 static void
88 process_rtx (desc)
89     rtx* desc;
90 {
91   if (GET_CODE (*desc) == DEFINE_INSN_AND_SPLIT) 
92     {
93       struct queue_elem* elem = xmalloc (sizeof (struct queue_elem));
94       const char *split_cond;
95   
96       /* Create a split with values from the insn_and_split. */
97       rtx split = rtx_alloc (DEFINE_SPLIT);
98       XEXP (split, 0) = copy_rtx (XEXP (*desc, 1));
99       remove_constraints (XEXP (split, 0));
100       split_cond = XSTR (split, 1) = XSTR (*desc, 4);
101   
102       /* If the split condition starts with "&&", append it to the
103          insn condition to create the new split condition.  */
104       if (split_cond[0] == '&' && split_cond[1] == '&')
105         {
106         const char *insn_cond = XSTR (*desc, 2);
107         char *combined = 
108             xmalloc (strlen (insn_cond) + strlen (split_cond) + 1);
109         strcpy (combined, insn_cond);
110         strcat (combined, split_cond);
111         XSTR (split, 1) = combined;
112         }
113   
114       XVEC (split, 2) = XVEC (*desc, 5);
115       XSTR (split, 3) = XSTR (*desc, 6);
116   
117       /* Fix up the DEFINE_INSN.  */
118       PUT_CODE (*desc, DEFINE_INSN);
119       XVEC (*desc, 4) = XVEC (*desc, 7);
120   
121       /* Return the DEFINE_INSN part, and put the DEFINE_SPLIT
122          in the queue.  */
123       elem->next = rtx_ready_queue;
124       elem->data = split;       
125       rtx_ready_queue = elem;  
126     }
127 }
128
129 /* The entry point for initializing the reader.  */
130
131 int 
132 init_md_reader (filename)
133     const char *filename;
134 {
135
136   input_file = fopen (filename, "r");
137
138   if (input_file == 0)
139     {
140       perror (filename);
141       return FATAL_EXIT_CODE;
142     }
143
144   read_rtx_filename = filename;
145   sequence_num = 0;
146   rtx_ready_queue = NULL; 
147
148   return SUCCESS_EXIT_CODE;
149 }
150
151
152 /* The entry point for reading a single rtx from an md file.  */
153
154 rtx 
155 read_md_rtx (lineno, seqnr)
156     int *lineno;
157     int *seqnr;
158
159   rtx desc;
160
161   if (rtx_ready_queue != NULL) 
162     {
163       desc = rtx_ready_queue->data;
164       rtx_ready_queue = rtx_ready_queue->next;
165     }
166   else 
167     {
168       int c;
169       c = read_skip_spaces (input_file);
170       if (c == EOF)
171         return NULL;
172
173       ungetc (c, input_file);
174       desc = read_rtx (input_file);
175       process_rtx (&desc);
176     }
177   *lineno = read_rtx_lineno;
178   *seqnr = sequence_num;
179   switch (GET_CODE (desc))
180     {
181       case DEFINE_INSN:
182       case DEFINE_EXPAND:
183       case DEFINE_SPLIT:
184       case DEFINE_PEEPHOLE:
185       case DEFINE_PEEPHOLE2:
186         sequence_num++;
187         break;
188
189       default:
190         break;
191     }
192
193   return desc;
194 }