annotate gcc/gensupport.c @ 127:4c56639505ff

fix function.c and add CbC-example Makefile
author mir3636
date Wed, 11 Apr 2018 18:46:58 +0900
parents 04ced10e8804
children 84e7813d76e9
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.
111
kono
parents: 67
diff changeset
2 Copyright (C) 2000-2017 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 {
kono
parents: 67
diff changeset
886 case 'i': case 'r': case 'w': case 's':
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
kono
parents: 67
diff changeset
1050 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
kono
parents: 67
diff changeset
1051 break;
kono
parents: 67
diff changeset
1052
kono
parents: 67
diff changeset
1053 default:
kono
parents: 67
diff changeset
1054 gcc_unreachable ();
kono
parents: 67
diff changeset
1055 }
kono
parents: 67
diff changeset
1056 }
kono
parents: 67
diff changeset
1057 return 1;
kono
parents: 67
diff changeset
1058 }
kono
parents: 67
diff changeset
1059
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1060 /* 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
1061 operands. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 collect_insn_data (rtx pattern, int *palt, int *pmax)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 enum rtx_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1068 int i, j, len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070 code = GET_CODE (pattern);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1071 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1072 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1073 case MATCH_OPERAND:
111
kono
parents: 67
diff changeset
1074 case MATCH_SCRATCH:
kono
parents: 67
diff changeset
1075 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
1076 *palt = (i > *palt ? i : *palt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079 case MATCH_OPERATOR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 case MATCH_PARALLEL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 i = XINT (pattern, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 if (i > *pmax)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 *pmax = i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 }
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 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091 len = GET_RTX_LENGTH (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 for (i = 0; i < len; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 switch (fmt[i])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 case 'e': case 'u':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 collect_insn_data (XEXP (pattern, i), palt, pmax);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 case 'V':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 if (XVEC (pattern, i) == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 case 'E':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108
111
kono
parents: 67
diff changeset
1109 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 }
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 static rtx
111
kono
parents: 67
diff changeset
1119 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
kono
parents: 67
diff changeset
1120 file_location loc)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1122 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123 enum rtx_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124 int i, j, len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126 code = GET_CODE (pattern);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1127 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1129 case MATCH_OPERAND:
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 const char *c = XSTR (pattern, 2);
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 if (n_alternatives (c) != 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134 {
111
kono
parents: 67
diff changeset
1135 error_at (loc, "too many alternatives for operand %d",
kono
parents: 67
diff changeset
1136 XINT (pattern, 0));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1138 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 /* Replicate C as needed to fill out ALT alternatives. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141 if (c && *c && alt > 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 size_t c_len = strlen (c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144 size_t len = alt * (c_len + 1);
111
kono
parents: 67
diff changeset
1145 char *new_c = XNEWVEC (char, len);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1147 memcpy (new_c, c, c_len);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148 for (i = 1; i < alt; ++i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 new_c[i * (c_len + 1) - 1] = ',';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 memcpy (&new_c[i * (c_len + 1)], c, c_len);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 new_c[len - 1] = '\0';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 XSTR (pattern, 2) = new_c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157 /* Fall through. */
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 case MATCH_OPERATOR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 case MATCH_SCRATCH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 case MATCH_PARALLEL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162 XINT (pattern, 0) += max_op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1164
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170 len = GET_RTX_LENGTH (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 for (i = 0; i < len; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 rtx r;
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 switch (fmt[i])
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 case 'e': case 'u':
111
kono
parents: 67
diff changeset
1178 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
1179 if (r == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1181 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1182
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1183 case 'E':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1184 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1185 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
111
kono
parents: 67
diff changeset
1187 alt, max_op, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1188 if (r == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1189 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192
111
kono
parents: 67
diff changeset
1193 case 'i': case 'r': case 'w': case '0': case 's':
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1194 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1195
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1196 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1197 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1198 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199 }
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 return pattern;
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
111
kono
parents: 67
diff changeset
1204 /* Duplicate constraints in PATTERN. If pattern is from original
kono
parents: 67
diff changeset
1205 rtl-template, we need to duplicate each alternative - for that we
kono
parents: 67
diff changeset
1206 need to use duplicate_each_alternative () as a functor ALTER.
kono
parents: 67
diff changeset
1207 If pattern is from output-pattern of define_subst, we need to
kono
parents: 67
diff changeset
1208 duplicate constraints in another way - with duplicate_alternatives ().
kono
parents: 67
diff changeset
1209 N_DUP is multiplication factor. */
kono
parents: 67
diff changeset
1210 static rtx
kono
parents: 67
diff changeset
1211 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
kono
parents: 67
diff changeset
1212 {
kono
parents: 67
diff changeset
1213 const char *fmt;
kono
parents: 67
diff changeset
1214 enum rtx_code code;
kono
parents: 67
diff changeset
1215 int i, j, len;
kono
parents: 67
diff changeset
1216
kono
parents: 67
diff changeset
1217 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
1218 switch (code)
kono
parents: 67
diff changeset
1219 {
kono
parents: 67
diff changeset
1220 case MATCH_OPERAND:
kono
parents: 67
diff changeset
1221 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
kono
parents: 67
diff changeset
1222 break;
kono
parents: 67
diff changeset
1223
kono
parents: 67
diff changeset
1224 default:
kono
parents: 67
diff changeset
1225 break;
kono
parents: 67
diff changeset
1226 }
kono
parents: 67
diff changeset
1227
kono
parents: 67
diff changeset
1228 fmt = GET_RTX_FORMAT (code);
kono
parents: 67
diff changeset
1229 len = GET_RTX_LENGTH (code);
kono
parents: 67
diff changeset
1230 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1231 {
kono
parents: 67
diff changeset
1232 rtx r;
kono
parents: 67
diff changeset
1233
kono
parents: 67
diff changeset
1234 switch (fmt[i])
kono
parents: 67
diff changeset
1235 {
kono
parents: 67
diff changeset
1236 case 'e': case 'u':
kono
parents: 67
diff changeset
1237 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
kono
parents: 67
diff changeset
1238 if (r == NULL)
kono
parents: 67
diff changeset
1239 return r;
kono
parents: 67
diff changeset
1240 break;
kono
parents: 67
diff changeset
1241
kono
parents: 67
diff changeset
1242 case 'E':
kono
parents: 67
diff changeset
1243 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1244 {
kono
parents: 67
diff changeset
1245 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
kono
parents: 67
diff changeset
1246 if (r == NULL)
kono
parents: 67
diff changeset
1247 return r;
kono
parents: 67
diff changeset
1248 }
kono
parents: 67
diff changeset
1249 break;
kono
parents: 67
diff changeset
1250
kono
parents: 67
diff changeset
1251 case 'i': case 'r': case 'w': case '0': case 's':
kono
parents: 67
diff changeset
1252 break;
kono
parents: 67
diff changeset
1253
kono
parents: 67
diff changeset
1254 default:
kono
parents: 67
diff changeset
1255 break;
kono
parents: 67
diff changeset
1256 }
kono
parents: 67
diff changeset
1257 }
kono
parents: 67
diff changeset
1258
kono
parents: 67
diff changeset
1259 return pattern;
kono
parents: 67
diff changeset
1260 }
kono
parents: 67
diff changeset
1261
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262 static const char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 alter_test_for_insn (struct queue_elem *ce_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 struct queue_elem *insn_elem)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 {
111
kono
parents: 67
diff changeset
1266 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
kono
parents: 67
diff changeset
1267 XSTR (insn_elem->data, 2));
kono
parents: 67
diff changeset
1268 }
kono
parents: 67
diff changeset
1269
kono
parents: 67
diff changeset
1270 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
kono
parents: 67
diff changeset
1271 to take "ce_enabled" into account. Return the new expression. */
kono
parents: 67
diff changeset
1272 static rtx
kono
parents: 67
diff changeset
1273 modify_attr_enabled_ce (rtx val)
kono
parents: 67
diff changeset
1274 {
kono
parents: 67
diff changeset
1275 rtx eq_attr, str;
kono
parents: 67
diff changeset
1276 rtx ite;
kono
parents: 67
diff changeset
1277 eq_attr = rtx_alloc (EQ_ATTR);
kono
parents: 67
diff changeset
1278 ite = rtx_alloc (IF_THEN_ELSE);
kono
parents: 67
diff changeset
1279 str = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
1280
kono
parents: 67
diff changeset
1281 XSTR (eq_attr, 0) = "ce_enabled";
kono
parents: 67
diff changeset
1282 XSTR (eq_attr, 1) = "yes";
kono
parents: 67
diff changeset
1283 XSTR (str, 0) = "no";
kono
parents: 67
diff changeset
1284 XEXP (ite, 0) = eq_attr;
kono
parents: 67
diff changeset
1285 XEXP (ite, 1) = val;
kono
parents: 67
diff changeset
1286 XEXP (ite, 2) = str;
kono
parents: 67
diff changeset
1287
kono
parents: 67
diff changeset
1288 return ite;
kono
parents: 67
diff changeset
1289 }
kono
parents: 67
diff changeset
1290
kono
parents: 67
diff changeset
1291 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
kono
parents: 67
diff changeset
1292 from a define_insn pattern. We must modify the "predicable" attribute
kono
parents: 67
diff changeset
1293 to be named "ce_enabled", and also change any "enabled" attribute that's
kono
parents: 67
diff changeset
1294 present so that it takes ce_enabled into account.
kono
parents: 67
diff changeset
1295 We rely on the fact that INSN was created with copy_rtx, and modify data
kono
parents: 67
diff changeset
1296 in-place. */
kono
parents: 67
diff changeset
1297
kono
parents: 67
diff changeset
1298 static void
kono
parents: 67
diff changeset
1299 alter_attrs_for_insn (rtx insn)
kono
parents: 67
diff changeset
1300 {
kono
parents: 67
diff changeset
1301 static bool global_changes_made = false;
kono
parents: 67
diff changeset
1302 rtvec vec = XVEC (insn, 4);
kono
parents: 67
diff changeset
1303 rtvec new_vec;
kono
parents: 67
diff changeset
1304 rtx val, set;
kono
parents: 67
diff changeset
1305 int num_elem;
kono
parents: 67
diff changeset
1306 int predicable_idx = -1;
kono
parents: 67
diff changeset
1307 int enabled_idx = -1;
kono
parents: 67
diff changeset
1308 int i;
kono
parents: 67
diff changeset
1309
kono
parents: 67
diff changeset
1310 if (! vec)
kono
parents: 67
diff changeset
1311 return;
kono
parents: 67
diff changeset
1312
kono
parents: 67
diff changeset
1313 num_elem = GET_NUM_ELEM (vec);
kono
parents: 67
diff changeset
1314 for (i = num_elem - 1; i >= 0; --i)
kono
parents: 67
diff changeset
1315 {
kono
parents: 67
diff changeset
1316 rtx sub = RTVEC_ELT (vec, i);
kono
parents: 67
diff changeset
1317 switch (GET_CODE (sub))
kono
parents: 67
diff changeset
1318 {
kono
parents: 67
diff changeset
1319 case SET_ATTR:
kono
parents: 67
diff changeset
1320 if (strcmp (XSTR (sub, 0), "predicable") == 0)
kono
parents: 67
diff changeset
1321 {
kono
parents: 67
diff changeset
1322 predicable_idx = i;
kono
parents: 67
diff changeset
1323 XSTR (sub, 0) = "ce_enabled";
kono
parents: 67
diff changeset
1324 }
kono
parents: 67
diff changeset
1325 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
kono
parents: 67
diff changeset
1326 {
kono
parents: 67
diff changeset
1327 enabled_idx = i;
kono
parents: 67
diff changeset
1328 XSTR (sub, 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1329 }
kono
parents: 67
diff changeset
1330 break;
kono
parents: 67
diff changeset
1331
kono
parents: 67
diff changeset
1332 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
1333 if (strcmp (XSTR (sub, 0), "predicable") == 0)
kono
parents: 67
diff changeset
1334 /* We already give an error elsewhere. */
kono
parents: 67
diff changeset
1335 return;
kono
parents: 67
diff changeset
1336 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
kono
parents: 67
diff changeset
1337 {
kono
parents: 67
diff changeset
1338 enabled_idx = i;
kono
parents: 67
diff changeset
1339 XSTR (sub, 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1340 }
kono
parents: 67
diff changeset
1341 break;
kono
parents: 67
diff changeset
1342
kono
parents: 67
diff changeset
1343 case SET:
kono
parents: 67
diff changeset
1344 if (GET_CODE (SET_DEST (sub)) != ATTR)
kono
parents: 67
diff changeset
1345 break;
kono
parents: 67
diff changeset
1346 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
kono
parents: 67
diff changeset
1347 {
kono
parents: 67
diff changeset
1348 sub = SET_SRC (sub);
kono
parents: 67
diff changeset
1349 if (GET_CODE (sub) == CONST_STRING)
kono
parents: 67
diff changeset
1350 {
kono
parents: 67
diff changeset
1351 predicable_idx = i;
kono
parents: 67
diff changeset
1352 XSTR (sub, 0) = "ce_enabled";
kono
parents: 67
diff changeset
1353 }
kono
parents: 67
diff changeset
1354 else
kono
parents: 67
diff changeset
1355 /* We already give an error elsewhere. */
kono
parents: 67
diff changeset
1356 return;
kono
parents: 67
diff changeset
1357 break;
kono
parents: 67
diff changeset
1358 }
kono
parents: 67
diff changeset
1359 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
kono
parents: 67
diff changeset
1360 {
kono
parents: 67
diff changeset
1361 enabled_idx = i;
kono
parents: 67
diff changeset
1362 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1363 }
kono
parents: 67
diff changeset
1364 break;
kono
parents: 67
diff changeset
1365
kono
parents: 67
diff changeset
1366 default:
kono
parents: 67
diff changeset
1367 gcc_unreachable ();
kono
parents: 67
diff changeset
1368 }
kono
parents: 67
diff changeset
1369 }
kono
parents: 67
diff changeset
1370 if (predicable_idx == -1)
kono
parents: 67
diff changeset
1371 return;
kono
parents: 67
diff changeset
1372
kono
parents: 67
diff changeset
1373 if (!global_changes_made)
kono
parents: 67
diff changeset
1374 {
kono
parents: 67
diff changeset
1375 struct queue_elem *elem;
kono
parents: 67
diff changeset
1376
kono
parents: 67
diff changeset
1377 global_changes_made = true;
kono
parents: 67
diff changeset
1378 add_define_attr ("ce_enabled");
kono
parents: 67
diff changeset
1379 add_define_attr ("nonce_enabled");
kono
parents: 67
diff changeset
1380
kono
parents: 67
diff changeset
1381 for (elem = define_attr_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
1382 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
kono
parents: 67
diff changeset
1383 {
kono
parents: 67
diff changeset
1384 XEXP (elem->data, 2)
kono
parents: 67
diff changeset
1385 = modify_attr_enabled_ce (XEXP (elem->data, 2));
kono
parents: 67
diff changeset
1386 }
kono
parents: 67
diff changeset
1387 }
kono
parents: 67
diff changeset
1388 if (enabled_idx == -1)
kono
parents: 67
diff changeset
1389 return;
kono
parents: 67
diff changeset
1390
kono
parents: 67
diff changeset
1391 new_vec = rtvec_alloc (num_elem + 1);
kono
parents: 67
diff changeset
1392 for (i = 0; i < num_elem; i++)
kono
parents: 67
diff changeset
1393 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
kono
parents: 67
diff changeset
1394 val = rtx_alloc (IF_THEN_ELSE);
kono
parents: 67
diff changeset
1395 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
kono
parents: 67
diff changeset
1396 XEXP (val, 1) = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
1397 XEXP (val, 2) = rtx_alloc (CONST_STRING);
kono
parents: 67
diff changeset
1398 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
kono
parents: 67
diff changeset
1399 XSTR (XEXP (val, 0), 1) = "yes";
kono
parents: 67
diff changeset
1400 XSTR (XEXP (val, 1), 0) = "yes";
kono
parents: 67
diff changeset
1401 XSTR (XEXP (val, 2), 0) = "no";
kono
parents: 67
diff changeset
1402 set = rtx_alloc (SET);
kono
parents: 67
diff changeset
1403 SET_DEST (set) = rtx_alloc (ATTR);
kono
parents: 67
diff changeset
1404 XSTR (SET_DEST (set), 0) = "enabled";
kono
parents: 67
diff changeset
1405 SET_SRC (set) = modify_attr_enabled_ce (val);
kono
parents: 67
diff changeset
1406 RTVEC_ELT (new_vec, i) = set;
kono
parents: 67
diff changeset
1407 XVEC (insn, 4) = new_vec;
kono
parents: 67
diff changeset
1408 }
kono
parents: 67
diff changeset
1409
kono
parents: 67
diff changeset
1410 /* As number of constraints is changed after define_subst, we need to
kono
parents: 67
diff changeset
1411 process attributes as well - we need to duplicate them the same way
kono
parents: 67
diff changeset
1412 that we duplicated constraints in original pattern
kono
parents: 67
diff changeset
1413 ELEM is a queue element, containing our rtl-template,
kono
parents: 67
diff changeset
1414 N_DUP - multiplication factor. */
kono
parents: 67
diff changeset
1415 static void
kono
parents: 67
diff changeset
1416 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup)
kono
parents: 67
diff changeset
1417 {
kono
parents: 67
diff changeset
1418 rtvec vec = XVEC (elem->data, 4);
kono
parents: 67
diff changeset
1419 int num_elem;
kono
parents: 67
diff changeset
1420 int i;
kono
parents: 67
diff changeset
1421
kono
parents: 67
diff changeset
1422 if (n_dup < 2 || ! vec)
kono
parents: 67
diff changeset
1423 return;
kono
parents: 67
diff changeset
1424
kono
parents: 67
diff changeset
1425 num_elem = GET_NUM_ELEM (vec);
kono
parents: 67
diff changeset
1426 for (i = num_elem - 1; i >= 0; --i)
kono
parents: 67
diff changeset
1427 {
kono
parents: 67
diff changeset
1428 rtx sub = RTVEC_ELT (vec, i);
kono
parents: 67
diff changeset
1429 switch (GET_CODE (sub))
kono
parents: 67
diff changeset
1430 {
kono
parents: 67
diff changeset
1431 case SET_ATTR:
kono
parents: 67
diff changeset
1432 if (strchr (XSTR (sub, 1), ',') != NULL)
kono
parents: 67
diff changeset
1433 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
kono
parents: 67
diff changeset
1434 break;
kono
parents: 67
diff changeset
1435
kono
parents: 67
diff changeset
1436 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
1437 case SET:
kono
parents: 67
diff changeset
1438 error_at (elem->loc,
kono
parents: 67
diff changeset
1439 "%s: `define_subst' does not support attributes "
kono
parents: 67
diff changeset
1440 "assigned by `set' and `set_attr_alternative'",
kono
parents: 67
diff changeset
1441 XSTR (elem->data, 0));
kono
parents: 67
diff changeset
1442 return;
kono
parents: 67
diff changeset
1443
kono
parents: 67
diff changeset
1444 default:
kono
parents: 67
diff changeset
1445 gcc_unreachable ();
kono
parents: 67
diff changeset
1446 }
kono
parents: 67
diff changeset
1447 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1448 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 /* 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
1451 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
1452 adjusted string. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1453
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454 static char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455 shift_output_template (char *dest, const char *src, int disp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 while (*src)
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 char c = *src++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 *dest++ = c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461 if (c == '%')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463 c = *src++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 if (ISDIGIT ((unsigned char) c))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 c += disp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 else if (ISALPHA (c))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 *dest++ = c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 c = *src++ + disp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 *dest++ = c;
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 }
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 return dest;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478 static const char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 alter_output_for_insn (struct queue_elem *ce_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 struct queue_elem *insn_elem,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 int alt, int max_op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 const char *ce_out, *insn_out;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 char *result, *p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 size_t len, ce_len, insn_len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 /* ??? Could coordinate with genoutput to not duplicate code here. */
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 ce_out = XSTR (ce_elem->data, 2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490 insn_out = XTMPL (insn_elem->data, 3);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 if (!ce_out || *ce_out == '\0')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492 return insn_out;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 ce_len = strlen (ce_out);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495 insn_len = strlen (insn_out);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497 if (*insn_out == '*')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 /* You must take care of the predicate yourself. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499 return insn_out;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 if (*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 len = (ce_len + 1) * alt + insn_len + 1;
111
kono
parents: 67
diff changeset
1504 p = result = XNEWVEC (char, len);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506 do
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 *p++ = *insn_out++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 while (ISSPACE ((unsigned char) *insn_out));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 if (*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 p = shift_output_template (p, ce_out, max_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515 *p++ = ' ';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519 *p++ = *insn_out++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 while (*insn_out && *insn_out != '\n');
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522 while (*insn_out);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 *p = '\0';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525 else
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 len = ce_len + 1 + insn_len + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528 result = XNEWVEC (char, len);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 p = shift_output_template (result, ce_out, max_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531 *p++ = ' ';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 memcpy (p, insn_out, insn_len + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1535 return result;
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
111
kono
parents: 67
diff changeset
1538 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
kono
parents: 67
diff changeset
1539 string, duplicated N_DUP times. */
kono
parents: 67
diff changeset
1540
kono
parents: 67
diff changeset
1541 static const char *
kono
parents: 67
diff changeset
1542 duplicate_alternatives (const char * str, int n_dup)
kono
parents: 67
diff changeset
1543 {
kono
parents: 67
diff changeset
1544 int i, len, new_len;
kono
parents: 67
diff changeset
1545 char *result, *sp;
kono
parents: 67
diff changeset
1546 const char *cp;
kono
parents: 67
diff changeset
1547
kono
parents: 67
diff changeset
1548 if (n_dup < 2)
kono
parents: 67
diff changeset
1549 return str;
kono
parents: 67
diff changeset
1550
kono
parents: 67
diff changeset
1551 while (ISSPACE (*str))
kono
parents: 67
diff changeset
1552 str++;
kono
parents: 67
diff changeset
1553
kono
parents: 67
diff changeset
1554 if (*str == '\0')
kono
parents: 67
diff changeset
1555 return str;
kono
parents: 67
diff changeset
1556
kono
parents: 67
diff changeset
1557 cp = str;
kono
parents: 67
diff changeset
1558 len = strlen (str);
kono
parents: 67
diff changeset
1559 new_len = (len + 1) * n_dup;
kono
parents: 67
diff changeset
1560
kono
parents: 67
diff changeset
1561 sp = result = XNEWVEC (char, new_len);
kono
parents: 67
diff changeset
1562
kono
parents: 67
diff changeset
1563 /* Global modifier characters mustn't be duplicated: skip if found. */
kono
parents: 67
diff changeset
1564 if (*cp == '=' || *cp == '+' || *cp == '%')
kono
parents: 67
diff changeset
1565 {
kono
parents: 67
diff changeset
1566 *sp++ = *cp++;
kono
parents: 67
diff changeset
1567 len--;
kono
parents: 67
diff changeset
1568 }
kono
parents: 67
diff changeset
1569
kono
parents: 67
diff changeset
1570 /* Copy original constraints N_DUP times. */
kono
parents: 67
diff changeset
1571 for (i = 0; i < n_dup; i++, sp += len+1)
kono
parents: 67
diff changeset
1572 {
kono
parents: 67
diff changeset
1573 memcpy (sp, cp, len);
kono
parents: 67
diff changeset
1574 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
kono
parents: 67
diff changeset
1575 }
kono
parents: 67
diff changeset
1576
kono
parents: 67
diff changeset
1577 return result;
kono
parents: 67
diff changeset
1578 }
kono
parents: 67
diff changeset
1579
kono
parents: 67
diff changeset
1580 /* 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
1581 each alternative from the original string is duplicated N_DUP times. */
kono
parents: 67
diff changeset
1582 static const char *
kono
parents: 67
diff changeset
1583 duplicate_each_alternative (const char * str, int n_dup)
kono
parents: 67
diff changeset
1584 {
kono
parents: 67
diff changeset
1585 int i, len, new_len;
kono
parents: 67
diff changeset
1586 char *result, *sp, *ep, *cp;
kono
parents: 67
diff changeset
1587
kono
parents: 67
diff changeset
1588 if (n_dup < 2)
kono
parents: 67
diff changeset
1589 return str;
kono
parents: 67
diff changeset
1590
kono
parents: 67
diff changeset
1591 while (ISSPACE (*str))
kono
parents: 67
diff changeset
1592 str++;
kono
parents: 67
diff changeset
1593
kono
parents: 67
diff changeset
1594 if (*str == '\0')
kono
parents: 67
diff changeset
1595 return str;
kono
parents: 67
diff changeset
1596
kono
parents: 67
diff changeset
1597 cp = xstrdup (str);
kono
parents: 67
diff changeset
1598
kono
parents: 67
diff changeset
1599 new_len = (strlen (cp) + 1) * n_dup;
kono
parents: 67
diff changeset
1600
kono
parents: 67
diff changeset
1601 sp = result = XNEWVEC (char, new_len);
kono
parents: 67
diff changeset
1602
kono
parents: 67
diff changeset
1603 /* Global modifier characters mustn't be duplicated: skip if found. */
kono
parents: 67
diff changeset
1604 if (*cp == '=' || *cp == '+' || *cp == '%')
kono
parents: 67
diff changeset
1605 *sp++ = *cp++;
kono
parents: 67
diff changeset
1606
kono
parents: 67
diff changeset
1607 do
kono
parents: 67
diff changeset
1608 {
kono
parents: 67
diff changeset
1609 if ((ep = strchr (cp, ',')) != NULL)
kono
parents: 67
diff changeset
1610 *ep++ = '\0';
kono
parents: 67
diff changeset
1611 len = strlen (cp);
kono
parents: 67
diff changeset
1612
kono
parents: 67
diff changeset
1613 /* Copy a constraint N_DUP times. */
kono
parents: 67
diff changeset
1614 for (i = 0; i < n_dup; i++, sp += len + 1)
kono
parents: 67
diff changeset
1615 {
kono
parents: 67
diff changeset
1616 memcpy (sp, cp, len);
kono
parents: 67
diff changeset
1617 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
kono
parents: 67
diff changeset
1618 }
kono
parents: 67
diff changeset
1619
kono
parents: 67
diff changeset
1620 cp = ep;
kono
parents: 67
diff changeset
1621 }
kono
parents: 67
diff changeset
1622 while (cp != NULL);
kono
parents: 67
diff changeset
1623
kono
parents: 67
diff changeset
1624 return result;
kono
parents: 67
diff changeset
1625 }
kono
parents: 67
diff changeset
1626
kono
parents: 67
diff changeset
1627 /* Alter the output of INSN whose pattern was modified by
kono
parents: 67
diff changeset
1628 DEFINE_SUBST. We must replicate output strings according
kono
parents: 67
diff changeset
1629 to the new number of alternatives ALT in substituted pattern.
kono
parents: 67
diff changeset
1630 If ALT equals 1, output has one alternative or defined by C
kono
parents: 67
diff changeset
1631 code, then output is returned without any changes. */
kono
parents: 67
diff changeset
1632
kono
parents: 67
diff changeset
1633 static const char *
kono
parents: 67
diff changeset
1634 alter_output_for_subst_insn (rtx insn, int alt)
kono
parents: 67
diff changeset
1635 {
kono
parents: 67
diff changeset
1636 const char *insn_out, *old_out;
kono
parents: 67
diff changeset
1637 char *new_out, *cp;
kono
parents: 67
diff changeset
1638 size_t old_len, new_len;
kono
parents: 67
diff changeset
1639 int j;
kono
parents: 67
diff changeset
1640
kono
parents: 67
diff changeset
1641 insn_out = XTMPL (insn, 3);
kono
parents: 67
diff changeset
1642
kono
parents: 67
diff changeset
1643 if (alt < 2 || *insn_out != '@')
kono
parents: 67
diff changeset
1644 return insn_out;
kono
parents: 67
diff changeset
1645
kono
parents: 67
diff changeset
1646 old_out = insn_out + 1;
kono
parents: 67
diff changeset
1647 while (ISSPACE (*old_out))
kono
parents: 67
diff changeset
1648 old_out++;
kono
parents: 67
diff changeset
1649 old_len = strlen (old_out);
kono
parents: 67
diff changeset
1650
kono
parents: 67
diff changeset
1651 new_len = alt * (old_len + 1) + 1;
kono
parents: 67
diff changeset
1652
kono
parents: 67
diff changeset
1653 new_out = XNEWVEC (char, new_len);
kono
parents: 67
diff changeset
1654 new_out[0] = '@';
kono
parents: 67
diff changeset
1655
kono
parents: 67
diff changeset
1656 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
kono
parents: 67
diff changeset
1657 {
kono
parents: 67
diff changeset
1658 memcpy (cp, old_out, old_len);
kono
parents: 67
diff changeset
1659 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
kono
parents: 67
diff changeset
1660 }
kono
parents: 67
diff changeset
1661
kono
parents: 67
diff changeset
1662 return new_out;
kono
parents: 67
diff changeset
1663 }
kono
parents: 67
diff changeset
1664
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1665 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668 process_one_cond_exec (struct queue_elem *ce_elem)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1670 struct queue_elem *insn_elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1671 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
1672 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1673 int alternatives, max_operand;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674 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
1675 char *new_name;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1678 if (! is_predicable (insn_elem))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 alternatives = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682 max_operand = -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1683 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 if (XVECLEN (ce_elem->data, 0) != 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687 {
111
kono
parents: 67
diff changeset
1688 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
1689 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1690 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
111
kono
parents: 67
diff changeset
1694 ce_elem->loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1695 if (pred == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1696 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1697
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1698 /* Construct a new pattern for the new insn. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1699 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
1700 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
1701 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
1702 XSTR (insn, 0) = new_name;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1703 pattern = rtx_alloc (COND_EXEC);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1704 XEXP (pattern, 0) = pred;
111
kono
parents: 67
diff changeset
1705 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
kono
parents: 67
diff changeset
1706 XVEC (insn, 1) = rtvec_alloc (1);
kono
parents: 67
diff changeset
1707 XVECEXP (insn, 1, 0) = pattern;
kono
parents: 67
diff changeset
1708
kono
parents: 67
diff changeset
1709 if (XVEC (ce_elem->data, 3) != NULL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1710 {
111
kono
parents: 67
diff changeset
1711 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
kono
parents: 67
diff changeset
1712 + XVECLEN (ce_elem->data, 3));
kono
parents: 67
diff changeset
1713 int i = 0;
kono
parents: 67
diff changeset
1714 int j = 0;
kono
parents: 67
diff changeset
1715 for (i = 0; i < XVECLEN (insn, 4); i++)
kono
parents: 67
diff changeset
1716 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
kono
parents: 67
diff changeset
1717
kono
parents: 67
diff changeset
1718 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
kono
parents: 67
diff changeset
1719 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
kono
parents: 67
diff changeset
1720
kono
parents: 67
diff changeset
1721 XVEC (insn, 4) = attributes;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1722 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1723
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1724 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
1725 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
1726 alternatives, max_operand);
111
kono
parents: 67
diff changeset
1727 alter_attrs_for_insn (insn);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1728
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1729 /* 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
1730 (a) is not reprocessed by other define_cond_exec patterns
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1731 (b) appears after all normal define_insn patterns.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1733 ??? B is debatable. If one has normal insns that match
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1734 cond_exec patterns, they will be preferred over these
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1735 generated patterns. Whether this matters in practice, or if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1736 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
1737 patterns into the define_insn chain just after their generator
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1738 is something we'll have to experiment with. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1739
111
kono
parents: 67
diff changeset
1740 queue_pattern (insn, &other_tail, insn_elem->loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1741
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1742 if (!insn_elem->split)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1743 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1744
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1745 /* 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
1746 generate a new split to handle the predicated insn. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1747 split = copy_rtx (insn_elem->split->data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1748 /* Predicate the pattern matched by the split. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1749 pattern = rtx_alloc (COND_EXEC);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1750 XEXP (pattern, 0) = pred;
111
kono
parents: 67
diff changeset
1751 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
kono
parents: 67
diff changeset
1752 XVEC (split, 0) = rtvec_alloc (1);
kono
parents: 67
diff changeset
1753 XVECEXP (split, 0, 0) = pattern;
kono
parents: 67
diff changeset
1754
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1755 /* Predicate all of the insns generated by the split. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1756 for (i = 0; i < XVECLEN (split, 2); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1757 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1758 pattern = rtx_alloc (COND_EXEC);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1759 XEXP (pattern, 0) = pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1760 XEXP (pattern, 1) = XVECEXP (split, 2, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1761 XVECEXP (split, 2, i) = pattern;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1762 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1763 /* Add the new split to the queue. */
111
kono
parents: 67
diff changeset
1764 queue_pattern (split, &other_tail, insn_elem->split->loc);
kono
parents: 67
diff changeset
1765 }
kono
parents: 67
diff changeset
1766 }
kono
parents: 67
diff changeset
1767
kono
parents: 67
diff changeset
1768 /* Try to apply define_substs to the given ELEM.
kono
parents: 67
diff changeset
1769 Only define_substs, specified via attributes would be applied.
kono
parents: 67
diff changeset
1770 If attribute, requiring define_subst, is set, but no define_subst
kono
parents: 67
diff changeset
1771 was applied, ELEM would be deleted. */
kono
parents: 67
diff changeset
1772
kono
parents: 67
diff changeset
1773 static void
kono
parents: 67
diff changeset
1774 process_substs_on_one_elem (struct queue_elem *elem,
kono
parents: 67
diff changeset
1775 struct queue_elem *queue)
kono
parents: 67
diff changeset
1776 {
kono
parents: 67
diff changeset
1777 struct queue_elem *subst_elem;
kono
parents: 67
diff changeset
1778 int i, j, patterns_match;
kono
parents: 67
diff changeset
1779
kono
parents: 67
diff changeset
1780 for (subst_elem = define_subst_queue;
kono
parents: 67
diff changeset
1781 subst_elem; subst_elem = subst_elem->next)
kono
parents: 67
diff changeset
1782 {
kono
parents: 67
diff changeset
1783 int alternatives, alternatives_subst;
kono
parents: 67
diff changeset
1784 rtx subst_pattern;
kono
parents: 67
diff changeset
1785 rtvec subst_pattern_vec;
kono
parents: 67
diff changeset
1786
kono
parents: 67
diff changeset
1787 if (!has_subst_attribute (elem, subst_elem))
kono
parents: 67
diff changeset
1788 continue;
kono
parents: 67
diff changeset
1789
kono
parents: 67
diff changeset
1790 /* Compare original rtl-pattern from define_insn with input
kono
parents: 67
diff changeset
1791 pattern from define_subst.
kono
parents: 67
diff changeset
1792 Also, check if numbers of alternatives are the same in all
kono
parents: 67
diff changeset
1793 match_operands. */
kono
parents: 67
diff changeset
1794 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
kono
parents: 67
diff changeset
1795 continue;
kono
parents: 67
diff changeset
1796 patterns_match = 1;
kono
parents: 67
diff changeset
1797 alternatives = -1;
kono
parents: 67
diff changeset
1798 alternatives_subst = -1;
kono
parents: 67
diff changeset
1799 for (j = 0; j < XVECLEN (elem->data, 1); j++)
kono
parents: 67
diff changeset
1800 {
kono
parents: 67
diff changeset
1801 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
kono
parents: 67
diff changeset
1802 XVECEXP (subst_elem->data, 1, j),
kono
parents: 67
diff changeset
1803 subst_elem->loc))
kono
parents: 67
diff changeset
1804 {
kono
parents: 67
diff changeset
1805 patterns_match = 0;
kono
parents: 67
diff changeset
1806 break;
kono
parents: 67
diff changeset
1807 }
kono
parents: 67
diff changeset
1808
kono
parents: 67
diff changeset
1809 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
kono
parents: 67
diff changeset
1810 &alternatives, subst_elem->loc))
kono
parents: 67
diff changeset
1811 {
kono
parents: 67
diff changeset
1812 patterns_match = 0;
kono
parents: 67
diff changeset
1813 break;
kono
parents: 67
diff changeset
1814 }
kono
parents: 67
diff changeset
1815 }
kono
parents: 67
diff changeset
1816
kono
parents: 67
diff changeset
1817 /* Check if numbers of alternatives are the same in all
kono
parents: 67
diff changeset
1818 match_operands in output template of define_subst. */
kono
parents: 67
diff changeset
1819 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
kono
parents: 67
diff changeset
1820 {
kono
parents: 67
diff changeset
1821 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
kono
parents: 67
diff changeset
1822 &alternatives_subst,
kono
parents: 67
diff changeset
1823 subst_elem->loc))
kono
parents: 67
diff changeset
1824 {
kono
parents: 67
diff changeset
1825 patterns_match = 0;
kono
parents: 67
diff changeset
1826 break;
kono
parents: 67
diff changeset
1827 }
kono
parents: 67
diff changeset
1828 }
kono
parents: 67
diff changeset
1829
kono
parents: 67
diff changeset
1830 if (!patterns_match)
kono
parents: 67
diff changeset
1831 continue;
kono
parents: 67
diff changeset
1832
kono
parents: 67
diff changeset
1833 /* Clear array in which we save occupied indexes of operands. */
kono
parents: 67
diff changeset
1834 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
kono
parents: 67
diff changeset
1835
kono
parents: 67
diff changeset
1836 /* Create a pattern, based on the output one from define_subst. */
kono
parents: 67
diff changeset
1837 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
kono
parents: 67
diff changeset
1838 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
kono
parents: 67
diff changeset
1839 {
kono
parents: 67
diff changeset
1840 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
kono
parents: 67
diff changeset
1841
kono
parents: 67
diff changeset
1842 /* Duplicate constraints in substitute-pattern. */
kono
parents: 67
diff changeset
1843 subst_pattern = alter_constraints (subst_pattern, alternatives,
kono
parents: 67
diff changeset
1844 duplicate_each_alternative);
kono
parents: 67
diff changeset
1845
kono
parents: 67
diff changeset
1846 subst_pattern = adjust_operands_numbers (subst_pattern);
kono
parents: 67
diff changeset
1847
kono
parents: 67
diff changeset
1848 /* Substitute match_dup and match_op_dup in the new pattern and
kono
parents: 67
diff changeset
1849 duplicate constraints. */
kono
parents: 67
diff changeset
1850 subst_pattern = subst_dup (subst_pattern, alternatives,
kono
parents: 67
diff changeset
1851 alternatives_subst);
kono
parents: 67
diff changeset
1852
kono
parents: 67
diff changeset
1853 replace_duplicating_operands_in_pattern (subst_pattern);
kono
parents: 67
diff changeset
1854
kono
parents: 67
diff changeset
1855 /* We don't need any constraints in DEFINE_EXPAND. */
kono
parents: 67
diff changeset
1856 if (GET_CODE (elem->data) == DEFINE_EXPAND)
kono
parents: 67
diff changeset
1857 remove_constraints (subst_pattern);
kono
parents: 67
diff changeset
1858
kono
parents: 67
diff changeset
1859 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
kono
parents: 67
diff changeset
1860 }
kono
parents: 67
diff changeset
1861 XVEC (elem->data, 1) = subst_pattern_vec;
kono
parents: 67
diff changeset
1862
kono
parents: 67
diff changeset
1863 for (i = 0; i < MAX_OPERANDS; i++)
kono
parents: 67
diff changeset
1864 match_operand_entries_in_pattern[i] = NULL;
kono
parents: 67
diff changeset
1865
kono
parents: 67
diff changeset
1866 if (GET_CODE (elem->data) == DEFINE_INSN)
kono
parents: 67
diff changeset
1867 {
kono
parents: 67
diff changeset
1868 XTMPL (elem->data, 3) =
kono
parents: 67
diff changeset
1869 alter_output_for_subst_insn (elem->data, alternatives_subst);
kono
parents: 67
diff changeset
1870 alter_attrs_for_subst_insn (elem, alternatives_subst);
kono
parents: 67
diff changeset
1871 }
kono
parents: 67
diff changeset
1872
kono
parents: 67
diff changeset
1873 /* Recalculate condition, joining conditions from original and
kono
parents: 67
diff changeset
1874 DEFINE_SUBST input patterns. */
kono
parents: 67
diff changeset
1875 XSTR (elem->data, 2)
kono
parents: 67
diff changeset
1876 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
kono
parents: 67
diff changeset
1877 XSTR (elem->data, 2));
kono
parents: 67
diff changeset
1878 /* Mark that subst was applied by changing attribute from "yes"
kono
parents: 67
diff changeset
1879 to "no". */
kono
parents: 67
diff changeset
1880 change_subst_attribute (elem, subst_elem, subst_false);
kono
parents: 67
diff changeset
1881 }
kono
parents: 67
diff changeset
1882
kono
parents: 67
diff changeset
1883 /* If ELEM contains a subst attribute with value "yes", then we
kono
parents: 67
diff changeset
1884 expected that a subst would be applied, but it wasn't - so,
kono
parents: 67
diff changeset
1885 we need to remove that elementto avoid duplicating. */
kono
parents: 67
diff changeset
1886 for (subst_elem = define_subst_queue;
kono
parents: 67
diff changeset
1887 subst_elem; subst_elem = subst_elem->next)
kono
parents: 67
diff changeset
1888 {
kono
parents: 67
diff changeset
1889 if (has_subst_attribute (elem, subst_elem))
kono
parents: 67
diff changeset
1890 {
kono
parents: 67
diff changeset
1891 remove_from_queue (elem, &queue);
kono
parents: 67
diff changeset
1892 return;
kono
parents: 67
diff changeset
1893 }
kono
parents: 67
diff changeset
1894 }
kono
parents: 67
diff changeset
1895 }
kono
parents: 67
diff changeset
1896
kono
parents: 67
diff changeset
1897 /* This is a subroutine of mark_operands_used_in_match_dup.
kono
parents: 67
diff changeset
1898 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
kono
parents: 67
diff changeset
1899 static void
kono
parents: 67
diff changeset
1900 mark_operands_from_match_dup (rtx pattern)
kono
parents: 67
diff changeset
1901 {
kono
parents: 67
diff changeset
1902 const char *fmt;
kono
parents: 67
diff changeset
1903 int i, j, len, opno;
kono
parents: 67
diff changeset
1904
kono
parents: 67
diff changeset
1905 if (GET_CODE (pattern) == MATCH_OPERAND
kono
parents: 67
diff changeset
1906 || GET_CODE (pattern) == MATCH_OPERATOR
kono
parents: 67
diff changeset
1907 || GET_CODE (pattern) == MATCH_PARALLEL)
kono
parents: 67
diff changeset
1908 {
kono
parents: 67
diff changeset
1909 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
1910 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
1911 used_operands_numbers [opno] = 1;
kono
parents: 67
diff changeset
1912 }
kono
parents: 67
diff changeset
1913 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
1914 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
1915 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1916 {
kono
parents: 67
diff changeset
1917 switch (fmt[i])
kono
parents: 67
diff changeset
1918 {
kono
parents: 67
diff changeset
1919 case 'e': case 'u':
kono
parents: 67
diff changeset
1920 mark_operands_from_match_dup (XEXP (pattern, i));
kono
parents: 67
diff changeset
1921 break;
kono
parents: 67
diff changeset
1922 case 'E':
kono
parents: 67
diff changeset
1923 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1924 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
kono
parents: 67
diff changeset
1925 break;
kono
parents: 67
diff changeset
1926 }
kono
parents: 67
diff changeset
1927 }
kono
parents: 67
diff changeset
1928 }
kono
parents: 67
diff changeset
1929
kono
parents: 67
diff changeset
1930 /* This is a subroutine of adjust_operands_numbers.
kono
parents: 67
diff changeset
1931 It goes through all expressions in PATTERN and when MATCH_DUP is
kono
parents: 67
diff changeset
1932 met, all MATCH_OPERANDs inside it is marked as occupied. The
kono
parents: 67
diff changeset
1933 process of marking is done by routin mark_operands_from_match_dup. */
kono
parents: 67
diff changeset
1934 static void
kono
parents: 67
diff changeset
1935 mark_operands_used_in_match_dup (rtx pattern)
kono
parents: 67
diff changeset
1936 {
kono
parents: 67
diff changeset
1937 const char *fmt;
kono
parents: 67
diff changeset
1938 int i, j, len, opno;
kono
parents: 67
diff changeset
1939
kono
parents: 67
diff changeset
1940 if (GET_CODE (pattern) == MATCH_DUP)
kono
parents: 67
diff changeset
1941 {
kono
parents: 67
diff changeset
1942 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
1943 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
1944 mark_operands_from_match_dup (operand_data[opno]);
kono
parents: 67
diff changeset
1945 return;
kono
parents: 67
diff changeset
1946 }
kono
parents: 67
diff changeset
1947 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
1948 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
1949 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
1950 {
kono
parents: 67
diff changeset
1951 switch (fmt[i])
kono
parents: 67
diff changeset
1952 {
kono
parents: 67
diff changeset
1953 case 'e': case 'u':
kono
parents: 67
diff changeset
1954 mark_operands_used_in_match_dup (XEXP (pattern, i));
kono
parents: 67
diff changeset
1955 break;
kono
parents: 67
diff changeset
1956 case 'E':
kono
parents: 67
diff changeset
1957 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
1958 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
kono
parents: 67
diff changeset
1959 break;
kono
parents: 67
diff changeset
1960 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1961 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1962 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1963
111
kono
parents: 67
diff changeset
1964 /* This is subroutine of renumerate_operands_in_pattern.
kono
parents: 67
diff changeset
1965 It finds first not-occupied operand-index. */
kono
parents: 67
diff changeset
1966 static int
kono
parents: 67
diff changeset
1967 find_first_unused_number_of_operand ()
kono
parents: 67
diff changeset
1968 {
kono
parents: 67
diff changeset
1969 int i;
kono
parents: 67
diff changeset
1970 for (i = 0; i < MAX_OPERANDS; i++)
kono
parents: 67
diff changeset
1971 if (!used_operands_numbers[i])
kono
parents: 67
diff changeset
1972 return i;
kono
parents: 67
diff changeset
1973 return MAX_OPERANDS;
kono
parents: 67
diff changeset
1974 }
kono
parents: 67
diff changeset
1975
kono
parents: 67
diff changeset
1976 /* This is subroutine of adjust_operands_numbers.
kono
parents: 67
diff changeset
1977 It visits all expressions in PATTERN and assigns not-occupied
kono
parents: 67
diff changeset
1978 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
kono
parents: 67
diff changeset
1979 PATTERN. */
kono
parents: 67
diff changeset
1980 static void
kono
parents: 67
diff changeset
1981 renumerate_operands_in_pattern (rtx pattern)
kono
parents: 67
diff changeset
1982 {
kono
parents: 67
diff changeset
1983 const char *fmt;
kono
parents: 67
diff changeset
1984 enum rtx_code code;
kono
parents: 67
diff changeset
1985 int i, j, len, new_opno;
kono
parents: 67
diff changeset
1986 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
1987
kono
parents: 67
diff changeset
1988 if (code == MATCH_OPERAND
kono
parents: 67
diff changeset
1989 || code == MATCH_OPERATOR)
kono
parents: 67
diff changeset
1990 {
kono
parents: 67
diff changeset
1991 new_opno = find_first_unused_number_of_operand ();
kono
parents: 67
diff changeset
1992 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
1993 XINT (pattern, 0) = new_opno;
kono
parents: 67
diff changeset
1994 used_operands_numbers [new_opno] = 1;
kono
parents: 67
diff changeset
1995 }
kono
parents: 67
diff changeset
1996
kono
parents: 67
diff changeset
1997 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
1998 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
1999 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2000 {
kono
parents: 67
diff changeset
2001 switch (fmt[i])
kono
parents: 67
diff changeset
2002 {
kono
parents: 67
diff changeset
2003 case 'e': case 'u':
kono
parents: 67
diff changeset
2004 renumerate_operands_in_pattern (XEXP (pattern, i));
kono
parents: 67
diff changeset
2005 break;
kono
parents: 67
diff changeset
2006 case 'E':
kono
parents: 67
diff changeset
2007 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
2008 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
kono
parents: 67
diff changeset
2009 break;
kono
parents: 67
diff changeset
2010 }
kono
parents: 67
diff changeset
2011 }
kono
parents: 67
diff changeset
2012 }
kono
parents: 67
diff changeset
2013
kono
parents: 67
diff changeset
2014 /* If output pattern of define_subst contains MATCH_DUP, then this
kono
parents: 67
diff changeset
2015 expression would be replaced with the pattern, matched with
kono
parents: 67
diff changeset
2016 MATCH_OPERAND from input pattern. This pattern could contain any
kono
parents: 67
diff changeset
2017 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
kono
parents: 67
diff changeset
2018 that a MATCH_OPERAND from output_pattern (if any) would have the
kono
parents: 67
diff changeset
2019 same number, as MATCH_OPERAND from copied pattern. To avoid such
kono
parents: 67
diff changeset
2020 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
kono
parents: 67
diff changeset
2021 laying in the output pattern outside of MATCH_DUPs. */
kono
parents: 67
diff changeset
2022 static rtx
kono
parents: 67
diff changeset
2023 adjust_operands_numbers (rtx pattern)
kono
parents: 67
diff changeset
2024 {
kono
parents: 67
diff changeset
2025 mark_operands_used_in_match_dup (pattern);
kono
parents: 67
diff changeset
2026
kono
parents: 67
diff changeset
2027 renumerate_operands_in_pattern (pattern);
kono
parents: 67
diff changeset
2028
kono
parents: 67
diff changeset
2029 return pattern;
kono
parents: 67
diff changeset
2030 }
kono
parents: 67
diff changeset
2031
kono
parents: 67
diff changeset
2032 /* Generate RTL expression
kono
parents: 67
diff changeset
2033 (match_dup OPNO)
kono
parents: 67
diff changeset
2034 */
kono
parents: 67
diff changeset
2035 static rtx
kono
parents: 67
diff changeset
2036 generate_match_dup (int opno)
kono
parents: 67
diff changeset
2037 {
kono
parents: 67
diff changeset
2038 rtx return_rtx = rtx_alloc (MATCH_DUP);
kono
parents: 67
diff changeset
2039 PUT_CODE (return_rtx, MATCH_DUP);
kono
parents: 67
diff changeset
2040 XINT (return_rtx, 0) = opno;
kono
parents: 67
diff changeset
2041 return return_rtx;
kono
parents: 67
diff changeset
2042 }
kono
parents: 67
diff changeset
2043
kono
parents: 67
diff changeset
2044 /* This routine checks all match_operands in PATTERN and if some of
kono
parents: 67
diff changeset
2045 have the same index, it replaces all of them except the first one to
kono
parents: 67
diff changeset
2046 match_dup.
kono
parents: 67
diff changeset
2047 Usually, match_operands with the same indexes are forbidden, but
kono
parents: 67
diff changeset
2048 after define_subst copy an RTL-expression from original template,
kono
parents: 67
diff changeset
2049 indexes of existed and just-copied match_operands could coincide.
kono
parents: 67
diff changeset
2050 To fix it, we replace one of them with match_dup. */
kono
parents: 67
diff changeset
2051 static rtx
kono
parents: 67
diff changeset
2052 replace_duplicating_operands_in_pattern (rtx pattern)
kono
parents: 67
diff changeset
2053 {
kono
parents: 67
diff changeset
2054 const char *fmt;
kono
parents: 67
diff changeset
2055 int i, j, len, opno;
kono
parents: 67
diff changeset
2056 rtx mdup;
kono
parents: 67
diff changeset
2057
kono
parents: 67
diff changeset
2058 if (GET_CODE (pattern) == MATCH_OPERAND)
kono
parents: 67
diff changeset
2059 {
kono
parents: 67
diff changeset
2060 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
2061 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
2062 if (match_operand_entries_in_pattern[opno] == NULL)
kono
parents: 67
diff changeset
2063 {
kono
parents: 67
diff changeset
2064 match_operand_entries_in_pattern[opno] = pattern;
kono
parents: 67
diff changeset
2065 return NULL;
kono
parents: 67
diff changeset
2066 }
kono
parents: 67
diff changeset
2067 else
kono
parents: 67
diff changeset
2068 {
kono
parents: 67
diff changeset
2069 /* Compare predicates before replacing with match_dup. */
kono
parents: 67
diff changeset
2070 if (strcmp (XSTR (pattern, 1),
kono
parents: 67
diff changeset
2071 XSTR (match_operand_entries_in_pattern[opno], 1)))
kono
parents: 67
diff changeset
2072 {
kono
parents: 67
diff changeset
2073 error ("duplicated match_operands with different predicates were"
kono
parents: 67
diff changeset
2074 " found.");
kono
parents: 67
diff changeset
2075 return NULL;
kono
parents: 67
diff changeset
2076 }
kono
parents: 67
diff changeset
2077 return generate_match_dup (opno);
kono
parents: 67
diff changeset
2078 }
kono
parents: 67
diff changeset
2079 }
kono
parents: 67
diff changeset
2080 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
2081 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
2082 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2083 {
kono
parents: 67
diff changeset
2084 switch (fmt[i])
kono
parents: 67
diff changeset
2085 {
kono
parents: 67
diff changeset
2086 case 'e': case 'u':
kono
parents: 67
diff changeset
2087 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
kono
parents: 67
diff changeset
2088 if (mdup)
kono
parents: 67
diff changeset
2089 XEXP (pattern, i) = mdup;
kono
parents: 67
diff changeset
2090 break;
kono
parents: 67
diff changeset
2091 case 'E':
kono
parents: 67
diff changeset
2092 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
2093 {
kono
parents: 67
diff changeset
2094 mdup =
kono
parents: 67
diff changeset
2095 replace_duplicating_operands_in_pattern (XVECEXP
kono
parents: 67
diff changeset
2096 (pattern, i, j));
kono
parents: 67
diff changeset
2097 if (mdup)
kono
parents: 67
diff changeset
2098 XVECEXP (pattern, i, j) = mdup;
kono
parents: 67
diff changeset
2099 }
kono
parents: 67
diff changeset
2100 break;
kono
parents: 67
diff changeset
2101 }
kono
parents: 67
diff changeset
2102 }
kono
parents: 67
diff changeset
2103 return NULL;
kono
parents: 67
diff changeset
2104 }
kono
parents: 67
diff changeset
2105
kono
parents: 67
diff changeset
2106 /* The routine modifies given input PATTERN of define_subst, replacing
kono
parents: 67
diff changeset
2107 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
kono
parents: 67
diff changeset
2108 pattern, whose operands are stored in OPERAND_DATA array.
kono
parents: 67
diff changeset
2109 It also duplicates constraints in operands - constraints from
kono
parents: 67
diff changeset
2110 define_insn operands are duplicated N_SUBST_ALT times, constraints
kono
parents: 67
diff changeset
2111 from define_subst operands are duplicated N_ALT times.
kono
parents: 67
diff changeset
2112 After the duplication, returned output rtl-pattern contains every
kono
parents: 67
diff changeset
2113 combination of input constraints Vs constraints from define_subst
kono
parents: 67
diff changeset
2114 output. */
kono
parents: 67
diff changeset
2115 static rtx
kono
parents: 67
diff changeset
2116 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
kono
parents: 67
diff changeset
2117 {
kono
parents: 67
diff changeset
2118 const char *fmt;
kono
parents: 67
diff changeset
2119 enum rtx_code code;
kono
parents: 67
diff changeset
2120 int i, j, len, opno;
kono
parents: 67
diff changeset
2121
kono
parents: 67
diff changeset
2122 code = GET_CODE (pattern);
kono
parents: 67
diff changeset
2123 switch (code)
kono
parents: 67
diff changeset
2124 {
kono
parents: 67
diff changeset
2125 case MATCH_DUP:
kono
parents: 67
diff changeset
2126 case MATCH_OP_DUP:
kono
parents: 67
diff changeset
2127 opno = XINT (pattern, 0);
kono
parents: 67
diff changeset
2128
kono
parents: 67
diff changeset
2129 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
kono
parents: 67
diff changeset
2130
kono
parents: 67
diff changeset
2131 if (operand_data[opno])
kono
parents: 67
diff changeset
2132 {
kono
parents: 67
diff changeset
2133 pattern = copy_rtx (operand_data[opno]);
kono
parents: 67
diff changeset
2134
kono
parents: 67
diff changeset
2135 /* Duplicate constraints. */
kono
parents: 67
diff changeset
2136 pattern = alter_constraints (pattern, n_subst_alt,
kono
parents: 67
diff changeset
2137 duplicate_alternatives);
kono
parents: 67
diff changeset
2138 }
kono
parents: 67
diff changeset
2139 break;
kono
parents: 67
diff changeset
2140
kono
parents: 67
diff changeset
2141 default:
kono
parents: 67
diff changeset
2142 break;
kono
parents: 67
diff changeset
2143 }
kono
parents: 67
diff changeset
2144
kono
parents: 67
diff changeset
2145 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
kono
parents: 67
diff changeset
2146 len = GET_RTX_LENGTH (GET_CODE (pattern));
kono
parents: 67
diff changeset
2147 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2148 {
kono
parents: 67
diff changeset
2149 switch (fmt[i])
kono
parents: 67
diff changeset
2150 {
kono
parents: 67
diff changeset
2151 case 'e': case 'u':
kono
parents: 67
diff changeset
2152 if (code != MATCH_DUP && code != MATCH_OP_DUP)
kono
parents: 67
diff changeset
2153 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
kono
parents: 67
diff changeset
2154 n_alt, n_subst_alt);
kono
parents: 67
diff changeset
2155 break;
kono
parents: 67
diff changeset
2156 case 'V':
kono
parents: 67
diff changeset
2157 if (XVEC (pattern, i) == NULL)
kono
parents: 67
diff changeset
2158 break;
kono
parents: 67
diff changeset
2159 /* FALLTHRU */
kono
parents: 67
diff changeset
2160 case 'E':
kono
parents: 67
diff changeset
2161 if (code != MATCH_DUP && code != MATCH_OP_DUP)
kono
parents: 67
diff changeset
2162 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
kono
parents: 67
diff changeset
2163 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
kono
parents: 67
diff changeset
2164 n_alt, n_subst_alt);
kono
parents: 67
diff changeset
2165 break;
kono
parents: 67
diff changeset
2166
kono
parents: 67
diff changeset
2167 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
kono
parents: 67
diff changeset
2168 break;
kono
parents: 67
diff changeset
2169
kono
parents: 67
diff changeset
2170 default:
kono
parents: 67
diff changeset
2171 gcc_unreachable ();
kono
parents: 67
diff changeset
2172 }
kono
parents: 67
diff changeset
2173 }
kono
parents: 67
diff changeset
2174 return pattern;
kono
parents: 67
diff changeset
2175 }
kono
parents: 67
diff changeset
2176
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2177 /* 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
2178 patterns appropriately. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2179
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2180 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2181 process_define_cond_exec (void)
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 struct queue_elem *elem;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2184
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2185 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
2186 if (have_error)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2187 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2188
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2189 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2190 process_one_cond_exec (elem);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2191 }
111
kono
parents: 67
diff changeset
2192
kono
parents: 67
diff changeset
2193 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
kono
parents: 67
diff changeset
2194 DEFINE_EXPAND patterns appropriately. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2195
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
2196 static void
111
kono
parents: 67
diff changeset
2197 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
2198 {
111
kono
parents: 67
diff changeset
2199 struct queue_elem *elem, *elem_attr;
kono
parents: 67
diff changeset
2200
kono
parents: 67
diff changeset
2201 /* Check if each define_subst has corresponding define_subst_attr. */
kono
parents: 67
diff changeset
2202 for (elem = define_subst_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
2203 {
kono
parents: 67
diff changeset
2204 for (elem_attr = define_subst_attr_queue;
kono
parents: 67
diff changeset
2205 elem_attr;
kono
parents: 67
diff changeset
2206 elem_attr = elem_attr->next)
kono
parents: 67
diff changeset
2207 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
kono
parents: 67
diff changeset
2208 goto found;
kono
parents: 67
diff changeset
2209
kono
parents: 67
diff changeset
2210 error_at (elem->loc,
kono
parents: 67
diff changeset
2211 "%s: `define_subst' must have at least one "
kono
parents: 67
diff changeset
2212 "corresponding `define_subst_attr'",
kono
parents: 67
diff changeset
2213 XSTR (elem->data, 0));
kono
parents: 67
diff changeset
2214 return;
kono
parents: 67
diff changeset
2215
kono
parents: 67
diff changeset
2216 found:
kono
parents: 67
diff changeset
2217 continue;
kono
parents: 67
diff changeset
2218 }
kono
parents: 67
diff changeset
2219
kono
parents: 67
diff changeset
2220 for (elem = define_insn_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
2221 process_substs_on_one_elem (elem, define_insn_queue);
kono
parents: 67
diff changeset
2222 for (elem = other_queue; elem ; elem = elem->next)
kono
parents: 67
diff changeset
2223 {
kono
parents: 67
diff changeset
2224 if (GET_CODE (elem->data) != DEFINE_EXPAND)
kono
parents: 67
diff changeset
2225 continue;
kono
parents: 67
diff changeset
2226 process_substs_on_one_elem (elem, other_queue);
kono
parents: 67
diff changeset
2227 }
kono
parents: 67
diff changeset
2228 }
kono
parents: 67
diff changeset
2229
kono
parents: 67
diff changeset
2230 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
kono
parents: 67
diff changeset
2231 the top-level elements. */
kono
parents: 67
diff changeset
2232
kono
parents: 67
diff changeset
2233 class gen_reader : public rtx_reader
kono
parents: 67
diff changeset
2234 {
kono
parents: 67
diff changeset
2235 public:
kono
parents: 67
diff changeset
2236 gen_reader () : rtx_reader (false) {}
kono
parents: 67
diff changeset
2237 void handle_unknown_directive (file_location, const char *);
kono
parents: 67
diff changeset
2238 };
kono
parents: 67
diff changeset
2239
kono
parents: 67
diff changeset
2240 void
kono
parents: 67
diff changeset
2241 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
kono
parents: 67
diff changeset
2242 {
kono
parents: 67
diff changeset
2243 auto_vec<rtx, 32> subrtxs;
kono
parents: 67
diff changeset
2244 if (!read_rtx (rtx_name, &subrtxs))
kono
parents: 67
diff changeset
2245 return;
kono
parents: 67
diff changeset
2246
kono
parents: 67
diff changeset
2247 rtx x;
kono
parents: 67
diff changeset
2248 unsigned int i;
kono
parents: 67
diff changeset
2249 FOR_EACH_VEC_ELT (subrtxs, i, x)
kono
parents: 67
diff changeset
2250 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
2251 }
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
2252
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
2253 /* 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
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 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
2256 htab_eq_string (const void *s1, const void *s2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2257 {
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
2258 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
2259 }
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
2260
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 /* Add mnemonic STR with length LEN to the mnemonic hash table
111
kono
parents: 67
diff changeset
2262 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
2263 and a permanent heap copy of STR is created. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2264
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
2265 static void
111
kono
parents: 67
diff changeset
2266 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
2267 {
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 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
2269 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
2270 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
2271
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 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
2273 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
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 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
2276
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 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
2278 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
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 /* 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
2281 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
2282 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
2283 *slot = new_str;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2284 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2285
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
2286 /* 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
2287 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
2288
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 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
2290
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 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
2292 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
2293 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
2294
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 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
2296 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
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 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
2299 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
2300 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
2301 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
2302 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
2303 rtvec new_vec;
111
kono
parents: 67
diff changeset
2304 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
2305
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 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
2307
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 /* 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
2309 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
2310 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
2311
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 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
2314 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
2315 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
2316
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 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
2318 {
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 const char *ep, *sp;
111
kono
parents: 67
diff changeset
2320 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
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 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
2323 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
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 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
2326 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
2327 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
2328
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 (i > 0)
111
kono
parents: 67
diff changeset
2330 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
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 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
2333 || (*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
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 {
111
kono
parents: 67
diff changeset
2336 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
2337 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
2338 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
2339 }
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
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 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
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 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
2344 {
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 /* 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
2346 instruction in the string. */
111
kono
parents: 67
diff changeset
2347 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
2348 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
2349
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
2350 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
2351 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
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++;
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 }
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 if (size == 0)
111
kono
parents: 67
diff changeset
2356 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
2357 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
2358 add_mnemonic_string (mnemonic_htab,
111
kono
parents: 67
diff changeset
2359 (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
2360 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
2361 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
2362 }
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
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 /* An insn definition might emit an empty string. */
111
kono
parents: 67
diff changeset
2365 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
2366 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
2367
111
kono
parents: 67
diff changeset
2368 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
2369
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 set_attr = rtx_alloc (SET_ATTR);
111
kono
parents: 67
diff changeset
2371 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
2372 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
2373 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
2374 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
2375
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 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
2377 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
2378 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
2379 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
2380
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 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
2382 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
2383 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
2384 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
2385 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
2386 }
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
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 /* 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
2389 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
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 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
2392 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
2393 {
111
kono
parents: 67
diff changeset
2394 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
kono
parents: 67
diff changeset
2395
kono
parents: 67
diff changeset
2396 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
kono
parents: 67
diff changeset
2397 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
2398 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
2399 }
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
2400
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 /* 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
2402 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
2403 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
2404 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
2405 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
2406
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 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
2408 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
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 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
2411 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
2412 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
2413 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
2414 int i;
111
kono
parents: 67
diff changeset
2415 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
2416
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 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
2418 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
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 /* 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
2421 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
2422 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
2423 && 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
2424 {
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 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
2426 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
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
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 /* 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
2430 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
2431 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
2432 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
2433
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 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
2435 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
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 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
2438 {
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 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
2440 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
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 /* Check if the insn definition already has
111
kono
parents: 67
diff changeset
2443 (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
2444 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
2445 for (i = 0; i < XVECLEN (insn, 4); i++)
111
kono
parents: 67
diff changeset
2446 {
kono
parents: 67
diff changeset
2447 rtx set_attr = XVECEXP (insn, 4, i);
kono
parents: 67
diff changeset
2448
kono
parents: 67
diff changeset
2449 switch (GET_CODE (set_attr))
kono
parents: 67
diff changeset
2450 {
kono
parents: 67
diff changeset
2451 case SET_ATTR:
kono
parents: 67
diff changeset
2452 case SET_ATTR_ALTERNATIVE:
kono
parents: 67
diff changeset
2453 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
kono
parents: 67
diff changeset
2454 found = true;
kono
parents: 67
diff changeset
2455 break;
kono
parents: 67
diff changeset
2456 case SET:
kono
parents: 67
diff changeset
2457 if (GET_CODE (SET_DEST (set_attr)) == ATTR
kono
parents: 67
diff changeset
2458 && strcmp (XSTR (SET_DEST (set_attr), 0),
kono
parents: 67
diff changeset
2459 MNEMONIC_ATTR_NAME) == 0)
kono
parents: 67
diff changeset
2460 found = true;
kono
parents: 67
diff changeset
2461 break;
kono
parents: 67
diff changeset
2462 default:
kono
parents: 67
diff changeset
2463 break;
kono
parents: 67
diff changeset
2464 }
kono
parents: 67
diff changeset
2465 }
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
2466
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
2467 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
2468 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
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
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 /* 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
2472 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
2473 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
2474 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
2475
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 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
2477
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 /* Replace the last ',' with the zero end character. */
111
kono
parents: 67
diff changeset
2479 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
kono
parents: 67
diff changeset
2480 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
kono
parents: 67
diff changeset
2481 }
kono
parents: 67
diff changeset
2482
kono
parents: 67
diff changeset
2483 /* Check if there are DEFINE_ATTRs with the same name. */
kono
parents: 67
diff changeset
2484 static void
kono
parents: 67
diff changeset
2485 check_define_attr_duplicates ()
kono
parents: 67
diff changeset
2486 {
kono
parents: 67
diff changeset
2487 struct queue_elem *elem;
kono
parents: 67
diff changeset
2488 htab_t attr_htab;
kono
parents: 67
diff changeset
2489 char * attr_name;
kono
parents: 67
diff changeset
2490 void **slot;
kono
parents: 67
diff changeset
2491
kono
parents: 67
diff changeset
2492 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
kono
parents: 67
diff changeset
2493
kono
parents: 67
diff changeset
2494 for (elem = define_attr_queue; elem; elem = elem->next)
kono
parents: 67
diff changeset
2495 {
kono
parents: 67
diff changeset
2496 attr_name = xstrdup (XSTR (elem->data, 0));
kono
parents: 67
diff changeset
2497
kono
parents: 67
diff changeset
2498 slot = htab_find_slot (attr_htab, attr_name, INSERT);
kono
parents: 67
diff changeset
2499
kono
parents: 67
diff changeset
2500 /* Duplicate. */
kono
parents: 67
diff changeset
2501 if (*slot)
kono
parents: 67
diff changeset
2502 {
kono
parents: 67
diff changeset
2503 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
kono
parents: 67
diff changeset
2504 htab_delete (attr_htab);
kono
parents: 67
diff changeset
2505 return;
kono
parents: 67
diff changeset
2506 }
kono
parents: 67
diff changeset
2507
kono
parents: 67
diff changeset
2508 *slot = attr_name;
kono
parents: 67
diff changeset
2509 }
kono
parents: 67
diff changeset
2510
kono
parents: 67
diff changeset
2511 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
2512 }
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
2513
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2514 /* The entry point for initializing the reader. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2515
111
kono
parents: 67
diff changeset
2516 rtx_reader *
kono
parents: 67
diff changeset
2517 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
2518 bool (*parse_opt) (const char *))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2519 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2520 /* Prepare to read input. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2521 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
2522 init_predicate_table ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2523 obstack_init (rtl_obstack);
111
kono
parents: 67
diff changeset
2524
kono
parents: 67
diff changeset
2525 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
kono
parents: 67
diff changeset
2526 insn_sequence_num = 1;
kono
parents: 67
diff changeset
2527
kono
parents: 67
diff changeset
2528 /* These sequences are not used as indices, so can start at 1 also. */
kono
parents: 67
diff changeset
2529 split_sequence_num = 1;
kono
parents: 67
diff changeset
2530 peephole2_sequence_num = 1;
kono
parents: 67
diff changeset
2531
kono
parents: 67
diff changeset
2532 gen_reader *reader = new gen_reader ();
kono
parents: 67
diff changeset
2533 reader->read_md_files (argc, argv, parse_opt);
kono
parents: 67
diff changeset
2534
kono
parents: 67
diff changeset
2535 if (define_attr_queue != NULL)
kono
parents: 67
diff changeset
2536 check_define_attr_duplicates ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2537
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2538 /* Process define_cond_exec patterns. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2539 if (define_cond_exec_queue != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2540 process_define_cond_exec ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2541
111
kono
parents: 67
diff changeset
2542 /* Process define_subst patterns. */
kono
parents: 67
diff changeset
2543 if (define_subst_queue != NULL)
kono
parents: 67
diff changeset
2544 process_define_subst ();
kono
parents: 67
diff changeset
2545
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
2546 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
2547 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
2548
111
kono
parents: 67
diff changeset
2549 if (have_error)
kono
parents: 67
diff changeset
2550 {
kono
parents: 67
diff changeset
2551 delete reader;
kono
parents: 67
diff changeset
2552 return NULL;
kono
parents: 67
diff changeset
2553 }
kono
parents: 67
diff changeset
2554
kono
parents: 67
diff changeset
2555 return reader;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2556 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2557
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2558 /* 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
2559 instead. */
111
kono
parents: 67
diff changeset
2560 rtx_reader *
kono
parents: 67
diff changeset
2561 init_rtx_reader_args (int argc, const char **argv)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2562 {
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
2563 return init_rtx_reader_args_cb (argc, argv, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2564 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2565
111
kono
parents: 67
diff changeset
2566 /* Try to read a single rtx from the file. Return true on success,
kono
parents: 67
diff changeset
2567 describing it in *INFO. */
kono
parents: 67
diff changeset
2568
kono
parents: 67
diff changeset
2569 bool
kono
parents: 67
diff changeset
2570 read_md_rtx (md_rtx_info *info)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2571 {
111
kono
parents: 67
diff changeset
2572 int truth, *counter;
kono
parents: 67
diff changeset
2573 rtx def;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2574
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2575 /* Discard insn patterns which we know can never match (because
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2576 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
2577 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
2578 elided patterns are never counted by the sequence numbering; it
111
kono
parents: 67
diff changeset
2579 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
2580 to use elided pattern numbers for anything. */
111
kono
parents: 67
diff changeset
2581 do
kono
parents: 67
diff changeset
2582 {
kono
parents: 67
diff changeset
2583 struct queue_elem **queue, *elem;
kono
parents: 67
diff changeset
2584
kono
parents: 67
diff changeset
2585 /* Read all patterns from a given queue before moving on to the next. */
kono
parents: 67
diff changeset
2586 if (define_attr_queue != NULL)
kono
parents: 67
diff changeset
2587 queue = &define_attr_queue;
kono
parents: 67
diff changeset
2588 else if (define_pred_queue != NULL)
kono
parents: 67
diff changeset
2589 queue = &define_pred_queue;
kono
parents: 67
diff changeset
2590 else if (define_insn_queue != NULL)
kono
parents: 67
diff changeset
2591 queue = &define_insn_queue;
kono
parents: 67
diff changeset
2592 else if (other_queue != NULL)
kono
parents: 67
diff changeset
2593 queue = &other_queue;
kono
parents: 67
diff changeset
2594 else
kono
parents: 67
diff changeset
2595 return false;
kono
parents: 67
diff changeset
2596
kono
parents: 67
diff changeset
2597 elem = *queue;
kono
parents: 67
diff changeset
2598 *queue = elem->next;
kono
parents: 67
diff changeset
2599 def = elem->data;
kono
parents: 67
diff changeset
2600 info->def = def;
kono
parents: 67
diff changeset
2601 info->loc = elem->loc;
kono
parents: 67
diff changeset
2602 free (elem);
kono
parents: 67
diff changeset
2603
kono
parents: 67
diff changeset
2604 truth = maybe_eval_c_test (get_c_test (def));
kono
parents: 67
diff changeset
2605 }
kono
parents: 67
diff changeset
2606 while (truth == 0 && insn_elision);
kono
parents: 67
diff changeset
2607
kono
parents: 67
diff changeset
2608 /* Perform code-specific processing and pick the appropriate sequence
kono
parents: 67
diff changeset
2609 number counter. */
kono
parents: 67
diff changeset
2610 switch (GET_CODE (def))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2611 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2612 case DEFINE_INSN:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2613 case DEFINE_EXPAND:
111
kono
parents: 67
diff changeset
2614 /* 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
2615 idea of insn numbering, whether or not elision is active. */
111
kono
parents: 67
diff changeset
2616 record_insn_name (insn_sequence_num, XSTR (def, 0));
kono
parents: 67
diff changeset
2617
kono
parents: 67
diff changeset
2618 /* Fall through. */
kono
parents: 67
diff changeset
2619 case DEFINE_PEEPHOLE:
kono
parents: 67
diff changeset
2620 counter = &insn_sequence_num;
kono
parents: 67
diff changeset
2621 break;
kono
parents: 67
diff changeset
2622
kono
parents: 67
diff changeset
2623 case DEFINE_SPLIT:
kono
parents: 67
diff changeset
2624 counter = &split_sequence_num;
kono
parents: 67
diff changeset
2625 break;
kono
parents: 67
diff changeset
2626
kono
parents: 67
diff changeset
2627 case DEFINE_PEEPHOLE2:
kono
parents: 67
diff changeset
2628 counter = &peephole2_sequence_num;
kono
parents: 67
diff changeset
2629 break;
kono
parents: 67
diff changeset
2630
kono
parents: 67
diff changeset
2631 default:
kono
parents: 67
diff changeset
2632 counter = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2633 break;
111
kono
parents: 67
diff changeset
2634 }
kono
parents: 67
diff changeset
2635
kono
parents: 67
diff changeset
2636 if (counter)
kono
parents: 67
diff changeset
2637 {
kono
parents: 67
diff changeset
2638 info->index = *counter;
kono
parents: 67
diff changeset
2639 if (truth != 0)
kono
parents: 67
diff changeset
2640 *counter += 1;
kono
parents: 67
diff changeset
2641 }
kono
parents: 67
diff changeset
2642 else
kono
parents: 67
diff changeset
2643 info->index = -1;
kono
parents: 67
diff changeset
2644
kono
parents: 67
diff changeset
2645 if (!rtx_locs)
kono
parents: 67
diff changeset
2646 rtx_locs = new hash_map <rtx, file_location>;
kono
parents: 67
diff changeset
2647 rtx_locs->put (info->def, info->loc);
kono
parents: 67
diff changeset
2648
kono
parents: 67
diff changeset
2649 return true;
kono
parents: 67
diff changeset
2650 }
kono
parents: 67
diff changeset
2651
kono
parents: 67
diff changeset
2652 /* Return the file location of DEFINE_* rtx X, which was previously
kono
parents: 67
diff changeset
2653 returned by read_md_rtx. */
kono
parents: 67
diff changeset
2654 file_location
kono
parents: 67
diff changeset
2655 get_file_location (rtx x)
kono
parents: 67
diff changeset
2656 {
kono
parents: 67
diff changeset
2657 gcc_assert (rtx_locs);
kono
parents: 67
diff changeset
2658 file_location *entry = rtx_locs->get (x);
kono
parents: 67
diff changeset
2659 gcc_assert (entry);
kono
parents: 67
diff changeset
2660 return *entry;
kono
parents: 67
diff changeset
2661 }
kono
parents: 67
diff changeset
2662
kono
parents: 67
diff changeset
2663 /* Return the number of possible INSN_CODEs. Only meaningful once the
kono
parents: 67
diff changeset
2664 whole file has been processed. */
kono
parents: 67
diff changeset
2665 unsigned int
kono
parents: 67
diff changeset
2666 get_num_insn_codes ()
kono
parents: 67
diff changeset
2667 {
kono
parents: 67
diff changeset
2668 return insn_sequence_num;
kono
parents: 67
diff changeset
2669 }
kono
parents: 67
diff changeset
2670
kono
parents: 67
diff changeset
2671 /* Return the C test that says whether definition rtx DEF can be used,
kono
parents: 67
diff changeset
2672 or "" if it can be used unconditionally. */
kono
parents: 67
diff changeset
2673
kono
parents: 67
diff changeset
2674 const char *
kono
parents: 67
diff changeset
2675 get_c_test (rtx x)
kono
parents: 67
diff changeset
2676 {
kono
parents: 67
diff changeset
2677 switch (GET_CODE (x))
kono
parents: 67
diff changeset
2678 {
kono
parents: 67
diff changeset
2679 case DEFINE_INSN:
kono
parents: 67
diff changeset
2680 case DEFINE_EXPAND:
kono
parents: 67
diff changeset
2681 case DEFINE_SUBST:
kono
parents: 67
diff changeset
2682 return XSTR (x, 2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2683
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2684 case DEFINE_SPLIT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2685 case DEFINE_PEEPHOLE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2686 case DEFINE_PEEPHOLE2:
111
kono
parents: 67
diff changeset
2687 return XSTR (x, 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2688
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2689 default:
111
kono
parents: 67
diff changeset
2690 return "";
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 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2693
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2694 /* Helper functions for insn elision. */
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 /* 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
2697 by its ->expr field. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2698 hashval_t
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2699 hash_c_test (const void *x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2700 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2701 const struct c_test *a = (const struct c_test *) x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2702 const unsigned char *base, *s = (const unsigned char *) a->expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2703 hashval_t hash;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2704 unsigned char c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2705 unsigned int len;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2706
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2707 base = s;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2708 hash = 0;
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 while ((c = *s++) != '\0')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2711 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2712 hash += c + (c << 17);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2713 hash ^= hash >> 2;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2716 len = s - base;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2717 hash += len + (len << 17);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2718 hash ^= hash >> 2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2719
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2720 return hash;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2721 }
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 /* Compare two c_test expression structures. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2724 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2725 cmp_c_test (const void *x, const void *y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2726 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2727 const struct c_test *a = (const struct c_test *) x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2728 const struct c_test *b = (const struct c_test *) 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 return !strcmp (a->expr, b->expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2731 }
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 /* 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
2734 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
2735 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
2736 known false, -1 for unknown. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2737 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2738 maybe_eval_c_test (const char *expr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2739 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2740 const struct c_test *test;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2741 struct c_test dummy;
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 if (expr[0] == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2744 return 1;
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 dummy.expr = expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2747 test = (const struct c_test *)htab_find (condition_table, &dummy);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2748 if (!test)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2749 return -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2750 return test->value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2751 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2752
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2753 /* 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
2754 value VAL. Duplicates clobber previous entries. */
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 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2757 add_c_test (const char *expr, int value)
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 struct c_test *test;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2760
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2761 if (expr[0] == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2762 return;
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 test = XNEW (struct c_test);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2765 test->expr = expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2766 test->value = value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2767
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2768 *(htab_find_slot (condition_table, test, INSERT)) = test;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2769 }
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 /* 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
2772 the condition structure and INFO. Stops when CALLBACK returns zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2773 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2774 traverse_c_tests (htab_trav callback, void *info)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2775 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2776 if (condition_table)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2777 htab_traverse (condition_table, callback, 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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2780 /* Helper functions for define_predicate and define_special_predicate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2781 processing. Shared between genrecog.c and genpreds.c. */
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 static htab_t predicate_table;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2784 struct pred_data *first_predicate;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2785 static struct pred_data **last_predicate = &first_predicate;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2786
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2787 static hashval_t
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2788 hash_struct_pred_data (const void *ptr)
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 return htab_hash_string (((const struct pred_data *)ptr)->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2791 }
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 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2794 eq_struct_pred_data (const void *a, const void *b)
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 return !strcmp (((const struct pred_data *)a)->name,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2797 ((const struct pred_data *)b)->name);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2800 struct pred_data *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2801 lookup_predicate (const char *name)
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 key;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2804 key.name = name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2805 return (struct pred_data *) htab_find (predicate_table, &key);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2806 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2807
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2808 /* Record that predicate PRED can accept CODE. */
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 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2811 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
2812 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2813 if (!pred->codes[code])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2814 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2815 pred->num_codes++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2816 pred->codes[code] = true;
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 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2819 pred->allows_non_const = 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 (code != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2822 && code != SUBREG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2823 && code != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2824 && code != CONCAT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2825 && code != PARALLEL
111
kono
parents: 67
diff changeset
2826 && code != STRICT_LOW_PART
kono
parents: 67
diff changeset
2827 && code != SCRATCH)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2828 pred->allows_non_lvalue = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2829
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2830 if (pred->num_codes == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2831 pred->singleton = code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2832 else if (pred->num_codes == 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2833 pred->singleton = UNKNOWN;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2834 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2835 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2836
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2837 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2838 add_predicate (struct pred_data *pred)
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 **slot = htab_find_slot (predicate_table, pred, INSERT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2841 if (*slot)
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 error ("duplicate predicate definition for '%s'", pred->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2844 return;
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 *slot = pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2847 *last_predicate = pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2848 last_predicate = &pred->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2849 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2850
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2851 /* 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
2852 has entries for all predicates defined in recog.c. */
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 struct std_pred_table
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2855 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2856 const char *name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2857 bool special;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2858 bool allows_const_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2859 RTX_CODE codes[NUM_RTX_CODE];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2860 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2861
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2862 static const struct std_pred_table std_preds[] = {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2863 {"general_operand", false, true, {SUBREG, REG, MEM}},
111
kono
parents: 67
diff changeset
2864 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
kono
parents: 67
diff changeset
2865 ZERO_EXTEND, SIGN_EXTEND, AND}},
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2866 {"register_operand", false, false, {SUBREG, REG}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2867 {"pmode_register_operand", true, false, {SUBREG, REG}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2868 {"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
2869 {"immediate_operand", false, true, {UNKNOWN}},
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2870 {"const_int_operand", false, false, {CONST_INT}},
111
kono
parents: 67
diff changeset
2871 #if TARGET_SUPPORTS_WIDE_INT
kono
parents: 67
diff changeset
2872 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
kono
parents: 67
diff changeset
2873 {"const_double_operand", false, false, {CONST_DOUBLE}},
kono
parents: 67
diff changeset
2874 #else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2875 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
111
kono
parents: 67
diff changeset
2876 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2877 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2878 {"nonmemory_operand", false, true, {SUBREG, REG}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2879 {"push_operand", false, false, {MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2880 {"pop_operand", false, false, {MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2881 {"memory_operand", false, false, {SUBREG, MEM}},
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2882 {"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
2883 {"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
2884 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
2885 LEU, LTU, GEU, GTU}},
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2886 {"comparison_operator", false, false, {EQ, NE,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2887 LE, LT, GE, GT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2888 LEU, LTU, GEU, GTU,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2889 UNORDERED, ORDERED,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2890 UNEQ, UNGE, UNGT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2891 UNLE, UNLT, LTGT}}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2892 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2893 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2894
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2895 /* Initialize the table of predicate definitions, starting with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2896 the information we have on generic predicates. */
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 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2899 init_predicate_table (void)
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 size_t i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2902 struct pred_data *pred;
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 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2905 eq_struct_pred_data, 0,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2906 xcalloc, free);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2907
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2908 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2909 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2910 pred = XCNEW (struct pred_data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2911 pred->name = std_preds[i].name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2912 pred->special = std_preds[i].special;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2913
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2914 for (j = 0; std_preds[i].codes[j] != 0; j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2915 add_predicate_code (pred, std_preds[i].codes[j]);
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 if (std_preds[i].allows_const_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2918 for (j = 0; j < NUM_RTX_CODE; j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2919 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
2920 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
2921
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2922 add_predicate (pred);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2923 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2924 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2925
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2926 /* 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
2927 like to annotate their output with insn names. */
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 /* Holds an array of names indexed by insn_code_number. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2930 static char **insn_name_ptr = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2931 static int insn_name_ptr_size = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2932
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2933 const char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2934 get_insn_name (int code)
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 if (code < insn_name_ptr_size)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2937 return insn_name_ptr[code];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2938 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2939 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2940 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2941
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2942 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2943 record_insn_name (int code, const char *name)
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 const char *last_real_name = "insn";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2946 static int last_real_code = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2947 char *new_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2948
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2949 if (insn_name_ptr_size <= code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2950 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2951 int new_size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2952 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
2953 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2954 memset (insn_name_ptr + insn_name_ptr_size, 0,
111
kono
parents: 67
diff changeset
2955 sizeof (char *) * (new_size - insn_name_ptr_size));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2956 insn_name_ptr_size = new_size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2957 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2958
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2959 if (!name || name[0] == '\0')
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 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2962 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
2963 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2964 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2965 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2966 last_real_name = new_name = xstrdup (name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2967 last_real_code = code;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2970 insn_name_ptr[code] = new_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2971 }
111
kono
parents: 67
diff changeset
2972
kono
parents: 67
diff changeset
2973 /* Make STATS describe the operands that appear in rtx X. */
kono
parents: 67
diff changeset
2974
kono
parents: 67
diff changeset
2975 static void
kono
parents: 67
diff changeset
2976 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
kono
parents: 67
diff changeset
2977 {
kono
parents: 67
diff changeset
2978 RTX_CODE code;
kono
parents: 67
diff changeset
2979 int i;
kono
parents: 67
diff changeset
2980 int len;
kono
parents: 67
diff changeset
2981 const char *fmt;
kono
parents: 67
diff changeset
2982
kono
parents: 67
diff changeset
2983 if (x == NULL_RTX)
kono
parents: 67
diff changeset
2984 return;
kono
parents: 67
diff changeset
2985
kono
parents: 67
diff changeset
2986 code = GET_CODE (x);
kono
parents: 67
diff changeset
2987 switch (code)
kono
parents: 67
diff changeset
2988 {
kono
parents: 67
diff changeset
2989 case MATCH_OPERAND:
kono
parents: 67
diff changeset
2990 case MATCH_OPERATOR:
kono
parents: 67
diff changeset
2991 case MATCH_PARALLEL:
kono
parents: 67
diff changeset
2992 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
kono
parents: 67
diff changeset
2993 break;
kono
parents: 67
diff changeset
2994
kono
parents: 67
diff changeset
2995 case MATCH_DUP:
kono
parents: 67
diff changeset
2996 case MATCH_OP_DUP:
kono
parents: 67
diff changeset
2997 case MATCH_PAR_DUP:
kono
parents: 67
diff changeset
2998 stats->num_dups++;
kono
parents: 67
diff changeset
2999 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
kono
parents: 67
diff changeset
3000 break;
kono
parents: 67
diff changeset
3001
kono
parents: 67
diff changeset
3002 case MATCH_SCRATCH:
kono
parents: 67
diff changeset
3003 if (stats->min_scratch_opno == -1)
kono
parents: 67
diff changeset
3004 stats->min_scratch_opno = XINT (x, 0);
kono
parents: 67
diff changeset
3005 else
kono
parents: 67
diff changeset
3006 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
kono
parents: 67
diff changeset
3007 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
kono
parents: 67
diff changeset
3008 break;
kono
parents: 67
diff changeset
3009
kono
parents: 67
diff changeset
3010 default:
kono
parents: 67
diff changeset
3011 break;
kono
parents: 67
diff changeset
3012 }
kono
parents: 67
diff changeset
3013
kono
parents: 67
diff changeset
3014 fmt = GET_RTX_FORMAT (code);
kono
parents: 67
diff changeset
3015 len = GET_RTX_LENGTH (code);
kono
parents: 67
diff changeset
3016 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
3017 {
kono
parents: 67
diff changeset
3018 if (fmt[i] == 'e' || fmt[i] == 'u')
kono
parents: 67
diff changeset
3019 get_pattern_stats_1 (stats, XEXP (x, i));
kono
parents: 67
diff changeset
3020 else if (fmt[i] == 'E')
kono
parents: 67
diff changeset
3021 {
kono
parents: 67
diff changeset
3022 int j;
kono
parents: 67
diff changeset
3023 for (j = 0; j < XVECLEN (x, i); j++)
kono
parents: 67
diff changeset
3024 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
kono
parents: 67
diff changeset
3025 }
kono
parents: 67
diff changeset
3026 }
kono
parents: 67
diff changeset
3027 }
kono
parents: 67
diff changeset
3028
kono
parents: 67
diff changeset
3029 /* Make STATS describe the operands that appear in instruction pattern
kono
parents: 67
diff changeset
3030 PATTERN. */
kono
parents: 67
diff changeset
3031
kono
parents: 67
diff changeset
3032 void
kono
parents: 67
diff changeset
3033 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
kono
parents: 67
diff changeset
3034 {
kono
parents: 67
diff changeset
3035 int i, len;
kono
parents: 67
diff changeset
3036
kono
parents: 67
diff changeset
3037 stats->max_opno = -1;
kono
parents: 67
diff changeset
3038 stats->max_dup_opno = -1;
kono
parents: 67
diff changeset
3039 stats->min_scratch_opno = -1;
kono
parents: 67
diff changeset
3040 stats->max_scratch_opno = -1;
kono
parents: 67
diff changeset
3041 stats->num_dups = 0;
kono
parents: 67
diff changeset
3042
kono
parents: 67
diff changeset
3043 len = GET_NUM_ELEM (pattern);
kono
parents: 67
diff changeset
3044 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
3045 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
kono
parents: 67
diff changeset
3046
kono
parents: 67
diff changeset
3047 stats->num_generator_args = stats->max_opno + 1;
kono
parents: 67
diff changeset
3048 stats->num_insn_operands = MAX (stats->max_opno,
kono
parents: 67
diff changeset
3049 stats->max_scratch_opno) + 1;
kono
parents: 67
diff changeset
3050 stats->num_operand_vars = MAX (stats->max_opno,
kono
parents: 67
diff changeset
3051 MAX (stats->max_dup_opno,
kono
parents: 67
diff changeset
3052 stats->max_scratch_opno)) + 1;
kono
parents: 67
diff changeset
3053 }
kono
parents: 67
diff changeset
3054
kono
parents: 67
diff changeset
3055 /* Return the emit_* function that should be used for pattern X, or NULL
kono
parents: 67
diff changeset
3056 if we can't pick a particular type at compile time and should instead
kono
parents: 67
diff changeset
3057 fall back to "emit". */
kono
parents: 67
diff changeset
3058
kono
parents: 67
diff changeset
3059 const char *
kono
parents: 67
diff changeset
3060 get_emit_function (rtx x)
kono
parents: 67
diff changeset
3061 {
kono
parents: 67
diff changeset
3062 switch (classify_insn (x))
kono
parents: 67
diff changeset
3063 {
kono
parents: 67
diff changeset
3064 case INSN:
kono
parents: 67
diff changeset
3065 return "emit_insn";
kono
parents: 67
diff changeset
3066
kono
parents: 67
diff changeset
3067 case CALL_INSN:
kono
parents: 67
diff changeset
3068 return "emit_call_insn";
kono
parents: 67
diff changeset
3069
kono
parents: 67
diff changeset
3070 case JUMP_INSN:
kono
parents: 67
diff changeset
3071 return "emit_jump_insn";
kono
parents: 67
diff changeset
3072
kono
parents: 67
diff changeset
3073 case UNKNOWN:
kono
parents: 67
diff changeset
3074 return NULL;
kono
parents: 67
diff changeset
3075
kono
parents: 67
diff changeset
3076 default:
kono
parents: 67
diff changeset
3077 gcc_unreachable ();
kono
parents: 67
diff changeset
3078 }
kono
parents: 67
diff changeset
3079 }
kono
parents: 67
diff changeset
3080
kono
parents: 67
diff changeset
3081 /* Return true if we must emit a barrier after pattern X. */
kono
parents: 67
diff changeset
3082
kono
parents: 67
diff changeset
3083 bool
kono
parents: 67
diff changeset
3084 needs_barrier_p (rtx x)
kono
parents: 67
diff changeset
3085 {
kono
parents: 67
diff changeset
3086 return (GET_CODE (x) == SET
kono
parents: 67
diff changeset
3087 && GET_CODE (SET_DEST (x)) == PC
kono
parents: 67
diff changeset
3088 && GET_CODE (SET_SRC (x)) == LABEL_REF);
kono
parents: 67
diff changeset
3089 }
kono
parents: 67
diff changeset
3090
kono
parents: 67
diff changeset
3091 #define NS "NULL"
kono
parents: 67
diff changeset
3092 #define ZS "'\\0'"
kono
parents: 67
diff changeset
3093 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
kono
parents: 67
diff changeset
3094 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
kono
parents: 67
diff changeset
3095 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
kono
parents: 67
diff changeset
3096 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
kono
parents: 67
diff changeset
3097 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
kono
parents: 67
diff changeset
3098 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3099 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3100 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3101 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
kono
parents: 67
diff changeset
3102 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
kono
parents: 67
diff changeset
3103 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
kono
parents: 67
diff changeset
3104
kono
parents: 67
diff changeset
3105 /* An array of all optabs. Note that the same optab can appear more
kono
parents: 67
diff changeset
3106 than once, with a different pattern. */
kono
parents: 67
diff changeset
3107 optab_def optabs[] = {
kono
parents: 67
diff changeset
3108 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
kono
parents: 67
diff changeset
3109 #include "optabs.def"
kono
parents: 67
diff changeset
3110 };
kono
parents: 67
diff changeset
3111
kono
parents: 67
diff changeset
3112 /* The number of entries in optabs[]. */
kono
parents: 67
diff changeset
3113 unsigned int num_optabs = ARRAY_SIZE (optabs);
kono
parents: 67
diff changeset
3114
kono
parents: 67
diff changeset
3115 #undef OPTAB_CL
kono
parents: 67
diff changeset
3116 #undef OPTAB_CX
kono
parents: 67
diff changeset
3117 #undef OPTAB_CD
kono
parents: 67
diff changeset
3118 #undef OPTAB_NL
kono
parents: 67
diff changeset
3119 #undef OPTAB_NC
kono
parents: 67
diff changeset
3120 #undef OPTAB_NX
kono
parents: 67
diff changeset
3121 #undef OPTAB_VL
kono
parents: 67
diff changeset
3122 #undef OPTAB_VC
kono
parents: 67
diff changeset
3123 #undef OPTAB_VX
kono
parents: 67
diff changeset
3124 #undef OPTAB_DC
kono
parents: 67
diff changeset
3125 #undef OPTAB_D
kono
parents: 67
diff changeset
3126
kono
parents: 67
diff changeset
3127 /* Return true if instruction NAME matches pattern PAT, storing information
kono
parents: 67
diff changeset
3128 about the match in P if so. */
kono
parents: 67
diff changeset
3129
kono
parents: 67
diff changeset
3130 static bool
kono
parents: 67
diff changeset
3131 match_pattern (optab_pattern *p, const char *name, const char *pat)
kono
parents: 67
diff changeset
3132 {
kono
parents: 67
diff changeset
3133 bool force_float = false;
kono
parents: 67
diff changeset
3134 bool force_int = false;
kono
parents: 67
diff changeset
3135 bool force_partial_int = false;
kono
parents: 67
diff changeset
3136 bool force_fixed = false;
kono
parents: 67
diff changeset
3137
kono
parents: 67
diff changeset
3138 if (pat == NULL)
kono
parents: 67
diff changeset
3139 return false;
kono
parents: 67
diff changeset
3140 for (; ; ++pat)
kono
parents: 67
diff changeset
3141 {
kono
parents: 67
diff changeset
3142 if (*pat != '$')
kono
parents: 67
diff changeset
3143 {
kono
parents: 67
diff changeset
3144 if (*pat != *name++)
kono
parents: 67
diff changeset
3145 return false;
kono
parents: 67
diff changeset
3146 if (*pat == '\0')
kono
parents: 67
diff changeset
3147 return true;
kono
parents: 67
diff changeset
3148 continue;
kono
parents: 67
diff changeset
3149 }
kono
parents: 67
diff changeset
3150 switch (*++pat)
kono
parents: 67
diff changeset
3151 {
kono
parents: 67
diff changeset
3152 case 'I':
kono
parents: 67
diff changeset
3153 force_int = 1;
kono
parents: 67
diff changeset
3154 break;
kono
parents: 67
diff changeset
3155 case 'P':
kono
parents: 67
diff changeset
3156 force_partial_int = 1;
kono
parents: 67
diff changeset
3157 break;
kono
parents: 67
diff changeset
3158 case 'F':
kono
parents: 67
diff changeset
3159 force_float = 1;
kono
parents: 67
diff changeset
3160 break;
kono
parents: 67
diff changeset
3161 case 'Q':
kono
parents: 67
diff changeset
3162 force_fixed = 1;
kono
parents: 67
diff changeset
3163 break;
kono
parents: 67
diff changeset
3164
kono
parents: 67
diff changeset
3165 case 'a':
kono
parents: 67
diff changeset
3166 case 'b':
kono
parents: 67
diff changeset
3167 {
kono
parents: 67
diff changeset
3168 int i;
kono
parents: 67
diff changeset
3169
kono
parents: 67
diff changeset
3170 /* This loop will stop at the first prefix match, so
kono
parents: 67
diff changeset
3171 look through the modes in reverse order, in case
kono
parents: 67
diff changeset
3172 there are extra CC modes and CC is a prefix of the
kono
parents: 67
diff changeset
3173 CC modes (as it should be). */
kono
parents: 67
diff changeset
3174 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
kono
parents: 67
diff changeset
3175 {
kono
parents: 67
diff changeset
3176 const char *p, *q;
kono
parents: 67
diff changeset
3177 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
kono
parents: 67
diff changeset
3178 if (TOLOWER (*p) != *q)
kono
parents: 67
diff changeset
3179 break;
kono
parents: 67
diff changeset
3180 if (*p == 0
kono
parents: 67
diff changeset
3181 && (! force_int || mode_class[i] == MODE_INT
kono
parents: 67
diff changeset
3182 || mode_class[i] == MODE_VECTOR_INT)
kono
parents: 67
diff changeset
3183 && (! force_partial_int
kono
parents: 67
diff changeset
3184 || mode_class[i] == MODE_INT
kono
parents: 67
diff changeset
3185 || mode_class[i] == MODE_PARTIAL_INT
kono
parents: 67
diff changeset
3186 || mode_class[i] == MODE_VECTOR_INT)
kono
parents: 67
diff changeset
3187 && (! force_float
kono
parents: 67
diff changeset
3188 || mode_class[i] == MODE_FLOAT
kono
parents: 67
diff changeset
3189 || mode_class[i] == MODE_DECIMAL_FLOAT
kono
parents: 67
diff changeset
3190 || mode_class[i] == MODE_COMPLEX_FLOAT
kono
parents: 67
diff changeset
3191 || mode_class[i] == MODE_VECTOR_FLOAT)
kono
parents: 67
diff changeset
3192 && (! force_fixed
kono
parents: 67
diff changeset
3193 || mode_class[i] == MODE_FRACT
kono
parents: 67
diff changeset
3194 || mode_class[i] == MODE_UFRACT
kono
parents: 67
diff changeset
3195 || mode_class[i] == MODE_ACCUM
kono
parents: 67
diff changeset
3196 || mode_class[i] == MODE_UACCUM
kono
parents: 67
diff changeset
3197 || mode_class[i] == MODE_VECTOR_FRACT
kono
parents: 67
diff changeset
3198 || mode_class[i] == MODE_VECTOR_UFRACT
kono
parents: 67
diff changeset
3199 || mode_class[i] == MODE_VECTOR_ACCUM
kono
parents: 67
diff changeset
3200 || mode_class[i] == MODE_VECTOR_UACCUM))
kono
parents: 67
diff changeset
3201 break;
kono
parents: 67
diff changeset
3202 }
kono
parents: 67
diff changeset
3203
kono
parents: 67
diff changeset
3204 if (i < 0)
kono
parents: 67
diff changeset
3205 return false;
kono
parents: 67
diff changeset
3206 name += strlen (GET_MODE_NAME (i));
kono
parents: 67
diff changeset
3207 if (*pat == 'a')
kono
parents: 67
diff changeset
3208 p->m1 = i;
kono
parents: 67
diff changeset
3209 else
kono
parents: 67
diff changeset
3210 p->m2 = i;
kono
parents: 67
diff changeset
3211
kono
parents: 67
diff changeset
3212 force_int = false;
kono
parents: 67
diff changeset
3213 force_partial_int = false;
kono
parents: 67
diff changeset
3214 force_float = false;
kono
parents: 67
diff changeset
3215 force_fixed = false;
kono
parents: 67
diff changeset
3216 }
kono
parents: 67
diff changeset
3217 break;
kono
parents: 67
diff changeset
3218
kono
parents: 67
diff changeset
3219 default:
kono
parents: 67
diff changeset
3220 gcc_unreachable ();
kono
parents: 67
diff changeset
3221 }
kono
parents: 67
diff changeset
3222 }
kono
parents: 67
diff changeset
3223 }
kono
parents: 67
diff changeset
3224
kono
parents: 67
diff changeset
3225 /* Return true if NAME is the name of an optab, describing it in P if so. */
kono
parents: 67
diff changeset
3226
kono
parents: 67
diff changeset
3227 bool
kono
parents: 67
diff changeset
3228 find_optab (optab_pattern *p, const char *name)
kono
parents: 67
diff changeset
3229 {
kono
parents: 67
diff changeset
3230 if (*name == 0 || *name == '*')
kono
parents: 67
diff changeset
3231 return false;
kono
parents: 67
diff changeset
3232
kono
parents: 67
diff changeset
3233 /* See if NAME matches one of the patterns we have for the optabs
kono
parents: 67
diff changeset
3234 we know about. */
kono
parents: 67
diff changeset
3235 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
kono
parents: 67
diff changeset
3236 {
kono
parents: 67
diff changeset
3237 p->m1 = p->m2 = 0;
kono
parents: 67
diff changeset
3238 if (match_pattern (p, name, optabs[pindex].pattern))
kono
parents: 67
diff changeset
3239 {
kono
parents: 67
diff changeset
3240 p->name = name;
kono
parents: 67
diff changeset
3241 p->op = optabs[pindex].op;
kono
parents: 67
diff changeset
3242 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
kono
parents: 67
diff changeset
3243 return true;
kono
parents: 67
diff changeset
3244 }
kono
parents: 67
diff changeset
3245 }
kono
parents: 67
diff changeset
3246 return false;
kono
parents: 67
diff changeset
3247 }