annotate gcc/gensupport.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Support routines for the various generation passes.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2000-2018 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "bconfig.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "coretypes.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "tm.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 #include "rtl.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "obstack.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "errors.h"
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
27 #include "read-md.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 #include "gensupport.h"
111
kono
parents: 67
diff changeset
29 #include "vec.h"
kono
parents: 67
diff changeset
30
kono
parents: 67
diff changeset
31 #define MAX_OPERANDS 40
kono
parents: 67
diff changeset
32
kono
parents: 67
diff changeset
33 static rtx operand_data[MAX_OPERANDS];
kono
parents: 67
diff changeset
34 static rtx match_operand_entries_in_pattern[MAX_OPERANDS];
kono
parents: 67
diff changeset
35 static char used_operands_numbers[MAX_OPERANDS];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 /* In case some macros used by files we include need it, define this here. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 int target_flags;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 int insn_elision = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 static struct obstack obstack;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 struct obstack *rtl_obstack = &obstack;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
111
kono
parents: 67
diff changeset
46 /* Counter for named patterns and INSN_CODEs. */
kono
parents: 67
diff changeset
47 static int insn_sequence_num;
kono
parents: 67
diff changeset
48
kono
parents: 67
diff changeset
49 /* Counter for define_splits. */
kono
parents: 67
diff changeset
50 static int split_sequence_num;
kono
parents: 67
diff changeset
51
kono
parents: 67
diff changeset
52 /* Counter for define_peephole2s. */
kono
parents: 67
diff changeset
53 static int peephole2_sequence_num;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 static int predicable_default;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 static const char *predicable_true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 static const char *predicable_false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58
111
kono
parents: 67
diff changeset
59 static const char *subst_true = "yes";
kono
parents: 67
diff changeset
60 static const char *subst_false = "no";
kono
parents: 67
diff changeset
61
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 static htab_t condition_table;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
111
kono
parents: 67
diff changeset
64 /* We initially queue all patterns, process the define_insn,
kono
parents: 67
diff changeset
65 define_cond_exec and define_subst patterns, then return
kono
parents: 67
diff changeset
66 them one at a time. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 struct queue_elem
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 rtx data;
111
kono
parents: 67
diff changeset
71 file_location loc;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 struct queue_elem *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 points to the generated DEFINE_SPLIT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 struct queue_elem *split;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
78 #define MNEMONIC_ATTR_NAME "mnemonic"
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
79 #define MNEMONIC_HTAB_SIZE 1024
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
80
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 static struct queue_elem *define_attr_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 static struct queue_elem **define_attr_tail = &define_attr_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 static struct queue_elem *define_pred_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 static struct queue_elem **define_pred_tail = &define_pred_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 static struct queue_elem *define_insn_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 static struct queue_elem **define_insn_tail = &define_insn_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 static struct queue_elem *define_cond_exec_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
111
kono
parents: 67
diff changeset
89 static struct queue_elem *define_subst_queue;
kono
parents: 67
diff changeset
90 static struct queue_elem **define_subst_tail = &define_subst_queue;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 static struct queue_elem *other_queue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 static struct queue_elem **other_tail = &other_queue;
111
kono
parents: 67
diff changeset
93 static struct queue_elem *define_subst_attr_queue;
kono
parents: 67
diff changeset
94 static struct queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
kono
parents: 67
diff changeset
95
kono
parents: 67
diff changeset
96 /* Mapping from DEFINE_* rtxes to their location in the source file. */
kono
parents: 67
diff changeset
97 static hash_map <rtx, file_location> *rtx_locs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 static void remove_constraints (rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 static int is_predicable (struct queue_elem *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 static void identify_predicable_attribute (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 static int n_alternatives (const char *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 static void collect_insn_data (rtx, int *, int *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 static const char *alter_test_for_insn (struct queue_elem *,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 struct queue_elem *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 static char *shift_output_template (char *, const char *, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 static const char *alter_output_for_insn (struct queue_elem *,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 struct queue_elem *,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 int, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 static void process_one_cond_exec (struct queue_elem *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 static void process_define_cond_exec (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 static void init_predicate_table (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 static void record_insn_name (int, const char *);
111
kono
parents: 67
diff changeset
115
kono
parents: 67
diff changeset
116 static bool has_subst_attribute (struct queue_elem *, struct queue_elem *);
kono
parents: 67
diff changeset
117 static const char * alter_output_for_subst_insn (rtx, int);
kono
parents: 67
diff changeset
118 static void alter_attrs_for_subst_insn (struct queue_elem *, int);
kono
parents: 67
diff changeset
119 static void process_substs_on_one_elem (struct queue_elem *,
kono
parents: 67
diff changeset
120 struct queue_elem *);
kono
parents: 67
diff changeset
121 static rtx subst_dup (rtx, int, int);
kono
parents: 67
diff changeset
122 static void process_define_subst (void);
kono
parents: 67
diff changeset
123
kono
parents: 67
diff changeset
124 static const char * duplicate_alternatives (const char *, int);
kono
parents: 67
diff changeset
125 static const char * duplicate_each_alternative (const char * str, int n_dup);
kono
parents: 67
diff changeset
126
kono
parents: 67
diff changeset
127 typedef const char * (*constraints_handler_t) (const char *, int);
kono
parents: 67
diff changeset
128 static rtx alter_constraints (rtx, int, constraints_handler_t);
kono
parents: 67
diff changeset
129 static rtx adjust_operands_numbers (rtx);
kono
parents: 67
diff changeset
130 static rtx replace_duplicating_operands_in_pattern (rtx);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 the gensupport programs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 rtx
111
kono
parents: 67
diff changeset
136 gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 HOST_WIDE_INT arg)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 rtx rt = rtx_alloc (CONST_INT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 XWINT (rt, 0) = arg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 return rt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 }
111
kono
parents: 67
diff changeset
144
kono
parents: 67
diff changeset
145 /* Return the rtx pattern specified by the list of rtxes in a
kono
parents: 67
diff changeset
146 define_insn or define_split. */
kono
parents: 67
diff changeset
147
kono
parents: 67
diff changeset
148 rtx
kono
parents: 67
diff changeset
149 add_implicit_parallel (rtvec vec)
kono
parents: 67
diff changeset
150 {
kono
parents: 67
diff changeset
151 if (GET_NUM_ELEM (vec) == 1)
kono
parents: 67
diff changeset
152 return RTVEC_ELT (vec, 0);
kono
parents: 67
diff changeset
153 else
kono
parents: 67
diff changeset
154 {
kono
parents: 67
diff changeset
155 rtx pattern = rtx_alloc (PARALLEL);
kono
parents: 67
diff changeset
156 XVEC (pattern, 0) = vec;
kono
parents: 67
diff changeset
157 return pattern;
kono
parents: 67
diff changeset
158 }
kono
parents: 67
diff changeset
159 }
kono
parents: 67
diff changeset
160
kono
parents: 67
diff changeset
161 /* Predicate handling.
kono
parents: 67
diff changeset
162
kono
parents: 67
diff changeset
163 We construct from the machine description a table mapping each
kono
parents: 67
diff changeset
164 predicate to a list of the rtl codes it can possibly match. The
kono
parents: 67
diff changeset
165 function 'maybe_both_true' uses it to deduce that there are no
kono
parents: 67
diff changeset
166 expressions that can be matches by certain pairs of tree nodes.
kono
parents: 67
diff changeset
167 Also, if a predicate can match only one code, we can hardwire that
kono
parents: 67
diff changeset
168 code into the node testing the predicate.
kono
parents: 67
diff changeset
169
kono
parents: 67
diff changeset
170 Some predicates are flagged as special. validate_pattern will not
kono
parents: 67
diff changeset
171 warn about modeless match_operand expressions if they have a
kono
parents: 67
diff changeset
172 special predicate. Predicates that allow only constants are also
kono
parents: 67
diff changeset
173 treated as special, for this purpose.
kono
parents: 67
diff changeset
174
kono
parents: 67
diff changeset
175 validate_pattern will warn about predicates that allow non-lvalues
kono
parents: 67
diff changeset
176 when they appear in destination operands.
kono
parents: 67
diff changeset
177
kono
parents: 67
diff changeset
178 Calculating the set of rtx codes that can possibly be accepted by a
kono
parents: 67
diff changeset
179 predicate expression EXP requires a three-state logic: any given
kono
parents: 67
diff changeset
180 subexpression may definitively accept a code C (Y), definitively
kono
parents: 67
diff changeset
181 reject a code C (N), or may have an indeterminate effect (I). N
kono
parents: 67
diff changeset
182 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
kono
parents: 67
diff changeset
183 truth tables.
kono
parents: 67
diff changeset
184
kono
parents: 67
diff changeset
185 a b a&b a|b
kono
parents: 67
diff changeset
186 Y Y Y Y
kono
parents: 67
diff changeset
187 N Y N Y
kono
parents: 67
diff changeset
188 N N N N
kono
parents: 67
diff changeset
189 I Y I Y
kono
parents: 67
diff changeset
190 I N N I
kono
parents: 67
diff changeset
191 I I I I
kono
parents: 67
diff changeset
192
kono
parents: 67
diff changeset
193 We represent Y with 1, N with 0, I with 2. If any code is left in
kono
parents: 67
diff changeset
194 an I state by the complete expression, we must assume that that
kono
parents: 67
diff changeset
195 code can be accepted. */
kono
parents: 67
diff changeset
196
kono
parents: 67
diff changeset
197 #define N 0
kono
parents: 67
diff changeset
198 #define Y 1
kono
parents: 67
diff changeset
199 #define I 2
kono
parents: 67
diff changeset
200
kono
parents: 67
diff changeset
201 #define TRISTATE_AND(a,b) \
kono
parents: 67
diff changeset
202 ((a) == I ? ((b) == N ? N : I) : \
kono
parents: 67
diff changeset
203 (b) == I ? ((a) == N ? N : I) : \
kono
parents: 67
diff changeset
204 (a) && (b))
kono
parents: 67
diff changeset
205
kono
parents: 67
diff changeset
206 #define TRISTATE_OR(a,b) \
kono
parents: 67
diff changeset
207 ((a) == I ? ((b) == Y ? Y : I) : \
kono
parents: 67
diff changeset
208 (b) == I ? ((a) == Y ? Y : I) : \
kono
parents: 67
diff changeset
209 (a) || (b))
kono
parents: 67
diff changeset
210
kono
parents: 67
diff changeset
211 #define TRISTATE_NOT(a) \
kono
parents: 67
diff changeset
212 ((a) == I ? I : !(a))
kono
parents: 67
diff changeset
213
kono
parents: 67
diff changeset
214 /* 0 means no warning about that code yet, 1 means warned. */
kono
parents: 67
diff changeset
215 static char did_you_mean_codes[NUM_RTX_CODE];
kono
parents: 67
diff changeset
216
kono
parents: 67
diff changeset
217 /* Recursively calculate the set of rtx codes accepted by the
kono
parents: 67
diff changeset
218 predicate expression EXP, writing the result to CODES. LOC is
kono
parents: 67
diff changeset
219 the .md file location of the directive containing EXP. */
kono
parents: 67
diff changeset
220
kono
parents: 67
diff changeset
221 void
kono
parents: 67
diff changeset
222 compute_test_codes (rtx exp, file_location loc, char *codes)
kono
parents: 67
diff changeset
223 {
kono
parents: 67
diff changeset
224 char op0_codes[NUM_RTX_CODE];
kono
parents: 67
diff changeset
225 char op1_codes[NUM_RTX_CODE];
kono
parents: 67
diff changeset
226 char op2_codes[NUM_RTX_CODE];
kono
parents: 67
diff changeset
227 int i;
kono
parents: 67
diff changeset
228
kono
parents: 67
diff changeset
229 switch (GET_CODE (exp))
kono
parents: 67
diff changeset
230 {
kono
parents: 67
diff changeset
231 case AND:
kono
parents: 67
diff changeset
232 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
kono
parents: 67
diff changeset
233 compute_test_codes (XEXP (exp, 1), loc, op1_codes);
kono
parents: 67
diff changeset
234 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
235 codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]);
kono
parents: 67
diff changeset
236 break;
kono
parents: 67
diff changeset
237
kono
parents: 67
diff changeset
238 case IOR:
kono
parents: 67
diff changeset
239 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
kono
parents: 67
diff changeset
240 compute_test_codes (XEXP (exp, 1), loc, op1_codes);
kono
parents: 67
diff changeset
241 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
242 codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]);
kono
parents: 67
diff changeset
243 break;
kono
parents: 67
diff changeset
244 case NOT:
kono
parents: 67
diff changeset
245 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
kono
parents: 67
diff changeset
246 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
247 codes[i] = TRISTATE_NOT (op0_codes[i]);
kono
parents: 67
diff changeset
248 break;
kono
parents: 67
diff changeset
249
kono
parents: 67
diff changeset
250 case IF_THEN_ELSE:
kono
parents: 67
diff changeset
251 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
kono
parents: 67
diff changeset
252 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
kono
parents: 67
diff changeset
253 compute_test_codes (XEXP (exp, 1), loc, op1_codes);
kono
parents: 67
diff changeset
254 compute_test_codes (XEXP (exp, 2), loc, op2_codes);
kono
parents: 67
diff changeset
255 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
256 codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]),
kono
parents: 67
diff changeset
257 TRISTATE_AND (TRISTATE_NOT (op0_codes[i]),
kono
parents: 67
diff changeset
258 op2_codes[i]));
kono
parents: 67
diff changeset
259 break;
kono
parents: 67
diff changeset
260
kono
parents: 67
diff changeset
261 case MATCH_CODE:
kono
parents: 67
diff changeset
262 /* MATCH_CODE allows a specified list of codes. However, if it
kono
parents: 67
diff changeset
263 does not apply to the top level of the expression, it does not
kono
parents: 67
diff changeset
264 constrain the set of codes for the top level. */
kono
parents: 67
diff changeset
265 if (XSTR (exp, 1)[0] != '\0')
kono
parents: 67
diff changeset
266 {
kono
parents: 67
diff changeset
267 memset (codes, Y, NUM_RTX_CODE);
kono
parents: 67
diff changeset
268 break;
kono
parents: 67
diff changeset
269 }
kono
parents: 67
diff changeset
270
kono
parents: 67
diff changeset
271 memset (codes, N, NUM_RTX_CODE);
kono
parents: 67
diff changeset
272 {
kono
parents: 67
diff changeset
273 const char *next_code = XSTR (exp, 0);
kono
parents: 67
diff changeset
274 const char *code;
kono
parents: 67
diff changeset
275
kono
parents: 67
diff changeset
276 if (*next_code == '\0')
kono
parents: 67
diff changeset
277 {
kono
parents: 67
diff changeset
278 error_at (loc, "empty match_code expression");
kono
parents: 67
diff changeset
279 break;
kono
parents: 67
diff changeset
280 }
kono
parents: 67
diff changeset
281
kono
parents: 67
diff changeset
282 while ((code = scan_comma_elt (&next_code)) != 0)
kono
parents: 67
diff changeset
283 {
kono
parents: 67
diff changeset
284 size_t n = next_code - code;
kono
parents: 67
diff changeset
285 int found_it = 0;
kono
parents: 67
diff changeset
286
kono
parents: 67
diff changeset
287 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
288 if (!strncmp (code, GET_RTX_NAME (i), n)
kono
parents: 67
diff changeset
289 && GET_RTX_NAME (i)[n] == '\0')
kono
parents: 67
diff changeset
290 {
kono
parents: 67
diff changeset
291 codes[i] = Y;
kono
parents: 67
diff changeset
292 found_it = 1;
kono
parents: 67
diff changeset
293 break;
kono
parents: 67
diff changeset
294 }
kono
parents: 67
diff changeset
295 if (!found_it)
kono
parents: 67
diff changeset
296 {
kono
parents: 67
diff changeset
297 error_at (loc, "match_code \"%.*s\" matches nothing",
kono
parents: 67
diff changeset
298 (int) n, code);
kono
parents: 67
diff changeset
299 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
300 if (!strncasecmp (code, GET_RTX_NAME (i), n)
kono
parents: 67
diff changeset
301 && GET_RTX_NAME (i)[n] == '\0'
kono
parents: 67
diff changeset
302 && !did_you_mean_codes[i])
kono
parents: 67
diff changeset
303 {
kono
parents: 67
diff changeset
304 did_you_mean_codes[i] = 1;
kono
parents: 67
diff changeset
305 message_at (loc, "(did you mean \"%s\"?)",
kono
parents: 67
diff changeset
306 GET_RTX_NAME (i));
kono
parents: 67
diff changeset
307 }
kono
parents: 67
diff changeset
308 }
kono
parents: 67
diff changeset
309 }
kono
parents: 67
diff changeset
310 }
kono
parents: 67
diff changeset
311 break;
kono
parents: 67
diff changeset
312
kono
parents: 67
diff changeset
313 case MATCH_OPERAND:
kono
parents: 67
diff changeset
314 /* MATCH_OPERAND disallows the set of codes that the named predicate
kono
parents: 67
diff changeset
315 disallows, and is indeterminate for the codes that it does allow. */
kono
parents: 67
diff changeset
316 {
kono
parents: 67
diff changeset
317 struct pred_data *p = lookup_predicate (XSTR (exp, 1));
kono
parents: 67
diff changeset
318 if (!p)
kono
parents: 67
diff changeset
319 {
kono
parents: 67
diff changeset
320 error_at (loc, "reference to unknown predicate '%s'",
kono
parents: 67
diff changeset
321 XSTR (exp, 1));
kono
parents: 67
diff changeset
322 break;
kono
parents: 67
diff changeset
323 }
kono
parents: 67
diff changeset
324 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
325 codes[i] = p->codes[i] ? I : N;
kono
parents: 67
diff changeset
326 }
kono
parents: 67
diff changeset
327 break;
kono
parents: 67
diff changeset
328
kono
parents: 67
diff changeset
329
kono
parents: 67
diff changeset
330 case MATCH_TEST:
kono
parents: 67
diff changeset
331 /* (match_test WHATEVER) is completely indeterminate. */
kono
parents: 67
diff changeset
332 memset (codes, I, NUM_RTX_CODE);
kono
parents: 67
diff changeset
333 break;
kono
parents: 67
diff changeset
334
kono
parents: 67
diff changeset
335 default:
kono
parents: 67
diff changeset
336 error_at (loc, "'%s' cannot be used in predicates or constraints",
kono
parents: 67
diff changeset
337 GET_RTX_NAME (GET_CODE (exp)));
kono
parents: 67
diff changeset
338 memset (codes, I, NUM_RTX_CODE);
kono
parents: 67
diff changeset
339 break;
kono
parents: 67
diff changeset
340 }
kono
parents: 67
diff changeset
341 }
kono
parents: 67
diff changeset
342
kono
parents: 67
diff changeset
343 #undef TRISTATE_OR
kono
parents: 67
diff changeset
344 #undef TRISTATE_AND
kono
parents: 67
diff changeset
345 #undef TRISTATE_NOT
kono
parents: 67
diff changeset
346
kono
parents: 67
diff changeset
347 /* Return true if NAME is a valid predicate name. */
kono
parents: 67
diff changeset
348
kono
parents: 67
diff changeset
349 static bool
kono
parents: 67
diff changeset
350 valid_predicate_name_p (const char *name)
kono
parents: 67
diff changeset
351 {
kono
parents: 67
diff changeset
352 const char *p;
kono
parents: 67
diff changeset
353
kono
parents: 67
diff changeset
354 if (!ISALPHA (name[0]) && name[0] != '_')
kono
parents: 67
diff changeset
355 return false;
kono
parents: 67
diff changeset
356 for (p = name + 1; *p; p++)
kono
parents: 67
diff changeset
357 if (!ISALNUM (*p) && *p != '_')
kono
parents: 67
diff changeset
358 return false;
kono
parents: 67
diff changeset
359 return true;
kono
parents: 67
diff changeset
360 }
kono
parents: 67
diff changeset
361
kono
parents: 67
diff changeset
362 /* Process define_predicate directive DESC, which appears at location LOC.
kono
parents: 67
diff changeset
363 Compute the set of codes that can be matched, and record this as a known
kono
parents: 67
diff changeset
364 predicate. */
kono
parents: 67
diff changeset
365
kono
parents: 67
diff changeset
366 static void
kono
parents: 67
diff changeset
367 process_define_predicate (rtx desc, file_location loc)
kono
parents: 67
diff changeset
368 {
kono
parents: 67
diff changeset
369 struct pred_data *pred;
kono
parents: 67
diff changeset
370 char codes[NUM_RTX_CODE];
kono
parents: 67
diff changeset
371 int i;
kono
parents: 67
diff changeset
372
kono
parents: 67
diff changeset
373 if (!valid_predicate_name_p (XSTR (desc, 0)))
kono
parents: 67
diff changeset
374 {
kono
parents: 67
diff changeset
375 error_at (loc, "%s: predicate name must be a valid C function name",
kono
parents: 67
diff changeset
376 XSTR (desc, 0));
kono
parents: 67
diff changeset
377 return;
kono
parents: 67
diff changeset
378 }
kono
parents: 67
diff changeset
379
kono
parents: 67
diff changeset
380 pred = XCNEW (struct pred_data);
kono
parents: 67
diff changeset
381 pred->name = XSTR (desc, 0);
kono
parents: 67
diff changeset
382 pred->exp = XEXP (desc, 1);
kono
parents: 67
diff changeset
383 pred->c_block = XSTR (desc, 2);
kono
parents: 67
diff changeset
384 if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE)
kono
parents: 67
diff changeset
385 pred->special = true;
kono
parents: 67
diff changeset
386
kono
parents: 67
diff changeset
387 compute_test_codes (XEXP (desc, 1), loc, codes);
kono
parents: 67
diff changeset
388
kono
parents: 67
diff changeset
389 for (i = 0; i < NUM_RTX_CODE; i++)
kono
parents: 67
diff changeset
390 if (codes[i] != N)
kono
parents: 67
diff changeset
391 add_predicate_code (pred, (enum rtx_code) i);
kono
parents: 67
diff changeset
392
kono
parents: 67
diff changeset
393 add_predicate (pred);
kono
parents: 67
diff changeset
394 }
kono
parents: 67
diff changeset
395 #undef I
kono
parents: 67
diff changeset
396 #undef N
kono
parents: 67
diff changeset
397 #undef Y
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 element. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 static struct queue_elem *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
111
kono
parents: 67
diff changeset
404 file_location loc)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 {
111
kono
parents: 67
diff changeset
406 struct queue_elem *e = XNEW (struct queue_elem);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 e->data = pattern;
111
kono
parents: 67
diff changeset
408 e->loc = loc;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 e->next = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 e->split = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 **list_tail = e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 *list_tail = &e->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 return e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415
111
kono
parents: 67
diff changeset
416 /* Remove element ELEM from QUEUE. */
kono
parents: 67
diff changeset
417 static void
kono
parents: 67
diff changeset
418 remove_from_queue (struct queue_elem *elem, struct queue_elem **queue)
kono
parents: 67
diff changeset
419 {
kono
parents: 67
diff changeset
420 struct queue_elem *prev, *e;
kono
parents: 67
diff changeset
421 prev = NULL;
kono
parents: 67
diff changeset
422 for (e = *queue; e ; e = e->next)
kono
parents: 67
diff changeset
423 {
kono
parents: 67
diff changeset
424 if (e == elem)
kono
parents: 67
diff changeset
425 break;
kono
parents: 67
diff changeset
426 prev = e;
kono
parents: 67
diff changeset
427 }
kono
parents: 67
diff changeset
428 if (e == NULL)
kono
parents: 67
diff changeset
429 return;
kono
parents: 67
diff changeset
430
kono
parents: 67
diff changeset
431 if (prev)
kono
parents: 67
diff changeset
432 prev->next = elem->next;
kono
parents: 67
diff changeset
433 else
kono
parents: 67
diff changeset
434 *queue = elem->next;
kono
parents: 67
diff changeset
435 }
kono
parents: 67
diff changeset
436
kono
parents: 67
diff changeset
437 /* Build a define_attr for an binary attribute with name NAME and
kono
parents: 67
diff changeset
438 possible values "yes" and "no", and queue it. */
kono
parents: 67
diff changeset
439 static void
kono
parents: 67
diff changeset
440 add_define_attr (const char *name)
kono
parents: 67
diff changeset
441 {
kono
parents: 67
diff changeset
442 struct queue_elem *e = XNEW (struct queue_elem);
kono
parents: 67
diff changeset
443 rtx t1 = rtx_alloc (DEFINE_ATTR);
kono
parents: 67
diff changeset
444 XSTR (t1, 0) = name;
kono
parents: 67
diff changeset
445 XSTR (t1, 1) = "no,yes";
kono
parents: 67
diff changeset
446 XEXP (t1, 2) = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
447 XSTR (XEXP (t1, 2), 0) = "yes";
kono
parents: 67
diff changeset
448 e->data = t1;
kono
parents: 67
diff changeset
449 e->loc = file_location ("built-in", -1, -1);
kono
parents: 67
diff changeset
450 e->next = define_attr_queue;
kono
parents: 67
diff changeset
451 define_attr_queue = e;
kono
parents: 67
diff changeset
452
kono
parents: 67
diff changeset
453 }
kono
parents: 67
diff changeset
454
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 /* Recursively remove constraints from an rtx. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 remove_constraints (rtx part)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 int i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 const char *format_ptr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 if (part == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 if (GET_CODE (part) == MATCH_OPERAND)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 XSTR (part, 2) = "";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 else if (GET_CODE (part) == MATCH_SCRATCH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 XSTR (part, 1) = "";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 switch (*format_ptr++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 case 'e':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 case 'u':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 remove_constraints (XEXP (part, i));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 case 'E':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 if (XVEC (part, i) != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 for (j = 0; j < XVECLEN (part, i); j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 remove_constraints (XVECEXP (part, i, j));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 /* Process a top level rtx in some way, queuing as appropriate. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 static void
111
kono
parents: 67
diff changeset
491 process_rtx (rtx desc, file_location loc)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 switch (GET_CODE (desc))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 case DEFINE_INSN:
111
kono
parents: 67
diff changeset
496 queue_pattern (desc, &define_insn_tail, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 case DEFINE_COND_EXEC:
111
kono
parents: 67
diff changeset
500 queue_pattern (desc, &define_cond_exec_tail, loc);
kono
parents: 67
diff changeset
501 break;
kono
parents: 67
diff changeset
502
kono
parents: 67
diff changeset
503 case DEFINE_SUBST:
kono
parents: 67
diff changeset
504 queue_pattern (desc, &define_subst_tail, loc);
kono
parents: 67
diff changeset
505 break;
kono
parents: 67
diff changeset
506
kono
parents: 67
diff changeset
507 case DEFINE_SUBST_ATTR:
kono
parents: 67
diff changeset
508 queue_pattern (desc, &define_subst_attr_tail, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 case DEFINE_ATTR:
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
512 case DEFINE_ENUM_ATTR:
111
kono
parents: 67
diff changeset
513 queue_pattern (desc, &define_attr_tail, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 case DEFINE_PREDICATE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 case DEFINE_SPECIAL_PREDICATE:
111
kono
parents: 67
diff changeset
518 process_define_predicate (desc, loc);
kono
parents: 67
diff changeset
519 /* Fall through. */
kono
parents: 67
diff changeset
520
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 case DEFINE_CONSTRAINT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 case DEFINE_REGISTER_CONSTRAINT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 case DEFINE_MEMORY_CONSTRAINT:
111
kono
parents: 67
diff changeset
524 case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 case DEFINE_ADDRESS_CONSTRAINT:
111
kono
parents: 67
diff changeset
526 queue_pattern (desc, &define_pred_tail, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 case DEFINE_INSN_AND_SPLIT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
531 const char *split_cond;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532 rtx split;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 rtvec attr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 struct queue_elem *insn_elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 struct queue_elem *split_elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 /* Create a split with values from the insn_and_split. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 split = rtx_alloc (DEFINE_SPLIT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 i = XVECLEN (desc, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 XVEC (split, 0) = rtvec_alloc (i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 while (--i >= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 remove_constraints (XVECEXP (split, 0, i));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 /* If the split condition starts with "&&", append it to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 insn condition to create the new split condition. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 split_cond = XSTR (desc, 4);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 if (split_cond[0] == '&' && split_cond[1] == '&')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 {
111
kono
parents: 67
diff changeset
554 rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
kono
parents: 67
diff changeset
555 split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
kono
parents: 67
diff changeset
556 split_cond + 2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 XSTR (split, 1) = split_cond;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 XVEC (split, 2) = XVEC (desc, 5);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 XSTR (split, 3) = XSTR (desc, 6);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 /* Fix up the DEFINE_INSN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 attr = XVEC (desc, 7);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 PUT_CODE (desc, DEFINE_INSN);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 XVEC (desc, 4) = attr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 /* Queue them. */
111
kono
parents: 67
diff changeset
568 insn_elem = queue_pattern (desc, &define_insn_tail, loc);
kono
parents: 67
diff changeset
569 split_elem = queue_pattern (split, &other_tail, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 insn_elem->split = split_elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 default:
111
kono
parents: 67
diff changeset
575 queue_pattern (desc, &other_tail, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 /* Return true if attribute PREDICABLE is true for ELEM, which holds
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 a DEFINE_INSN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 is_predicable (struct queue_elem *elem)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 rtvec vec = XVEC (elem->data, 4);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 const char *value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 if (! vec)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 return predicable_default;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 rtx sub = RTVEC_ELT (vec, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 switch (GET_CODE (sub))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 case SET_ATTR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 if (strcmp (XSTR (sub, 0), "predicable") == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 value = XSTR (sub, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 goto found;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 case SET_ATTR_ALTERNATIVE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 if (strcmp (XSTR (sub, 0), "predicable") == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 {
111
kono
parents: 67
diff changeset
609 error_at (elem->loc, "multiple alternatives for `predicable'");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 case SET:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 if (GET_CODE (SET_DEST (sub)) != ATTR
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 sub = SET_SRC (sub);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 if (GET_CODE (sub) == CONST_STRING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 value = XSTR (sub, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 goto found;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
625 /* ??? It would be possible to handle this if we really tried.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
626 It's not easy though, and I'm not going to bother until it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 really proves necessary. */
111
kono
parents: 67
diff changeset
628 error_at (elem->loc, "non-constant value for `predicable'");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
632 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 return predicable_default;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 found:
111
kono
parents: 67
diff changeset
639 /* Find out which value we're looking at. Multiple alternatives means at
kono
parents: 67
diff changeset
640 least one is predicable. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 if (strchr (value, ',') != NULL)
111
kono
parents: 67
diff changeset
642 return 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 if (strcmp (value, predicable_true) == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 if (strcmp (value, predicable_false) == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
646 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647
111
kono
parents: 67
diff changeset
648 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651
111
kono
parents: 67
diff changeset
652 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
kono
parents: 67
diff changeset
653 static void
kono
parents: 67
diff changeset
654 change_subst_attribute (struct queue_elem *elem,
kono
parents: 67
diff changeset
655 struct queue_elem *subst_elem,
kono
parents: 67
diff changeset
656 const char *new_value)
kono
parents: 67
diff changeset
657 {
kono
parents: 67
diff changeset
658 rtvec attrs_vec = XVEC (elem->data, 4);
kono
parents: 67
diff changeset
659 const char *subst_name = XSTR (subst_elem->data, 0);
kono
parents: 67
diff changeset
660 int i;
kono
parents: 67
diff changeset
661
kono
parents: 67
diff changeset
662 if (! attrs_vec)
kono
parents: 67
diff changeset
663 return;
kono
parents: 67
diff changeset
664
kono
parents: 67
diff changeset
665 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
kono
parents: 67
diff changeset
666 {
kono
parents: 67
diff changeset
667 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
kono
parents: 67
diff changeset
668 if (GET_CODE (cur_attr) != SET_ATTR)
kono
parents: 67
diff changeset
669 continue;
kono
parents: 67
diff changeset
670 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
kono
parents: 67
diff changeset
671 {
kono
parents: 67
diff changeset
672 XSTR (cur_attr, 1) = new_value;
kono
parents: 67
diff changeset
673 return;
kono
parents: 67
diff changeset
674 }
kono
parents: 67
diff changeset
675 }
kono
parents: 67
diff changeset
676 }
kono
parents: 67
diff changeset
677
kono
parents: 67
diff changeset
678 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
kono
parents: 67
diff changeset
679 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
kono
parents: 67
diff changeset
680 DEFINE_SUBST isn't applied to patterns without such attribute. In other
kono
parents: 67
diff changeset
681 words, we suppose the default value of the attribute to be 'no' since it is
kono
parents: 67
diff changeset
682 always generated automatically in read-rtl.c. */
kono
parents: 67
diff changeset
683 static bool
kono
parents: 67
diff changeset
684 has_subst_attribute (struct queue_elem *elem, struct queue_elem *subst_elem)
kono
parents: 67
diff changeset
685 {
kono
parents: 67
diff changeset
686 rtvec attrs_vec = XVEC (elem->data, 4);
kono
parents: 67
diff changeset
687 const char *value, *subst_name = XSTR (subst_elem->data, 0);
kono
parents: 67
diff changeset
688 int i;
kono
parents: 67
diff changeset
689
kono
parents: 67
diff changeset
690 if (! attrs_vec)
kono
parents: 67
diff changeset
691 return false;
kono
parents: 67
diff changeset
692
kono
parents: 67
diff changeset
693 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
kono
parents: 67
diff changeset
694 {
kono
parents: 67
diff changeset
695 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
kono
parents: 67
diff changeset
696 switch (GET_CODE (cur_attr))
kono
parents: 67
diff changeset
697 {
kono
parents: 67
diff changeset
698 case SET_ATTR:
kono
parents: 67
diff changeset
699 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
kono
parents: 67
diff changeset
700 {
kono
parents: 67
diff changeset
701 value = XSTR (cur_attr, 1);
kono
parents: 67
diff changeset
702 goto found;
kono
parents: 67
diff changeset
703 }
kono
parents: 67
diff changeset
704 break;
kono
parents: 67
diff changeset
705
kono
parents: 67
diff changeset
706 case SET:
kono
parents: 67
diff changeset
707 if (GET_CODE (SET_DEST (cur_attr)) != ATTR
kono
parents: 67
diff changeset
708 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
kono
parents: 67
diff changeset
709 break;
kono
parents: 67
diff changeset
710 cur_attr = SET_SRC (cur_attr);
kono
parents: 67
diff changeset
711 if (GET_CODE (cur_attr) == CONST_STRING)
kono
parents: 67
diff changeset
712 {
kono
parents: 67
diff changeset
713 value = XSTR (cur_attr, 0);
kono
parents: 67
diff changeset
714 goto found;
kono
parents: 67
diff changeset
715 }
kono
parents: 67
diff changeset
716
kono
parents: 67
diff changeset
717 /* Only (set_attr "subst" "yes/no") and
kono
parents: 67
diff changeset
718 (set (attr "subst" (const_string "yes/no")))
kono
parents: 67
diff changeset
719 are currently allowed. */
kono
parents: 67
diff changeset
720 error_at (elem->loc, "unsupported value for `%s'", subst_name);
kono
parents: 67
diff changeset
721 return false;
kono
parents: 67
diff changeset
722
kono
parents: 67
diff changeset
723 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
724 error_at (elem->loc,
kono
parents: 67
diff changeset
725 "%s: `set_attr_alternative' is unsupported by "
kono
parents: 67
diff changeset
726 "`define_subst'", XSTR (elem->data, 0));
kono
parents: 67
diff changeset
727 return false;
kono
parents: 67
diff changeset
728
kono
parents: 67
diff changeset
729
kono
parents: 67
diff changeset
730 default:
kono
parents: 67
diff changeset
731 gcc_unreachable ();
kono
parents: 67
diff changeset
732 }
kono
parents: 67
diff changeset
733 }
kono
parents: 67
diff changeset
734
kono
parents: 67
diff changeset
735 return false;
kono
parents: 67
diff changeset
736
kono
parents: 67
diff changeset
737 found:
kono
parents: 67
diff changeset
738 if (strcmp (value, subst_true) == 0)
kono
parents: 67
diff changeset
739 return true;
kono
parents: 67
diff changeset
740 if (strcmp (value, subst_false) == 0)
kono
parents: 67
diff changeset
741 return false;
kono
parents: 67
diff changeset
742
kono
parents: 67
diff changeset
743 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
kono
parents: 67
diff changeset
744 value, subst_name);
kono
parents: 67
diff changeset
745 return false;
kono
parents: 67
diff changeset
746 }
kono
parents: 67
diff changeset
747
kono
parents: 67
diff changeset
748 /* Compare RTL-template of original define_insn X to input RTL-template of
kono
parents: 67
diff changeset
749 define_subst PT. Return 1 if the templates match, 0 otherwise.
kono
parents: 67
diff changeset
750 During the comparison, the routine also fills global_array OPERAND_DATA. */
kono
parents: 67
diff changeset
751 static bool
kono
parents: 67
diff changeset
752 subst_pattern_match (rtx x, rtx pt, file_location loc)
kono
parents: 67
diff changeset
753 {
kono
parents: 67
diff changeset
754 RTX_CODE code, code_pt;
kono
parents: 67
diff changeset
755 int i, j, len;
kono
parents: 67
diff changeset
756 const char *fmt, *pred_name;
kono
parents: 67
diff changeset
757
kono
parents: 67
diff changeset
758 code = GET_CODE (x);
kono
parents: 67
diff changeset
759 code_pt = GET_CODE (pt);
kono
parents: 67
diff changeset
760
kono
parents: 67
diff changeset
761 if (code_pt == MATCH_OPERAND)
kono
parents: 67
diff changeset
762 {
kono
parents: 67
diff changeset
763 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
kono
parents: 67
diff changeset
764 always accept them. */
kono
parents: 67
diff changeset
765 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
kono
parents: 67
diff changeset
766 && (code != MATCH_DUP && code != MATCH_OP_DUP))
kono
parents: 67
diff changeset
767 return false; /* Modes don't match. */
kono
parents: 67
diff changeset
768
kono
parents: 67
diff changeset
769 if (code == MATCH_OPERAND)
kono
parents: 67
diff changeset
770 {
kono
parents: 67
diff changeset
771 pred_name = XSTR (pt, 1);
kono
parents: 67
diff changeset
772 if (pred_name[0] != 0)
kono
parents: 67
diff changeset
773 {
kono
parents: 67
diff changeset
774 const struct pred_data *pred_pt = lookup_predicate (pred_name);
kono
parents: 67
diff changeset
775 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
kono
parents: 67
diff changeset
776 return false; /* Predicates don't match. */
kono
parents: 67
diff changeset
777 }
kono
parents: 67
diff changeset
778 }
kono
parents: 67
diff changeset
779
kono
parents: 67
diff changeset
780 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
kono
parents: 67
diff changeset
781 operand_data[XINT (pt, 0)] = x;
kono
parents: 67
diff changeset
782 return true;
kono
parents: 67
diff changeset
783 }
kono
parents: 67
diff changeset
784
kono
parents: 67
diff changeset
785 if (code_pt == MATCH_OPERATOR)
kono
parents: 67
diff changeset
786 {
kono
parents: 67
diff changeset
787 int x_vecexp_pos = -1;
kono
parents: 67
diff changeset
788
kono
parents: 67
diff changeset
789 /* Compare modes. */
kono
parents: 67
diff changeset
790 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
kono
parents: 67
diff changeset
791 return false;
kono
parents: 67
diff changeset
792
kono
parents: 67
diff changeset
793 /* In case X is also match_operator, compare predicates. */
kono
parents: 67
diff changeset
794 if (code == MATCH_OPERATOR)
kono
parents: 67
diff changeset
795 {
kono
parents: 67
diff changeset
796 pred_name = XSTR (pt, 1);
kono
parents: 67
diff changeset
797 if (pred_name[0] != 0)
kono
parents: 67
diff changeset
798 {
kono
parents: 67
diff changeset
799 const struct pred_data *pred_pt = lookup_predicate (pred_name);
kono
parents: 67
diff changeset
800 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
kono
parents: 67
diff changeset
801 return false;
kono
parents: 67
diff changeset
802 }
kono
parents: 67
diff changeset
803 }
kono
parents: 67
diff changeset
804
kono
parents: 67
diff changeset
805 /* Compare operands.
kono
parents: 67
diff changeset
806 MATCH_OPERATOR in input template could match in original template
kono
parents: 67
diff changeset
807 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
kono
parents: 67
diff changeset
808 In the first case operands are at (XVECEXP (x, 2, j)), in the second
kono
parents: 67
diff changeset
809 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
kono
parents: 67
diff changeset
810 X_VECEXP_POS variable shows, where to look for these operands. */
kono
parents: 67
diff changeset
811 if (code == UNSPEC
kono
parents: 67
diff changeset
812 || code == UNSPEC_VOLATILE)
kono
parents: 67
diff changeset
813 x_vecexp_pos = 0;
kono
parents: 67
diff changeset
814 else if (code == MATCH_OPERATOR)
kono
parents: 67
diff changeset
815 x_vecexp_pos = 2;
kono
parents: 67
diff changeset
816 else
kono
parents: 67
diff changeset
817 x_vecexp_pos = -1;
kono
parents: 67
diff changeset
818
kono
parents: 67
diff changeset
819 /* MATCH_OPERATOR or UNSPEC case. */
kono
parents: 67
diff changeset
820 if (x_vecexp_pos >= 0)
kono
parents: 67
diff changeset
821 {
kono
parents: 67
diff changeset
822 /* Compare operands number in X and PT. */
kono
parents: 67
diff changeset
823 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
kono
parents: 67
diff changeset
824 return false;
kono
parents: 67
diff changeset
825 for (j = 0; j < XVECLEN (pt, 2); j++)
kono
parents: 67
diff changeset
826 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
kono
parents: 67
diff changeset
827 XVECEXP (pt, 2, j), loc))
kono
parents: 67
diff changeset
828 return false;
kono
parents: 67
diff changeset
829 }
kono
parents: 67
diff changeset
830
kono
parents: 67
diff changeset
831 /* Ordinary operator. */
kono
parents: 67
diff changeset
832 else
kono
parents: 67
diff changeset
833 {
kono
parents: 67
diff changeset
834 /* Compare operands number in X and PT.
kono
parents: 67
diff changeset
835 We count operands differently for X and PT since we compare
kono
parents: 67
diff changeset
836 an operator (with operands directly in RTX) and MATCH_OPERATOR
kono
parents: 67
diff changeset
837 (that has a vector with operands). */
kono
parents: 67
diff changeset
838 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
kono
parents: 67
diff changeset
839 return false;
kono
parents: 67
diff changeset
840 for (j = 0; j < XVECLEN (pt, 2); j++)
kono
parents: 67
diff changeset
841 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
kono
parents: 67
diff changeset
842 return false;
kono
parents: 67
diff changeset
843 }
kono
parents: 67
diff changeset
844
kono
parents: 67
diff changeset
845 /* Store the operand to OPERAND_DATA array. */
kono
parents: 67
diff changeset
846 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
kono
parents: 67
diff changeset
847 operand_data[XINT (pt, 0)] = x;
kono
parents: 67
diff changeset
848 return true;
kono
parents: 67
diff changeset
849 }
kono
parents: 67
diff changeset
850
kono
parents: 67
diff changeset
851 if (code_pt == MATCH_PAR_DUP
kono
parents: 67
diff changeset
852 || code_pt == MATCH_DUP
kono
parents: 67
diff changeset
853 || code_pt == MATCH_OP_DUP
kono
parents: 67
diff changeset
854 || code_pt == MATCH_SCRATCH
kono
parents: 67
diff changeset
855 || code_pt == MATCH_PARALLEL)
kono
parents: 67
diff changeset
856 {
kono
parents: 67
diff changeset
857 /* Currently interface for these constructions isn't defined -
kono
parents: 67
diff changeset
858 probably they aren't needed in input template of define_subst at all.
kono
parents: 67
diff changeset
859 So, for now their usage in define_subst is forbidden. */
kono
parents: 67
diff changeset
860 error_at (loc, "%s cannot be used in define_subst",
kono
parents: 67
diff changeset
861 GET_RTX_NAME (code_pt));
kono
parents: 67
diff changeset
862 }
kono
parents: 67
diff changeset
863
kono
parents: 67
diff changeset
864 gcc_assert (code != MATCH_PAR_DUP
kono
parents: 67
diff changeset
865 && code_pt != MATCH_DUP
kono
parents: 67
diff changeset
866 && code_pt != MATCH_OP_DUP
kono
parents: 67
diff changeset
867 && code_pt != MATCH_SCRATCH
kono
parents: 67
diff changeset
868 && code_pt != MATCH_PARALLEL
kono
parents: 67
diff changeset
869 && code_pt != MATCH_OPERAND
kono
parents: 67
diff changeset
870 && code_pt != MATCH_OPERATOR);
kono
parents: 67
diff changeset
871 /* If PT is none of the handled above, then we match only expressions with
kono
parents: 67
diff changeset
872 the same code in X. */
kono
parents: 67
diff changeset
873 if (code != code_pt)
kono
parents: 67
diff changeset
874 return false;
kono
parents: 67
diff changeset
875
kono
parents: 67
diff changeset
876 fmt = GET_RTX_FORMAT (code_pt);
kono
parents: 67
diff changeset
877 len = GET_RTX_LENGTH (code_pt);
kono
parents: 67
diff changeset
878
kono
parents: 67
diff changeset
879 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
880 {
kono
parents: 67
diff changeset
881 if (fmt[i] == '0')
kono
parents: 67
diff changeset
882 break;
kono
parents: 67
diff changeset
883
kono
parents: 67
diff changeset
884 switch (fmt[i])
kono
parents: 67
diff changeset
885 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886 case 'r': case 'p': case 'i': case 'w': case 's':
111
kono
parents: 67
diff changeset
887 continue;
kono
parents: 67
diff changeset
888
kono
parents: 67
diff changeset
889 case 'e': case 'u':
kono
parents: 67
diff changeset
890 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
kono
parents: 67
diff changeset
891 return false;
kono
parents: 67
diff changeset
892 break;
kono
parents: 67
diff changeset
893 case 'E':
kono
parents: 67
diff changeset
894 {
kono
parents: 67
diff changeset
895 if (XVECLEN (x, i) != XVECLEN (pt, i))
kono
parents: 67
diff changeset
896 return false;
kono
parents: 67
diff changeset
897 for (j = 0; j < XVECLEN (pt, i); j++)
kono
parents: 67
diff changeset
898 if (!subst_pattern_match (XVECEXP (x, i, j),
kono
parents: 67
diff changeset
899 XVECEXP (pt, i, j), loc))
kono
parents: 67
diff changeset
900 return false;
kono
parents: 67
diff changeset
901 break;
kono
parents: 67
diff changeset
902 }
kono
parents: 67
diff changeset
903 default:
kono
parents: 67
diff changeset
904 gcc_unreachable ();
kono
parents: 67
diff changeset
905 }
kono
parents: 67
diff changeset
906 }
kono
parents: 67
diff changeset
907
kono
parents: 67
diff changeset
908 return true;
kono
parents: 67
diff changeset
909 }
kono
parents: 67
diff changeset
910
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911 /* Examine the attribute "predicable"; discover its boolean values
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 and its default. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 identify_predicable_attribute (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
916 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
917 struct queue_elem *elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918 char *p_true, *p_false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919 const char *value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
921 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
922 for (elem = define_attr_queue; elem ; elem = elem->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
923 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
924 goto found;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
925
111
kono
parents: 67
diff changeset
926 error_at (define_cond_exec_queue->loc,
kono
parents: 67
diff changeset
927 "attribute `predicable' not defined");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 found:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 value = XSTR (elem->data, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 p_false = xstrdup (value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933 p_true = strchr (p_false, ',');
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 if (p_true == NULL || strchr (++p_true, ',') != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 {
111
kono
parents: 67
diff changeset
936 error_at (elem->loc, "attribute `predicable' is not a boolean");
kono
parents: 67
diff changeset
937 free (p_false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
938 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
940 p_true[-1] = '\0';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
941
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
942 predicable_true = p_true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 predicable_false = p_false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
944
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 switch (GET_CODE (XEXP (elem->data, 2)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947 case CONST_STRING:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 value = XSTR (XEXP (elem->data, 2), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951 case CONST:
111
kono
parents: 67
diff changeset
952 error_at (elem->loc, "attribute `predicable' cannot be const");
kono
parents: 67
diff changeset
953 free (p_false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 default:
111
kono
parents: 67
diff changeset
957 error_at (elem->loc,
kono
parents: 67
diff changeset
958 "attribute `predicable' must have a constant default");
kono
parents: 67
diff changeset
959 free (p_false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
962
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963 if (strcmp (value, p_true) == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
964 predicable_default = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 else if (strcmp (value, p_false) == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 predicable_default = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 {
111
kono
parents: 67
diff changeset
969 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
kono
parents: 67
diff changeset
970 value);
kono
parents: 67
diff changeset
971 free (p_false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 /* Return the number of alternatives in constraint S. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 n_alternatives (const char *s)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
979 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 int n = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
981
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 if (s)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
983 while (*s)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
984 n += (*s++ == ',');
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
985
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986 return n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
987 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988
111
kono
parents: 67
diff changeset
989 /* The routine scans rtl PATTERN, find match_operand in it and counts
kono
parents: 67
diff changeset
990 number of alternatives. If PATTERN contains several match_operands
kono
parents: 67
diff changeset
991 with different number of alternatives, error is emitted, and the
kono
parents: 67
diff changeset
992 routine returns 0. If all match_operands in PATTERN have the same
kono
parents: 67
diff changeset
993 number of alternatives, it's stored in N_ALT, and the routine returns 1.
kono
parents: 67
diff changeset
994 LOC is the location of PATTERN, for error reporting. */
kono
parents: 67
diff changeset
995 static int
kono
parents: 67
diff changeset
996 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
kono
parents: 67
diff changeset
997 {
kono
parents: 67
diff changeset
998 const char *fmt;
kono
parents: 67
diff changeset
999 enum rtx_code code;
kono
parents: 67
diff changeset
1000 int i, j, len;
kono
parents: 67
diff changeset
1001
kono
parents: 67
diff changeset
1002 if (!n_alt)
kono
parents: 67
diff changeset
1003 return 0;
kono
parents: 67
diff changeset
1004
kono
parents: 67
diff changeset
1005 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
1006 switch (code)
kono
parents: 67
diff changeset
1007 {
kono
parents: 67
diff changeset
1008 case MATCH_OPERAND:
kono
parents: 67
diff changeset
1009 i = n_alternatives (XSTR (pattern, 2));
kono
parents: 67
diff changeset
1010 /* n_alternatives returns 1 if constraint string is empty -
kono
parents: 67
diff changeset
1011 here we fix it up. */
kono
parents: 67
diff changeset
1012 if (!*(XSTR (pattern, 2)))
kono
parents: 67
diff changeset
1013 i = 0;
kono
parents: 67
diff changeset
1014 if (*n_alt <= 0)
kono
parents: 67
diff changeset
1015 *n_alt = i;
kono
parents: 67
diff changeset
1016
kono
parents: 67
diff changeset
1017 else if (i && i != *n_alt)
kono
parents: 67
diff changeset
1018 {
kono
parents: 67
diff changeset
1019 error_at (loc, "wrong number of alternatives in operand %d",
kono
parents: 67
diff changeset
1020 XINT (pattern, 0));
kono
parents: 67
diff changeset
1021 return 0;
kono
parents: 67
diff changeset
1022 }
kono
parents: 67
diff changeset
1023
kono
parents: 67
diff changeset
1024 default:
kono
parents: 67
diff changeset
1025 break;
kono
parents: 67
diff changeset
1026 }
kono
parents: 67
diff changeset
1027
kono
parents: 67
diff changeset
1028 fmt = GET_RTX_FORMAT (code);
kono
parents: 67
diff changeset
1029 len = GET_RTX_LENGTH (code);
kono
parents: 67
diff changeset
1030 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1031 {
kono
parents: 67
diff changeset
1032 switch (fmt[i])
kono
parents: 67
diff changeset
1033 {
kono
parents: 67
diff changeset
1034 case 'e': case 'u':
kono
parents: 67
diff changeset
1035 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
kono
parents: 67
diff changeset
1036 return 0;
kono
parents: 67
diff changeset
1037 break;
kono
parents: 67
diff changeset
1038
kono
parents: 67
diff changeset
1039 case 'V':
kono
parents: 67
diff changeset
1040 if (XVEC (pattern, i) == NULL)
kono
parents: 67
diff changeset
1041 break;
kono
parents: 67
diff changeset
1042 /* FALLTHRU */
kono
parents: 67
diff changeset
1043
kono
parents: 67
diff changeset
1044 case 'E':
kono
parents: 67
diff changeset
1045 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1046 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
kono
parents: 67
diff changeset
1047 return 0;
kono
parents: 67
diff changeset
1048 break;
kono
parents: 67
diff changeset
1049
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1050 case 'r': case 'p': case 'i': case 'w':
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1051 case '0': case 's': case 'S': case 'T':
111
kono
parents: 67
diff changeset
1052 break;
kono
parents: 67
diff changeset
1053
kono
parents: 67
diff changeset
1054 default:
kono
parents: 67
diff changeset
1055 gcc_unreachable ();
kono
parents: 67
diff changeset
1056 }
kono
parents: 67
diff changeset
1057 }
kono
parents: 67
diff changeset
1058 return 1;
kono
parents: 67
diff changeset
1059 }
kono
parents: 67
diff changeset
1060
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061 /* Determine how many alternatives there are in INSN, and how many
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062 operands. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065 collect_insn_data (rtx pattern, int *palt, int *pmax)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1068 enum rtx_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069 int i, j, len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1071 code = GET_CODE (pattern);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1072 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1073 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1074 case MATCH_OPERAND:
111
kono
parents: 67
diff changeset
1075 case MATCH_SCRATCH:
kono
parents: 67
diff changeset
1076 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 *palt = (i > *palt ? i : *palt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 case MATCH_OPERATOR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 case MATCH_PARALLEL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 i = XINT (pattern, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 if (i > *pmax)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 *pmax = i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 len = GET_RTX_LENGTH (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093 for (i = 0; i < len; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 switch (fmt[i])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 case 'e': case 'u':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 collect_insn_data (XEXP (pattern, i), palt, pmax);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 case 'V':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 if (XVEC (pattern, i) == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 case 'E':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1110 case 'r': case 'p': case 'i': case 'w':
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1111 case '0': case 's': case 'S': case 'T':
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120 static rtx
111
kono
parents: 67
diff changeset
1121 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
kono
parents: 67
diff changeset
1122 file_location loc)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1125 enum rtx_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126 int i, j, len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1127
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128 code = GET_CODE (pattern);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1129 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1130 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1131 case MATCH_OPERAND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1132 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1133 const char *c = XSTR (pattern, 2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135 if (n_alternatives (c) != 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136 {
111
kono
parents: 67
diff changeset
1137 error_at (loc, "too many alternatives for operand %d",
kono
parents: 67
diff changeset
1138 XINT (pattern, 0));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 /* Replicate C as needed to fill out ALT alternatives. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 if (c && *c && alt > 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 size_t c_len = strlen (c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146 size_t len = alt * (c_len + 1);
111
kono
parents: 67
diff changeset
1147 char *new_c = XNEWVEC (char, len);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149 memcpy (new_c, c, c_len);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 for (i = 1; i < alt; ++i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 new_c[i * (c_len + 1) - 1] = ',';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 memcpy (&new_c[i * (c_len + 1)], c, c_len);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155 new_c[len - 1] = '\0';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 XSTR (pattern, 2) = new_c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 case MATCH_OPERATOR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162 case MATCH_SCRATCH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163 case MATCH_PARALLEL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1164 XINT (pattern, 0) += max_op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172 len = GET_RTX_LENGTH (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 for (i = 0; i < len; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 rtx r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1176
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1177 switch (fmt[i])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 case 'e': case 'u':
111
kono
parents: 67
diff changeset
1180 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1181 if (r == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1182 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1183 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1184
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1185 case 'E':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1187 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1188 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
111
kono
parents: 67
diff changeset
1189 alt, max_op, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 if (r == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1193 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1194
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1195 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1196 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1197
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1198 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1200 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1202
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1203 return pattern;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1204 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1205
111
kono
parents: 67
diff changeset
1206 /* Duplicate constraints in PATTERN. If pattern is from original
kono
parents: 67
diff changeset
1207 rtl-template, we need to duplicate each alternative - for that we
kono
parents: 67
diff changeset
1208 need to use duplicate_each_alternative () as a functor ALTER.
kono
parents: 67
diff changeset
1209 If pattern is from output-pattern of define_subst, we need to
kono
parents: 67
diff changeset
1210 duplicate constraints in another way - with duplicate_alternatives ().
kono
parents: 67
diff changeset
1211 N_DUP is multiplication factor. */
kono
parents: 67
diff changeset
1212 static rtx
kono
parents: 67
diff changeset
1213 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
kono
parents: 67
diff changeset
1214 {
kono
parents: 67
diff changeset
1215 const char *fmt;
kono
parents: 67
diff changeset
1216 enum rtx_code code;
kono
parents: 67
diff changeset
1217 int i, j, len;
kono
parents: 67
diff changeset
1218
kono
parents: 67
diff changeset
1219 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
1220 switch (code)
kono
parents: 67
diff changeset
1221 {
kono
parents: 67
diff changeset
1222 case MATCH_OPERAND:
kono
parents: 67
diff changeset
1223 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
kono
parents: 67
diff changeset
1224 break;
kono
parents: 67
diff changeset
1225
kono
parents: 67
diff changeset
1226 default:
kono
parents: 67
diff changeset
1227 break;
kono
parents: 67
diff changeset
1228 }
kono
parents: 67
diff changeset
1229
kono
parents: 67
diff changeset
1230 fmt = GET_RTX_FORMAT (code);
kono
parents: 67
diff changeset
1231 len = GET_RTX_LENGTH (code);
kono
parents: 67
diff changeset
1232 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1233 {
kono
parents: 67
diff changeset
1234 rtx r;
kono
parents: 67
diff changeset
1235
kono
parents: 67
diff changeset
1236 switch (fmt[i])
kono
parents: 67
diff changeset
1237 {
kono
parents: 67
diff changeset
1238 case 'e': case 'u':
kono
parents: 67
diff changeset
1239 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
kono
parents: 67
diff changeset
1240 if (r == NULL)
kono
parents: 67
diff changeset
1241 return r;
kono
parents: 67
diff changeset
1242 break;
kono
parents: 67
diff changeset
1243
kono
parents: 67
diff changeset
1244 case 'E':
kono
parents: 67
diff changeset
1245 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1246 {
kono
parents: 67
diff changeset
1247 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
kono
parents: 67
diff changeset
1248 if (r == NULL)
kono
parents: 67
diff changeset
1249 return r;
kono
parents: 67
diff changeset
1250 }
kono
parents: 67
diff changeset
1251 break;
kono
parents: 67
diff changeset
1252
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1253 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
111
kono
parents: 67
diff changeset
1254 break;
kono
parents: 67
diff changeset
1255
kono
parents: 67
diff changeset
1256 default:
kono
parents: 67
diff changeset
1257 break;
kono
parents: 67
diff changeset
1258 }
kono
parents: 67
diff changeset
1259 }
kono
parents: 67
diff changeset
1260
kono
parents: 67
diff changeset
1261 return pattern;
kono
parents: 67
diff changeset
1262 }
kono
parents: 67
diff changeset
1263
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 static const char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 alter_test_for_insn (struct queue_elem *ce_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 struct queue_elem *insn_elem)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 {
111
kono
parents: 67
diff changeset
1268 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
kono
parents: 67
diff changeset
1269 XSTR (insn_elem->data, 2));
kono
parents: 67
diff changeset
1270 }
kono
parents: 67
diff changeset
1271
kono
parents: 67
diff changeset
1272 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
kono
parents: 67
diff changeset
1273 to take "ce_enabled" into account. Return the new expression. */
kono
parents: 67
diff changeset
1274 static rtx
kono
parents: 67
diff changeset
1275 modify_attr_enabled_ce (rtx val)
kono
parents: 67
diff changeset
1276 {
kono
parents: 67
diff changeset
1277 rtx eq_attr, str;
kono
parents: 67
diff changeset
1278 rtx ite;
kono
parents: 67
diff changeset
1279 eq_attr = rtx_alloc (EQ_ATTR);
kono
parents: 67
diff changeset
1280 ite = rtx_alloc (IF_THEN_ELSE);
kono
parents: 67
diff changeset
1281 str = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
1282
kono
parents: 67
diff changeset
1283 XSTR (eq_attr, 0) = "ce_enabled";
kono
parents: 67
diff changeset
1284 XSTR (eq_attr, 1) = "yes";
kono
parents: 67
diff changeset
1285 XSTR (str, 0) = "no";
kono
parents: 67
diff changeset
1286 XEXP (ite, 0) = eq_attr;
kono
parents: 67
diff changeset
1287 XEXP (ite, 1) = val;
kono
parents: 67
diff changeset
1288 XEXP (ite, 2) = str;
kono
parents: 67
diff changeset
1289
kono
parents: 67
diff changeset
1290 return ite;
kono
parents: 67
diff changeset
1291 }
kono
parents: 67
diff changeset
1292
kono
parents: 67
diff changeset
1293 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
kono
parents: 67
diff changeset
1294 from a define_insn pattern. We must modify the "predicable" attribute
kono
parents: 67
diff changeset
1295 to be named "ce_enabled", and also change any "enabled" attribute that's
kono
parents: 67
diff changeset
1296 present so that it takes ce_enabled into account.
kono
parents: 67
diff changeset
1297 We rely on the fact that INSN was created with copy_rtx, and modify data
kono
parents: 67
diff changeset
1298 in-place. */
kono
parents: 67
diff changeset
1299
kono
parents: 67
diff changeset
1300 static void
kono
parents: 67
diff changeset
1301 alter_attrs_for_insn (rtx insn)
kono
parents: 67
diff changeset
1302 {
kono
parents: 67
diff changeset
1303 static bool global_changes_made = false;
kono
parents: 67
diff changeset
1304 rtvec vec = XVEC (insn, 4);
kono
parents: 67
diff changeset
1305 rtvec new_vec;
kono
parents: 67
diff changeset
1306 rtx val, set;
kono
parents: 67
diff changeset
1307 int num_elem;
kono
parents: 67
diff changeset
1308 int predicable_idx = -1;
kono
parents: 67
diff changeset
1309 int enabled_idx = -1;
kono
parents: 67
diff changeset
1310 int i;
kono
parents: 67
diff changeset
1311
kono
parents: 67
diff changeset
1312 if (! vec)
kono
parents: 67
diff changeset
1313 return;
kono
parents: 67
diff changeset
1314
kono
parents: 67
diff changeset
1315 num_elem = GET_NUM_ELEM (vec);
kono
parents: 67
diff changeset
1316 for (i = num_elem - 1; i >= 0; --i)
kono
parents: 67
diff changeset
1317 {
kono
parents: 67
diff changeset
1318 rtx sub = RTVEC_ELT (vec, i);
kono
parents: 67
diff changeset
1319 switch (GET_CODE (sub))
kono
parents: 67
diff changeset
1320 {
kono
parents: 67
diff changeset
1321 case SET_ATTR:
kono
parents: 67
diff changeset
1322 if (strcmp (XSTR (sub, 0), "predicable") == 0)
kono
parents: 67
diff changeset
1323 {
kono
parents: 67
diff changeset
1324 predicable_idx = i;
kono
parents: 67
diff changeset
1325 XSTR (sub, 0) = "ce_enabled";
kono
parents: 67
diff changeset
1326 }
kono
parents: 67
diff changeset
1327 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
kono
parents: 67
diff changeset
1328 {
kono
parents: 67
diff changeset
1329 enabled_idx = i;
kono
parents: 67
diff changeset
1330 XSTR (sub, 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1331 }
kono
parents: 67
diff changeset
1332 break;
kono
parents: 67
diff changeset
1333
kono
parents: 67
diff changeset
1334 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
1335 if (strcmp (XSTR (sub, 0), "predicable") == 0)
kono
parents: 67
diff changeset
1336 /* We already give an error elsewhere. */
kono
parents: 67
diff changeset
1337 return;
kono
parents: 67
diff changeset
1338 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
kono
parents: 67
diff changeset
1339 {
kono
parents: 67
diff changeset
1340 enabled_idx = i;
kono
parents: 67
diff changeset
1341 XSTR (sub, 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1342 }
kono
parents: 67
diff changeset
1343 break;
kono
parents: 67
diff changeset
1344
kono
parents: 67
diff changeset
1345 case SET:
kono
parents: 67
diff changeset
1346 if (GET_CODE (SET_DEST (sub)) != ATTR)
kono
parents: 67
diff changeset
1347 break;
kono
parents: 67
diff changeset
1348 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
kono
parents: 67
diff changeset
1349 {
kono
parents: 67
diff changeset
1350 sub = SET_SRC (sub);
kono
parents: 67
diff changeset
1351 if (GET_CODE (sub) == CONST_STRING)
kono
parents: 67
diff changeset
1352 {
kono
parents: 67
diff changeset
1353 predicable_idx = i;
kono
parents: 67
diff changeset
1354 XSTR (sub, 0) = "ce_enabled";
kono
parents: 67
diff changeset
1355 }
kono
parents: 67
diff changeset
1356 else
kono
parents: 67
diff changeset
1357 /* We already give an error elsewhere. */
kono
parents: 67
diff changeset
1358 return;
kono
parents: 67
diff changeset
1359 break;
kono
parents: 67
diff changeset
1360 }
kono
parents: 67
diff changeset
1361 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
kono
parents: 67
diff changeset
1362 {
kono
parents: 67
diff changeset
1363 enabled_idx = i;
kono
parents: 67
diff changeset
1364 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1365 }
kono
parents: 67
diff changeset
1366 break;
kono
parents: 67
diff changeset
1367
kono
parents: 67
diff changeset
1368 default:
kono
parents: 67
diff changeset
1369 gcc_unreachable ();
kono
parents: 67
diff changeset
1370 }
kono
parents: 67
diff changeset
1371 }
kono
parents: 67
diff changeset
1372 if (predicable_idx == -1)
kono
parents: 67
diff changeset
1373 return;
kono
parents: 67
diff changeset
1374
kono
parents: 67
diff changeset
1375 if (!global_changes_made)
kono
parents: 67
diff changeset
1376 {
kono
parents: 67
diff changeset
1377 struct queue_elem *elem;
kono
parents: 67
diff changeset
1378
kono
parents: 67
diff changeset
1379 global_changes_made = true;
kono
parents: 67
diff changeset
1380 add_define_attr ("ce_enabled");
kono
parents: 67
diff changeset
1381 add_define_attr ("nonce_enabled");
kono
parents: 67
diff changeset
1382
kono
parents: 67
diff changeset
1383 for (elem = define_attr_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
1384 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
kono
parents: 67
diff changeset
1385 {
kono
parents: 67
diff changeset
1386 XEXP (elem->data, 2)
kono
parents: 67
diff changeset
1387 = modify_attr_enabled_ce (XEXP (elem->data, 2));
kono
parents: 67
diff changeset
1388 }
kono
parents: 67
diff changeset
1389 }
kono
parents: 67
diff changeset
1390 if (enabled_idx == -1)
kono
parents: 67
diff changeset
1391 return;
kono
parents: 67
diff changeset
1392
kono
parents: 67
diff changeset
1393 new_vec = rtvec_alloc (num_elem + 1);
kono
parents: 67
diff changeset
1394 for (i = 0; i < num_elem; i++)
kono
parents: 67
diff changeset
1395 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
kono
parents: 67
diff changeset
1396 val = rtx_alloc (IF_THEN_ELSE);
kono
parents: 67
diff changeset
1397 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
kono
parents: 67
diff changeset
1398 XEXP (val, 1) = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
1399 XEXP (val, 2) = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
1400 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1401 XSTR (XEXP (val, 0), 1) = "yes";
kono
parents: 67
diff changeset
1402 XSTR (XEXP (val, 1), 0) = "yes";
kono
parents: 67
diff changeset
1403 XSTR (XEXP (val, 2), 0) = "no";
kono
parents: 67
diff changeset
1404 set = rtx_alloc (SET);
kono
parents: 67
diff changeset
1405 SET_DEST (set) = rtx_alloc (ATTR);
kono
parents: 67
diff changeset
1406 XSTR (SET_DEST (set), 0) = "enabled";
kono
parents: 67
diff changeset
1407 SET_SRC (set) = modify_attr_enabled_ce (val);
kono
parents: 67
diff changeset
1408 RTVEC_ELT (new_vec, i) = set;
kono
parents: 67
diff changeset
1409 XVEC (insn, 4) = new_vec;
kono
parents: 67
diff changeset
1410 }
kono
parents: 67
diff changeset
1411
kono
parents: 67
diff changeset
1412 /* As number of constraints is changed after define_subst, we need to
kono
parents: 67
diff changeset
1413 process attributes as well - we need to duplicate them the same way
kono
parents: 67
diff changeset
1414 that we duplicated constraints in original pattern
kono
parents: 67
diff changeset
1415 ELEM is a queue element, containing our rtl-template,
kono
parents: 67
diff changeset
1416 N_DUP - multiplication factor. */
kono
parents: 67
diff changeset
1417 static void
kono
parents: 67
diff changeset
1418 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup)
kono
parents: 67
diff changeset
1419 {
kono
parents: 67
diff changeset
1420 rtvec vec = XVEC (elem->data, 4);
kono
parents: 67
diff changeset
1421 int num_elem;
kono
parents: 67
diff changeset
1422 int i;
kono
parents: 67
diff changeset
1423
kono
parents: 67
diff changeset
1424 if (n_dup < 2 || ! vec)
kono
parents: 67
diff changeset
1425 return;
kono
parents: 67
diff changeset
1426
kono
parents: 67
diff changeset
1427 num_elem = GET_NUM_ELEM (vec);
kono
parents: 67
diff changeset
1428 for (i = num_elem - 1; i >= 0; --i)
kono
parents: 67
diff changeset
1429 {
kono
parents: 67
diff changeset
1430 rtx sub = RTVEC_ELT (vec, i);
kono
parents: 67
diff changeset
1431 switch (GET_CODE (sub))
kono
parents: 67
diff changeset
1432 {
kono
parents: 67
diff changeset
1433 case SET_ATTR:
kono
parents: 67
diff changeset
1434 if (strchr (XSTR (sub, 1), ',') != NULL)
kono
parents: 67
diff changeset
1435 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
kono
parents: 67
diff changeset
1436 break;
kono
parents: 67
diff changeset
1437
kono
parents: 67
diff changeset
1438 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
1439 case SET:
kono
parents: 67
diff changeset
1440 error_at (elem->loc,
kono
parents: 67
diff changeset
1441 "%s: `define_subst' does not support attributes "
kono
parents: 67
diff changeset
1442 "assigned by `set' and `set_attr_alternative'",
kono
parents: 67
diff changeset
1443 XSTR (elem->data, 0));
kono
parents: 67
diff changeset
1444 return;
kono
parents: 67
diff changeset
1445
kono
parents: 67
diff changeset
1446 default:
kono
parents: 67
diff changeset
1447 gcc_unreachable ();
kono
parents: 67
diff changeset
1448 }
kono
parents: 67
diff changeset
1449 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1451
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 /* Adjust all of the operand numbers in SRC to match the shift they'll
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1453 get from an operand displacement of DISP. Return a pointer after the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454 adjusted string. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 static char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 shift_output_template (char *dest, const char *src, int disp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1458 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1459 while (*src)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461 char c = *src++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462 *dest++ = c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463 if (c == '%')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 c = *src++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 if (ISDIGIT ((unsigned char) c))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 c += disp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 else if (ISALPHA (c))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 *dest++ = c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 c = *src++ + disp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1473 *dest++ = c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1476
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1477 return dest;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 static const char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 alter_output_for_insn (struct queue_elem *ce_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 struct queue_elem *insn_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 int alt, int max_op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 const char *ce_out, *insn_out;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486 char *result, *p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 size_t len, ce_len, insn_len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489 /* ??? Could coordinate with genoutput to not duplicate code here. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 ce_out = XSTR (ce_elem->data, 2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492 insn_out = XTMPL (insn_elem->data, 3);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493 if (!ce_out || *ce_out == '\0')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 return insn_out;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496 ce_len = strlen (ce_out);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497 insn_len = strlen (insn_out);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499 if (*insn_out == '*')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 /* You must take care of the predicate yourself. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 return insn_out;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503 if (*insn_out == '@')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 len = (ce_len + 1) * alt + insn_len + 1;
111
kono
parents: 67
diff changeset
1506 p = result = XNEWVEC (char, len);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1508 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511 *p++ = *insn_out++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 while (ISSPACE ((unsigned char) *insn_out));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1513
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1514 if (*insn_out != '#')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516 p = shift_output_template (p, ce_out, max_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517 *p++ = ' ';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 *p++ = *insn_out++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522 while (*insn_out && *insn_out != '\n');
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 while (*insn_out);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525 *p = '\0';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 len = ce_len + 1 + insn_len + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 result = XNEWVEC (char, len);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 p = shift_output_template (result, ce_out, max_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533 *p++ = ' ';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 memcpy (p, insn_out, insn_len + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1535 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1536
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1537 return result;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1538 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1539
111
kono
parents: 67
diff changeset
1540 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
kono
parents: 67
diff changeset
1541 string, duplicated N_DUP times. */
kono
parents: 67
diff changeset
1542
kono
parents: 67
diff changeset
1543 static const char *
kono
parents: 67
diff changeset
1544 duplicate_alternatives (const char * str, int n_dup)
kono
parents: 67
diff changeset
1545 {
kono
parents: 67
diff changeset
1546 int i, len, new_len;
kono
parents: 67
diff changeset
1547 char *result, *sp;
kono
parents: 67
diff changeset
1548 const char *cp;
kono
parents: 67
diff changeset
1549
kono
parents: 67
diff changeset
1550 if (n_dup < 2)
kono
parents: 67
diff changeset
1551 return str;
kono
parents: 67
diff changeset
1552
kono
parents: 67
diff changeset
1553 while (ISSPACE (*str))
kono
parents: 67
diff changeset
1554 str++;
kono
parents: 67
diff changeset
1555
kono
parents: 67
diff changeset
1556 if (*str == '\0')
kono
parents: 67
diff changeset
1557 return str;
kono
parents: 67
diff changeset
1558
kono
parents: 67
diff changeset
1559 cp = str;
kono
parents: 67
diff changeset
1560 len = strlen (str);
kono
parents: 67
diff changeset
1561 new_len = (len + 1) * n_dup;
kono
parents: 67
diff changeset
1562
kono
parents: 67
diff changeset
1563 sp = result = XNEWVEC (char, new_len);
kono
parents: 67
diff changeset
1564
kono
parents: 67
diff changeset
1565 /* Global modifier characters mustn't be duplicated: skip if found. */
kono
parents: 67
diff changeset
1566 if (*cp == '=' || *cp == '+' || *cp == '%')
kono
parents: 67
diff changeset
1567 {
kono
parents: 67
diff changeset
1568 *sp++ = *cp++;
kono
parents: 67
diff changeset
1569 len--;
kono
parents: 67
diff changeset
1570 }
kono
parents: 67
diff changeset
1571
kono
parents: 67
diff changeset
1572 /* Copy original constraints N_DUP times. */
kono
parents: 67
diff changeset
1573 for (i = 0; i < n_dup; i++, sp += len+1)
kono
parents: 67
diff changeset
1574 {
kono
parents: 67
diff changeset
1575 memcpy (sp, cp, len);
kono
parents: 67
diff changeset
1576 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
kono
parents: 67
diff changeset
1577 }
kono
parents: 67
diff changeset
1578
kono
parents: 67
diff changeset
1579 return result;
kono
parents: 67
diff changeset
1580 }
kono
parents: 67
diff changeset
1581
kono
parents: 67
diff changeset
1582 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
kono
parents: 67
diff changeset
1583 each alternative from the original string is duplicated N_DUP times. */
kono
parents: 67
diff changeset
1584 static const char *
kono
parents: 67
diff changeset
1585 duplicate_each_alternative (const char * str, int n_dup)
kono
parents: 67
diff changeset
1586 {
kono
parents: 67
diff changeset
1587 int i, len, new_len;
kono
parents: 67
diff changeset
1588 char *result, *sp, *ep, *cp;
kono
parents: 67
diff changeset
1589
kono
parents: 67
diff changeset
1590 if (n_dup < 2)
kono
parents: 67
diff changeset
1591 return str;
kono
parents: 67
diff changeset
1592
kono
parents: 67
diff changeset
1593 while (ISSPACE (*str))
kono
parents: 67
diff changeset
1594 str++;
kono
parents: 67
diff changeset
1595
kono
parents: 67
diff changeset
1596 if (*str == '\0')
kono
parents: 67
diff changeset
1597 return str;
kono
parents: 67
diff changeset
1598
kono
parents: 67
diff changeset
1599 cp = xstrdup (str);
kono
parents: 67
diff changeset
1600
kono
parents: 67
diff changeset
1601 new_len = (strlen (cp) + 1) * n_dup;
kono
parents: 67
diff changeset
1602
kono
parents: 67
diff changeset
1603 sp = result = XNEWVEC (char, new_len);
kono
parents: 67
diff changeset
1604
kono
parents: 67
diff changeset
1605 /* Global modifier characters mustn't be duplicated: skip if found. */
kono
parents: 67
diff changeset
1606 if (*cp == '=' || *cp == '+' || *cp == '%')
kono
parents: 67
diff changeset
1607 *sp++ = *cp++;
kono
parents: 67
diff changeset
1608
kono
parents: 67
diff changeset
1609 do
kono
parents: 67
diff changeset
1610 {
kono
parents: 67
diff changeset
1611 if ((ep = strchr (cp, ',')) != NULL)
kono
parents: 67
diff changeset
1612 *ep++ = '\0';
kono
parents: 67
diff changeset
1613 len = strlen (cp);
kono
parents: 67
diff changeset
1614
kono
parents: 67
diff changeset
1615 /* Copy a constraint N_DUP times. */
kono
parents: 67
diff changeset
1616 for (i = 0; i < n_dup; i++, sp += len + 1)
kono
parents: 67
diff changeset
1617 {
kono
parents: 67
diff changeset
1618 memcpy (sp, cp, len);
kono
parents: 67
diff changeset
1619 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
kono
parents: 67
diff changeset
1620 }
kono
parents: 67
diff changeset
1621
kono
parents: 67
diff changeset
1622 cp = ep;
kono
parents: 67
diff changeset
1623 }
kono
parents: 67
diff changeset
1624 while (cp != NULL);
kono
parents: 67
diff changeset
1625
kono
parents: 67
diff changeset
1626 return result;
kono
parents: 67
diff changeset
1627 }
kono
parents: 67
diff changeset
1628
kono
parents: 67
diff changeset
1629 /* Alter the output of INSN whose pattern was modified by
kono
parents: 67
diff changeset
1630 DEFINE_SUBST. We must replicate output strings according
kono
parents: 67
diff changeset
1631 to the new number of alternatives ALT in substituted pattern.
kono
parents: 67
diff changeset
1632 If ALT equals 1, output has one alternative or defined by C
kono
parents: 67
diff changeset
1633 code, then output is returned without any changes. */
kono
parents: 67
diff changeset
1634
kono
parents: 67
diff changeset
1635 static const char *
kono
parents: 67
diff changeset
1636 alter_output_for_subst_insn (rtx insn, int alt)
kono
parents: 67
diff changeset
1637 {
kono
parents: 67
diff changeset
1638 const char *insn_out, *old_out;
kono
parents: 67
diff changeset
1639 char *new_out, *cp;
kono
parents: 67
diff changeset
1640 size_t old_len, new_len;
kono
parents: 67
diff changeset
1641 int j;
kono
parents: 67
diff changeset
1642
kono
parents: 67
diff changeset
1643 insn_out = XTMPL (insn, 3);
kono
parents: 67
diff changeset
1644
kono
parents: 67
diff changeset
1645 if (alt < 2 || *insn_out != '@')
kono
parents: 67
diff changeset
1646 return insn_out;
kono
parents: 67
diff changeset
1647
kono
parents: 67
diff changeset
1648 old_out = insn_out + 1;
kono
parents: 67
diff changeset
1649 while (ISSPACE (*old_out))
kono
parents: 67
diff changeset
1650 old_out++;
kono
parents: 67
diff changeset
1651 old_len = strlen (old_out);
kono
parents: 67
diff changeset
1652
kono
parents: 67
diff changeset
1653 new_len = alt * (old_len + 1) + 1;
kono
parents: 67
diff changeset
1654
kono
parents: 67
diff changeset
1655 new_out = XNEWVEC (char, new_len);
kono
parents: 67
diff changeset
1656 new_out[0] = '@';
kono
parents: 67
diff changeset
1657
kono
parents: 67
diff changeset
1658 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
kono
parents: 67
diff changeset
1659 {
kono
parents: 67
diff changeset
1660 memcpy (cp, old_out, old_len);
kono
parents: 67
diff changeset
1661 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
kono
parents: 67
diff changeset
1662 }
kono
parents: 67
diff changeset
1663
kono
parents: 67
diff changeset
1664 return new_out;
kono
parents: 67
diff changeset
1665 }
kono
parents: 67
diff changeset
1666
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1670 process_one_cond_exec (struct queue_elem *ce_elem)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1671 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1672 struct queue_elem *insn_elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1673 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1675 int alternatives, max_operand;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 rtx pred, insn, pattern, split;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1677 char *new_name;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1678 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 if (! is_predicable (insn_elem))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1683 alternatives = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1684 max_operand = -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1685 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 max_operand += 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1688 if (XVECLEN (ce_elem->data, 0) != 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1689 {
111
kono
parents: 67
diff changeset
1690 error_at (ce_elem->loc, "too many patterns in predicate");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1694 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1695 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
111
kono
parents: 67
diff changeset
1696 ce_elem->loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1697 if (pred == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1698 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1699
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1700 /* Construct a new pattern for the new insn. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1701 insn = copy_rtx (insn_elem->data);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1702 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1703 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1704 XSTR (insn, 0) = new_name;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1705 pattern = rtx_alloc (COND_EXEC);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1706 XEXP (pattern, 0) = pred;
111
kono
parents: 67
diff changeset
1707 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
kono
parents: 67
diff changeset
1708 XVEC (insn, 1) = rtvec_alloc (1);
kono
parents: 67
diff changeset
1709 XVECEXP (insn, 1, 0) = pattern;
kono
parents: 67
diff changeset
1710
kono
parents: 67
diff changeset
1711 if (XVEC (ce_elem->data, 3) != NULL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1712 {
111
kono
parents: 67
diff changeset
1713 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
kono
parents: 67
diff changeset
1714 + XVECLEN (ce_elem->data, 3));
kono
parents: 67
diff changeset
1715 int i = 0;
kono
parents: 67
diff changeset
1716 int j = 0;
kono
parents: 67
diff changeset
1717 for (i = 0; i < XVECLEN (insn, 4); i++)
kono
parents: 67
diff changeset
1718 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
kono
parents: 67
diff changeset
1719
kono
parents: 67
diff changeset
1720 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
kono
parents: 67
diff changeset
1721 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
kono
parents: 67
diff changeset
1722
kono
parents: 67
diff changeset
1723 XVEC (insn, 4) = attributes;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1724 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1725
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1726 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1727 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1728 alternatives, max_operand);
111
kono
parents: 67
diff changeset
1729 alter_attrs_for_insn (insn);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1730
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1731 /* Put the new pattern on the `other' list so that it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1732 (a) is not reprocessed by other define_cond_exec patterns
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1733 (b) appears after all normal define_insn patterns.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1734
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1735 ??? B is debatable. If one has normal insns that match
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1736 cond_exec patterns, they will be preferred over these
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1737 generated patterns. Whether this matters in practice, or if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1738 it's a good thing, or whether we should thread these new
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1739 patterns into the define_insn chain just after their generator
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1740 is something we'll have to experiment with. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1741
111
kono
parents: 67
diff changeset
1742 queue_pattern (insn, &other_tail, insn_elem->loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1743
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1744 if (!insn_elem->split)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1745 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1746
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1747 /* If the original insn came from a define_insn_and_split,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1748 generate a new split to handle the predicated insn. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1749 split = copy_rtx (insn_elem->split->data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1750 /* Predicate the pattern matched by the split. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1751 pattern = rtx_alloc (COND_EXEC);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1752 XEXP (pattern, 0) = pred;
111
kono
parents: 67
diff changeset
1753 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
kono
parents: 67
diff changeset
1754 XVEC (split, 0) = rtvec_alloc (1);
kono
parents: 67
diff changeset
1755 XVECEXP (split, 0, 0) = pattern;
kono
parents: 67
diff changeset
1756
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1757 /* Predicate all of the insns generated by the split. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1758 for (i = 0; i < XVECLEN (split, 2); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1759 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1760 pattern = rtx_alloc (COND_EXEC);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1761 XEXP (pattern, 0) = pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1762 XEXP (pattern, 1) = XVECEXP (split, 2, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1763 XVECEXP (split, 2, i) = pattern;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1764 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1765 /* Add the new split to the queue. */
111
kono
parents: 67
diff changeset
1766 queue_pattern (split, &other_tail, insn_elem->split->loc);
kono
parents: 67
diff changeset
1767 }
kono
parents: 67
diff changeset
1768 }
kono
parents: 67
diff changeset
1769
kono
parents: 67
diff changeset
1770 /* Try to apply define_substs to the given ELEM.
kono
parents: 67
diff changeset
1771 Only define_substs, specified via attributes would be applied.
kono
parents: 67
diff changeset
1772 If attribute, requiring define_subst, is set, but no define_subst
kono
parents: 67
diff changeset
1773 was applied, ELEM would be deleted. */
kono
parents: 67
diff changeset
1774
kono
parents: 67
diff changeset
1775 static void
kono
parents: 67
diff changeset
1776 process_substs_on_one_elem (struct queue_elem *elem,
kono
parents: 67
diff changeset
1777 struct queue_elem *queue)
kono
parents: 67
diff changeset
1778 {
kono
parents: 67
diff changeset
1779 struct queue_elem *subst_elem;
kono
parents: 67
diff changeset
1780 int i, j, patterns_match;
kono
parents: 67
diff changeset
1781
kono
parents: 67
diff changeset
1782 for (subst_elem = define_subst_queue;
kono
parents: 67
diff changeset
1783 subst_elem; subst_elem = subst_elem->next)
kono
parents: 67
diff changeset
1784 {
kono
parents: 67
diff changeset
1785 int alternatives, alternatives_subst;
kono
parents: 67
diff changeset
1786 rtx subst_pattern;
kono
parents: 67
diff changeset
1787 rtvec subst_pattern_vec;
kono
parents: 67
diff changeset
1788
kono
parents: 67
diff changeset
1789 if (!has_subst_attribute (elem, subst_elem))
kono
parents: 67
diff changeset
1790 continue;
kono
parents: 67
diff changeset
1791
kono
parents: 67
diff changeset
1792 /* Compare original rtl-pattern from define_insn with input
kono
parents: 67
diff changeset
1793 pattern from define_subst.
kono
parents: 67
diff changeset
1794 Also, check if numbers of alternatives are the same in all
kono
parents: 67
diff changeset
1795 match_operands. */
kono
parents: 67
diff changeset
1796 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
kono
parents: 67
diff changeset
1797 continue;
kono
parents: 67
diff changeset
1798 patterns_match = 1;
kono
parents: 67
diff changeset
1799 alternatives = -1;
kono
parents: 67
diff changeset
1800 alternatives_subst = -1;
kono
parents: 67
diff changeset
1801 for (j = 0; j < XVECLEN (elem->data, 1); j++)
kono
parents: 67
diff changeset
1802 {
kono
parents: 67
diff changeset
1803 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
kono
parents: 67
diff changeset
1804 XVECEXP (subst_elem->data, 1, j),
kono
parents: 67
diff changeset
1805 subst_elem->loc))
kono
parents: 67
diff changeset
1806 {
kono
parents: 67
diff changeset
1807 patterns_match = 0;
kono
parents: 67
diff changeset
1808 break;
kono
parents: 67
diff changeset
1809 }
kono
parents: 67
diff changeset
1810
kono
parents: 67
diff changeset
1811 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
kono
parents: 67
diff changeset
1812 &alternatives, subst_elem->loc))
kono
parents: 67
diff changeset
1813 {
kono
parents: 67
diff changeset
1814 patterns_match = 0;
kono
parents: 67
diff changeset
1815 break;
kono
parents: 67
diff changeset
1816 }
kono
parents: 67
diff changeset
1817 }
kono
parents: 67
diff changeset
1818
kono
parents: 67
diff changeset
1819 /* Check if numbers of alternatives are the same in all
kono
parents: 67
diff changeset
1820 match_operands in output template of define_subst. */
kono
parents: 67
diff changeset
1821 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
kono
parents: 67
diff changeset
1822 {
kono
parents: 67
diff changeset
1823 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
kono
parents: 67
diff changeset
1824 &alternatives_subst,
kono
parents: 67
diff changeset
1825 subst_elem->loc))
kono
parents: 67
diff changeset
1826 {
kono
parents: 67
diff changeset
1827 patterns_match = 0;
kono
parents: 67
diff changeset
1828 break;
kono
parents: 67
diff changeset
1829 }
kono
parents: 67
diff changeset
1830 }
kono
parents: 67
diff changeset
1831
kono
parents: 67
diff changeset
1832 if (!patterns_match)
kono
parents: 67
diff changeset
1833 continue;
kono
parents: 67
diff changeset
1834
kono
parents: 67
diff changeset
1835 /* Clear array in which we save occupied indexes of operands. */
kono
parents: 67
diff changeset
1836 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
kono
parents: 67
diff changeset
1837
kono
parents: 67
diff changeset
1838 /* Create a pattern, based on the output one from define_subst. */
kono
parents: 67
diff changeset
1839 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
kono
parents: 67
diff changeset
1840 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
kono
parents: 67
diff changeset
1841 {
kono
parents: 67
diff changeset
1842 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
kono
parents: 67
diff changeset
1843
kono
parents: 67
diff changeset
1844 /* Duplicate constraints in substitute-pattern. */
kono
parents: 67
diff changeset
1845 subst_pattern = alter_constraints (subst_pattern, alternatives,
kono
parents: 67
diff changeset
1846 duplicate_each_alternative);
kono
parents: 67
diff changeset
1847
kono
parents: 67
diff changeset
1848 subst_pattern = adjust_operands_numbers (subst_pattern);
kono
parents: 67
diff changeset
1849
kono
parents: 67
diff changeset
1850 /* Substitute match_dup and match_op_dup in the new pattern and
kono
parents: 67
diff changeset
1851 duplicate constraints. */
kono
parents: 67
diff changeset
1852 subst_pattern = subst_dup (subst_pattern, alternatives,
kono
parents: 67
diff changeset
1853 alternatives_subst);
kono
parents: 67
diff changeset
1854
kono
parents: 67
diff changeset
1855 replace_duplicating_operands_in_pattern (subst_pattern);
kono
parents: 67
diff changeset
1856
kono
parents: 67
diff changeset
1857 /* We don't need any constraints in DEFINE_EXPAND. */
kono
parents: 67
diff changeset
1858 if (GET_CODE (elem->data) == DEFINE_EXPAND)
kono
parents: 67
diff changeset
1859 remove_constraints (subst_pattern);
kono
parents: 67
diff changeset
1860
kono
parents: 67
diff changeset
1861 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
kono
parents: 67
diff changeset
1862 }
kono
parents: 67
diff changeset
1863 XVEC (elem->data, 1) = subst_pattern_vec;
kono
parents: 67
diff changeset
1864
kono
parents: 67
diff changeset
1865 for (i = 0; i < MAX_OPERANDS; i++)
kono
parents: 67
diff changeset
1866 match_operand_entries_in_pattern[i] = NULL;
kono
parents: 67
diff changeset
1867
kono
parents: 67
diff changeset
1868 if (GET_CODE (elem->data) == DEFINE_INSN)
kono
parents: 67
diff changeset
1869 {
kono
parents: 67
diff changeset
1870 XTMPL (elem->data, 3) =
kono
parents: 67
diff changeset
1871 alter_output_for_subst_insn (elem->data, alternatives_subst);
kono
parents: 67
diff changeset
1872 alter_attrs_for_subst_insn (elem, alternatives_subst);
kono
parents: 67
diff changeset
1873 }
kono
parents: 67
diff changeset
1874
kono
parents: 67
diff changeset
1875 /* Recalculate condition, joining conditions from original and
kono
parents: 67
diff changeset
1876 DEFINE_SUBST input patterns. */
kono
parents: 67
diff changeset
1877 XSTR (elem->data, 2)
kono
parents: 67
diff changeset
1878 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
kono
parents: 67
diff changeset
1879 XSTR (elem->data, 2));
kono
parents: 67
diff changeset
1880 /* Mark that subst was applied by changing attribute from "yes"
kono
parents: 67
diff changeset
1881 to "no". */
kono
parents: 67
diff changeset
1882 change_subst_attribute (elem, subst_elem, subst_false);
kono
parents: 67
diff changeset
1883 }
kono
parents: 67
diff changeset
1884
kono
parents: 67
diff changeset
1885 /* If ELEM contains a subst attribute with value "yes", then we
kono
parents: 67
diff changeset
1886 expected that a subst would be applied, but it wasn't - so,
kono
parents: 67
diff changeset
1887 we need to remove that elementto avoid duplicating. */
kono
parents: 67
diff changeset
1888 for (subst_elem = define_subst_queue;
kono
parents: 67
diff changeset
1889 subst_elem; subst_elem = subst_elem->next)
kono
parents: 67
diff changeset
1890 {
kono
parents: 67
diff changeset
1891 if (has_subst_attribute (elem, subst_elem))
kono
parents: 67
diff changeset
1892 {
kono
parents: 67
diff changeset
1893 remove_from_queue (elem, &queue);
kono
parents: 67
diff changeset
1894 return;
kono
parents: 67
diff changeset
1895 }
kono
parents: 67
diff changeset
1896 }
kono
parents: 67
diff changeset
1897 }
kono
parents: 67
diff changeset
1898
kono
parents: 67
diff changeset
1899 /* This is a subroutine of mark_operands_used_in_match_dup.
kono
parents: 67
diff changeset
1900 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
kono
parents: 67
diff changeset
1901 static void
kono
parents: 67
diff changeset
1902 mark_operands_from_match_dup (rtx pattern)
kono
parents: 67
diff changeset
1903 {
kono
parents: 67
diff changeset
1904 const char *fmt;
kono
parents: 67
diff changeset
1905 int i, j, len, opno;
kono
parents: 67
diff changeset
1906
kono
parents: 67
diff changeset
1907 if (GET_CODE (pattern) == MATCH_OPERAND
kono
parents: 67
diff changeset
1908 || GET_CODE (pattern) == MATCH_OPERATOR
kono
parents: 67
diff changeset
1909 || GET_CODE (pattern) == MATCH_PARALLEL)
kono
parents: 67
diff changeset
1910 {
kono
parents: 67
diff changeset
1911 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
1912 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
1913 used_operands_numbers [opno] = 1;
kono
parents: 67
diff changeset
1914 }
kono
parents: 67
diff changeset
1915 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
1916 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
1917 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1918 {
kono
parents: 67
diff changeset
1919 switch (fmt[i])
kono
parents: 67
diff changeset
1920 {
kono
parents: 67
diff changeset
1921 case 'e': case 'u':
kono
parents: 67
diff changeset
1922 mark_operands_from_match_dup (XEXP (pattern, i));
kono
parents: 67
diff changeset
1923 break;
kono
parents: 67
diff changeset
1924 case 'E':
kono
parents: 67
diff changeset
1925 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1926 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
kono
parents: 67
diff changeset
1927 break;
kono
parents: 67
diff changeset
1928 }
kono
parents: 67
diff changeset
1929 }
kono
parents: 67
diff changeset
1930 }
kono
parents: 67
diff changeset
1931
kono
parents: 67
diff changeset
1932 /* This is a subroutine of adjust_operands_numbers.
kono
parents: 67
diff changeset
1933 It goes through all expressions in PATTERN and when MATCH_DUP is
kono
parents: 67
diff changeset
1934 met, all MATCH_OPERANDs inside it is marked as occupied. The
kono
parents: 67
diff changeset
1935 process of marking is done by routin mark_operands_from_match_dup. */
kono
parents: 67
diff changeset
1936 static void
kono
parents: 67
diff changeset
1937 mark_operands_used_in_match_dup (rtx pattern)
kono
parents: 67
diff changeset
1938 {
kono
parents: 67
diff changeset
1939 const char *fmt;
kono
parents: 67
diff changeset
1940 int i, j, len, opno;
kono
parents: 67
diff changeset
1941
kono
parents: 67
diff changeset
1942 if (GET_CODE (pattern) == MATCH_DUP)
kono
parents: 67
diff changeset
1943 {
kono
parents: 67
diff changeset
1944 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
1945 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
1946 mark_operands_from_match_dup (operand_data[opno]);
kono
parents: 67
diff changeset
1947 return;
kono
parents: 67
diff changeset
1948 }
kono
parents: 67
diff changeset
1949 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
1950 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
1951 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1952 {
kono
parents: 67
diff changeset
1953 switch (fmt[i])
kono
parents: 67
diff changeset
1954 {
kono
parents: 67
diff changeset
1955 case 'e': case 'u':
kono
parents: 67
diff changeset
1956 mark_operands_used_in_match_dup (XEXP (pattern, i));
kono
parents: 67
diff changeset
1957 break;
kono
parents: 67
diff changeset
1958 case 'E':
kono
parents: 67
diff changeset
1959 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1960 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
kono
parents: 67
diff changeset
1961 break;
kono
parents: 67
diff changeset
1962 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1963 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1964 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1965
111
kono
parents: 67
diff changeset
1966 /* This is subroutine of renumerate_operands_in_pattern.
kono
parents: 67
diff changeset
1967 It finds first not-occupied operand-index. */
kono
parents: 67
diff changeset
1968 static int
kono
parents: 67
diff changeset
1969 find_first_unused_number_of_operand ()
kono
parents: 67
diff changeset
1970 {
kono
parents: 67
diff changeset
1971 int i;
kono
parents: 67
diff changeset
1972 for (i = 0; i < MAX_OPERANDS; i++)
kono
parents: 67
diff changeset
1973 if (!used_operands_numbers[i])
kono
parents: 67
diff changeset
1974 return i;
kono
parents: 67
diff changeset
1975 return MAX_OPERANDS;
kono
parents: 67
diff changeset
1976 }
kono
parents: 67
diff changeset
1977
kono
parents: 67
diff changeset
1978 /* This is subroutine of adjust_operands_numbers.
kono
parents: 67
diff changeset
1979 It visits all expressions in PATTERN and assigns not-occupied
kono
parents: 67
diff changeset
1980 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
kono
parents: 67
diff changeset
1981 PATTERN. */
kono
parents: 67
diff changeset
1982 static void
kono
parents: 67
diff changeset
1983 renumerate_operands_in_pattern (rtx pattern)
kono
parents: 67
diff changeset
1984 {
kono
parents: 67
diff changeset
1985 const char *fmt;
kono
parents: 67
diff changeset
1986 enum rtx_code code;
kono
parents: 67
diff changeset
1987 int i, j, len, new_opno;
kono
parents: 67
diff changeset
1988 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
1989
kono
parents: 67
diff changeset
1990 if (code == MATCH_OPERAND
kono
parents: 67
diff changeset
1991 || code == MATCH_OPERATOR)
kono
parents: 67
diff changeset
1992 {
kono
parents: 67
diff changeset
1993 new_opno = find_first_unused_number_of_operand ();
kono
parents: 67
diff changeset
1994 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
1995 XINT (pattern, 0) = new_opno;
kono
parents: 67
diff changeset
1996 used_operands_numbers [new_opno] = 1;
kono
parents: 67
diff changeset
1997 }
kono
parents: 67
diff changeset
1998
kono
parents: 67
diff changeset
1999 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
2000 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
2001 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2002 {
kono
parents: 67
diff changeset
2003 switch (fmt[i])
kono
parents: 67
diff changeset
2004 {
kono
parents: 67
diff changeset
2005 case 'e': case 'u':
kono
parents: 67
diff changeset
2006 renumerate_operands_in_pattern (XEXP (pattern, i));
kono
parents: 67
diff changeset
2007 break;
kono
parents: 67
diff changeset
2008 case 'E':
kono
parents: 67
diff changeset
2009 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
2010 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
kono
parents: 67
diff changeset
2011 break;
kono
parents: 67
diff changeset
2012 }
kono
parents: 67
diff changeset
2013 }
kono
parents: 67
diff changeset
2014 }
kono
parents: 67
diff changeset
2015
kono
parents: 67
diff changeset
2016 /* If output pattern of define_subst contains MATCH_DUP, then this
kono
parents: 67
diff changeset
2017 expression would be replaced with the pattern, matched with
kono
parents: 67
diff changeset
2018 MATCH_OPERAND from input pattern. This pattern could contain any
kono
parents: 67
diff changeset
2019 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
kono
parents: 67
diff changeset
2020 that a MATCH_OPERAND from output_pattern (if any) would have the
kono
parents: 67
diff changeset
2021 same number, as MATCH_OPERAND from copied pattern. To avoid such
kono
parents: 67
diff changeset
2022 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
kono
parents: 67
diff changeset
2023 laying in the output pattern outside of MATCH_DUPs. */
kono
parents: 67
diff changeset
2024 static rtx
kono
parents: 67
diff changeset
2025 adjust_operands_numbers (rtx pattern)
kono
parents: 67
diff changeset
2026 {
kono
parents: 67
diff changeset
2027 mark_operands_used_in_match_dup (pattern);
kono
parents: 67
diff changeset
2028
kono
parents: 67
diff changeset
2029 renumerate_operands_in_pattern (pattern);
kono
parents: 67
diff changeset
2030
kono
parents: 67
diff changeset
2031 return pattern;
kono
parents: 67
diff changeset
2032 }
kono
parents: 67
diff changeset
2033
kono
parents: 67
diff changeset
2034 /* Generate RTL expression
kono
parents: 67
diff changeset
2035 (match_dup OPNO)
kono
parents: 67
diff changeset
2036 */
kono
parents: 67
diff changeset
2037 static rtx
kono
parents: 67
diff changeset
2038 generate_match_dup (int opno)
kono
parents: 67
diff changeset
2039 {
kono
parents: 67
diff changeset
2040 rtx return_rtx = rtx_alloc (MATCH_DUP);
kono
parents: 67
diff changeset
2041 PUT_CODE (return_rtx, MATCH_DUP);
kono
parents: 67
diff changeset
2042 XINT (return_rtx, 0) = opno;
kono
parents: 67
diff changeset
2043 return return_rtx;
kono
parents: 67
diff changeset
2044 }
kono
parents: 67
diff changeset
2045
kono
parents: 67
diff changeset
2046 /* This routine checks all match_operands in PATTERN and if some of
kono
parents: 67
diff changeset
2047 have the same index, it replaces all of them except the first one to
kono
parents: 67
diff changeset
2048 match_dup.
kono
parents: 67
diff changeset
2049 Usually, match_operands with the same indexes are forbidden, but
kono
parents: 67
diff changeset
2050 after define_subst copy an RTL-expression from original template,
kono
parents: 67
diff changeset
2051 indexes of existed and just-copied match_operands could coincide.
kono
parents: 67
diff changeset
2052 To fix it, we replace one of them with match_dup. */
kono
parents: 67
diff changeset
2053 static rtx
kono
parents: 67
diff changeset
2054 replace_duplicating_operands_in_pattern (rtx pattern)
kono
parents: 67
diff changeset
2055 {
kono
parents: 67
diff changeset
2056 const char *fmt;
kono
parents: 67
diff changeset
2057 int i, j, len, opno;
kono
parents: 67
diff changeset
2058 rtx mdup;
kono
parents: 67
diff changeset
2059
kono
parents: 67
diff changeset
2060 if (GET_CODE (pattern) == MATCH_OPERAND)
kono
parents: 67
diff changeset
2061 {
kono
parents: 67
diff changeset
2062 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
2063 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
2064 if (match_operand_entries_in_pattern[opno] == NULL)
kono
parents: 67
diff changeset
2065 {
kono
parents: 67
diff changeset
2066 match_operand_entries_in_pattern[opno] = pattern;
kono
parents: 67
diff changeset
2067 return NULL;
kono
parents: 67
diff changeset
2068 }
kono
parents: 67
diff changeset
2069 else
kono
parents: 67
diff changeset
2070 {
kono
parents: 67
diff changeset
2071 /* Compare predicates before replacing with match_dup. */
kono
parents: 67
diff changeset
2072 if (strcmp (XSTR (pattern, 1),
kono
parents: 67
diff changeset
2073 XSTR (match_operand_entries_in_pattern[opno], 1)))
kono
parents: 67
diff changeset
2074 {
kono
parents: 67
diff changeset
2075 error ("duplicated match_operands with different predicates were"
kono
parents: 67
diff changeset
2076 " found.");
kono
parents: 67
diff changeset
2077 return NULL;
kono
parents: 67
diff changeset
2078 }
kono
parents: 67
diff changeset
2079 return generate_match_dup (opno);
kono
parents: 67
diff changeset
2080 }
kono
parents: 67
diff changeset
2081 }
kono
parents: 67
diff changeset
2082 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
2083 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
2084 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2085 {
kono
parents: 67
diff changeset
2086 switch (fmt[i])
kono
parents: 67
diff changeset
2087 {
kono
parents: 67
diff changeset
2088 case 'e': case 'u':
kono
parents: 67
diff changeset
2089 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
kono
parents: 67
diff changeset
2090 if (mdup)
kono
parents: 67
diff changeset
2091 XEXP (pattern, i) = mdup;
kono
parents: 67
diff changeset
2092 break;
kono
parents: 67
diff changeset
2093 case 'E':
kono
parents: 67
diff changeset
2094 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
2095 {
kono
parents: 67
diff changeset
2096 mdup =
kono
parents: 67
diff changeset
2097 replace_duplicating_operands_in_pattern (XVECEXP
kono
parents: 67
diff changeset
2098 (pattern, i, j));
kono
parents: 67
diff changeset
2099 if (mdup)
kono
parents: 67
diff changeset
2100 XVECEXP (pattern, i, j) = mdup;
kono
parents: 67
diff changeset
2101 }
kono
parents: 67
diff changeset
2102 break;
kono
parents: 67
diff changeset
2103 }
kono
parents: 67
diff changeset
2104 }
kono
parents: 67
diff changeset
2105 return NULL;
kono
parents: 67
diff changeset
2106 }
kono
parents: 67
diff changeset
2107
kono
parents: 67
diff changeset
2108 /* The routine modifies given input PATTERN of define_subst, replacing
kono
parents: 67
diff changeset
2109 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
kono
parents: 67
diff changeset
2110 pattern, whose operands are stored in OPERAND_DATA array.
kono
parents: 67
diff changeset
2111 It also duplicates constraints in operands - constraints from
kono
parents: 67
diff changeset
2112 define_insn operands are duplicated N_SUBST_ALT times, constraints
kono
parents: 67
diff changeset
2113 from define_subst operands are duplicated N_ALT times.
kono
parents: 67
diff changeset
2114 After the duplication, returned output rtl-pattern contains every
kono
parents: 67
diff changeset
2115 combination of input constraints Vs constraints from define_subst
kono
parents: 67
diff changeset
2116 output. */
kono
parents: 67
diff changeset
2117 static rtx
kono
parents: 67
diff changeset
2118 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
kono
parents: 67
diff changeset
2119 {
kono
parents: 67
diff changeset
2120 const char *fmt;
kono
parents: 67
diff changeset
2121 enum rtx_code code;
kono
parents: 67
diff changeset
2122 int i, j, len, opno;
kono
parents: 67
diff changeset
2123
kono
parents: 67
diff changeset
2124 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
2125 switch (code)
kono
parents: 67
diff changeset
2126 {
kono
parents: 67
diff changeset
2127 case MATCH_DUP:
kono
parents: 67
diff changeset
2128 case MATCH_OP_DUP:
kono
parents: 67
diff changeset
2129 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
2130
kono
parents: 67
diff changeset
2131 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
2132
kono
parents: 67
diff changeset
2133 if (operand_data[opno])
kono
parents: 67
diff changeset
2134 {
kono
parents: 67
diff changeset
2135 pattern = copy_rtx (operand_data[opno]);
kono
parents: 67
diff changeset
2136
kono
parents: 67
diff changeset
2137 /* Duplicate constraints. */
kono
parents: 67
diff changeset
2138 pattern = alter_constraints (pattern, n_subst_alt,
kono
parents: 67
diff changeset
2139 duplicate_alternatives);
kono
parents: 67
diff changeset
2140 }
kono
parents: 67
diff changeset
2141 break;
kono
parents: 67
diff changeset
2142
kono
parents: 67
diff changeset
2143 default:
kono
parents: 67
diff changeset
2144 break;
kono
parents: 67
diff changeset
2145 }
kono
parents: 67
diff changeset
2146
kono
parents: 67
diff changeset
2147 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
2148 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
2149 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2150 {
kono
parents: 67
diff changeset
2151 switch (fmt[i])
kono
parents: 67
diff changeset
2152 {
kono
parents: 67
diff changeset
2153 case 'e': case 'u':
kono
parents: 67
diff changeset
2154 if (code != MATCH_DUP && code != MATCH_OP_DUP)
kono
parents: 67
diff changeset
2155 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
kono
parents: 67
diff changeset
2156 n_alt, n_subst_alt);
kono
parents: 67
diff changeset
2157 break;
kono
parents: 67
diff changeset
2158 case 'V':
kono
parents: 67
diff changeset
2159 if (XVEC (pattern, i) == NULL)
kono
parents: 67
diff changeset
2160 break;
kono
parents: 67
diff changeset
2161 /* FALLTHRU */
kono
parents: 67
diff changeset
2162 case 'E':
kono
parents: 67
diff changeset
2163 if (code != MATCH_DUP && code != MATCH_OP_DUP)
kono
parents: 67
diff changeset
2164 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
2165 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
kono
parents: 67
diff changeset
2166 n_alt, n_subst_alt);
kono
parents: 67
diff changeset
2167 break;
kono
parents: 67
diff changeset
2168
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2169 case 'r': case 'p': case 'i': case 'w':
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2170 case '0': case 's': case 'S': case 'T':
111
kono
parents: 67
diff changeset
2171 break;
kono
parents: 67
diff changeset
2172
kono
parents: 67
diff changeset
2173 default:
kono
parents: 67
diff changeset
2174 gcc_unreachable ();
kono
parents: 67
diff changeset
2175 }
kono
parents: 67
diff changeset
2176 }
kono
parents: 67
diff changeset
2177 return pattern;
kono
parents: 67
diff changeset
2178 }
kono
parents: 67
diff changeset
2179
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2180 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2181 patterns appropriately. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2182
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2183 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2184 process_define_cond_exec (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2185 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2186 struct queue_elem *elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2187
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2188 identify_predicable_attribute ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2189 if (have_error)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2190 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2191
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2192 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2193 process_one_cond_exec (elem);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2194 }
111
kono
parents: 67
diff changeset
2195
kono
parents: 67
diff changeset
2196 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
kono
parents: 67
diff changeset
2197 DEFINE_EXPAND patterns appropriately. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2198
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2199 static void
111
kono
parents: 67
diff changeset
2200 process_define_subst (void)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2201 {
111
kono
parents: 67
diff changeset
2202 struct queue_elem *elem, *elem_attr;
kono
parents: 67
diff changeset
2203
kono
parents: 67
diff changeset
2204 /* Check if each define_subst has corresponding define_subst_attr. */
kono
parents: 67
diff changeset
2205 for (elem = define_subst_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
2206 {
kono
parents: 67
diff changeset
2207 for (elem_attr = define_subst_attr_queue;
kono
parents: 67
diff changeset
2208 elem_attr;
kono
parents: 67
diff changeset
2209 elem_attr = elem_attr->next)
kono
parents: 67
diff changeset
2210 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
kono
parents: 67
diff changeset
2211 goto found;
kono
parents: 67
diff changeset
2212
kono
parents: 67
diff changeset
2213 error_at (elem->loc,
kono
parents: 67
diff changeset
2214 "%s: `define_subst' must have at least one "
kono
parents: 67
diff changeset
2215 "corresponding `define_subst_attr'",
kono
parents: 67
diff changeset
2216 XSTR (elem->data, 0));
kono
parents: 67
diff changeset
2217 return;
kono
parents: 67
diff changeset
2218
kono
parents: 67
diff changeset
2219 found:
kono
parents: 67
diff changeset
2220 continue;
kono
parents: 67
diff changeset
2221 }
kono
parents: 67
diff changeset
2222
kono
parents: 67
diff changeset
2223 for (elem = define_insn_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
2224 process_substs_on_one_elem (elem, define_insn_queue);
kono
parents: 67
diff changeset
2225 for (elem = other_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
2226 {
kono
parents: 67
diff changeset
2227 if (GET_CODE (elem->data) != DEFINE_EXPAND)
kono
parents: 67
diff changeset
2228 continue;
kono
parents: 67
diff changeset
2229 process_substs_on_one_elem (elem, other_queue);
kono
parents: 67
diff changeset
2230 }
kono
parents: 67
diff changeset
2231 }
kono
parents: 67
diff changeset
2232
kono
parents: 67
diff changeset
2233 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
kono
parents: 67
diff changeset
2234 the top-level elements. */
kono
parents: 67
diff changeset
2235
kono
parents: 67
diff changeset
2236 class gen_reader : public rtx_reader
kono
parents: 67
diff changeset
2237 {
kono
parents: 67
diff changeset
2238 public:
kono
parents: 67
diff changeset
2239 gen_reader () : rtx_reader (false) {}
kono
parents: 67
diff changeset
2240 void handle_unknown_directive (file_location, const char *);
kono
parents: 67
diff changeset
2241 };
kono
parents: 67
diff changeset
2242
kono
parents: 67
diff changeset
2243 void
kono
parents: 67
diff changeset
2244 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
kono
parents: 67
diff changeset
2245 {
kono
parents: 67
diff changeset
2246 auto_vec<rtx, 32> subrtxs;
kono
parents: 67
diff changeset
2247 if (!read_rtx (rtx_name, &subrtxs))
kono
parents: 67
diff changeset
2248 return;
kono
parents: 67
diff changeset
2249
kono
parents: 67
diff changeset
2250 rtx x;
kono
parents: 67
diff changeset
2251 unsigned int i;
kono
parents: 67
diff changeset
2252 FOR_EACH_VEC_ELT (subrtxs, i, x)
kono
parents: 67
diff changeset
2253 process_rtx (x, loc);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2254 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2255
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2256 /* Comparison function for the mnemonic hash table. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2257
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2258 static int
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2259 htab_eq_string (const void *s1, const void *s2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2260 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2261 return strcmp ((const char*)s1, (const char*)s2) == 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2262 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2263
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2264 /* Add mnemonic STR with length LEN to the mnemonic hash table
111
kono
parents: 67
diff changeset
2265 MNEMONIC_HTAB. A trailing zero end character is appended to STR
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2266 and a permanent heap copy of STR is created. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2267
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2268 static void
111
kono
parents: 67
diff changeset
2269 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2270 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2271 char *new_str;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2272 void **slot;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2273 char *str_zero = (char*)alloca (len + 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2274
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2275 memcpy (str_zero, str, len);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2276 str_zero[len] = '\0';
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2277
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2278 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2279
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2280 if (*slot)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2281 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2282
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2283 /* Not found; create a permanent copy and add it to the hash table. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2284 new_str = XNEWVAR (char, len + 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2285 memcpy (new_str, str_zero, len + 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2286 *slot = new_str;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2287 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2288
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2289 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2290 table in MNEMONIC_HTAB.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2291
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2292 The mnemonics cannot be found if they are emitted using C code.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2293
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2294 If a mnemonic string contains ';' or a newline the string assumed
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2295 to consist of more than a single instruction. The attribute value
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2296 will then be set to the user defined default value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2297
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2298 static void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2299 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2300 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2301 const char *template_code, *cp;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2302 int i;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2303 int vec_len;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2304 rtx set_attr;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2305 char *attr_name;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2306 rtvec new_vec;
111
kono
parents: 67
diff changeset
2307 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2308
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2309 template_code = XTMPL (insn, 3);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2310
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2311 /* Skip patterns which use C code to emit the template. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2312 if (template_code[0] == '*')
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2313 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2314
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2315 if (template_code[0] == '@')
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2316 cp = &template_code[1];
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2317 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2318 cp = &template_code[0];
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2319
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2320 for (i = 0; *cp; )
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2321 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2322 const char *ep, *sp;
111
kono
parents: 67
diff changeset
2323 size_t size = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2324
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2325 while (ISSPACE (*cp))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2326 cp++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2327
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2328 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2329 if (!ISSPACE (*ep))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2330 sp = ep + 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2331
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2332 if (i > 0)
111
kono
parents: 67
diff changeset
2333 obstack_1grow (string_obstack, ',');
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2334
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2335 while (cp < sp && ((*cp >= '0' && *cp <= '9')
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2336 || (*cp >= 'a' && *cp <= 'z')))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2337
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2338 {
111
kono
parents: 67
diff changeset
2339 obstack_1grow (string_obstack, *cp);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2340 cp++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2341 size++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2342 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2343
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2344 while (cp < sp)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2345 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2346 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2347 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2348 /* Don't set a value if there are more than one
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2349 instruction in the string. */
111
kono
parents: 67
diff changeset
2350 obstack_blank_fast (string_obstack, -size);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2351 size = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2352
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2353 cp = sp;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2354 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2355 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2356 cp++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2357 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2358 if (size == 0)
111
kono
parents: 67
diff changeset
2359 obstack_1grow (string_obstack, '*');
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2360 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2361 add_mnemonic_string (mnemonic_htab,
111
kono
parents: 67
diff changeset
2362 (char *) obstack_next_free (string_obstack) - size,
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2363 size);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2364 i++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2365 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2366
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2367 /* An insn definition might emit an empty string. */
111
kono
parents: 67
diff changeset
2368 if (obstack_object_size (string_obstack) == 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2369 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2370
111
kono
parents: 67
diff changeset
2371 obstack_1grow (string_obstack, '\0');
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2372
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2373 set_attr = rtx_alloc (SET_ATTR);
111
kono
parents: 67
diff changeset
2374 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2375 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2376 strcpy (attr_name, MNEMONIC_ATTR_NAME);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2377 XSTR (set_attr, 0) = attr_name;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2378
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2379 if (!XVEC (insn, 4))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2380 vec_len = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2381 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2382 vec_len = XVECLEN (insn, 4);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2383
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2384 new_vec = rtvec_alloc (vec_len + 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2385 for (i = 0; i < vec_len; i++)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2386 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2387 RTVEC_ELT (new_vec, vec_len) = set_attr;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2388 XVEC (insn, 4) = new_vec;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2389 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2390
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2391 /* This function is called for the elements in the mnemonic hashtable
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2392 and generates a comma separated list of the mnemonics. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2393
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2394 static int
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2395 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2396 {
111
kono
parents: 67
diff changeset
2397 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
kono
parents: 67
diff changeset
2398
kono
parents: 67
diff changeset
2399 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
kono
parents: 67
diff changeset
2400 obstack_1grow (string_obstack, ',');
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2401 return 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2402 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2403
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2404 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2405 insn definition in case the back end requests it by defining the
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2406 mnemonic attribute. The values for the attribute will be extracted
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2407 from the output patterns of the insn definitions as far as
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2408 possible. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2409
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2410 static void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2411 gen_mnemonic_attr (void)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2412 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2413 struct queue_elem *elem;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2414 rtx mnemonic_attr = NULL;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2415 htab_t mnemonic_htab;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2416 const char *str, *p;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2417 int i;
111
kono
parents: 67
diff changeset
2418 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2419
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2420 if (have_error)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2421 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2422
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2423 /* Look for the DEFINE_ATTR for `mnemonic'. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2424 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2425 if (GET_CODE (elem->data) == DEFINE_ATTR
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2426 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2427 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2428 mnemonic_attr = elem->data;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2429 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2430 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2431
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2432 /* A (define_attr "mnemonic" "...") indicates that the back-end
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2433 wants a mnemonic attribute to be generated. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2434 if (!mnemonic_attr)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2435 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2436
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2437 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2438 htab_eq_string, 0, xcalloc, free);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2439
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2440 for (elem = define_insn_queue; elem; elem = elem->next)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2441 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2442 rtx insn = elem->data;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2443 bool found = false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2444
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2445 /* Check if the insn definition already has
111
kono
parents: 67
diff changeset
2446 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2447 if (XVEC (insn, 4))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2448 for (i = 0; i < XVECLEN (insn, 4); i++)
111
kono
parents: 67
diff changeset
2449 {
kono
parents: 67
diff changeset
2450 rtx set_attr = XVECEXP (insn, 4, i);
kono
parents: 67
diff changeset
2451
kono
parents: 67
diff changeset
2452 switch (GET_CODE (set_attr))
kono
parents: 67
diff changeset
2453 {
kono
parents: 67
diff changeset
2454 case SET_ATTR:
kono
parents: 67
diff changeset
2455 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
2456 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
kono
parents: 67
diff changeset
2457 found = true;
kono
parents: 67
diff changeset
2458 break;
kono
parents: 67
diff changeset
2459 case SET:
kono
parents: 67
diff changeset
2460 if (GET_CODE (SET_DEST (set_attr)) == ATTR
kono
parents: 67
diff changeset
2461 && strcmp (XSTR (SET_DEST (set_attr), 0),
kono
parents: 67
diff changeset
2462 MNEMONIC_ATTR_NAME) == 0)
kono
parents: 67
diff changeset
2463 found = true;
kono
parents: 67
diff changeset
2464 break;
kono
parents: 67
diff changeset
2465 default:
kono
parents: 67
diff changeset
2466 break;
kono
parents: 67
diff changeset
2467 }
kono
parents: 67
diff changeset
2468 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2469
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2470 if (!found)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2471 gen_mnemonic_setattr (mnemonic_htab, insn);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2472 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2473
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2474 /* Add the user defined values to the hash table. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2475 str = XSTR (mnemonic_attr, 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2476 while ((p = scan_comma_elt (&str)) != NULL)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2477 add_mnemonic_string (mnemonic_htab, p, str - p);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2478
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2479 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2480
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2481 /* Replace the last ',' with the zero end character. */
111
kono
parents: 67
diff changeset
2482 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
kono
parents: 67
diff changeset
2483 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
kono
parents: 67
diff changeset
2484 }
kono
parents: 67
diff changeset
2485
kono
parents: 67
diff changeset
2486 /* Check if there are DEFINE_ATTRs with the same name. */
kono
parents: 67
diff changeset
2487 static void
kono
parents: 67
diff changeset
2488 check_define_attr_duplicates ()
kono
parents: 67
diff changeset
2489 {
kono
parents: 67
diff changeset
2490 struct queue_elem *elem;
kono
parents: 67
diff changeset
2491 htab_t attr_htab;
kono
parents: 67
diff changeset
2492 char * attr_name;
kono
parents: 67
diff changeset
2493 void **slot;
kono
parents: 67
diff changeset
2494
kono
parents: 67
diff changeset
2495 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
kono
parents: 67
diff changeset
2496
kono
parents: 67
diff changeset
2497 for (elem = define_attr_queue; elem; elem = elem->next)
kono
parents: 67
diff changeset
2498 {
kono
parents: 67
diff changeset
2499 attr_name = xstrdup (XSTR (elem->data, 0));
kono
parents: 67
diff changeset
2500
kono
parents: 67
diff changeset
2501 slot = htab_find_slot (attr_htab, attr_name, INSERT);
kono
parents: 67
diff changeset
2502
kono
parents: 67
diff changeset
2503 /* Duplicate. */
kono
parents: 67
diff changeset
2504 if (*slot)
kono
parents: 67
diff changeset
2505 {
kono
parents: 67
diff changeset
2506 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
kono
parents: 67
diff changeset
2507 htab_delete (attr_htab);
kono
parents: 67
diff changeset
2508 return;
kono
parents: 67
diff changeset
2509 }
kono
parents: 67
diff changeset
2510
kono
parents: 67
diff changeset
2511 *slot = attr_name;
kono
parents: 67
diff changeset
2512 }
kono
parents: 67
diff changeset
2513
kono
parents: 67
diff changeset
2514 htab_delete (attr_htab);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2515 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2516
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2517 /* The entry point for initializing the reader. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2518
111
kono
parents: 67
diff changeset
2519 rtx_reader *
kono
parents: 67
diff changeset
2520 init_rtx_reader_args_cb (int argc, const char **argv,
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2521 bool (*parse_opt) (const char *))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2522 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2523 /* Prepare to read input. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2524 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2525 init_predicate_table ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2526 obstack_init (rtl_obstack);
111
kono
parents: 67
diff changeset
2527
kono
parents: 67
diff changeset
2528 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
kono
parents: 67
diff changeset
2529 insn_sequence_num = 1;
kono
parents: 67
diff changeset
2530
kono
parents: 67
diff changeset
2531 /* These sequences are not used as indices, so can start at 1 also. */
kono
parents: 67
diff changeset
2532 split_sequence_num = 1;
kono
parents: 67
diff changeset
2533 peephole2_sequence_num = 1;
kono
parents: 67
diff changeset
2534
kono
parents: 67
diff changeset
2535 gen_reader *reader = new gen_reader ();
kono
parents: 67
diff changeset
2536 reader->read_md_files (argc, argv, parse_opt);
kono
parents: 67
diff changeset
2537
kono
parents: 67
diff changeset
2538 if (define_attr_queue != NULL)
kono
parents: 67
diff changeset
2539 check_define_attr_duplicates ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2540
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2541 /* Process define_cond_exec patterns. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2542 if (define_cond_exec_queue != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2543 process_define_cond_exec ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2544
111
kono
parents: 67
diff changeset
2545 /* Process define_subst patterns. */
kono
parents: 67
diff changeset
2546 if (define_subst_queue != NULL)
kono
parents: 67
diff changeset
2547 process_define_subst ();
kono
parents: 67
diff changeset
2548
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2549 if (define_attr_queue != NULL)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2550 gen_mnemonic_attr ();
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2551
111
kono
parents: 67
diff changeset
2552 if (have_error)
kono
parents: 67
diff changeset
2553 {
kono
parents: 67
diff changeset
2554 delete reader;
kono
parents: 67
diff changeset
2555 return NULL;
kono
parents: 67
diff changeset
2556 }
kono
parents: 67
diff changeset
2557
kono
parents: 67
diff changeset
2558 return reader;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2559 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2560
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2561 /* Programs that don't have their own options can use this entry point
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2562 instead. */
111
kono
parents: 67
diff changeset
2563 rtx_reader *
kono
parents: 67
diff changeset
2564 init_rtx_reader_args (int argc, const char **argv)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2565 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2566 return init_rtx_reader_args_cb (argc, argv, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2567 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2568
111
kono
parents: 67
diff changeset
2569 /* Try to read a single rtx from the file. Return true on success,
kono
parents: 67
diff changeset
2570 describing it in *INFO. */
kono
parents: 67
diff changeset
2571
kono
parents: 67
diff changeset
2572 bool
kono
parents: 67
diff changeset
2573 read_md_rtx (md_rtx_info *info)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2574 {
111
kono
parents: 67
diff changeset
2575 int truth, *counter;
kono
parents: 67
diff changeset
2576 rtx def;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2577
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2578 /* Discard insn patterns which we know can never match (because
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2579 their C test is provably always false). If insn_elision is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2580 false, our caller needs to see all the patterns. Note that the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2581 elided patterns are never counted by the sequence numbering; it
111
kono
parents: 67
diff changeset
2582 is the caller's responsibility, when insn_elision is false, not
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2583 to use elided pattern numbers for anything. */
111
kono
parents: 67
diff changeset
2584 do
kono
parents: 67
diff changeset
2585 {
kono
parents: 67
diff changeset
2586 struct queue_elem **queue, *elem;
kono
parents: 67
diff changeset
2587
kono
parents: 67
diff changeset
2588 /* Read all patterns from a given queue before moving on to the next. */
kono
parents: 67
diff changeset
2589 if (define_attr_queue != NULL)
kono
parents: 67
diff changeset
2590 queue = &define_attr_queue;
kono
parents: 67
diff changeset
2591 else if (define_pred_queue != NULL)
kono
parents: 67
diff changeset
2592 queue = &define_pred_queue;
kono
parents: 67
diff changeset
2593 else if (define_insn_queue != NULL)
kono
parents: 67
diff changeset
2594 queue = &define_insn_queue;
kono
parents: 67
diff changeset
2595 else if (other_queue != NULL)
kono
parents: 67
diff changeset
2596 queue = &other_queue;
kono
parents: 67
diff changeset
2597 else
kono
parents: 67
diff changeset
2598 return false;
kono
parents: 67
diff changeset
2599
kono
parents: 67
diff changeset
2600 elem = *queue;
kono
parents: 67
diff changeset
2601 *queue = elem->next;
kono
parents: 67
diff changeset
2602 def = elem->data;
kono
parents: 67
diff changeset
2603 info->def = def;
kono
parents: 67
diff changeset
2604 info->loc = elem->loc;
kono
parents: 67
diff changeset
2605 free (elem);
kono
parents: 67
diff changeset
2606
kono
parents: 67
diff changeset
2607 truth = maybe_eval_c_test (get_c_test (def));
kono
parents: 67
diff changeset
2608 }
kono
parents: 67
diff changeset
2609 while (truth == 0 && insn_elision);
kono
parents: 67
diff changeset
2610
kono
parents: 67
diff changeset
2611 /* Perform code-specific processing and pick the appropriate sequence
kono
parents: 67
diff changeset
2612 number counter. */
kono
parents: 67
diff changeset
2613 switch (GET_CODE (def))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2614 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2615 case DEFINE_INSN:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2616 case DEFINE_EXPAND:
111
kono
parents: 67
diff changeset
2617 /* insn_sequence_num is used here so the name table will match caller's
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2618 idea of insn numbering, whether or not elision is active. */
111
kono
parents: 67
diff changeset
2619 record_insn_name (insn_sequence_num, XSTR (def, 0));
kono
parents: 67
diff changeset
2620
kono
parents: 67
diff changeset
2621 /* Fall through. */
kono
parents: 67
diff changeset
2622 case DEFINE_PEEPHOLE:
kono
parents: 67
diff changeset
2623 counter = &insn_sequence_num;
kono
parents: 67
diff changeset
2624 break;
kono
parents: 67
diff changeset
2625
kono
parents: 67
diff changeset
2626 case DEFINE_SPLIT:
kono
parents: 67
diff changeset
2627 counter = &split_sequence_num;
kono
parents: 67
diff changeset
2628 break;
kono
parents: 67
diff changeset
2629
kono
parents: 67
diff changeset
2630 case DEFINE_PEEPHOLE2:
kono
parents: 67
diff changeset
2631 counter = &peephole2_sequence_num;
kono
parents: 67
diff changeset
2632 break;
kono
parents: 67
diff changeset
2633
kono
parents: 67
diff changeset
2634 default:
kono
parents: 67
diff changeset
2635 counter = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2636 break;
111
kono
parents: 67
diff changeset
2637 }
kono
parents: 67
diff changeset
2638
kono
parents: 67
diff changeset
2639 if (counter)
kono
parents: 67
diff changeset
2640 {
kono
parents: 67
diff changeset
2641 info->index = *counter;
kono
parents: 67
diff changeset
2642 if (truth != 0)
kono
parents: 67
diff changeset
2643 *counter += 1;
kono
parents: 67
diff changeset
2644 }
kono
parents: 67
diff changeset
2645 else
kono
parents: 67
diff changeset
2646 info->index = -1;
kono
parents: 67
diff changeset
2647
kono
parents: 67
diff changeset
2648 if (!rtx_locs)
kono
parents: 67
diff changeset
2649 rtx_locs = new hash_map <rtx, file_location>;
kono
parents: 67
diff changeset
2650 rtx_locs->put (info->def, info->loc);
kono
parents: 67
diff changeset
2651
kono
parents: 67
diff changeset
2652 return true;
kono
parents: 67
diff changeset
2653 }
kono
parents: 67
diff changeset
2654
kono
parents: 67
diff changeset
2655 /* Return the file location of DEFINE_* rtx X, which was previously
kono
parents: 67
diff changeset
2656 returned by read_md_rtx. */
kono
parents: 67
diff changeset
2657 file_location
kono
parents: 67
diff changeset
2658 get_file_location (rtx x)
kono
parents: 67
diff changeset
2659 {
kono
parents: 67
diff changeset
2660 gcc_assert (rtx_locs);
kono
parents: 67
diff changeset
2661 file_location *entry = rtx_locs->get (x);
kono
parents: 67
diff changeset
2662 gcc_assert (entry);
kono
parents: 67
diff changeset
2663 return *entry;
kono
parents: 67
diff changeset
2664 }
kono
parents: 67
diff changeset
2665
kono
parents: 67
diff changeset
2666 /* Return the number of possible INSN_CODEs. Only meaningful once the
kono
parents: 67
diff changeset
2667 whole file has been processed. */
kono
parents: 67
diff changeset
2668 unsigned int
kono
parents: 67
diff changeset
2669 get_num_insn_codes ()
kono
parents: 67
diff changeset
2670 {
kono
parents: 67
diff changeset
2671 return insn_sequence_num;
kono
parents: 67
diff changeset
2672 }
kono
parents: 67
diff changeset
2673
kono
parents: 67
diff changeset
2674 /* Return the C test that says whether definition rtx DEF can be used,
kono
parents: 67
diff changeset
2675 or "" if it can be used unconditionally. */
kono
parents: 67
diff changeset
2676
kono
parents: 67
diff changeset
2677 const char *
kono
parents: 67
diff changeset
2678 get_c_test (rtx x)
kono
parents: 67
diff changeset
2679 {
kono
parents: 67
diff changeset
2680 switch (GET_CODE (x))
kono
parents: 67
diff changeset
2681 {
kono
parents: 67
diff changeset
2682 case DEFINE_INSN:
kono
parents: 67
diff changeset
2683 case DEFINE_EXPAND:
kono
parents: 67
diff changeset
2684 case DEFINE_SUBST:
kono
parents: 67
diff changeset
2685 return XSTR (x, 2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2686
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2687 case DEFINE_SPLIT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2688 case DEFINE_PEEPHOLE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2689 case DEFINE_PEEPHOLE2:
111
kono
parents: 67
diff changeset
2690 return XSTR (x, 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2692 default:
111
kono
parents: 67
diff changeset
2693 return "";
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2694 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2695 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2696
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2697 /* Helper functions for insn elision. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2698
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2699 /* Compute a hash function of a c_test structure, which is keyed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2700 by its ->expr field. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2701 hashval_t
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2702 hash_c_test (const void *x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2703 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2704 const struct c_test *a = (const struct c_test *) x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2705 const unsigned char *base, *s = (const unsigned char *) a->expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2706 hashval_t hash;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2707 unsigned char c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2708 unsigned int len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2709
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2710 base = s;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2711 hash = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2712
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2713 while ((c = *s++) != '\0')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2714 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2715 hash += c + (c << 17);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2716 hash ^= hash >> 2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2717 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2718
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2719 len = s - base;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2720 hash += len + (len << 17);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2721 hash ^= hash >> 2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2722
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2723 return hash;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2724 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2725
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2726 /* Compare two c_test expression structures. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2727 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2728 cmp_c_test (const void *x, const void *y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2729 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2730 const struct c_test *a = (const struct c_test *) x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2731 const struct c_test *b = (const struct c_test *) y;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2733 return !strcmp (a->expr, b->expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2734 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2735
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2736 /* Given a string representing a C test expression, look it up in the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2737 condition_table and report whether or not its value is known
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2738 at compile time. Returns a tristate: 1 for known true, 0 for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2739 known false, -1 for unknown. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2740 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2741 maybe_eval_c_test (const char *expr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2742 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2743 const struct c_test *test;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2744 struct c_test dummy;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2745
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2746 if (expr[0] == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2747 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2748
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2749 dummy.expr = expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2750 test = (const struct c_test *)htab_find (condition_table, &dummy);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2751 if (!test)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2752 return -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2753 return test->value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2754 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2755
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2756 /* Record the C test expression EXPR in the condition_table, with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2757 value VAL. Duplicates clobber previous entries. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2758
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2759 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2760 add_c_test (const char *expr, int value)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2761 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2762 struct c_test *test;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2763
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2764 if (expr[0] == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2765 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2766
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2767 test = XNEW (struct c_test);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2768 test->expr = expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2769 test->value = value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2770
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2771 *(htab_find_slot (condition_table, test, INSERT)) = test;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2772 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2773
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2774 /* For every C test, call CALLBACK with two arguments: a pointer to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2775 the condition structure and INFO. Stops when CALLBACK returns zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2776 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2777 traverse_c_tests (htab_trav callback, void *info)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2778 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2779 if (condition_table)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2780 htab_traverse (condition_table, callback, info);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2781 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2782
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2783 /* Helper functions for define_predicate and define_special_predicate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2784 processing. Shared between genrecog.c and genpreds.c. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2785
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2786 static htab_t predicate_table;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2787 struct pred_data *first_predicate;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2788 static struct pred_data **last_predicate = &first_predicate;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2789
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2790 static hashval_t
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2791 hash_struct_pred_data (const void *ptr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2792 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2793 return htab_hash_string (((const struct pred_data *)ptr)->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2794 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2795
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2796 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2797 eq_struct_pred_data (const void *a, const void *b)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2798 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2799 return !strcmp (((const struct pred_data *)a)->name,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2800 ((const struct pred_data *)b)->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2801 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2802
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2803 struct pred_data *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2804 lookup_predicate (const char *name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2805 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2806 struct pred_data key;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2807 key.name = name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2808 return (struct pred_data *) htab_find (predicate_table, &key);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2809 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2810
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2811 /* Record that predicate PRED can accept CODE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2812
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2813 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2814 add_predicate_code (struct pred_data *pred, enum rtx_code code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2815 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2816 if (!pred->codes[code])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2817 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2818 pred->num_codes++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2819 pred->codes[code] = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2820
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2821 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2822 pred->allows_non_const = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2823
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2824 if (code != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2825 && code != SUBREG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2826 && code != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2827 && code != CONCAT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2828 && code != PARALLEL
111
kono
parents: 67
diff changeset
2829 && code != STRICT_LOW_PART
kono
parents: 67
diff changeset
2830 && code != SCRATCH)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2831 pred->allows_non_lvalue = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2832
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2833 if (pred->num_codes == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2834 pred->singleton = code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2835 else if (pred->num_codes == 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2836 pred->singleton = UNKNOWN;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2837 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2838 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2839
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2840 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2841 add_predicate (struct pred_data *pred)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2842 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2843 void **slot = htab_find_slot (predicate_table, pred, INSERT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2844 if (*slot)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2845 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2846 error ("duplicate predicate definition for '%s'", pred->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2847 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2848 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2849 *slot = pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2850 *last_predicate = pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2851 last_predicate = &pred->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2852 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2853
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2854 /* This array gives the initial content of the predicate table. It
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2855 has entries for all predicates defined in recog.c. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2856
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2857 struct std_pred_table
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2858 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2859 const char *name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2860 bool special;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2861 bool allows_const_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2862 RTX_CODE codes[NUM_RTX_CODE];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2863 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2864
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2865 static const struct std_pred_table std_preds[] = {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2866 {"general_operand", false, true, {SUBREG, REG, MEM}},
111
kono
parents: 67
diff changeset
2867 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
kono
parents: 67
diff changeset
2868 ZERO_EXTEND, SIGN_EXTEND, AND}},
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2869 {"register_operand", false, false, {SUBREG, REG}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2870 {"pmode_register_operand", true, false, {SUBREG, REG}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2871 {"scratch_operand", false, false, {SCRATCH, REG}},
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2872 {"immediate_operand", false, true, {UNKNOWN}},
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2873 {"const_int_operand", false, false, {CONST_INT}},
111
kono
parents: 67
diff changeset
2874 #if TARGET_SUPPORTS_WIDE_INT
kono
parents: 67
diff changeset
2875 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
kono
parents: 67
diff changeset
2876 {"const_double_operand", false, false, {CONST_DOUBLE}},
kono
parents: 67
diff changeset
2877 #else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2878 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
111
kono
parents: 67
diff changeset
2879 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2880 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2881 {"nonmemory_operand", false, true, {SUBREG, REG}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2882 {"push_operand", false, false, {MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2883 {"pop_operand", false, false, {MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2884 {"memory_operand", false, false, {SUBREG, MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2885 {"indirect_operand", false, false, {SUBREG, MEM}},
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2886 {"ordered_comparison_operator", false, false, {EQ, NE,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2887 LE, LT, GE, GT,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2888 LEU, LTU, GEU, GTU}},
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2889 {"comparison_operator", false, false, {EQ, NE,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2890 LE, LT, GE, GT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2891 LEU, LTU, GEU, GTU,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2892 UNORDERED, ORDERED,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2893 UNEQ, UNGE, UNGT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2894 UNLE, UNLT, LTGT}}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2895 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2896 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2897
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2898 /* Initialize the table of predicate definitions, starting with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2899 the information we have on generic predicates. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2900
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2901 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2902 init_predicate_table (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2903 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2904 size_t i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2905 struct pred_data *pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2906
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2907 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2908 eq_struct_pred_data, 0,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2909 xcalloc, free);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2910
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2911 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2912 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2913 pred = XCNEW (struct pred_data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2914 pred->name = std_preds[i].name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2915 pred->special = std_preds[i].special;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2916
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2917 for (j = 0; std_preds[i].codes[j] != 0; j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2918 add_predicate_code (pred, std_preds[i].codes[j]);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2919
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2920 if (std_preds[i].allows_const_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2921 for (j = 0; j < NUM_RTX_CODE; j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2922 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2923 add_predicate_code (pred, (enum rtx_code) j);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2924
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2925 add_predicate (pred);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2926 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2927 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2928
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2929 /* These functions allow linkage with print-rtl.c. Also, some generators
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2930 like to annotate their output with insn names. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2931
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2932 /* Holds an array of names indexed by insn_code_number. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2933 static char **insn_name_ptr = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2934 static int insn_name_ptr_size = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2935
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2936 const char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2937 get_insn_name (int code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2938 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2939 if (code < insn_name_ptr_size)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2940 return insn_name_ptr[code];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2941 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2942 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2943 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2944
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2945 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2946 record_insn_name (int code, const char *name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2947 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2948 static const char *last_real_name = "insn";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2949 static int last_real_code = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2950 char *new_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2951
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2952 if (insn_name_ptr_size <= code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2953 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2954 int new_size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2955 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2956 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2957 memset (insn_name_ptr + insn_name_ptr_size, 0,
111
kono
parents: 67
diff changeset
2958 sizeof (char *) * (new_size - insn_name_ptr_size));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2959 insn_name_ptr_size = new_size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2960 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2961
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2962 if (!name || name[0] == '\0')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2963 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2964 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2965 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2966 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2967 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2968 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2969 last_real_name = new_name = xstrdup (name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2970 last_real_code = code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2971 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2972
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2973 insn_name_ptr[code] = new_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2974 }
111
kono
parents: 67
diff changeset
2975
kono
parents: 67
diff changeset
2976 /* Make STATS describe the operands that appear in rtx X. */
kono
parents: 67
diff changeset
2977
kono
parents: 67
diff changeset
2978 static void
kono
parents: 67
diff changeset
2979 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
kono
parents: 67
diff changeset
2980 {
kono
parents: 67
diff changeset
2981 RTX_CODE code;
kono
parents: 67
diff changeset
2982 int i;
kono
parents: 67
diff changeset
2983 int len;
kono
parents: 67
diff changeset
2984 const char *fmt;
kono
parents: 67
diff changeset
2985
kono
parents: 67
diff changeset
2986 if (x == NULL_RTX)
kono
parents: 67
diff changeset
2987 return;
kono
parents: 67
diff changeset
2988
kono
parents: 67
diff changeset
2989 code = GET_CODE (x);
kono
parents: 67
diff changeset
2990 switch (code)
kono
parents: 67
diff changeset
2991 {
kono
parents: 67
diff changeset
2992 case MATCH_OPERAND:
kono
parents: 67
diff changeset
2993 case MATCH_OPERATOR:
kono
parents: 67
diff changeset
2994 case MATCH_PARALLEL:
kono
parents: 67
diff changeset
2995 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
kono
parents: 67
diff changeset
2996 break;
kono
parents: 67
diff changeset
2997
kono
parents: 67
diff changeset
2998 case MATCH_DUP:
kono
parents: 67
diff changeset
2999 case MATCH_OP_DUP:
kono
parents: 67
diff changeset
3000 case MATCH_PAR_DUP:
kono
parents: 67
diff changeset
3001 stats->num_dups++;
kono
parents: 67
diff changeset
3002 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
kono
parents: 67
diff changeset
3003 break;
kono
parents: 67
diff changeset
3004
kono
parents: 67
diff changeset
3005 case MATCH_SCRATCH:
kono
parents: 67
diff changeset
3006 if (stats->min_scratch_opno == -1)
kono
parents: 67
diff changeset
3007 stats->min_scratch_opno = XINT (x, 0);
kono
parents: 67
diff changeset
3008 else
kono
parents: 67
diff changeset
3009 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
kono
parents: 67
diff changeset
3010 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
kono
parents: 67
diff changeset
3011 break;
kono
parents: 67
diff changeset
3012
kono
parents: 67
diff changeset
3013 default:
kono
parents: 67
diff changeset
3014 break;
kono
parents: 67
diff changeset
3015 }
kono
parents: 67
diff changeset
3016
kono
parents: 67
diff changeset
3017 fmt = GET_RTX_FORMAT (code);
kono
parents: 67
diff changeset
3018 len = GET_RTX_LENGTH (code);
kono
parents: 67
diff changeset
3019 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
3020 {
kono
parents: 67
diff changeset
3021 if (fmt[i] == 'e' || fmt[i] == 'u')
kono
parents: 67
diff changeset
3022 get_pattern_stats_1 (stats, XEXP (x, i));
kono
parents: 67
diff changeset
3023 else if (fmt[i] == 'E')
kono
parents: 67
diff changeset
3024 {
kono
parents: 67
diff changeset
3025 int j;
kono
parents: 67
diff changeset
3026 for (j = 0; j < XVECLEN (x, i); j++)
kono
parents: 67
diff changeset
3027 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
kono
parents: 67
diff changeset
3028 }
kono
parents: 67
diff changeset
3029 }
kono
parents: 67
diff changeset
3030 }
kono
parents: 67
diff changeset
3031
kono
parents: 67
diff changeset
3032 /* Make STATS describe the operands that appear in instruction pattern
kono
parents: 67
diff changeset
3033 PATTERN. */
kono
parents: 67
diff changeset
3034
kono
parents: 67
diff changeset
3035 void
kono
parents: 67
diff changeset
3036 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
kono
parents: 67
diff changeset
3037 {
kono
parents: 67
diff changeset
3038 int i, len;
kono
parents: 67
diff changeset
3039
kono
parents: 67
diff changeset
3040 stats->max_opno = -1;
kono
parents: 67
diff changeset
3041 stats->max_dup_opno = -1;
kono
parents: 67
diff changeset
3042 stats->min_scratch_opno = -1;
kono
parents: 67
diff changeset
3043 stats->max_scratch_opno = -1;
kono
parents: 67
diff changeset
3044 stats->num_dups = 0;
kono
parents: 67
diff changeset
3045
kono
parents: 67
diff changeset
3046 len = GET_NUM_ELEM (pattern);
kono
parents: 67
diff changeset
3047 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
3048 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
kono
parents: 67
diff changeset
3049
kono
parents: 67
diff changeset
3050 stats->num_generator_args = stats->max_opno + 1;
kono
parents: 67
diff changeset
3051 stats->num_insn_operands = MAX (stats->max_opno,
kono
parents: 67
diff changeset
3052 stats->max_scratch_opno) + 1;
kono
parents: 67
diff changeset
3053 stats->num_operand_vars = MAX (stats->max_opno,
kono
parents: 67
diff changeset
3054 MAX (stats->max_dup_opno,
kono
parents: 67
diff changeset
3055 stats->max_scratch_opno)) + 1;
kono
parents: 67
diff changeset
3056 }
kono
parents: 67
diff changeset
3057
kono
parents: 67
diff changeset
3058 /* Return the emit_* function that should be used for pattern X, or NULL
kono
parents: 67
diff changeset
3059 if we can't pick a particular type at compile time and should instead
kono
parents: 67
diff changeset
3060 fall back to "emit". */
kono
parents: 67
diff changeset
3061
kono
parents: 67
diff changeset
3062 const char *
kono
parents: 67
diff changeset
3063 get_emit_function (rtx x)
kono
parents: 67
diff changeset
3064 {
kono
parents: 67
diff changeset
3065 switch (classify_insn (x))
kono
parents: 67
diff changeset
3066 {
kono
parents: 67
diff changeset
3067 case INSN:
kono
parents: 67
diff changeset
3068 return "emit_insn";
kono
parents: 67
diff changeset
3069
kono
parents: 67
diff changeset
3070 case CALL_INSN:
kono
parents: 67
diff changeset
3071 return "emit_call_insn";
kono
parents: 67
diff changeset
3072
kono
parents: 67
diff changeset
3073 case JUMP_INSN:
kono
parents: 67
diff changeset
3074 return "emit_jump_insn";
kono
parents: 67
diff changeset
3075
kono
parents: 67
diff changeset
3076 case UNKNOWN:
kono
parents: 67
diff changeset
3077 return NULL;
kono
parents: 67
diff changeset
3078
kono
parents: 67
diff changeset
3079 default:
kono
parents: 67
diff changeset
3080 gcc_unreachable ();
kono
parents: 67
diff changeset
3081 }
kono
parents: 67
diff changeset
3082 }
kono
parents: 67
diff changeset
3083
kono
parents: 67
diff changeset
3084 /* Return true if we must emit a barrier after pattern X. */
kono
parents: 67
diff changeset
3085
kono
parents: 67
diff changeset
3086 bool
kono
parents: 67
diff changeset
3087 needs_barrier_p (rtx x)
kono
parents: 67
diff changeset
3088 {
kono
parents: 67
diff changeset
3089 return (GET_CODE (x) == SET
kono
parents: 67
diff changeset
3090 && GET_CODE (SET_DEST (x)) == PC
kono
parents: 67
diff changeset
3091 && GET_CODE (SET_SRC (x)) == LABEL_REF);
kono
parents: 67
diff changeset
3092 }
kono
parents: 67
diff changeset
3093
kono
parents: 67
diff changeset
3094 #define NS "NULL"
kono
parents: 67
diff changeset
3095 #define ZS "'\\0'"
kono
parents: 67
diff changeset
3096 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
kono
parents: 67
diff changeset
3097 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
kono
parents: 67
diff changeset
3098 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
kono
parents: 67
diff changeset
3099 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
kono
parents: 67
diff changeset
3100 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
kono
parents: 67
diff changeset
3101 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3102 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3103 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3104 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3105 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
kono
parents: 67
diff changeset
3106 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
kono
parents: 67
diff changeset
3107
kono
parents: 67
diff changeset
3108 /* An array of all optabs. Note that the same optab can appear more
kono
parents: 67
diff changeset
3109 than once, with a different pattern. */
kono
parents: 67
diff changeset
3110 optab_def optabs[] = {
kono
parents: 67
diff changeset
3111 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
kono
parents: 67
diff changeset
3112 #include "optabs.def"
kono
parents: 67
diff changeset
3113 };
kono
parents: 67
diff changeset
3114
kono
parents: 67
diff changeset
3115 /* The number of entries in optabs[]. */
kono
parents: 67
diff changeset
3116 unsigned int num_optabs = ARRAY_SIZE (optabs);
kono
parents: 67
diff changeset
3117
kono
parents: 67
diff changeset
3118 #undef OPTAB_CL
kono
parents: 67
diff changeset
3119 #undef OPTAB_CX
kono
parents: 67
diff changeset
3120 #undef OPTAB_CD
kono
parents: 67
diff changeset
3121 #undef OPTAB_NL
kono
parents: 67
diff changeset
3122 #undef OPTAB_NC
kono
parents: 67
diff changeset
3123 #undef OPTAB_NX
kono
parents: 67
diff changeset
3124 #undef OPTAB_VL
kono
parents: 67
diff changeset
3125 #undef OPTAB_VC
kono
parents: 67
diff changeset
3126 #undef OPTAB_VX
kono
parents: 67
diff changeset
3127 #undef OPTAB_DC
kono
parents: 67
diff changeset
3128 #undef OPTAB_D
kono
parents: 67
diff changeset
3129
kono
parents: 67
diff changeset
3130 /* Return true if instruction NAME matches pattern PAT, storing information
kono
parents: 67
diff changeset
3131 about the match in P if so. */
kono
parents: 67
diff changeset
3132
kono
parents: 67
diff changeset
3133 static bool
kono
parents: 67
diff changeset
3134 match_pattern (optab_pattern *p, const char *name, const char *pat)
kono
parents: 67
diff changeset
3135 {
kono
parents: 67
diff changeset
3136 bool force_float = false;
kono
parents: 67
diff changeset
3137 bool force_int = false;
kono
parents: 67
diff changeset
3138 bool force_partial_int = false;
kono
parents: 67
diff changeset
3139 bool force_fixed = false;
kono
parents: 67
diff changeset
3140
kono
parents: 67
diff changeset
3141 if (pat == NULL)
kono
parents: 67
diff changeset
3142 return false;
kono
parents: 67
diff changeset
3143 for (; ; ++pat)
kono
parents: 67
diff changeset
3144 {
kono
parents: 67
diff changeset
3145 if (*pat != '$')
kono
parents: 67
diff changeset
3146 {
kono
parents: 67
diff changeset
3147 if (*pat != *name++)
kono
parents: 67
diff changeset
3148 return false;
kono
parents: 67
diff changeset
3149 if (*pat == '\0')
kono
parents: 67
diff changeset
3150 return true;
kono
parents: 67
diff changeset
3151 continue;
kono
parents: 67
diff changeset
3152 }
kono
parents: 67
diff changeset
3153 switch (*++pat)
kono
parents: 67
diff changeset
3154 {
kono
parents: 67
diff changeset
3155 case 'I':
kono
parents: 67
diff changeset
3156 force_int = 1;
kono
parents: 67
diff changeset
3157 break;
kono
parents: 67
diff changeset
3158 case 'P':
kono
parents: 67
diff changeset
3159 force_partial_int = 1;
kono
parents: 67
diff changeset
3160 break;
kono
parents: 67
diff changeset
3161 case 'F':
kono
parents: 67
diff changeset
3162 force_float = 1;
kono
parents: 67
diff changeset
3163 break;
kono
parents: 67
diff changeset
3164 case 'Q':
kono
parents: 67
diff changeset
3165 force_fixed = 1;
kono
parents: 67
diff changeset
3166 break;
kono
parents: 67
diff changeset
3167
kono
parents: 67
diff changeset
3168 case 'a':
kono
parents: 67
diff changeset
3169 case 'b':
kono
parents: 67
diff changeset
3170 {
kono
parents: 67
diff changeset
3171 int i;
kono
parents: 67
diff changeset
3172
kono
parents: 67
diff changeset
3173 /* This loop will stop at the first prefix match, so
kono
parents: 67
diff changeset
3174 look through the modes in reverse order, in case
kono
parents: 67
diff changeset
3175 there are extra CC modes and CC is a prefix of the
kono
parents: 67
diff changeset
3176 CC modes (as it should be). */
kono
parents: 67
diff changeset
3177 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
kono
parents: 67
diff changeset
3178 {
kono
parents: 67
diff changeset
3179 const char *p, *q;
kono
parents: 67
diff changeset
3180 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
kono
parents: 67
diff changeset
3181 if (TOLOWER (*p) != *q)
kono
parents: 67
diff changeset
3182 break;
kono
parents: 67
diff changeset
3183 if (*p == 0
kono
parents: 67
diff changeset
3184 && (! force_int || mode_class[i] == MODE_INT
kono
parents: 67
diff changeset
3185 || mode_class[i] == MODE_VECTOR_INT)
kono
parents: 67
diff changeset
3186 && (! force_partial_int
kono
parents: 67
diff changeset
3187 || mode_class[i] == MODE_INT
kono
parents: 67
diff changeset
3188 || mode_class[i] == MODE_PARTIAL_INT
kono
parents: 67
diff changeset
3189 || mode_class[i] == MODE_VECTOR_INT)
kono
parents: 67
diff changeset
3190 && (! force_float
kono
parents: 67
diff changeset
3191 || mode_class[i] == MODE_FLOAT
kono
parents: 67
diff changeset
3192 || mode_class[i] == MODE_DECIMAL_FLOAT
kono
parents: 67
diff changeset
3193 || mode_class[i] == MODE_COMPLEX_FLOAT
kono
parents: 67
diff changeset
3194 || mode_class[i] == MODE_VECTOR_FLOAT)
kono
parents: 67
diff changeset
3195 && (! force_fixed
kono
parents: 67
diff changeset
3196 || mode_class[i] == MODE_FRACT
kono
parents: 67
diff changeset
3197 || mode_class[i] == MODE_UFRACT
kono
parents: 67
diff changeset
3198 || mode_class[i] == MODE_ACCUM
kono
parents: 67
diff changeset
3199 || mode_class[i] == MODE_UACCUM
kono
parents: 67
diff changeset
3200 || mode_class[i] == MODE_VECTOR_FRACT
kono
parents: 67
diff changeset
3201 || mode_class[i] == MODE_VECTOR_UFRACT
kono
parents: 67
diff changeset
3202 || mode_class[i] == MODE_VECTOR_ACCUM
kono
parents: 67
diff changeset
3203 || mode_class[i] == MODE_VECTOR_UACCUM))
kono
parents: 67
diff changeset
3204 break;
kono
parents: 67
diff changeset
3205 }
kono
parents: 67
diff changeset
3206
kono
parents: 67
diff changeset
3207 if (i < 0)
kono
parents: 67
diff changeset
3208 return false;
kono
parents: 67
diff changeset
3209 name += strlen (GET_MODE_NAME (i));
kono
parents: 67
diff changeset
3210 if (*pat == 'a')
kono
parents: 67
diff changeset
3211 p->m1 = i;
kono
parents: 67
diff changeset
3212 else
kono
parents: 67
diff changeset
3213 p->m2 = i;
kono
parents: 67
diff changeset
3214
kono
parents: 67
diff changeset
3215 force_int = false;
kono
parents: 67
diff changeset
3216 force_partial_int = false;
kono
parents: 67
diff changeset
3217 force_float = false;
kono
parents: 67
diff changeset
3218 force_fixed = false;
kono
parents: 67
diff changeset
3219 }
kono
parents: 67
diff changeset
3220 break;
kono
parents: 67
diff changeset
3221
kono
parents: 67
diff changeset
3222 default:
kono
parents: 67
diff changeset
3223 gcc_unreachable ();
kono
parents: 67
diff changeset
3224 }
kono
parents: 67
diff changeset
3225 }
kono
parents: 67
diff changeset
3226 }
kono
parents: 67
diff changeset
3227
kono
parents: 67
diff changeset
3228 /* Return true if NAME is the name of an optab, describing it in P if so. */
kono
parents: 67
diff changeset
3229
kono
parents: 67
diff changeset
3230 bool
kono
parents: 67
diff changeset
3231 find_optab (optab_pattern *p, const char *name)
kono
parents: 67
diff changeset
3232 {
kono
parents: 67
diff changeset
3233 if (*name == 0 || *name == '*')
kono
parents: 67
diff changeset
3234 return false;
kono
parents: 67
diff changeset
3235
kono
parents: 67
diff changeset
3236 /* See if NAME matches one of the patterns we have for the optabs
kono
parents: 67
diff changeset
3237 we know about. */
kono
parents: 67
diff changeset
3238 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
kono
parents: 67
diff changeset
3239 {
kono
parents: 67
diff changeset
3240 p->m1 = p->m2 = 0;
kono
parents: 67
diff changeset
3241 if (match_pattern (p, name, optabs[pindex].pattern))
kono
parents: 67
diff changeset
3242 {
kono
parents: 67
diff changeset
3243 p->name = name;
kono
parents: 67
diff changeset
3244 p->op = optabs[pindex].op;
kono
parents: 67
diff changeset
3245 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
kono
parents: 67
diff changeset
3246 return true;
kono
parents: 67
diff changeset
3247 }
kono
parents: 67
diff changeset
3248 }
kono
parents: 67
diff changeset
3249 return false;
kono
parents: 67
diff changeset
3250 }