Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/rx/predicates.md @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 ;; Predicate definitions for Renesas RX. | |
2 ;; Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
3 ;; Contributed by Red Hat. | |
4 ;; | |
5 ;; This file is part of GCC. | |
6 ;; | |
7 ;; GCC is free software; you can redistribute it and/or modify | |
8 ;; it under the terms of the GNU General Public License as published by | |
9 ;; the Free Software Foundation; either version 3, or (at your option) | |
10 ;; any later version. | |
11 ;; | |
12 ;; GCC is distributed in the hope that it will be useful, | |
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 ;; GNU General Public License for more details. | |
16 ;; | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
20 | |
21 | |
22 | |
23 ;; Check that the operand is suitable for a call insn. | |
24 ;; Only registers and symbol refs are allowed. | |
25 | |
26 (define_predicate "rx_call_operand" | |
27 (match_code "symbol_ref,reg") | |
28 ) | |
29 | |
30 ;; For sibcall operations we can only use a symbolic address. | |
31 | |
32 (define_predicate "rx_symbolic_call_operand" | |
33 (match_code "symbol_ref") | |
34 ) | |
35 | |
36 ;; Check that the operand is suitable for a shift insn | |
37 ;; Only small integers or a value in a register are permitted. | |
38 | |
39 (define_predicate "rx_shift_operand" | |
40 (match_code "const_int,reg") | |
41 { | |
42 if (CONST_INT_P (op)) | |
43 return IN_RANGE (INTVAL (op), 0, 31); | |
44 return true; | |
45 } | |
46 ) | |
47 | |
48 ;; Check that the operand is suitable as the source operand | |
49 ;; for a logic or arithmeitc instruction. Registers, integers | |
50 ;; and a restricted subset of memory addresses are allowed. | |
51 | |
52 (define_predicate "rx_source_operand" | |
53 (match_code "const_int,reg,mem") | |
54 { | |
55 if (CONST_INT_P (op)) | |
56 return rx_is_legitimate_constant (op); | |
57 | |
58 if (! MEM_P (op)) | |
59 return true; | |
60 | |
61 /* Do not allow size conversions whilst accessing memory. */ | |
62 if (GET_MODE (op) != mode) | |
63 return false; | |
64 | |
65 return rx_is_restricted_memory_address (XEXP (op, 0), mode); | |
66 } | |
67 ) | |
68 | |
69 ;; Check that the operand is suitable as the source operand | |
70 ;; for a comparison instruction. This is the same as | |
71 ;; rx_source_operand except that SUBREGs are allowed but | |
72 ;; CONST_INTs are not. | |
73 | |
74 (define_predicate "rx_compare_operand" | |
75 (match_code "subreg,reg,mem") | |
76 { | |
77 if (GET_CODE (op) == SUBREG) | |
78 return REG_P (XEXP (op, 0)); | |
79 | |
80 if (! MEM_P (op)) | |
81 return true; | |
82 | |
83 return rx_is_restricted_memory_address (XEXP (op, 0), mode); | |
84 } | |
85 ) | |
86 | |
87 ;; Return true if OP is a store multiple operation. This looks like: | |
88 ;; | |
89 ;; [(set (SP) (MINUS (SP) (INT))) | |
90 ;; (set (MEM (SP)) (REG)) | |
91 ;; (set (MEM (MINUS (SP) (INT))) (REG)) {optionally repeated} | |
92 ;; ] | |
93 | |
94 (define_special_predicate "rx_store_multiple_vector" | |
95 (match_code "parallel") | |
96 { | |
97 int count = XVECLEN (op, 0); | |
98 unsigned int src_regno; | |
99 rtx element; | |
100 int i; | |
101 | |
102 /* Perform a quick check so we don't blow up below. */ | |
103 if (count <= 2) | |
104 return false; | |
105 | |
106 /* Check that the first element of the vector is the stack adjust. */ | |
107 element = XVECEXP (op, 0, 0); | |
108 if ( ! SET_P (element) | |
109 || ! REG_P (SET_DEST (element)) | |
110 || REGNO (SET_DEST (element)) != SP_REG | |
111 || GET_CODE (SET_SRC (element)) != MINUS | |
112 || ! REG_P (XEXP (SET_SRC (element), 0)) | |
113 || REGNO (XEXP (SET_SRC (element), 0)) != SP_REG | |
114 || ! CONST_INT_P (XEXP (SET_SRC (element), 1))) | |
115 return false; | |
116 | |
117 /* Check that the next element is the first push. */ | |
118 element = XVECEXP (op, 0, 1); | |
119 if ( ! SET_P (element) | |
120 || ! REG_P (SET_SRC (element)) | |
121 || GET_MODE (SET_SRC (element)) != SImode | |
122 || ! MEM_P (SET_DEST (element)) | |
123 || GET_MODE (SET_DEST (element)) != SImode | |
124 || GET_CODE (XEXP (SET_DEST (element), 0)) != MINUS | |
125 || ! REG_P (XEXP (XEXP (SET_DEST (element), 0), 0)) | |
126 || REGNO (XEXP (XEXP (SET_DEST (element), 0), 0)) != SP_REG | |
127 || ! CONST_INT_P (XEXP (XEXP (SET_DEST (element), 0), 1)) | |
128 || INTVAL (XEXP (XEXP (SET_DEST (element), 0), 1)) | |
129 != GET_MODE_SIZE (SImode)) | |
130 return false; | |
131 | |
132 src_regno = REGNO (SET_SRC (element)); | |
133 | |
134 /* Check that the remaining elements use SP-<disp> | |
135 addressing and decreasing register numbers. */ | |
136 for (i = 2; i < count; i++) | |
137 { | |
138 element = XVECEXP (op, 0, i); | |
139 | |
140 if ( ! SET_P (element) | |
141 || ! REG_P (SET_SRC (element)) | |
142 || GET_MODE (SET_SRC (element)) != SImode | |
143 || REGNO (SET_SRC (element)) != src_regno - (i - 1) | |
144 || ! MEM_P (SET_DEST (element)) | |
145 || GET_MODE (SET_DEST (element)) != SImode | |
146 || GET_CODE (XEXP (SET_DEST (element), 0)) != MINUS | |
147 || ! REG_P (XEXP (XEXP (SET_DEST (element), 0), 0)) | |
148 || REGNO (XEXP (XEXP (SET_DEST (element), 0), 0)) != SP_REG | |
149 || ! CONST_INT_P (XEXP (XEXP (SET_DEST (element), 0), 1)) | |
150 || INTVAL (XEXP (XEXP (SET_DEST (element), 0), 1)) | |
151 != i * GET_MODE_SIZE (SImode)) | |
152 return false; | |
153 } | |
154 return true; | |
155 }) | |
156 | |
157 ;; Return true if OP is a load multiple operation. | |
158 ;; This looks like: | |
159 ;; [(set (SP) (PLUS (SP) (INT))) | |
160 ;; (set (REG) (MEM (SP))) | |
161 ;; (set (REG) (MEM (PLUS (SP) (INT)))) {optionally repeated} | |
162 ;; ] | |
163 | |
164 (define_special_predicate "rx_load_multiple_vector" | |
165 (match_code "parallel") | |
166 { | |
167 int count = XVECLEN (op, 0); | |
168 unsigned int dest_regno; | |
169 rtx element; | |
170 int i; | |
171 | |
172 /* Perform a quick check so we don't blow up below. */ | |
173 if (count <= 2) | |
174 return false; | |
175 | |
176 /* Check that the first element of the vector is the stack adjust. */ | |
177 element = XVECEXP (op, 0, 0); | |
178 if ( ! SET_P (element) | |
179 || ! REG_P (SET_DEST (element)) | |
180 || REGNO (SET_DEST (element)) != SP_REG | |
181 || GET_CODE (SET_SRC (element)) != PLUS | |
182 || ! REG_P (XEXP (SET_SRC (element), 0)) | |
183 || REGNO (XEXP (SET_SRC (element), 0)) != SP_REG | |
184 || ! CONST_INT_P (XEXP (SET_SRC (element), 1))) | |
185 return false; | |
186 | |
187 /* Check that the next element is the first push. */ | |
188 element = XVECEXP (op, 0, 1); | |
189 if ( ! SET_P (element) | |
190 || ! REG_P (SET_DEST (element)) | |
191 || ! MEM_P (SET_SRC (element)) | |
192 || ! REG_P (XEXP (SET_SRC (element), 0)) | |
193 || REGNO (XEXP (SET_SRC (element), 0)) != SP_REG) | |
194 return false; | |
195 | |
196 dest_regno = REGNO (SET_DEST (element)); | |
197 | |
198 /* Check that the remaining elements use SP+<disp> | |
199 addressing and incremental register numbers. */ | |
200 for (i = 2; i < count; i++) | |
201 { | |
202 element = XVECEXP (op, 0, i); | |
203 | |
204 if ( ! SET_P (element) | |
205 || ! REG_P (SET_DEST (element)) | |
206 || GET_MODE (SET_DEST (element)) != SImode | |
207 || REGNO (SET_DEST (element)) != dest_regno + (i - 1) | |
208 || ! MEM_P (SET_SRC (element)) | |
209 || GET_MODE (SET_SRC (element)) != SImode | |
210 || GET_CODE (XEXP (SET_SRC (element), 0)) != PLUS | |
211 || ! REG_P (XEXP (XEXP (SET_SRC (element), 0), 0)) | |
212 || REGNO (XEXP (XEXP (SET_SRC (element), 0), 0)) != SP_REG | |
213 || ! CONST_INT_P (XEXP (XEXP (SET_SRC (element), 0), 1)) | |
214 || INTVAL (XEXP (XEXP (SET_SRC (element), 0), 1)) | |
215 != (i - 1) * GET_MODE_SIZE (SImode)) | |
216 return false; | |
217 } | |
218 return true; | |
219 }) | |
220 | |
221 ;; Return true if OP is a pop-and-return load multiple operation. | |
222 ;; This looks like: | |
223 ;; [(set (SP) (PLUS (SP) (INT))) | |
224 ;; (set (REG) (MEM (SP))) | |
225 ;; (set (REG) (MEM (PLUS (SP) (INT)))) {optional and possibly repeated} | |
226 ;; (return) | |
227 ;; ] | |
228 | |
229 (define_special_predicate "rx_rtsd_vector" | |
230 (match_code "parallel") | |
231 { | |
232 int count = XVECLEN (op, 0); | |
233 unsigned int dest_regno; | |
234 rtx element; | |
235 int i; | |
236 | |
237 /* Perform a quick check so we don't blow up below. */ | |
238 if (count <= 2) | |
239 return false; | |
240 | |
241 /* Check that the first element of the vector is the stack adjust. */ | |
242 element = XVECEXP (op, 0, 0); | |
243 if ( ! SET_P (element) | |
244 || ! REG_P (SET_DEST (element)) | |
245 || REGNO (SET_DEST (element)) != SP_REG | |
246 || GET_CODE (SET_SRC (element)) != PLUS | |
247 || ! REG_P (XEXP (SET_SRC (element), 0)) | |
248 || REGNO (XEXP (SET_SRC (element), 0)) != SP_REG | |
249 || ! CONST_INT_P (XEXP (SET_SRC (element), 1))) | |
250 return false; | |
251 | |
252 /* Check that the next element is the first push. */ | |
253 element = XVECEXP (op, 0, 1); | |
254 if ( ! SET_P (element) | |
255 || ! REG_P (SET_DEST (element)) | |
256 || ! MEM_P (SET_SRC (element)) | |
257 || ! REG_P (XEXP (SET_SRC (element), 0)) | |
258 || REGNO (XEXP (SET_SRC (element), 0)) != SP_REG) | |
259 return false; | |
260 | |
261 dest_regno = REGNO (SET_DEST (element)); | |
262 | |
263 /* Check that the remaining elements, if any, and except | |
264 for the last one, use SP+<disp> addressing and incremental | |
265 register numbers. */ | |
266 for (i = 2; i < count - 1; i++) | |
267 { | |
268 element = XVECEXP (op, 0, i); | |
269 | |
270 if ( ! SET_P (element) | |
271 || ! REG_P (SET_DEST (element)) | |
272 || GET_MODE (SET_DEST (element)) != SImode | |
273 || REGNO (SET_DEST (element)) != dest_regno + (i - 1) | |
274 || ! MEM_P (SET_SRC (element)) | |
275 || GET_MODE (SET_SRC (element)) != SImode | |
276 || GET_CODE (XEXP (SET_SRC (element), 0)) != PLUS | |
277 || ! REG_P (XEXP (XEXP (SET_SRC (element), 0), 0)) | |
278 || REGNO (XEXP (XEXP (SET_SRC (element), 0), 0)) != SP_REG | |
279 || ! CONST_INT_P (XEXP (XEXP (SET_SRC (element), 0), 1)) | |
280 || INTVAL (XEXP (XEXP (SET_SRC (element), 0), 1)) | |
281 != (i - 1) * GET_MODE_SIZE (SImode)) | |
282 return false; | |
283 } | |
284 | |
285 /* The last element must be a RETURN. */ | |
286 element = XVECEXP (op, 0, count - 1); | |
287 return GET_CODE (element) == RETURN; | |
288 }) |