Use new tail-calling mechanism on ARM.
[official-gcc.git] / gcc / gensupport.c
blob9e77a97c057f1f6d507e99c398343a33f1ca1d0d
1 /* Read machine descriptions, return top level rtx for use by the
2 various generation passes.
4 Copyright (C) 2000 Free Software Foundation, Inc.
6 This file is part of GNU CC.
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.
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.
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. */
23 #include "hconfig.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "errors.h"
27 #include "gensupport.h"
29 static FILE *input_file;
31 static int sequence_num;
33 struct queue_elem {
34 rtx data;
35 struct queue_elem *next;
38 static struct queue_elem *rtx_ready_queue;
40 static void remove_constraints PARAMS ((rtx));
41 static void process_rtx PARAMS ((rtx *));
43 /* Recursively remove constraints from an rtx. */
45 static void
46 remove_constraints (part)
47 rtx part;
49 register int i, j;
50 register const char *format_ptr;
52 if (part == 0)
53 return;
55 if (GET_CODE (part) == MATCH_OPERAND)
56 XSTR (part, 2) = "";
57 else if (GET_CODE (part) == MATCH_SCRATCH)
58 XSTR (part, 1) = "";
60 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
62 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
63 switch (*format_ptr++)
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;
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 */
87 static void
88 process_rtx (desc)
89 rtx* desc;
91 if (GET_CODE (*desc) == DEFINE_INSN_AND_SPLIT)
93 struct queue_elem* elem = xmalloc (sizeof (struct queue_elem));
94 const char *split_cond;
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);
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] == '&')
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;
114 XVEC (split, 2) = XVEC (*desc, 5);
115 XSTR (split, 3) = XSTR (*desc, 6);
117 /* Fix up the DEFINE_INSN. */
118 PUT_CODE (*desc, DEFINE_INSN);
119 XVEC (*desc, 4) = XVEC (*desc, 7);
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;
129 /* The entry point for initializing the reader. */
131 int
132 init_md_reader (filename)
133 const char *filename;
136 input_file = fopen (filename, "r");
138 if (input_file == 0)
140 perror (filename);
141 return FATAL_EXIT_CODE;
144 read_rtx_filename = filename;
145 sequence_num = 0;
146 rtx_ready_queue = NULL;
148 return SUCCESS_EXIT_CODE;
152 /* The entry point for reading a single rtx from an md file. */
154 rtx
155 read_md_rtx (lineno, seqnr)
156 int *lineno;
157 int *seqnr;
159 rtx desc;
161 if (rtx_ready_queue != NULL)
163 desc = rtx_ready_queue->data;
164 rtx_ready_queue = rtx_ready_queue->next;
166 else
168 int c;
169 c = read_skip_spaces (input_file);
170 if (c == EOF)
171 return NULL;
173 ungetc (c, input_file);
174 desc = read_rtx (input_file);
175 process_rtx (&desc);
177 *lineno = read_rtx_lineno;
178 *seqnr = sequence_num;
179 switch (GET_CODE (desc))
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;
189 default:
190 break;
193 return desc;