Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/arm/predicates.md @ 68:561a7518be6b
update gcc-4.6
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 21 Aug 2011 07:07:55 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for ARM and Thumb |
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
|
2 ;; Copyright (C) 2004, 2007, 2008, 2010 Free Software Foundation, Inc. |
0 | 3 ;; Contributed by ARM Ltd. |
4 | |
5 ;; This file is part of GCC. | |
6 | |
7 ;; GCC is free software; you can redistribute it and/or modify it | |
8 ;; under the terms of the GNU General Public License as published | |
9 ;; by the Free Software Foundation; either version 3, or (at your | |
10 ;; option) any later version. | |
11 | |
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 ;; 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 (define_predicate "s_register_operand" | |
22 (match_code "reg,subreg") | |
23 { | |
24 if (GET_CODE (op) == SUBREG) | |
25 op = SUBREG_REG (op); | |
26 /* We don't consider registers whose class is NO_REGS | |
27 to be a register operand. */ | |
28 /* XXX might have to check for lo regs only for thumb ??? */ | |
29 return (GET_CODE (op) == REG | |
30 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
31 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); | |
32 }) | |
33 | |
34 ;; Any hard register. | |
35 (define_predicate "arm_hard_register_operand" | |
36 (match_code "reg") | |
37 { | |
38 return REGNO (op) < FIRST_PSEUDO_REGISTER; | |
39 }) | |
40 | |
41 ;; A low register. | |
42 (define_predicate "low_register_operand" | |
43 (and (match_code "reg") | |
44 (match_test "REGNO (op) <= LAST_LO_REGNUM"))) | |
45 | |
46 ;; A low register or const_int. | |
47 (define_predicate "low_reg_or_int_operand" | |
48 (ior (match_code "const_int") | |
49 (match_operand 0 "low_register_operand"))) | |
50 | |
51 ;; Any core register, or any pseudo. */ | |
52 (define_predicate "arm_general_register_operand" | |
53 (match_code "reg,subreg") | |
54 { | |
55 if (GET_CODE (op) == SUBREG) | |
56 op = SUBREG_REG (op); | |
57 | |
58 return (GET_CODE (op) == REG | |
59 && (REGNO (op) <= LAST_ARM_REGNUM | |
60 || REGNO (op) >= FIRST_PSEUDO_REGISTER)); | |
61 }) | |
62 | |
63 (define_predicate "f_register_operand" | |
64 (match_code "reg,subreg") | |
65 { | |
66 if (GET_CODE (op) == SUBREG) | |
67 op = SUBREG_REG (op); | |
68 | |
69 /* We don't consider registers whose class is NO_REGS | |
70 to be a register operand. */ | |
71 return (GET_CODE (op) == REG | |
72 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
73 || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS)); | |
74 }) | |
75 | |
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
|
76 (define_predicate "vfp_register_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
77 (match_code "reg,subreg") |
f6334be47118
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 { |
f6334be47118
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 if (GET_CODE (op) == SUBREG) |
f6334be47118
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 op = SUBREG_REG (op); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
81 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
82 /* We don't consider registers whose class is NO_REGS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
83 to be a register operand. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
84 return (GET_CODE (op) == REG |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
85 && (REGNO (op) >= FIRST_PSEUDO_REGISTER |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
86 || REGNO_REG_CLASS (REGNO (op)) == VFP_D0_D7_REGS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
87 || REGNO_REG_CLASS (REGNO (op)) == VFP_LO_REGS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
88 || (TARGET_VFPD32 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
89 && REGNO_REG_CLASS (REGNO (op)) == VFP_REGS))); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
90 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
91 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 (define_special_predicate "subreg_lowpart_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
93 (and (match_code "subreg") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
94 (match_test "subreg_lowpart_p (op)"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
95 |
0 | 96 ;; Reg, subreg(reg) or const_int. |
97 (define_predicate "reg_or_int_operand" | |
98 (ior (match_code "const_int") | |
99 (match_operand 0 "s_register_operand"))) | |
100 | |
101 (define_predicate "arm_immediate_operand" | |
102 (and (match_code "const_int") | |
103 (match_test "const_ok_for_arm (INTVAL (op))"))) | |
104 | |
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
|
105 ;; A constant value which fits into two instructions, each taking |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
106 ;; an arithmetic constant operand for one of the words. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
107 (define_predicate "arm_immediate_di_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
108 (and (match_code "const_int,const_double") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
109 (match_test "arm_const_double_by_immediates (op)"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
110 |
0 | 111 (define_predicate "arm_neg_immediate_operand" |
112 (and (match_code "const_int") | |
113 (match_test "const_ok_for_arm (-INTVAL (op))"))) | |
114 | |
115 (define_predicate "arm_not_immediate_operand" | |
116 (and (match_code "const_int") | |
117 (match_test "const_ok_for_arm (~INTVAL (op))"))) | |
118 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
119 (define_predicate "const0_operand" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
120 (and (match_code "const_int") |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
121 (match_test "INTVAL (op) == 0"))) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
122 |
0 | 123 ;; Something valid on the RHS of an ARM data-processing instruction |
124 (define_predicate "arm_rhs_operand" | |
125 (ior (match_operand 0 "s_register_operand") | |
126 (match_operand 0 "arm_immediate_operand"))) | |
127 | |
128 (define_predicate "arm_rhsm_operand" | |
129 (ior (match_operand 0 "arm_rhs_operand") | |
130 (match_operand 0 "memory_operand"))) | |
131 | |
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
|
132 (define_predicate "shift_amount_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
133 (ior (and (match_test "TARGET_ARM") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
134 (match_operand 0 "s_register_operand")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
135 (match_operand 0 "const_int_operand"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
136 |
0 | 137 (define_predicate "arm_add_operand" |
138 (ior (match_operand 0 "arm_rhs_operand") | |
139 (match_operand 0 "arm_neg_immediate_operand"))) | |
140 | |
141 (define_predicate "arm_addimm_operand" | |
142 (ior (match_operand 0 "arm_immediate_operand") | |
143 (match_operand 0 "arm_neg_immediate_operand"))) | |
144 | |
145 (define_predicate "arm_not_operand" | |
146 (ior (match_operand 0 "arm_rhs_operand") | |
147 (match_operand 0 "arm_not_immediate_operand"))) | |
148 | |
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
|
149 (define_predicate "arm_di_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
150 (ior (match_operand 0 "s_register_operand") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
151 (match_operand 0 "arm_immediate_di_operand"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
152 |
0 | 153 ;; True if the operand is a memory reference which contains an |
154 ;; offsettable address. | |
155 (define_predicate "offsettable_memory_operand" | |
156 (and (match_code "mem") | |
157 (match_test | |
158 "offsettable_address_p (reload_completed | reload_in_progress, | |
159 mode, XEXP (op, 0))"))) | |
160 | |
161 ;; True if the operand is a memory operand that does not have an | |
162 ;; automodified base register (and thus will not generate output reloads). | |
163 (define_predicate "call_memory_operand" | |
164 (and (match_code "mem") | |
165 (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) | |
166 != RTX_AUTOINC") | |
167 (match_operand 0 "memory_operand")))) | |
168 | |
169 (define_predicate "arm_reload_memory_operand" | |
170 (and (match_code "mem,reg,subreg") | |
171 (match_test "(!CONSTANT_P (op) | |
172 && (true_regnum(op) == -1 | |
173 || (GET_CODE (op) == REG | |
174 && REGNO (op) >= FIRST_PSEUDO_REGISTER)))"))) | |
175 | |
176 ;; True for valid operands for the rhs of an floating point insns. | |
177 ;; Allows regs or certain consts on FPA, just regs for everything else. | |
178 (define_predicate "arm_float_rhs_operand" | |
179 (ior (match_operand 0 "s_register_operand") | |
180 (and (match_code "const_double") | |
181 (match_test "TARGET_FPA && arm_const_double_rtx (op)")))) | |
182 | |
183 (define_predicate "arm_float_add_operand" | |
184 (ior (match_operand 0 "arm_float_rhs_operand") | |
185 (and (match_code "const_double") | |
186 (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)")))) | |
187 | |
188 (define_predicate "vfp_compare_operand" | |
189 (ior (match_operand 0 "s_register_operand") | |
190 (and (match_code "const_double") | |
191 (match_test "arm_const_double_rtx (op)")))) | |
192 | |
193 (define_predicate "arm_float_compare_operand" | |
194 (if_then_else (match_test "TARGET_VFP") | |
195 (match_operand 0 "vfp_compare_operand") | |
196 (match_operand 0 "arm_float_rhs_operand"))) | |
197 | |
198 ;; True for valid index operands. | |
199 (define_predicate "index_operand" | |
200 (ior (match_operand 0 "s_register_operand") | |
201 (and (match_operand 0 "immediate_operand") | |
202 (match_test "(GET_CODE (op) != CONST_INT | |
203 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))")))) | |
204 | |
205 ;; True for operators that can be combined with a shift in ARM state. | |
206 (define_special_predicate "shiftable_operator" | |
207 (and (match_code "plus,minus,ior,xor,and") | |
208 (match_test "mode == GET_MODE (op)"))) | |
209 | |
210 ;; True for logical binary operators. | |
211 (define_special_predicate "logical_binary_operator" | |
212 (and (match_code "ior,xor,and") | |
213 (match_test "mode == GET_MODE (op)"))) | |
214 | |
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
|
215 ;; True for commutative operators |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
216 (define_special_predicate "commutative_binary_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
217 (and (match_code "ior,xor,and,plus") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
218 (match_test "mode == GET_MODE (op)"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
219 |
0 | 220 ;; True for shift operators. |
221 (define_special_predicate "shift_operator" | |
222 (and (ior (ior (and (match_code "mult") | |
223 (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
224 (and (match_code "rotate") | |
225 (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT | |
226 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) | |
227 (match_code "ashift,ashiftrt,lshiftrt,rotatert")) | |
228 (match_test "mode == GET_MODE (op)"))) | |
229 | |
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
|
230 ;; True for MULT, to identify which variant of shift_operator is in use. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
231 (define_special_predicate "mult_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
232 (match_code "mult")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
233 |
0 | 234 ;; True for operators that have 16-bit thumb variants. */ |
235 (define_special_predicate "thumb_16bit_operator" | |
236 (match_code "plus,minus,and,ior,xor")) | |
237 | |
238 ;; True for EQ & NE | |
239 (define_special_predicate "equality_operator" | |
240 (match_code "eq,ne")) | |
241 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
242 ;; True for integer comparisons and, if FP is active, for comparisons |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
243 ;; other than LTGT or UNEQ. |
0 | 244 (define_special_predicate "arm_comparison_operator" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
245 (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
246 (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
247 && (TARGET_FPA || TARGET_VFP)") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
248 (match_code "unordered,ordered,unlt,unle,unge,ungt")))) |
0 | 249 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
250 (define_special_predicate "lt_ge_comparison_operator" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
251 (match_code "lt,ge")) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
252 |
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
|
253 (define_special_predicate "noov_comparison_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
254 (match_code "lt,ge,eq,ne")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
255 |
0 | 256 (define_special_predicate "minmax_operator" |
257 (and (match_code "smin,smax,umin,umax") | |
258 (match_test "mode == GET_MODE (op)"))) | |
259 | |
260 (define_special_predicate "cc_register" | |
261 (and (match_code "reg") | |
262 (and (match_test "REGNO (op) == CC_REGNUM") | |
263 (ior (match_test "mode == GET_MODE (op)") | |
264 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))) | |
265 | |
266 (define_special_predicate "dominant_cc_register" | |
267 (match_code "reg") | |
268 { | |
269 if (mode == VOIDmode) | |
270 { | |
271 mode = GET_MODE (op); | |
272 | |
273 if (GET_MODE_CLASS (mode) != MODE_CC) | |
274 return false; | |
275 } | |
276 | |
277 return (cc_register (op, mode) | |
278 && (mode == CC_DNEmode | |
279 || mode == CC_DEQmode | |
280 || mode == CC_DLEmode | |
281 || mode == CC_DLTmode | |
282 || mode == CC_DGEmode | |
283 || mode == CC_DGTmode | |
284 || mode == CC_DLEUmode | |
285 || mode == CC_DLTUmode | |
286 || mode == CC_DGEUmode | |
287 || mode == CC_DGTUmode)); | |
288 }) | |
289 | |
290 (define_special_predicate "arm_extendqisi_mem_op" | |
291 (and (match_operand 0 "memory_operand") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
292 (match_test "arm_legitimate_address_outer_p (mode, XEXP (op, 0), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
293 SIGN_EXTEND, 0)"))) |
0 | 294 |
295 (define_special_predicate "arm_reg_or_extendqisi_mem_op" | |
296 (ior (match_operand 0 "arm_extendqisi_mem_op") | |
297 (match_operand 0 "s_register_operand"))) | |
298 | |
299 (define_predicate "power_of_two_operand" | |
300 (match_code "const_int") | |
301 { | |
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
|
302 unsigned HOST_WIDE_INT value = INTVAL (op) & 0xffffffff; |
0 | 303 |
304 return value != 0 && (value & (value - 1)) == 0; | |
305 }) | |
306 | |
307 (define_predicate "nonimmediate_di_operand" | |
308 (match_code "reg,subreg,mem") | |
309 { | |
310 if (s_register_operand (op, mode)) | |
311 return true; | |
312 | |
313 if (GET_CODE (op) == SUBREG) | |
314 op = SUBREG_REG (op); | |
315 | |
316 return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0)); | |
317 }) | |
318 | |
319 (define_predicate "di_operand" | |
320 (ior (match_code "const_int,const_double") | |
321 (and (match_code "reg,subreg,mem") | |
322 (match_operand 0 "nonimmediate_di_operand")))) | |
323 | |
324 (define_predicate "nonimmediate_soft_df_operand" | |
325 (match_code "reg,subreg,mem") | |
326 { | |
327 if (s_register_operand (op, mode)) | |
328 return true; | |
329 | |
330 if (GET_CODE (op) == SUBREG) | |
331 op = SUBREG_REG (op); | |
332 | |
333 return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0)); | |
334 }) | |
335 | |
336 (define_predicate "soft_df_operand" | |
337 (ior (match_code "const_double") | |
338 (and (match_code "reg,subreg,mem") | |
339 (match_operand 0 "nonimmediate_soft_df_operand")))) | |
340 | |
341 (define_predicate "const_shift_operand" | |
342 (and (match_code "const_int") | |
343 (ior (match_operand 0 "power_of_two_operand") | |
344 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32")))) | |
345 | |
346 | |
347 (define_special_predicate "load_multiple_operation" | |
348 (match_code "parallel") | |
349 { | |
350 HOST_WIDE_INT count = XVECLEN (op, 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
|
351 unsigned dest_regno; |
0 | 352 rtx src_addr; |
353 HOST_WIDE_INT i = 1, base = 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
|
354 HOST_WIDE_INT offset = 0; |
0 | 355 rtx elt; |
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
|
356 bool addr_reg_loaded = 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
|
357 bool update = false; |
0 | 358 |
359 if (count <= 1 | |
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
|
360 || GET_CODE (XVECEXP (op, 0, 0)) != SET |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
361 || !REG_P (SET_DEST (XVECEXP (op, 0, 0)))) |
0 | 362 return false; |
363 | |
364 /* Check to see if this might be a write-back. */ | |
365 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
366 { | |
367 i++; | |
368 base = 1; | |
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
|
369 update = true; |
0 | 370 |
371 /* Now check it more carefully. */ | |
372 if (GET_CODE (SET_DEST (elt)) != REG | |
373 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
374 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
375 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
376 return false; | |
377 } | |
378 | |
379 /* Perform a quick check so we don't blow up below. */ | |
380 if (count <= i | |
381 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
382 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG | |
383 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM) | |
384 return false; | |
385 | |
386 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); | |
387 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 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
|
388 if (GET_CODE (src_addr) == PLUS) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
389 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
390 if (GET_CODE (XEXP (src_addr, 1)) != CONST_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
|
391 return 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
|
392 offset = INTVAL (XEXP (src_addr, 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
|
393 src_addr = XEXP (src_addr, 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
|
394 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
395 if (!REG_P (src_addr)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
396 return false; |
0 | 397 |
398 for (; i < count; i++) | |
399 { | |
400 elt = XVECEXP (op, 0, i); | |
401 | |
402 if (GET_CODE (elt) != SET | |
403 || GET_CODE (SET_DEST (elt)) != REG | |
404 || GET_MODE (SET_DEST (elt)) != SImode | |
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
|
405 || REGNO (SET_DEST (elt)) <= dest_regno |
0 | 406 || GET_CODE (SET_SRC (elt)) != MEM |
407 || GET_MODE (SET_SRC (elt)) != SImode | |
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
|
408 || ((GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
409 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
410 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_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
|
411 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != offset + (i - base) * 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
|
412 && (!REG_P (XEXP (SET_SRC (elt), 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
|
413 || offset + (i - base) * 4 != 0))) |
0 | 414 return false; |
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
|
415 dest_regno = REGNO (SET_DEST (elt)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
416 if (dest_regno == REGNO (src_addr)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
417 addr_reg_loaded = true; |
0 | 418 } |
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
|
419 /* For Thumb, we only have updating instructions. If the pattern does |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
420 not describe an update, it must be because the address register is |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
421 in the list of loaded registers - on the hardware, this has the effect |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
422 of overriding the update. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
423 if (update && addr_reg_loaded) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
424 return 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
|
425 if (TARGET_THUMB1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
426 return update || addr_reg_loaded; |
0 | 427 return true; |
428 }) | |
429 | |
430 (define_special_predicate "store_multiple_operation" | |
431 (match_code "parallel") | |
432 { | |
433 HOST_WIDE_INT count = XVECLEN (op, 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
|
434 unsigned src_regno; |
0 | 435 rtx dest_addr; |
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
|
436 HOST_WIDE_INT i = 1, base = 0, offset = 0; |
0 | 437 rtx elt; |
438 | |
439 if (count <= 1 | |
440 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
441 return false; | |
442 | |
443 /* Check to see if this might be a write-back. */ | |
444 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
445 { | |
446 i++; | |
447 base = 1; | |
448 | |
449 /* Now check it more carefully. */ | |
450 if (GET_CODE (SET_DEST (elt)) != REG | |
451 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
452 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
453 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
454 return false; | |
455 } | |
456 | |
457 /* Perform a quick check so we don't blow up below. */ | |
458 if (count <= i | |
459 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
460 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM | |
461 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG) | |
462 return false; | |
463 | |
464 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); | |
465 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); | |
466 | |
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
|
467 if (GET_CODE (dest_addr) == PLUS) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
468 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
469 if (GET_CODE (XEXP (dest_addr, 1)) != CONST_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
|
470 return 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
|
471 offset = INTVAL (XEXP (dest_addr, 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
|
472 dest_addr = XEXP (dest_addr, 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
|
473 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
474 if (!REG_P (dest_addr)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
475 return 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
|
476 |
0 | 477 for (; i < count; i++) |
478 { | |
479 elt = XVECEXP (op, 0, i); | |
480 | |
481 if (GET_CODE (elt) != SET | |
482 || GET_CODE (SET_SRC (elt)) != REG | |
483 || GET_MODE (SET_SRC (elt)) != SImode | |
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
|
484 || REGNO (SET_SRC (elt)) <= src_regno |
0 | 485 || GET_CODE (SET_DEST (elt)) != MEM |
486 || GET_MODE (SET_DEST (elt)) != SImode | |
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
|
487 || ((GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
488 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
489 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_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
|
490 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != offset + (i - base) * 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
|
491 && (!REG_P (XEXP (SET_DEST (elt), 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
|
492 || offset + (i - base) * 4 != 0))) |
0 | 493 return false; |
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
|
494 src_regno = REGNO (SET_SRC (elt)); |
0 | 495 } |
496 | |
497 return true; | |
498 }) | |
499 | |
500 (define_special_predicate "multi_register_push" | |
501 (match_code "parallel") | |
502 { | |
503 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
504 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC) | |
505 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT)) | |
506 return false; | |
507 | |
508 return true; | |
509 }) | |
510 | |
511 ;;------------------------------------------------------------------------- | |
512 ;; | |
513 ;; Thumb predicates | |
514 ;; | |
515 | |
516 (define_predicate "thumb1_cmp_operand" | |
517 (ior (and (match_code "reg,subreg") | |
518 (match_operand 0 "s_register_operand")) | |
519 (and (match_code "const_int") | |
520 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256")))) | |
521 | |
522 (define_predicate "thumb1_cmpneg_operand" | |
523 (and (match_code "const_int") | |
524 (match_test "INTVAL (op) < 0 && INTVAL (op) > -256"))) | |
525 | |
526 ;; Return TRUE if a result can be stored in OP without clobbering the | |
527 ;; condition code register. Prior to reload we only accept a | |
528 ;; register. After reload we have to be able to handle memory as | |
529 ;; well, since a pseudo may not get a hard reg and reload cannot | |
530 ;; handle output-reloads on jump insns. | |
531 | |
532 ;; We could possibly handle mem before reload as well, but that might | |
533 ;; complicate things with the need to handle increment | |
534 ;; side-effects. | |
535 (define_predicate "thumb_cbrch_target_operand" | |
536 (and (match_code "reg,subreg,mem") | |
537 (ior (match_operand 0 "s_register_operand") | |
538 (and (match_test "reload_in_progress || reload_completed") | |
539 (match_operand 0 "memory_operand"))))) | |
540 | |
541 ;;------------------------------------------------------------------------- | |
542 ;; | |
543 ;; MAVERICK predicates | |
544 ;; | |
545 | |
546 (define_predicate "cirrus_register_operand" | |
547 (match_code "reg,subreg") | |
548 { | |
549 if (GET_CODE (op) == SUBREG) | |
550 op = SUBREG_REG (op); | |
551 | |
552 return (GET_CODE (op) == REG | |
553 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS | |
554 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS)); | |
555 }) | |
556 | |
557 (define_predicate "cirrus_fp_register" | |
558 (match_code "reg,subreg") | |
559 { | |
560 if (GET_CODE (op) == SUBREG) | |
561 op = SUBREG_REG (op); | |
562 | |
563 return (GET_CODE (op) == REG | |
564 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
565 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS)); | |
566 }) | |
567 | |
568 (define_predicate "cirrus_shift_const" | |
569 (and (match_code "const_int") | |
570 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) | |
571 | |
572 | |
573 ;; Neon predicates | |
574 | |
575 (define_predicate "const_multiple_of_8_operand" | |
576 (match_code "const_int") | |
577 { | |
578 unsigned HOST_WIDE_INT val = INTVAL (op); | |
579 return (val & 7) == 0; | |
580 }) | |
581 | |
582 (define_predicate "imm_for_neon_mov_operand" | |
583 (match_code "const_vector") | |
584 { | |
585 return neon_immediate_valid_for_move (op, mode, NULL, NULL); | |
586 }) | |
587 | |
588 (define_predicate "imm_for_neon_logic_operand" | |
589 (match_code "const_vector") | |
590 { | |
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
|
591 return (TARGET_NEON |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
592 && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); |
0 | 593 }) |
594 | |
595 (define_predicate "imm_for_neon_inv_logic_operand" | |
596 (match_code "const_vector") | |
597 { | |
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
|
598 return (TARGET_NEON |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
599 && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); |
0 | 600 }) |
601 | |
602 (define_predicate "neon_logic_op2" | |
603 (ior (match_operand 0 "imm_for_neon_logic_operand") | |
604 (match_operand 0 "s_register_operand"))) | |
605 | |
606 (define_predicate "neon_inv_logic_op2" | |
607 (ior (match_operand 0 "imm_for_neon_inv_logic_operand") | |
608 (match_operand 0 "s_register_operand"))) | |
609 | |
610 ;; TODO: We could check lane numbers more precisely based on the mode. | |
611 (define_predicate "neon_lane_number" | |
612 (and (match_code "const_int") | |
613 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7"))) | |
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
|
614 ;; Predicates for named expanders that overlap multiple ISAs. |
0 | 615 |
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
|
616 (define_predicate "cmpdi_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
617 (if_then_else (match_test "TARGET_HARD_FLOAT && TARGET_MAVERICK") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
618 (and (match_test "TARGET_ARM") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
619 (match_operand 0 "cirrus_fp_register")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
620 (and (match_test "TARGET_32BIT") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
621 (match_operand 0 "arm_di_operand")))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
622 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
623 ;; True if the operand is memory reference suitable for a ldrex/strex. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
624 (define_predicate "arm_sync_memory_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
625 (and (match_operand 0 "memory_operand") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
626 (match_code "reg" "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
|
627 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
628 ;; Predicates for parallel expanders based on mode. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
629 (define_special_predicate "vect_par_constant_high" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
630 (match_code "parallel") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
631 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
632 HOST_WIDE_INT count = XVECLEN (op, 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
|
633 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
|
634 int base = GET_MODE_NUNITS (mode); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
635 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
636 if ((count < 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
|
637 || (count != base/2)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
638 return 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
|
639 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
640 if (!VECTOR_MODE_P (mode)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
641 return 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
|
642 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
643 for (i = 0; i < count; 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
|
644 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
645 rtx elt = XVECEXP (op, 0, 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
|
646 int val; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
647 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
648 if (GET_CODE (elt) != CONST_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
|
649 return 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
|
650 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
651 val = INTVAL (elt); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
652 if (val != (base/2) + 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
|
653 return 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
|
654 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
655 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
656 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
657 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
658 (define_special_predicate "vect_par_constant_low" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
659 (match_code "parallel") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
660 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
661 HOST_WIDE_INT count = XVECLEN (op, 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
|
662 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
|
663 int base = GET_MODE_NUNITS (mode); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
664 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
665 if ((count < 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
|
666 || (count != base/2)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
667 return 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
|
668 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
669 if (!VECTOR_MODE_P (mode)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
670 return 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
|
671 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
672 for (i = 0; i < count; 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
|
673 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
674 rtx elt = XVECEXP (op, 0, 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
|
675 int val; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
676 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
677 if (GET_CODE (elt) != CONST_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
|
678 return 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
|
679 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
680 val = INTVAL (elt); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
681 if (val != 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
|
682 return 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
|
683 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
684 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
685 }) |