annotate gcc/config/rs6000/predicates.md @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
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 ;; Predicate definitions for POWER and PowerPC.
111
kono
parents: 67
diff changeset
2 ;; Copyright (C) 2005-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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 ;; it 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,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 ;; GNU General Public 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 ;; Return 1 for anything except PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 (define_predicate "any_operand"
111
kono
parents: 67
diff changeset
22 (match_code "const_int,const_double,const_wide_int,const,symbol_ref,label_ref,subreg,reg,mem"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 ;; Return 1 for any PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 (define_predicate "any_parallel_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 (match_code "parallel"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 ;; Return 1 if op is COUNT register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 (define_predicate "count_register_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 (and (match_code "reg")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 (match_test "REGNO (op) == CTR_REGNO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 || REGNO (op) > LAST_VIRTUAL_REGISTER")))
111
kono
parents: 67
diff changeset
33
kono
parents: 67
diff changeset
34 ;; Return 1 if op is a SUBREG that is used to look at a SFmode value as
kono
parents: 67
diff changeset
35 ;; and integer or vice versa.
kono
parents: 67
diff changeset
36 ;;
kono
parents: 67
diff changeset
37 ;; In the normal case where SFmode is in a floating point/vector register, it
kono
parents: 67
diff changeset
38 ;; is stored as a DFmode and has a different format. If we don't transform the
kono
parents: 67
diff changeset
39 ;; value, things that use logical operations on the values will get the wrong
kono
parents: 67
diff changeset
40 ;; value.
kono
parents: 67
diff changeset
41 ;;
kono
parents: 67
diff changeset
42 ;; If we don't have 64-bit and direct move, this conversion will be done by
kono
parents: 67
diff changeset
43 ;; store and load, instead of by fiddling with the bits within the register.
kono
parents: 67
diff changeset
44 (define_predicate "sf_subreg_operand"
kono
parents: 67
diff changeset
45 (match_code "subreg")
kono
parents: 67
diff changeset
46 {
kono
parents: 67
diff changeset
47 rtx inner_reg = SUBREG_REG (op);
kono
parents: 67
diff changeset
48 machine_mode inner_mode = GET_MODE (inner_reg);
kono
parents: 67
diff changeset
49
kono
parents: 67
diff changeset
50 if (TARGET_ALLOW_SF_SUBREG || !REG_P (inner_reg))
kono
parents: 67
diff changeset
51 return 0;
kono
parents: 67
diff changeset
52
kono
parents: 67
diff changeset
53 if ((mode == SFmode && GET_MODE_CLASS (inner_mode) == MODE_INT)
kono
parents: 67
diff changeset
54 || (GET_MODE_CLASS (mode) == MODE_INT && inner_mode == SFmode))
kono
parents: 67
diff changeset
55 {
kono
parents: 67
diff changeset
56 if (INT_REGNO_P (REGNO (inner_reg)))
kono
parents: 67
diff changeset
57 return 0;
kono
parents: 67
diff changeset
58
kono
parents: 67
diff changeset
59 return 1;
kono
parents: 67
diff changeset
60 }
kono
parents: 67
diff changeset
61 return 0;
kono
parents: 67
diff changeset
62 })
kono
parents: 67
diff changeset
63
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 ;; Return 1 if op is an Altivec register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 (define_predicate "altivec_register_operand"
111
kono
parents: 67
diff changeset
66 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
67 {
kono
parents: 67
diff changeset
68 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
69 {
kono
parents: 67
diff changeset
70 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
71 return 0;
kono
parents: 67
diff changeset
72
kono
parents: 67
diff changeset
73 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
74 }
kono
parents: 67
diff changeset
75
kono
parents: 67
diff changeset
76 if (!REG_P (op))
kono
parents: 67
diff changeset
77 return 0;
kono
parents: 67
diff changeset
78
kono
parents: 67
diff changeset
79 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
80 return 1;
kono
parents: 67
diff changeset
81
kono
parents: 67
diff changeset
82 return ALTIVEC_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
83 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
85 ;; Return 1 if op is a VSX register.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
86 (define_predicate "vsx_register_operand"
111
kono
parents: 67
diff changeset
87 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
88 {
kono
parents: 67
diff changeset
89 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
90 {
kono
parents: 67
diff changeset
91 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
92 return 0;
kono
parents: 67
diff changeset
93
kono
parents: 67
diff changeset
94 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
95 }
kono
parents: 67
diff changeset
96
kono
parents: 67
diff changeset
97 if (!REG_P (op))
kono
parents: 67
diff changeset
98 return 0;
kono
parents: 67
diff changeset
99
kono
parents: 67
diff changeset
100 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
101 return 1;
kono
parents: 67
diff changeset
102
kono
parents: 67
diff changeset
103 return VSX_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
104 })
kono
parents: 67
diff changeset
105
kono
parents: 67
diff changeset
106 ;; Like vsx_register_operand, but allow SF SUBREGS
kono
parents: 67
diff changeset
107 (define_predicate "vsx_reg_sfsubreg_ok"
kono
parents: 67
diff changeset
108 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
109 {
kono
parents: 67
diff changeset
110 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
111 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
112
kono
parents: 67
diff changeset
113 if (!REG_P (op))
kono
parents: 67
diff changeset
114 return 0;
kono
parents: 67
diff changeset
115
kono
parents: 67
diff changeset
116 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
117 return 1;
kono
parents: 67
diff changeset
118
kono
parents: 67
diff changeset
119 return VSX_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
120 })
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
121
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
122 ;; Return 1 if op is a vector register that operates on floating point vectors
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
123 ;; (either altivec or VSX).
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
124 (define_predicate "vfloat_operand"
111
kono
parents: 67
diff changeset
125 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
126 {
kono
parents: 67
diff changeset
127 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
128 {
kono
parents: 67
diff changeset
129 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
130 return 0;
kono
parents: 67
diff changeset
131
kono
parents: 67
diff changeset
132 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
133 }
kono
parents: 67
diff changeset
134
kono
parents: 67
diff changeset
135 if (!REG_P (op))
kono
parents: 67
diff changeset
136 return 0;
kono
parents: 67
diff changeset
137
kono
parents: 67
diff changeset
138 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
139 return 1;
kono
parents: 67
diff changeset
140
kono
parents: 67
diff changeset
141 return VFLOAT_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
142 })
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
143
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
144 ;; Return 1 if op is a vector register that operates on integer vectors
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
145 ;; (only altivec, VSX doesn't support integer vectors)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
146 (define_predicate "vint_operand"
111
kono
parents: 67
diff changeset
147 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
148 {
kono
parents: 67
diff changeset
149 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
150 {
kono
parents: 67
diff changeset
151 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
152 return 0;
kono
parents: 67
diff changeset
153
kono
parents: 67
diff changeset
154 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
155 }
kono
parents: 67
diff changeset
156
kono
parents: 67
diff changeset
157 if (!REG_P (op))
kono
parents: 67
diff changeset
158 return 0;
kono
parents: 67
diff changeset
159
kono
parents: 67
diff changeset
160 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
161 return 1;
kono
parents: 67
diff changeset
162
kono
parents: 67
diff changeset
163 return VINT_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
164 })
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
165
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
166 ;; Return 1 if op is a vector register to do logical operations on (and, or,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
167 ;; xor, etc.)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
168 (define_predicate "vlogical_operand"
111
kono
parents: 67
diff changeset
169 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
170 {
kono
parents: 67
diff changeset
171 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
172 {
kono
parents: 67
diff changeset
173 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
174 return 0;
kono
parents: 67
diff changeset
175
kono
parents: 67
diff changeset
176 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
177 }
kono
parents: 67
diff changeset
178
kono
parents: 67
diff changeset
179
kono
parents: 67
diff changeset
180 if (!REG_P (op))
kono
parents: 67
diff changeset
181 return 0;
kono
parents: 67
diff changeset
182
kono
parents: 67
diff changeset
183 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
184 return 1;
kono
parents: 67
diff changeset
185
kono
parents: 67
diff changeset
186 return VLOGICAL_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
187 })
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
188
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
189 ;; Return 1 if op is the carry register.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
190 (define_predicate "ca_operand"
111
kono
parents: 67
diff changeset
191 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
192 {
kono
parents: 67
diff changeset
193 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
194 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
195
kono
parents: 67
diff changeset
196 if (!REG_P (op))
kono
parents: 67
diff changeset
197 return 0;
kono
parents: 67
diff changeset
198
kono
parents: 67
diff changeset
199 return CA_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
200 })
kono
parents: 67
diff changeset
201
kono
parents: 67
diff changeset
202 ;; Return 1 if operand is constant zero (scalars and vectors).
kono
parents: 67
diff changeset
203 (define_predicate "zero_constant"
kono
parents: 67
diff changeset
204 (and (match_code "const_int,const_double,const_wide_int,const_vector")
kono
parents: 67
diff changeset
205 (match_test "op == CONST0_RTX (mode)")))
kono
parents: 67
diff changeset
206
kono
parents: 67
diff changeset
207 ;; Return 1 if operand is constant -1 (scalars and vectors).
kono
parents: 67
diff changeset
208 (define_predicate "all_ones_constant"
kono
parents: 67
diff changeset
209 (and (match_code "const_int,const_double,const_wide_int,const_vector")
kono
parents: 67
diff changeset
210 (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 ;; Return 1 if op is a signed 5-bit constant integer.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 (define_predicate "s5bit_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216
111
kono
parents: 67
diff changeset
217 ;; Return 1 if op is a unsigned 3-bit constant integer.
kono
parents: 67
diff changeset
218 (define_predicate "u3bit_cint_operand"
kono
parents: 67
diff changeset
219 (and (match_code "const_int")
kono
parents: 67
diff changeset
220 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7")))
kono
parents: 67
diff changeset
221
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 ;; Return 1 if op is a unsigned 5-bit constant integer.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 (define_predicate "u5bit_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
111
kono
parents: 67
diff changeset
227 ;; Return 1 if op is a unsigned 6-bit constant integer.
kono
parents: 67
diff changeset
228 (define_predicate "u6bit_cint_operand"
kono
parents: 67
diff changeset
229 (and (match_code "const_int")
kono
parents: 67
diff changeset
230 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 63")))
kono
parents: 67
diff changeset
231
kono
parents: 67
diff changeset
232 ;; Return 1 if op is an unsigned 7-bit constant integer.
kono
parents: 67
diff changeset
233 (define_predicate "u7bit_cint_operand"
kono
parents: 67
diff changeset
234 (and (match_code "const_int")
kono
parents: 67
diff changeset
235 (match_test "IN_RANGE (INTVAL (op), 0, 127)")))
kono
parents: 67
diff changeset
236
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 ;; Return 1 if op is a signed 8-bit constant integer.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 ;; Integer multiplication complete more quickly
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 (define_predicate "s8bit_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242
111
kono
parents: 67
diff changeset
243 ;; Return 1 if op is a unsigned 10-bit constant integer.
kono
parents: 67
diff changeset
244 (define_predicate "u10bit_cint_operand"
kono
parents: 67
diff changeset
245 (and (match_code "const_int")
kono
parents: 67
diff changeset
246 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 1023")))
kono
parents: 67
diff changeset
247
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 ;; Return 1 if op is a constant integer that can fit in a D field.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 (define_predicate "short_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 (match_test "satisfies_constraint_I (op)")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 ;; Return 1 if op is a constant integer that can fit in an unsigned D field.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 (define_predicate "u_short_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 (match_test "satisfies_constraint_K (op)")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257
111
kono
parents: 67
diff changeset
258 ;; Return 1 if op is a constant integer that is a signed 16-bit constant
kono
parents: 67
diff changeset
259 ;; shifted left 16 bits
kono
parents: 67
diff changeset
260 (define_predicate "upper16_cint_operand"
kono
parents: 67
diff changeset
261 (and (match_code "const_int")
kono
parents: 67
diff changeset
262 (match_test "satisfies_constraint_L (op)")))
kono
parents: 67
diff changeset
263
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 ;; Return 1 if op is a constant integer that cannot fit in a signed D field.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 (define_predicate "non_short_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 (match_test "(unsigned HOST_WIDE_INT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 (INTVAL (op) + 0x8000) >= 0x10000")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 ;; Return 1 if op is a positive constant integer that is an exact power of 2.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 (define_predicate "exact_log2_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 (match_test "INTVAL (op) > 0 && exact_log2 (INTVAL (op)) >= 0")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274
111
kono
parents: 67
diff changeset
275 ;; Match op = 0 or op = 1.
kono
parents: 67
diff changeset
276 (define_predicate "const_0_to_1_operand"
kono
parents: 67
diff changeset
277 (and (match_code "const_int")
kono
parents: 67
diff changeset
278 (match_test "IN_RANGE (INTVAL (op), 0, 1)")))
kono
parents: 67
diff changeset
279
kono
parents: 67
diff changeset
280 ;; Match op = 0..3.
kono
parents: 67
diff changeset
281 (define_predicate "const_0_to_3_operand"
kono
parents: 67
diff changeset
282 (and (match_code "const_int")
kono
parents: 67
diff changeset
283 (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
kono
parents: 67
diff changeset
284
kono
parents: 67
diff changeset
285 ;; Match op = 2 or op = 3.
kono
parents: 67
diff changeset
286 (define_predicate "const_2_to_3_operand"
kono
parents: 67
diff changeset
287 (and (match_code "const_int")
kono
parents: 67
diff changeset
288 (match_test "IN_RANGE (INTVAL (op), 2, 3)")))
kono
parents: 67
diff changeset
289
kono
parents: 67
diff changeset
290 ;; Match op = 0..7.
kono
parents: 67
diff changeset
291 (define_predicate "const_0_to_7_operand"
kono
parents: 67
diff changeset
292 (and (match_code "const_int")
kono
parents: 67
diff changeset
293 (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
kono
parents: 67
diff changeset
294
kono
parents: 67
diff changeset
295 ;; Match op = 0..11
kono
parents: 67
diff changeset
296 (define_predicate "const_0_to_12_operand"
kono
parents: 67
diff changeset
297 (and (match_code "const_int")
kono
parents: 67
diff changeset
298 (match_test "IN_RANGE (INTVAL (op), 0, 12)")))
kono
parents: 67
diff changeset
299
kono
parents: 67
diff changeset
300 ;; Match op = 0..15
kono
parents: 67
diff changeset
301 (define_predicate "const_0_to_15_operand"
kono
parents: 67
diff changeset
302 (and (match_code "const_int")
kono
parents: 67
diff changeset
303 (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
kono
parents: 67
diff changeset
304
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 ;; Return 1 if op is a register that is not special.
111
kono
parents: 67
diff changeset
306 ;; Disallow (SUBREG:SF (REG:SI)) and (SUBREG:SI (REG:SF)) on VSX systems where
kono
parents: 67
diff changeset
307 ;; you need to be careful in moving a SFmode to SImode and vice versa due to
kono
parents: 67
diff changeset
308 ;; the fact that SFmode is represented as DFmode in the VSX registers.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 (define_predicate "gpc_reg_operand"
111
kono
parents: 67
diff changeset
310 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
311 {
kono
parents: 67
diff changeset
312 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
313 {
kono
parents: 67
diff changeset
314 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
315 return 0;
kono
parents: 67
diff changeset
316
kono
parents: 67
diff changeset
317 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
318 }
kono
parents: 67
diff changeset
319
kono
parents: 67
diff changeset
320 if (!REG_P (op))
kono
parents: 67
diff changeset
321 return 0;
kono
parents: 67
diff changeset
322
kono
parents: 67
diff changeset
323 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
324 return 1;
kono
parents: 67
diff changeset
325
kono
parents: 67
diff changeset
326 if (TARGET_ALTIVEC && ALTIVEC_REGNO_P (REGNO (op)))
kono
parents: 67
diff changeset
327 return 1;
kono
parents: 67
diff changeset
328
kono
parents: 67
diff changeset
329 if (TARGET_VSX && VSX_REGNO_P (REGNO (op)))
kono
parents: 67
diff changeset
330 return 1;
kono
parents: 67
diff changeset
331
kono
parents: 67
diff changeset
332 return INT_REGNO_P (REGNO (op)) || FP_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
333 })
kono
parents: 67
diff changeset
334
kono
parents: 67
diff changeset
335 ;; Return 1 if op is a general purpose register. Unlike gpc_reg_operand, don't
kono
parents: 67
diff changeset
336 ;; allow floating point or vector registers. Since vector registers are not
kono
parents: 67
diff changeset
337 ;; allowed, we don't have to reject SFmode/SImode subregs.
kono
parents: 67
diff changeset
338 (define_predicate "int_reg_operand"
kono
parents: 67
diff changeset
339 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
340 {
kono
parents: 67
diff changeset
341 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
342 {
kono
parents: 67
diff changeset
343 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode))
kono
parents: 67
diff changeset
344 return 0;
kono
parents: 67
diff changeset
345
kono
parents: 67
diff changeset
346 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
347 }
kono
parents: 67
diff changeset
348
kono
parents: 67
diff changeset
349 if (!REG_P (op))
kono
parents: 67
diff changeset
350 return 0;
kono
parents: 67
diff changeset
351
kono
parents: 67
diff changeset
352 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
353 return 1;
kono
parents: 67
diff changeset
354
kono
parents: 67
diff changeset
355 return INT_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
356 })
kono
parents: 67
diff changeset
357
kono
parents: 67
diff changeset
358 ;; Like int_reg_operand, but don't return true for pseudo registers
kono
parents: 67
diff changeset
359 ;; We don't have to check for SF SUBREGS because pseudo registers
kono
parents: 67
diff changeset
360 ;; are not allowed, and SF SUBREGs are ok within GPR registers.
kono
parents: 67
diff changeset
361 (define_predicate "int_reg_operand_not_pseudo"
kono
parents: 67
diff changeset
362 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
363 {
kono
parents: 67
diff changeset
364 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
365 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
366
kono
parents: 67
diff changeset
367 if (!REG_P (op))
kono
parents: 67
diff changeset
368 return 0;
kono
parents: 67
diff changeset
369
kono
parents: 67
diff changeset
370 if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
371 return 0;
kono
parents: 67
diff changeset
372
kono
parents: 67
diff changeset
373 return INT_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
374 })
kono
parents: 67
diff changeset
375
kono
parents: 67
diff changeset
376 ;; Like int_reg_operand, but only return true for base registers
kono
parents: 67
diff changeset
377 (define_predicate "base_reg_operand"
kono
parents: 67
diff changeset
378 (match_operand 0 "int_reg_operand")
kono
parents: 67
diff changeset
379 {
kono
parents: 67
diff changeset
380 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
381 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
382
kono
parents: 67
diff changeset
383 if (!REG_P (op))
kono
parents: 67
diff changeset
384 return 0;
kono
parents: 67
diff changeset
385
kono
parents: 67
diff changeset
386 return (REGNO (op) != FIRST_GPR_REGNO);
kono
parents: 67
diff changeset
387 })
kono
parents: 67
diff changeset
388
kono
parents: 67
diff changeset
389
kono
parents: 67
diff changeset
390 ;; Return true if this is a traditional floating point register
kono
parents: 67
diff changeset
391 (define_predicate "fpr_reg_operand"
kono
parents: 67
diff changeset
392 (match_code "reg,subreg")
kono
parents: 67
diff changeset
393 {
kono
parents: 67
diff changeset
394 HOST_WIDE_INT r;
kono
parents: 67
diff changeset
395
kono
parents: 67
diff changeset
396 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
397 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
398
kono
parents: 67
diff changeset
399 if (!REG_P (op))
kono
parents: 67
diff changeset
400 return 0;
kono
parents: 67
diff changeset
401
kono
parents: 67
diff changeset
402 r = REGNO (op);
kono
parents: 67
diff changeset
403 if (r >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
404 return 1;
kono
parents: 67
diff changeset
405
kono
parents: 67
diff changeset
406 return FP_REGNO_P (r);
kono
parents: 67
diff changeset
407 })
kono
parents: 67
diff changeset
408
kono
parents: 67
diff changeset
409 ;; Return true if this is a register that can has D-form addressing (GPR and
kono
parents: 67
diff changeset
410 ;; traditional FPR registers for scalars). ISA 3.0 (power9) adds D-form
kono
parents: 67
diff changeset
411 ;; addressing for scalars in Altivec registers.
kono
parents: 67
diff changeset
412 ;;
kono
parents: 67
diff changeset
413 ;; If this is a pseudo only allow for GPR fusion in power8. If we have the
kono
parents: 67
diff changeset
414 ;; power9 fusion allow the floating point types.
kono
parents: 67
diff changeset
415 (define_predicate "toc_fusion_or_p9_reg_operand"
kono
parents: 67
diff changeset
416 (match_code "reg,subreg")
kono
parents: 67
diff changeset
417 {
kono
parents: 67
diff changeset
418 HOST_WIDE_INT r;
kono
parents: 67
diff changeset
419 bool gpr_p = (mode == QImode || mode == HImode || mode == SImode
kono
parents: 67
diff changeset
420 || mode == SFmode
kono
parents: 67
diff changeset
421 || (TARGET_POWERPC64 && (mode == DImode || mode == DFmode)));
kono
parents: 67
diff changeset
422 bool fpr_p = (TARGET_P9_FUSION
kono
parents: 67
diff changeset
423 && (mode == DFmode || mode == SFmode
kono
parents: 67
diff changeset
424 || (TARGET_POWERPC64 && mode == DImode)));
kono
parents: 67
diff changeset
425 bool vmx_p = (TARGET_P9_FUSION && TARGET_P9_VECTOR
kono
parents: 67
diff changeset
426 && (mode == DFmode || mode == SFmode));
kono
parents: 67
diff changeset
427
kono
parents: 67
diff changeset
428 if (!TARGET_P8_FUSION)
kono
parents: 67
diff changeset
429 return 0;
kono
parents: 67
diff changeset
430
kono
parents: 67
diff changeset
431 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
432 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
433
kono
parents: 67
diff changeset
434 if (!REG_P (op))
kono
parents: 67
diff changeset
435 return 0;
kono
parents: 67
diff changeset
436
kono
parents: 67
diff changeset
437 r = REGNO (op);
kono
parents: 67
diff changeset
438 if (r >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
439 return (gpr_p || fpr_p || vmx_p);
kono
parents: 67
diff changeset
440
kono
parents: 67
diff changeset
441 if (INT_REGNO_P (r))
kono
parents: 67
diff changeset
442 return gpr_p;
kono
parents: 67
diff changeset
443
kono
parents: 67
diff changeset
444 if (FP_REGNO_P (r))
kono
parents: 67
diff changeset
445 return fpr_p;
kono
parents: 67
diff changeset
446
kono
parents: 67
diff changeset
447 if (ALTIVEC_REGNO_P (r))
kono
parents: 67
diff changeset
448 return vmx_p;
kono
parents: 67
diff changeset
449
kono
parents: 67
diff changeset
450 return 0;
kono
parents: 67
diff changeset
451 })
kono
parents: 67
diff changeset
452
kono
parents: 67
diff changeset
453 ;; Return 1 if op is a HTM specific SPR register.
kono
parents: 67
diff changeset
454 (define_predicate "htm_spr_reg_operand"
kono
parents: 67
diff changeset
455 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
456 {
kono
parents: 67
diff changeset
457 if (!TARGET_HTM)
kono
parents: 67
diff changeset
458 return 0;
kono
parents: 67
diff changeset
459
kono
parents: 67
diff changeset
460 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
461 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
462
kono
parents: 67
diff changeset
463 if (!REG_P (op))
kono
parents: 67
diff changeset
464 return 0;
kono
parents: 67
diff changeset
465
kono
parents: 67
diff changeset
466 switch (REGNO (op))
kono
parents: 67
diff changeset
467 {
kono
parents: 67
diff changeset
468 case TFHAR_REGNO:
kono
parents: 67
diff changeset
469 case TFIAR_REGNO:
kono
parents: 67
diff changeset
470 case TEXASR_REGNO:
kono
parents: 67
diff changeset
471 return 1;
kono
parents: 67
diff changeset
472 default:
kono
parents: 67
diff changeset
473 break;
kono
parents: 67
diff changeset
474 }
kono
parents: 67
diff changeset
475
kono
parents: 67
diff changeset
476 /* Unknown SPR. */
kono
parents: 67
diff changeset
477 return 0;
kono
parents: 67
diff changeset
478 })
kono
parents: 67
diff changeset
479
kono
parents: 67
diff changeset
480 ;; Return 1 if op is a general purpose register that is an even register
kono
parents: 67
diff changeset
481 ;; which suitable for a load/store quad operation
kono
parents: 67
diff changeset
482 ;; Subregs are not allowed here because when they are combine can
kono
parents: 67
diff changeset
483 ;; create (subreg:PTI (reg:TI pseudo)) which will cause reload to
kono
parents: 67
diff changeset
484 ;; think the innermost reg needs reloading, in TImode instead of
kono
parents: 67
diff changeset
485 ;; PTImode. So reload will choose a reg in TImode which has no
kono
parents: 67
diff changeset
486 ;; requirement that the reg be even.
kono
parents: 67
diff changeset
487 (define_predicate "quad_int_reg_operand"
kono
parents: 67
diff changeset
488 (match_code "reg")
kono
parents: 67
diff changeset
489 {
kono
parents: 67
diff changeset
490 HOST_WIDE_INT r;
kono
parents: 67
diff changeset
491
kono
parents: 67
diff changeset
492 if (!TARGET_QUAD_MEMORY && !TARGET_QUAD_MEMORY_ATOMIC)
kono
parents: 67
diff changeset
493 return 0;
kono
parents: 67
diff changeset
494
kono
parents: 67
diff changeset
495 r = REGNO (op);
kono
parents: 67
diff changeset
496 if (r >= FIRST_PSEUDO_REGISTER)
kono
parents: 67
diff changeset
497 return 1;
kono
parents: 67
diff changeset
498
kono
parents: 67
diff changeset
499 return (INT_REGNO_P (r) && ((r & 1) == 0));
kono
parents: 67
diff changeset
500 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 ;; Return 1 if op is a register that is a condition register field.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 (define_predicate "cc_reg_operand"
111
kono
parents: 67
diff changeset
504 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
505 {
kono
parents: 67
diff changeset
506 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
507 op = SUBREG_REG (op);
kono
parents: 67
diff changeset
508
kono
parents: 67
diff changeset
509 if (!REG_P (op))
kono
parents: 67
diff changeset
510 return 0;
kono
parents: 67
diff changeset
511
kono
parents: 67
diff changeset
512 if (REGNO (op) > LAST_VIRTUAL_REGISTER)
kono
parents: 67
diff changeset
513 return 1;
kono
parents: 67
diff changeset
514
kono
parents: 67
diff changeset
515 return CR_REGNO_P (REGNO (op));
kono
parents: 67
diff changeset
516 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 ;; Return 1 if op is a register that is a condition register field not cr0.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 (define_predicate "cc_reg_not_cr0_operand"
111
kono
parents: 67
diff changeset
520 (match_operand 0 "register_operand")
kono
parents: 67
diff changeset
521 {
kono
parents: 67
diff changeset
522 if (GET_CODE (op) == SUBREG)
kono
parents: 67
diff changeset
523 op = SUBREG_REG (op);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524
111
kono
parents: 67
diff changeset
525 if (!REG_P (op))
kono
parents: 67
diff changeset
526 return 0;
kono
parents: 67
diff changeset
527
kono
parents: 67
diff changeset
528 if (REGNO (op) > LAST_VIRTUAL_REGISTER)
kono
parents: 67
diff changeset
529 return 1;
kono
parents: 67
diff changeset
530
kono
parents: 67
diff changeset
531 return CR_REGNO_NOT_CR0_P (REGNO (op));
kono
parents: 67
diff changeset
532 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 ;; Return 1 if op is a constant integer valid for D field
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 ;; or non-special register register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 (define_predicate "reg_or_short_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 (if_then_else (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 (match_operand 0 "short_cint_operand")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 (match_operand 0 "gpc_reg_operand")))
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 ;; Return 1 if op is a constant integer valid for DS field
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 ;; or non-special register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 (define_predicate "reg_or_aligned_short_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 (if_then_else (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 (and (match_operand 0 "short_cint_operand")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 (match_test "!(INTVAL (op) & 3)"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 (match_operand 0 "gpc_reg_operand")))
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 ;; Return 1 if op is a constant integer whose high-order 16 bits are zero
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 ;; or non-special register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 (define_predicate "reg_or_u_short_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 (if_then_else (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 (match_operand 0 "u_short_cint_operand")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 (match_operand 0 "gpc_reg_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555
111
kono
parents: 67
diff changeset
556 ;; Return 1 if op is any constant integer or a non-special register.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 (define_predicate "reg_or_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 (ior (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 (match_operand 0 "gpc_reg_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560
111
kono
parents: 67
diff changeset
561 ;; Return 1 if op is constant zero or a non-special register.
kono
parents: 67
diff changeset
562 (define_predicate "reg_or_zero_operand"
kono
parents: 67
diff changeset
563 (ior (match_operand 0 "zero_constant")
kono
parents: 67
diff changeset
564 (match_operand 0 "gpc_reg_operand")))
kono
parents: 67
diff changeset
565
kono
parents: 67
diff changeset
566 ;; Return 1 if op is a constant integer valid for addition with addis, addi.
kono
parents: 67
diff changeset
567 (define_predicate "add_cint_operand"
kono
parents: 67
diff changeset
568 (and (match_code "const_int")
kono
parents: 67
diff changeset
569 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)
kono
parents: 67
diff changeset
570 + (mode == SImode ? 0x80000000 : 0x80008000))
kono
parents: 67
diff changeset
571 < (unsigned HOST_WIDE_INT) 0x100000000ll")))
kono
parents: 67
diff changeset
572
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 ;; Return 1 if op is a constant integer valid for addition
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 ;; or non-special register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 (define_predicate "reg_or_add_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 (if_then_else (match_code "const_int")
111
kono
parents: 67
diff changeset
577 (match_operand 0 "add_cint_operand")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 (match_operand 0 "gpc_reg_operand")))
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 1 if op is a constant integer valid for subtraction
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 ;; or non-special register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 (define_predicate "reg_or_sub_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 (if_then_else (match_code "const_int")
111
kono
parents: 67
diff changeset
584 (match_test "(unsigned HOST_WIDE_INT)
kono
parents: 67
diff changeset
585 (- UINTVAL (op) + (mode == SImode ? 0x80000000 : 0x80008000))
kono
parents: 67
diff changeset
586 < (unsigned HOST_WIDE_INT) 0x100000000ll")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 (match_operand 0 "gpc_reg_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 ;; Return 1 if op is any 32-bit unsigned constant integer
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 ;; or non-special register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 (define_predicate "reg_or_logical_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 (if_then_else (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 && INTVAL (op) >= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 || ((INTVAL (op) & GET_MODE_MASK (mode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)")
111
kono
parents: 67
diff changeset
597 (match_operand 0 "gpc_reg_operand")))
kono
parents: 67
diff changeset
598
kono
parents: 67
diff changeset
599 ;; Like reg_or_logical_cint_operand, but allow vsx registers
kono
parents: 67
diff changeset
600 (define_predicate "vsx_reg_or_cint_operand"
kono
parents: 67
diff changeset
601 (ior (match_operand 0 "vsx_register_operand")
kono
parents: 67
diff changeset
602 (match_operand 0 "reg_or_logical_cint_operand")))
0
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 ;; Return 1 if operand is a CONST_DOUBLE that can be set in a register
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 ;; with no more than one instruction per word.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 (define_predicate "easy_fp_constant"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 (match_code "const_double")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 if (GET_MODE (op) != mode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 /* Consider all constants with -msoft-float to be easy. */
111
kono
parents: 67
diff changeset
614 if ((TARGET_SOFT_FLOAT
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 && mode != DImode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618
111
kono
parents: 67
diff changeset
619 /* 0.0D is not all zero bits. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 if (DECIMAL_FLOAT_MODE_P (mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622
111
kono
parents: 67
diff changeset
623 /* The constant 0.0 is easy under VSX. */
kono
parents: 67
diff changeset
624 if (TARGET_VSX && SCALAR_FLOAT_MODE_P (mode) && op == CONST0_RTX (mode))
kono
parents: 67
diff changeset
625 return 1;
kono
parents: 67
diff changeset
626
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 /* If we are using V.4 style PIC, consider all constants to be hard. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
628 if (flag_pic && DEFAULT_ABI == ABI_V4)
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
111
kono
parents: 67
diff changeset
631 /* If we have real FPRs, consider floating point constants hard (other than
kono
parents: 67
diff changeset
632 0.0 under VSX), so that the constant gets pushed to memory during the
kono
parents: 67
diff changeset
633 early RTL phases. This has the advantage that double precision constants
kono
parents: 67
diff changeset
634 that can be represented in single precision without a loss of precision
kono
parents: 67
diff changeset
635 will use single precision loads. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 switch (mode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 {
111
kono
parents: 67
diff changeset
639 case E_KFmode:
kono
parents: 67
diff changeset
640 case E_IFmode:
kono
parents: 67
diff changeset
641 case E_TFmode:
kono
parents: 67
diff changeset
642 case E_DFmode:
kono
parents: 67
diff changeset
643 case E_SFmode:
kono
parents: 67
diff changeset
644 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645
111
kono
parents: 67
diff changeset
646 case E_DImode:
kono
parents: 67
diff changeset
647 return (num_insns_constant (op, DImode) <= 2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648
111
kono
parents: 67
diff changeset
649 case E_SImode:
kono
parents: 67
diff changeset
650 return 1;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
651
111
kono
parents: 67
diff changeset
652 default:
kono
parents: 67
diff changeset
653 gcc_unreachable ();
kono
parents: 67
diff changeset
654 }
kono
parents: 67
diff changeset
655 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656
111
kono
parents: 67
diff changeset
657 ;; Return 1 if the operand is a constant that can loaded with a XXSPLTIB
kono
parents: 67
diff changeset
658 ;; instruction and then a VUPKHSB, VECSB2W or VECSB2D instruction.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659
111
kono
parents: 67
diff changeset
660 (define_predicate "xxspltib_constant_split"
kono
parents: 67
diff changeset
661 (match_code "const_vector,vec_duplicate,const_int")
kono
parents: 67
diff changeset
662 {
kono
parents: 67
diff changeset
663 int value = 256;
kono
parents: 67
diff changeset
664 int num_insns = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665
111
kono
parents: 67
diff changeset
666 if (!xxspltib_constant_p (op, mode, &num_insns, &value))
kono
parents: 67
diff changeset
667 return false;
kono
parents: 67
diff changeset
668
kono
parents: 67
diff changeset
669 return num_insns > 1;
kono
parents: 67
diff changeset
670 })
kono
parents: 67
diff changeset
671
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672
111
kono
parents: 67
diff changeset
673 ;; Return 1 if the operand is constant that can loaded directly with a XXSPLTIB
kono
parents: 67
diff changeset
674 ;; instruction.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675
111
kono
parents: 67
diff changeset
676 (define_predicate "xxspltib_constant_nosplit"
kono
parents: 67
diff changeset
677 (match_code "const_vector,vec_duplicate,const_int")
kono
parents: 67
diff changeset
678 {
kono
parents: 67
diff changeset
679 int value = 256;
kono
parents: 67
diff changeset
680 int num_insns = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681
111
kono
parents: 67
diff changeset
682 if (!xxspltib_constant_p (op, mode, &num_insns, &value))
kono
parents: 67
diff changeset
683 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684
111
kono
parents: 67
diff changeset
685 return num_insns == 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 ;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 ;; vector register without using memory.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 (define_predicate "easy_vector_constant"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 (match_code "const_vector")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 /* As the paired vectors are actually FPRs it seems that there is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 no easy way to load a CONST_VECTOR without using memory. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 if (TARGET_PAIRED_FLOAT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697
111
kono
parents: 67
diff changeset
698 /* Because IEEE 128-bit floating point is considered a vector type
kono
parents: 67
diff changeset
699 in order to pass it in VSX registers, it might use this function
kono
parents: 67
diff changeset
700 instead of easy_fp_constant. */
kono
parents: 67
diff changeset
701 if (FLOAT128_VECTOR_P (mode))
kono
parents: 67
diff changeset
702 return easy_fp_constant (op, mode);
kono
parents: 67
diff changeset
703
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
704 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 {
111
kono
parents: 67
diff changeset
706 int value = 256;
kono
parents: 67
diff changeset
707 int num_insns = -1;
kono
parents: 67
diff changeset
708
kono
parents: 67
diff changeset
709 if (zero_constant (op, mode) || all_ones_constant (op, mode))
kono
parents: 67
diff changeset
710 return true;
kono
parents: 67
diff changeset
711
kono
parents: 67
diff changeset
712 if (TARGET_P9_VECTOR
kono
parents: 67
diff changeset
713 && xxspltib_constant_p (op, mode, &num_insns, &value))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
714 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
715
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 return easy_altivec_constant (op, mode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 ;; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 (define_predicate "easy_vector_constant_add_self"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 (and (match_code "const_vector")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 (and (match_test "TARGET_ALTIVEC")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 (match_test "easy_altivec_constant (op, mode)")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
728 HOST_WIDE_INT val;
111
kono
parents: 67
diff changeset
729 int elt;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
730 if (mode == V2DImode || mode == V2DFmode)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
731 return 0;
111
kono
parents: 67
diff changeset
732 elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0;
kono
parents: 67
diff changeset
733 val = const_vector_elt_as_int (op, elt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 val = ((val & 0xff) ^ 0x80) - 0x80;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 return EASY_VECTOR_15_ADD_SELF (val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
738 ;; Same as easy_vector_constant but only for EASY_VECTOR_MSB.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
739 (define_predicate "easy_vector_constant_msb"
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
740 (and (match_code "const_vector")
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
741 (and (match_test "TARGET_ALTIVEC")
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
742 (match_test "easy_altivec_constant (op, mode)")))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
743 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
744 HOST_WIDE_INT val;
111
kono
parents: 67
diff changeset
745 int elt;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
746 if (mode == V2DImode || mode == V2DFmode)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
747 return 0;
111
kono
parents: 67
diff changeset
748 elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0;
kono
parents: 67
diff changeset
749 val = const_vector_elt_as_int (op, elt);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
750 return EASY_VECTOR_MSB (val, GET_MODE_INNER (mode));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
751 })
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
752
111
kono
parents: 67
diff changeset
753 ;; Return true if this is an easy altivec constant that we form
kono
parents: 67
diff changeset
754 ;; by using VSLDOI.
kono
parents: 67
diff changeset
755 (define_predicate "easy_vector_constant_vsldoi"
kono
parents: 67
diff changeset
756 (and (match_code "const_vector")
kono
parents: 67
diff changeset
757 (and (match_test "TARGET_ALTIVEC")
kono
parents: 67
diff changeset
758 (and (match_test "easy_altivec_constant (op, mode)")
kono
parents: 67
diff changeset
759 (match_test "vspltis_shifted (op) != 0")))))
kono
parents: 67
diff changeset
760
kono
parents: 67
diff changeset
761 ;; Return 1 if operand is a vector int register or is either a vector constant
kono
parents: 67
diff changeset
762 ;; of all 0 bits of a vector constant of all 1 bits.
kono
parents: 67
diff changeset
763 (define_predicate "vector_int_reg_or_same_bit"
kono
parents: 67
diff changeset
764 (match_code "reg,subreg,const_vector")
kono
parents: 67
diff changeset
765 {
kono
parents: 67
diff changeset
766 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
kono
parents: 67
diff changeset
767 return 0;
kono
parents: 67
diff changeset
768
kono
parents: 67
diff changeset
769 else if (REG_P (op) || SUBREG_P (op))
kono
parents: 67
diff changeset
770 return vint_operand (op, mode);
kono
parents: 67
diff changeset
771
kono
parents: 67
diff changeset
772 else
kono
parents: 67
diff changeset
773 return op == CONST0_RTX (mode) || op == CONSTM1_RTX (mode);
kono
parents: 67
diff changeset
774 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
776 ;; Return 1 if operand is 0.0.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 (define_predicate "zero_fp_constant"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 (and (match_code "const_double")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 (match_test "SCALAR_FLOAT_MODE_P (mode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 && op == CONST0_RTX (mode)")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 ;; Return 1 if the operand is in volatile memory. Note that during the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 ;; RTL generation phase, memory_operand does not return TRUE for volatile
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 ;; memory references. So this function allows us to recognize volatile
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 ;; references where it's safe.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 (define_predicate "volatile_mem_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 (and (and (match_code "mem")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 (match_test "MEM_VOLATILE_P (op)"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 (if_then_else (match_test "reload_completed")
111
kono
parents: 67
diff changeset
790 (match_operand 0 "memory_operand")
kono
parents: 67
diff changeset
791 (match_test "memory_address_p (mode, XEXP (op, 0))"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 ;; Return 1 if the operand is an offsettable memory operand.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
794 (define_predicate "offsettable_mem_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
795 (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
796 (match_test "offsettable_nonstrict_memref_p (op)")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797
111
kono
parents: 67
diff changeset
798 ;; Return 1 if the operand is a simple offsettable memory operand
kono
parents: 67
diff changeset
799 ;; that does not include pre-increment, post-increment, etc.
kono
parents: 67
diff changeset
800 (define_predicate "simple_offsettable_mem_operand"
kono
parents: 67
diff changeset
801 (match_operand 0 "offsettable_mem_operand")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 {
111
kono
parents: 67
diff changeset
803 rtx addr = XEXP (op, 0);
kono
parents: 67
diff changeset
804
kono
parents: 67
diff changeset
805 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
kono
parents: 67
diff changeset
806 return 0;
kono
parents: 67
diff changeset
807
kono
parents: 67
diff changeset
808 if (!CONSTANT_P (XEXP (addr, 1)))
kono
parents: 67
diff changeset
809 return 0;
kono
parents: 67
diff changeset
810
kono
parents: 67
diff changeset
811 return base_reg_operand (XEXP (addr, 0), Pmode);
kono
parents: 67
diff changeset
812 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813
111
kono
parents: 67
diff changeset
814 ;; Return 1 if the operand is suitable for load/store quad memory.
kono
parents: 67
diff changeset
815 ;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx).
kono
parents: 67
diff changeset
816 (define_predicate "quad_memory_operand"
kono
parents: 67
diff changeset
817 (match_code "mem")
kono
parents: 67
diff changeset
818 {
kono
parents: 67
diff changeset
819 if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI)
kono
parents: 67
diff changeset
820 return false;
kono
parents: 67
diff changeset
821
kono
parents: 67
diff changeset
822 if (GET_MODE_SIZE (mode) != 16 || !MEM_P (op) || MEM_ALIGN (op) < 128)
kono
parents: 67
diff changeset
823 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824
111
kono
parents: 67
diff changeset
825 return quad_address_p (XEXP (op, 0), mode, false);
kono
parents: 67
diff changeset
826 })
kono
parents: 67
diff changeset
827
kono
parents: 67
diff changeset
828 ;; Return 1 if the operand is suitable for load/store to vector registers with
kono
parents: 67
diff changeset
829 ;; d-form addressing (register+offset), which was added in ISA 3.0.
kono
parents: 67
diff changeset
830 ;; Unlike quad_memory_operand, we do not have to check for alignment.
kono
parents: 67
diff changeset
831 (define_predicate "vsx_quad_dform_memory_operand"
kono
parents: 67
diff changeset
832 (match_code "mem")
kono
parents: 67
diff changeset
833 {
kono
parents: 67
diff changeset
834 if (!TARGET_P9_VECTOR || !MEM_P (op) || GET_MODE_SIZE (mode) != 16)
kono
parents: 67
diff changeset
835 return false;
kono
parents: 67
diff changeset
836
kono
parents: 67
diff changeset
837 return quad_address_p (XEXP (op, 0), mode, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
839
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 ;; Return 1 if the operand is an indexed or indirect memory operand.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 (define_predicate "indexed_or_indirect_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 (match_code "mem")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
843 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
844 op = XEXP (op, 0);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
845 if (VECTOR_MEM_ALTIVEC_P (mode)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
846 && GET_CODE (op) == AND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
847 && GET_CODE (XEXP (op, 1)) == CONST_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
848 && INTVAL (XEXP (op, 1)) == -16)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 op = XEXP (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
850
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
851 return indexed_or_indirect_address (op, mode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
852 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
853
111
kono
parents: 67
diff changeset
854 ;; Like indexed_or_indirect_operand, but also allow a GPR register if direct
kono
parents: 67
diff changeset
855 ;; moves are supported.
kono
parents: 67
diff changeset
856 (define_predicate "reg_or_indexed_operand"
kono
parents: 67
diff changeset
857 (match_code "mem,reg,subreg")
kono
parents: 67
diff changeset
858 {
kono
parents: 67
diff changeset
859 if (MEM_P (op))
kono
parents: 67
diff changeset
860 return indexed_or_indirect_operand (op, mode);
kono
parents: 67
diff changeset
861 else if (TARGET_DIRECT_MOVE)
kono
parents: 67
diff changeset
862 return register_operand (op, mode);
kono
parents: 67
diff changeset
863 return
kono
parents: 67
diff changeset
864 0;
kono
parents: 67
diff changeset
865 })
kono
parents: 67
diff changeset
866
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
867 ;; Return 1 if the operand is an indexed or indirect memory operand with an
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
868 ;; AND -16 in it, used to recognize when we need to switch to Altivec loads
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
869 ;; to realign loops instead of VSX (altivec silently ignores the bottom bits,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
870 ;; while VSX uses the full address and traps)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
871 (define_predicate "altivec_indexed_or_indirect_operand"
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
872 (match_code "mem")
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
873 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
874 op = 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
875 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
876 && GET_CODE (op) == AND
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
877 && GET_CODE (XEXP (op, 1)) == CONST_INT
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
878 && INTVAL (XEXP (op, 1)) == -16)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
879 return indexed_or_indirect_address (XEXP (op, 0), mode);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
880
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
881 return 0;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
882 })
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
883
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884 ;; Return 1 if the operand is an indexed or indirect address.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
885 (define_special_predicate "indexed_or_indirect_address"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
886 (and (match_test "REG_P (op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
887 || (GET_CODE (op) == PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
888 /* Omit testing REG_P (XEXP (op, 0)). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
889 && REG_P (XEXP (op, 1)))")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
890 (match_operand 0 "address_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
891
111
kono
parents: 67
diff changeset
892 ;; Return 1 if the operand is an index-form address.
kono
parents: 67
diff changeset
893 (define_special_predicate "indexed_address"
kono
parents: 67
diff changeset
894 (match_test "(GET_CODE (op) == PLUS
kono
parents: 67
diff changeset
895 && REG_P (XEXP (op, 0))
kono
parents: 67
diff changeset
896 && REG_P (XEXP (op, 1)))"))
kono
parents: 67
diff changeset
897
kono
parents: 67
diff changeset
898 ;; Return 1 if the operand is a MEM with an update-form address. This may
kono
parents: 67
diff changeset
899 ;; also include update-indexed form.
kono
parents: 67
diff changeset
900 (define_special_predicate "update_address_mem"
kono
parents: 67
diff changeset
901 (match_test "(MEM_P (op)
kono
parents: 67
diff changeset
902 && (GET_CODE (XEXP (op, 0)) == PRE_INC
kono
parents: 67
diff changeset
903 || GET_CODE (XEXP (op, 0)) == PRE_DEC
kono
parents: 67
diff changeset
904 || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))"))
kono
parents: 67
diff changeset
905
kono
parents: 67
diff changeset
906 ;; Return 1 if the operand is a MEM with an indexed-form address.
kono
parents: 67
diff changeset
907 (define_special_predicate "indexed_address_mem"
kono
parents: 67
diff changeset
908 (match_test "(MEM_P (op)
kono
parents: 67
diff changeset
909 && (indexed_address (XEXP (op, 0), mode)
kono
parents: 67
diff changeset
910 || (GET_CODE (XEXP (op, 0)) == PRE_MODIFY
kono
parents: 67
diff changeset
911 && indexed_address (XEXP (XEXP (op, 0), 1), mode))))"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 ;; Return 1 if the operand is either a non-special register or can be used
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 ;; as the operand of a `mode' add insn.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 (define_predicate "add_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
916 (if_then_else (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
917 (match_test "satisfies_constraint_I (op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918 || satisfies_constraint_L (op)")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919 (match_operand 0 "gpc_reg_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920
111
kono
parents: 67
diff changeset
921 ;; Return 1 if the operand is either a non-special register, or 0, or -1.
kono
parents: 67
diff changeset
922 (define_predicate "adde_operand"
kono
parents: 67
diff changeset
923 (if_then_else (match_code "const_int")
kono
parents: 67
diff changeset
924 (match_test "INTVAL (op) == 0 || INTVAL (op) == -1")
kono
parents: 67
diff changeset
925 (match_operand 0 "gpc_reg_operand")))
kono
parents: 67
diff changeset
926
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 ;; Return 1 if OP is a constant but not a valid add_operand.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 (define_predicate "non_add_cint_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 (and (match_code "const_int")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 (match_test "!satisfies_constraint_I (op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 && !satisfies_constraint_L (op)")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933 ;; Return 1 if the operand is a constant that can be used as the operand
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 ;; of an OR or XOR.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 (define_predicate "logical_const_operand"
111
kono
parents: 67
diff changeset
936 (match_code "const_int")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
937 {
111
kono
parents: 67
diff changeset
938 HOST_WIDE_INT opl;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939
111
kono
parents: 67
diff changeset
940 opl = INTVAL (op) & GET_MODE_MASK (mode);
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 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 ;; Return 1 if the operand is a non-special register or a constant that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947 ;; can be used as the operand of an OR or XOR.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 (define_predicate "logical_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 (ior (match_operand 0 "gpc_reg_operand")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 (match_operand 0 "logical_const_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 ;; Return 1 if op is a constant that is not a logical operand, but could
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 ;; be split into one.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 (define_predicate "non_logical_cint_operand"
111
kono
parents: 67
diff changeset
955 (and (match_code "const_int,const_wide_int")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 (and (not (match_operand 0 "logical_operand"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 (match_operand 0 "reg_or_logical_cint_operand"))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 ;; Return 1 if the operand is either a non-special register or a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 ;; constant that can be used as the operand of a logical AND.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 (define_predicate "and_operand"
111
kono
parents: 67
diff changeset
962 (ior (and (match_code "const_int")
kono
parents: 67
diff changeset
963 (match_test "rs6000_is_valid_and_mask (op, mode)"))
kono
parents: 67
diff changeset
964 (if_then_else (match_test "fixed_regs[CR0_REGNO]")
kono
parents: 67
diff changeset
965 (match_operand 0 "gpc_reg_operand")
kono
parents: 67
diff changeset
966 (match_operand 0 "logical_operand"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 ;; Return 1 if the operand is either a logical operand or a short cint operand.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969 (define_predicate "scc_eq_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
970 (ior (match_operand 0 "logical_operand")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
971 (match_operand 0 "short_cint_operand")))
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 ;; Return 1 if the operand is a general non-special register or memory operand.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 (define_predicate "reg_or_mem_operand"
111
kono
parents: 67
diff changeset
975 (ior (match_operand 0 "memory_operand")
kono
parents: 67
diff changeset
976 (and (match_code "mem")
kono
parents: 67
diff changeset
977 (match_test "macho_lo_sum_memory_operand (op, mode)"))
kono
parents: 67
diff changeset
978 (match_operand 0 "volatile_mem_operand")
kono
parents: 67
diff changeset
979 (match_operand 0 "gpc_reg_operand")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
981 ;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 (define_predicate "zero_reg_mem_operand"
111
kono
parents: 67
diff changeset
983 (ior (and (match_test "TARGET_VSX")
kono
parents: 67
diff changeset
984 (match_operand 0 "zero_fp_constant"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
985 (match_operand 0 "reg_or_mem_operand")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986
111
kono
parents: 67
diff changeset
987 ;; Return 1 if the operand is a CONST_INT and it is the element for 64-bit
kono
parents: 67
diff changeset
988 ;; data types inside of a vector that scalar instructions operate on
kono
parents: 67
diff changeset
989 (define_predicate "vsx_scalar_64bit"
kono
parents: 67
diff changeset
990 (match_code "const_int")
kono
parents: 67
diff changeset
991 {
kono
parents: 67
diff changeset
992 return (INTVAL (op) == VECTOR_ELEMENT_SCALAR_64BIT);
kono
parents: 67
diff changeset
993 })
kono
parents: 67
diff changeset
994
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995 ;; Return 1 if the operand is a general register or memory operand without
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 ;; pre_inc or pre_dec or pre_modify, which produces invalid form of PowerPC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
997 ;; lwa instruction.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
998 (define_predicate "lwa_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999 (match_code "reg,subreg,mem")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1001 rtx inner, addr, offset;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1003 inner = op;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 if (reload_completed && GET_CODE (inner) == SUBREG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 inner = SUBREG_REG (inner);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1007 if (gpc_reg_operand (inner, mode))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1008 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1009 if (!memory_operand (inner, mode))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1010 return false;
111
kono
parents: 67
diff changeset
1011
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1012 addr = XEXP (inner, 0);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1013 if (GET_CODE (addr) == PRE_INC
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1014 || GET_CODE (addr) == PRE_DEC
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1015 || (GET_CODE (addr) == PRE_MODIFY
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1016 && !legitimate_indexed_address_p (XEXP (addr, 1), 0)))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1017 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1018 if (GET_CODE (addr) == LO_SUM
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1019 && GET_CODE (XEXP (addr, 0)) == REG
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1020 && GET_CODE (XEXP (addr, 1)) == CONST)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1021 addr = XEXP (XEXP (addr, 1), 0);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1022 if (GET_CODE (addr) != PLUS)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1023 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1024 offset = XEXP (addr, 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1025 if (GET_CODE (offset) != CONST_INT)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1026 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1027 return INTVAL (offset) % 4 == 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1028 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1029
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1030 ;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1031 (define_predicate "symbol_ref_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1032 (and (match_code "symbol_ref")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 (match_test "(mode == VOIDmode || GET_MODE (op) == mode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034 && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1035
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1036 ;; Return 1 if op is an operand that can be loaded via the GOT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1037 ;; or non-special register register field no cr0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1038 (define_predicate "got_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1039 (match_code "symbol_ref,const,label_ref"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1040
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1041 ;; Return 1 if op is a simple reference that can be loaded via the GOT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1042 ;; excluding labels involving addition.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1043 (define_predicate "got_no_const_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1044 (match_code "symbol_ref,label_ref"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1045
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1046 ;; Return 1 if op is a SYMBOL_REF for a TLS symbol.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1047 (define_predicate "rs6000_tls_symbol_ref"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1048 (and (match_code "symbol_ref")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1049 (match_test "RS6000_SYMBOL_REF_TLS_P (op)")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1050
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1051 ;; Return 1 if the operand, used inside a MEM, is a valid first argument
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1052 ;; to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1053 (define_predicate "call_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1054 (if_then_else (match_code "reg")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1055 (match_test "REGNO (op) == LR_REGNO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1056 || REGNO (op) == CTR_REGNO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057 || REGNO (op) >= FIRST_PSEUDO_REGISTER")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058 (match_code "symbol_ref")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1059
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1060 ;; Return 1 if the operand is a SYMBOL_REF for a function known to be in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061 ;; this file.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062 (define_predicate "current_file_function_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063 (and (match_code "symbol_ref")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
111
kono
parents: 67
diff changeset
1065 && (SYMBOL_REF_LOCAL_P (op)
kono
parents: 67
diff changeset
1066 || (op == XEXP (DECL_RTL (current_function_decl), 0)
kono
parents: 67
diff changeset
1067 && !decl_replaceable_p (current_function_decl)))
kono
parents: 67
diff changeset
1068 && !((DEFAULT_ABI == ABI_AIX
kono
parents: 67
diff changeset
1069 || DEFAULT_ABI == ABI_ELFv2)
kono
parents: 67
diff changeset
1070 && (SYMBOL_REF_EXTERNAL_P (op)
kono
parents: 67
diff changeset
1071 || SYMBOL_REF_WEAK (op)))")))
0
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 ;; Return 1 if this operand is a valid input for a move insn.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1074 (define_predicate "input_operand"
111
kono
parents: 67
diff changeset
1075 (match_code "symbol_ref,const,reg,subreg,mem,
kono
parents: 67
diff changeset
1076 const_double,const_wide_int,const_vector,const_int")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 /* Memory is always valid. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079 if (memory_operand (op, mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 /* For floating-point, easy constants are valid. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 if (SCALAR_FLOAT_MODE_P (mode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 && easy_fp_constant (op, mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 /* Allow any integer constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 if (GET_MODE_CLASS (mode) == MODE_INT
111
kono
parents: 67
diff changeset
1089 && CONST_SCALAR_INT_P (op))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 /* Allow easy vector constants. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093 if (GET_CODE (op) == CONST_VECTOR
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 && easy_vector_constant (op, mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 /* For floating-point or multi-word mode, the only remaining valid type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 is a register. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 if (SCALAR_FLOAT_MODE_P (mode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 return register_operand (op, mode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102
111
kono
parents: 67
diff changeset
1103 /* We don't allow moving the carry bit around. */
kono
parents: 67
diff changeset
1104 if (ca_operand (op, mode))
kono
parents: 67
diff changeset
1105 return 0;
kono
parents: 67
diff changeset
1106
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 /* The only cases left are integral modes one word or smaller (we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 do not get called for MODE_CC values). These can be in any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109 register. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 if (register_operand (op, mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 to be valid. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 if (DEFAULT_ABI == ABI_V4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 && small_data_operand (op, Pmode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120 return 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
111
kono
parents: 67
diff changeset
1123 ;; Return 1 if this operand is a valid input for a vsx_splat insn.
kono
parents: 67
diff changeset
1124 (define_predicate "splat_input_operand"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1125 (match_code "reg,subreg,mem")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126 {
111
kono
parents: 67
diff changeset
1127 machine_mode vmode;
kono
parents: 67
diff changeset
1128
kono
parents: 67
diff changeset
1129 if (mode == DFmode)
kono
parents: 67
diff changeset
1130 vmode = V2DFmode;
kono
parents: 67
diff changeset
1131 else if (mode == DImode)
kono
parents: 67
diff changeset
1132 vmode = V2DImode;
kono
parents: 67
diff changeset
1133 else if (mode == SImode && TARGET_P9_VECTOR)
kono
parents: 67
diff changeset
1134 vmode = V4SImode;
kono
parents: 67
diff changeset
1135 else if (mode == SFmode && TARGET_P9_VECTOR)
kono
parents: 67
diff changeset
1136 vmode = V4SFmode;
kono
parents: 67
diff changeset
1137 else
kono
parents: 67
diff changeset
1138 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139
111
kono
parents: 67
diff changeset
1140 if (MEM_P (op))
kono
parents: 67
diff changeset
1141 {
kono
parents: 67
diff changeset
1142 rtx addr = XEXP (op, 0);
kono
parents: 67
diff changeset
1143
kono
parents: 67
diff changeset
1144 if (! volatile_ok && MEM_VOLATILE_P (op))
kono
parents: 67
diff changeset
1145 return 0;
kono
parents: 67
diff changeset
1146
kono
parents: 67
diff changeset
1147 if (lra_in_progress || reload_completed)
kono
parents: 67
diff changeset
1148 return indexed_or_indirect_address (addr, vmode);
kono
parents: 67
diff changeset
1149 else
kono
parents: 67
diff changeset
1150 return memory_address_addr_space_p (vmode, addr, MEM_ADDR_SPACE (op));
kono
parents: 67
diff changeset
1151 }
kono
parents: 67
diff changeset
1152 return gpc_reg_operand (op, mode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154
111
kono
parents: 67
diff changeset
1155 ;; Return true if operand is an operator used in rotate-and-mask instructions.
kono
parents: 67
diff changeset
1156 (define_predicate "rotate_mask_operator"
kono
parents: 67
diff changeset
1157 (match_code "rotate,ashift,lshiftrt"))
kono
parents: 67
diff changeset
1158
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159 ;; Return true if operand is boolean operator.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 (define_predicate "boolean_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 (match_code "and,ior,xor"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163 ;; Return true if operand is OR-form of boolean operator.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1164 (define_predicate "boolean_or_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165 (match_code "ior,xor"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 ;; Return true if operand is an equality operator.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 (define_special_predicate "equality_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 (match_code "eq,ne"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 ;; Return 1 if OP is a comparison operation that is valid for a branch
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172 ;; instruction. We check the opcode against the mode of the CC value.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 ;; validate_condition_mode is an assertion.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 (define_predicate "branch_comparison_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 (and (match_operand 0 "comparison_operator")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1176 (and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1177 (match_test "validate_condition_mode (GET_CODE (op),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 GET_MODE (XEXP (op, 0))),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 1"))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180
111
kono
parents: 67
diff changeset
1181 ;; Return 1 if OP is an unsigned comparison operator.
kono
parents: 67
diff changeset
1182 (define_predicate "unsigned_comparison_operator"
kono
parents: 67
diff changeset
1183 (match_code "ltu,gtu,leu,geu"))
kono
parents: 67
diff changeset
1184
kono
parents: 67
diff changeset
1185 ;; Return 1 if OP is a signed comparison operator.
kono
parents: 67
diff changeset
1186 (define_predicate "signed_comparison_operator"
kono
parents: 67
diff changeset
1187 (match_code "lt,gt,le,ge"))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1188
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1189 ;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 ;; it must be a positive comparison.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191 (define_predicate "scc_comparison_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192 (and (match_operand 0 "branch_comparison_operator")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1193 (match_code "eq,lt,gt,ltu,gtu,unordered")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1194
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1195 ;; Return 1 if OP is a comparison operation whose inverse would be valid for
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1196 ;; an SCC insn.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1197 (define_predicate "scc_rev_comparison_operator"
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1198 (and (match_operand 0 "branch_comparison_operator")
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1199 (match_code "ne,le,ge,leu,geu,ordered")))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1200
111
kono
parents: 67
diff changeset
1201 ;; Return 1 if OP is a comparison operator suitable for floating point
kono
parents: 67
diff changeset
1202 ;; vector/scalar comparisons that generate a -1/0 mask.
kono
parents: 67
diff changeset
1203 (define_predicate "fpmask_comparison_operator"
kono
parents: 67
diff changeset
1204 (match_code "eq,gt,ge"))
kono
parents: 67
diff changeset
1205
kono
parents: 67
diff changeset
1206 ;; Return 1 if OP is a comparison operator suitable for vector/scalar
kono
parents: 67
diff changeset
1207 ;; comparisons that generate a 0/-1 mask (i.e. the inverse of
kono
parents: 67
diff changeset
1208 ;; fpmask_comparison_operator).
kono
parents: 67
diff changeset
1209 (define_predicate "invert_fpmask_comparison_operator"
kono
parents: 67
diff changeset
1210 (match_code "ne,unlt,unle"))
kono
parents: 67
diff changeset
1211
kono
parents: 67
diff changeset
1212 ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar
kono
parents: 67
diff changeset
1213 ;; comparisons that generate a -1/0 mask.
kono
parents: 67
diff changeset
1214 (define_predicate "vecint_comparison_operator"
kono
parents: 67
diff changeset
1215 (match_code "eq,gt,gtu"))
kono
parents: 67
diff changeset
1216
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1217 ;; Return 1 if OP is a comparison operation that is valid for a branch
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1218 ;; insn, which is true if the corresponding bit in the CC register is set.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219 (define_predicate "branch_positive_comparison_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1220 (and (match_operand 0 "branch_comparison_operator")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221 (match_code "eq,lt,gt,ltu,gtu,unordered")))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1222
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1223 ;; Return 1 if OP is a load multiple operation, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1224 (define_predicate "load_multiple_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1227 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1228 unsigned int dest_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1229 rtx src_addr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1230 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1231
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232 /* Perform a quick check so we don't blow up below. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1233 if (count <= 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1236 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1237 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1238
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1239 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1240 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1241
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1242 for (i = 1; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1243 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1244 rtx elt = XVECEXP (op, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1245
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1246 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1247 || GET_CODE (SET_DEST (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1248 || GET_MODE (SET_DEST (elt)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1249 || REGNO (SET_DEST (elt)) != dest_regno + i
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1250 || GET_CODE (SET_SRC (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1251 || GET_MODE (SET_SRC (elt)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1252 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1253 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1254 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1255 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1256 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1257 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1258
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1259 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1260 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1261
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262 ;; Return 1 if OP is a store multiple operation, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 ;; The second vector element is a CLOBBER.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 (define_predicate "store_multiple_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 int count = XVECLEN (op, 0) - 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 unsigned int src_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269 rtx dest_addr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1271
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272 /* Perform a quick check so we don't blow up below. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1273 if (count <= 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1274 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1275 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1276 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1277 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1280 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1281
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1282 for (i = 1; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1283 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1284 rtx elt = XVECEXP (op, 0, i + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1285
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1286 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1287 || GET_CODE (SET_SRC (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288 || GET_MODE (SET_SRC (elt)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1289 || REGNO (SET_SRC (elt)) != src_regno + i
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 || GET_CODE (SET_DEST (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 || GET_MODE (SET_DEST (elt)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1293 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1295 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1296 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1298
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 ;; Return 1 if OP is valid for a save_world call in prologue, known to be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1303 ;; a PARLLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 (define_predicate "save_world_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1307 int index;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 rtx elt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 if (count != 54)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1313 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 index = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1316 if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317 || GET_CODE (XVECEXP (op, 0, index++)) != USE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1318 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320 for (i=1; i <= 18; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1323 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1324 || GET_CODE (SET_DEST (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1325 || ! memory_operand (SET_DEST (elt), DFmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 || GET_CODE (SET_SRC (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1327 || GET_MODE (SET_SRC (elt)) != DFmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1328 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1329 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1330
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1331 for (i=1; i <= 12; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1332 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1333 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1334 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1335 || GET_CODE (SET_DEST (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1336 || GET_CODE (SET_SRC (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1337 || GET_MODE (SET_SRC (elt)) != V4SImode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1338 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1339 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1340
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1341 for (i=1; i <= 19; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1342 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1343 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1345 || GET_CODE (SET_DEST (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1346 || ! memory_operand (SET_DEST (elt), Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1347 || GET_CODE (SET_SRC (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1348 || GET_MODE (SET_SRC (elt)) != Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1349 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1350 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1353 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 || GET_CODE (SET_DEST (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1355 || ! memory_operand (SET_DEST (elt), Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1356 || GET_CODE (SET_SRC (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1357 || REGNO (SET_SRC (elt)) != CR2_REGNO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 || GET_MODE (SET_SRC (elt)) != Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1359 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1360
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1361 if (GET_CODE (XVECEXP (op, 0, index++)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1362 || GET_CODE (XVECEXP (op, 0, index++)) != SET)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1363 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1364 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1365 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1366
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1367 ;; Return 1 if OP is valid for a restore_world call in epilogue, known to be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1368 ;; a PARLLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1369 (define_predicate "restore_world_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1370 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1371 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372 int index;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1374 rtx elt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1375 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1376
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1377 if (count != 59)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1378 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1379
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1380 index = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1381 if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1382 || GET_CODE (XVECEXP (op, 0, index++)) != USE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 || GET_CODE (XVECEXP (op, 0, index++)) != USE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1387 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1388 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1389 || GET_CODE (SET_SRC (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1390 || ! memory_operand (SET_SRC (elt), Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1391 || GET_CODE (SET_DEST (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1392 || REGNO (SET_DEST (elt)) != CR2_REGNO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1393 || GET_MODE (SET_DEST (elt)) != Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1394 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1395
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1396 for (i=1; i <= 19; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1398 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1399 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1400 || GET_CODE (SET_SRC (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1401 || ! memory_operand (SET_SRC (elt), Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1402 || GET_CODE (SET_DEST (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403 || GET_MODE (SET_DEST (elt)) != Pmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407 for (i=1; i <= 12; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1409 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1410 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411 || GET_CODE (SET_SRC (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 || GET_CODE (SET_DEST (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 || GET_MODE (SET_DEST (elt)) != V4SImode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1414 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1416
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 for (i=1; i <= 18; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1419 elt = XVECEXP (op, 0, index++);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1420 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1421 || GET_CODE (SET_SRC (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1422 || ! memory_operand (SET_SRC (elt), DFmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 || GET_CODE (SET_DEST (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424 || GET_MODE (SET_DEST (elt)) != DFmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1425 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1426 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1427
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428 if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 || GET_CODE (XVECEXP (op, 0, index++)) != USE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 ;; Return 1 if OP is valid for a vrsave call, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 (define_predicate "vrsave_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1442 unsigned int dest_regno, src_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1444
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1445 if (count <= 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1448 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449 || XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPECV_SET_VRSAVE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1451
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1453 src_regno = REGNO (XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455 if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1458 for (i = 1; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1459 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 rtx elt = XVECEXP (op, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462 if (GET_CODE (elt) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463 && GET_CODE (elt) != SET)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 ;; Return 1 if OP is valid for mfcr insn, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 (define_predicate "mfcr_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 (match_code "parallel")
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 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 int i;
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 /* Perform a quick check so we don't blow up below. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478 if (count < 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 for (i = 0; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486 rtx exp = XVECEXP (op, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 rtx unspec;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488 int maskval;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489 rtx src_reg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 src_reg = XVECEXP (SET_SRC (exp), 0, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493 if (GET_CODE (src_reg) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 || GET_MODE (src_reg) != CCmode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495 || ! CR_REGNO_P (REGNO (src_reg)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 if (GET_CODE (exp) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499 || GET_CODE (SET_DEST (exp)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 || GET_MODE (SET_DEST (exp)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 || ! INT_REGNO_P (REGNO (SET_DEST (exp))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503 unspec = SET_SRC (exp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg));
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 if (GET_CODE (unspec) != UNSPEC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507 || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1508 || XVECLEN (unspec, 0) != 2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509 || XVECEXP (unspec, 0, 0) != src_reg
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 return 0;
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 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517 ;; Return 1 if OP is valid for mtcrf insn, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 (define_predicate "mtcrf_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 rtx src_reg;
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 /* Perform a quick check so we don't blow up below. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 if (count < 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533 if (GET_CODE (src_reg) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 || GET_MODE (src_reg) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1535 || ! INT_REGNO_P (REGNO (src_reg)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1536 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1537
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1538 for (i = 0; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1539 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1540 rtx exp = XVECEXP (op, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1541 rtx unspec;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542 int maskval;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1543
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1544 if (GET_CODE (exp) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545 || GET_CODE (SET_DEST (exp)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1546 || GET_MODE (SET_DEST (exp)) != CCmode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1547 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1548 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1549 unspec = SET_SRC (exp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1550 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1551
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1552 if (GET_CODE (unspec) != UNSPEC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1553 || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1554 || XVECLEN (unspec, 0) != 2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1555 || XVECEXP (unspec, 0, 0) != src_reg
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1556 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1557 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1558 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1559 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1560 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1561 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1562
111
kono
parents: 67
diff changeset
1563 ;; Return 1 if OP is valid for crsave insn, known to be a PARALLEL.
kono
parents: 67
diff changeset
1564 (define_predicate "crsave_operation"
kono
parents: 67
diff changeset
1565 (match_code "parallel")
kono
parents: 67
diff changeset
1566 {
kono
parents: 67
diff changeset
1567 int count = XVECLEN (op, 0);
kono
parents: 67
diff changeset
1568 int i;
kono
parents: 67
diff changeset
1569
kono
parents: 67
diff changeset
1570 for (i = 1; i < count; i++)
kono
parents: 67
diff changeset
1571 {
kono
parents: 67
diff changeset
1572 rtx exp = XVECEXP (op, 0, i);
kono
parents: 67
diff changeset
1573
kono
parents: 67
diff changeset
1574 if (GET_CODE (exp) != USE
kono
parents: 67
diff changeset
1575 || GET_CODE (XEXP (exp, 0)) != REG
kono
parents: 67
diff changeset
1576 || GET_MODE (XEXP (exp, 0)) != CCmode
kono
parents: 67
diff changeset
1577 || ! CR_REGNO_P (REGNO (XEXP (exp, 0))))
kono
parents: 67
diff changeset
1578 return 0;
kono
parents: 67
diff changeset
1579 }
kono
parents: 67
diff changeset
1580 return 1;
kono
parents: 67
diff changeset
1581 })
kono
parents: 67
diff changeset
1582
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1583 ;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1584 (define_predicate "lmw_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1585 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588 unsigned int dest_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1589 rtx src_addr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1590 unsigned int base_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591 HOST_WIDE_INT offset;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1592 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1593
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1594 /* Perform a quick check so we don't blow up below. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1595 if (count <= 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1601 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604 if (dest_regno > 31
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 || count != 32 - (int) dest_regno)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1606 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1607
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608 if (legitimate_indirect_address_p (src_addr, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1609 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1610 offset = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 base_regno = REGNO (src_addr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612 if (base_regno == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1613 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1614 }
111
kono
parents: 67
diff changeset
1615 else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1616 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1617 offset = INTVAL (XEXP (src_addr, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1618 base_regno = REGNO (XEXP (src_addr, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1619 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1620 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1621 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1622
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1623 for (i = 0; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1624 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1625 rtx elt = XVECEXP (op, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 rtx newaddr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1627 rtx addr_reg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1628 HOST_WIDE_INT newoffset;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1629
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1630 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1631 || GET_CODE (SET_DEST (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632 || GET_MODE (SET_DEST (elt)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1633 || REGNO (SET_DEST (elt)) != dest_regno + i
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1634 || GET_CODE (SET_SRC (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635 || GET_MODE (SET_SRC (elt)) != SImode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637 newaddr = XEXP (SET_SRC (elt), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638 if (legitimate_indirect_address_p (newaddr, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1639 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1640 newoffset = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1641 addr_reg = newaddr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1642 }
111
kono
parents: 67
diff changeset
1643 else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1644 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1645 addr_reg = XEXP (newaddr, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1646 newoffset = INTVAL (XEXP (newaddr, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1647 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1648 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1649 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1650 if (REGNO (addr_reg) != base_regno
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1651 || newoffset != offset + 4 * i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1652 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1653 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1654
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1655 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1656 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1657
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1658 ;; Return 1 if OP is valid for stmw insn, known to be a PARALLEL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1659 (define_predicate "stmw_operation"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1660 (match_code "parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1661 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1662 int count = XVECLEN (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1663 unsigned int src_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1664 rtx dest_addr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1665 unsigned int base_regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666 HOST_WIDE_INT offset;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669 /* Perform a quick check so we don't blow up below. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1670 if (count <= 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1671 || GET_CODE (XVECEXP (op, 0, 0)) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1672 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1673 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1675
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1678
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679 if (src_regno > 31
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 || count != 32 - (int) src_regno)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1683 if (legitimate_indirect_address_p (dest_addr, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1684 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1685 offset = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 base_regno = REGNO (dest_addr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687 if (base_regno == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1688 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1689 }
111
kono
parents: 67
diff changeset
1690 else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false))
0
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 offset = INTVAL (XEXP (dest_addr, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 base_regno = REGNO (XEXP (dest_addr, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1694 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1695 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1696 return 0;
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 for (i = 0; i < count; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1699 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1700 rtx elt = XVECEXP (op, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1701 rtx newaddr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1702 rtx addr_reg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1703 HOST_WIDE_INT newoffset;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1704
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1705 if (GET_CODE (elt) != SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1706 || GET_CODE (SET_SRC (elt)) != REG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1707 || GET_MODE (SET_SRC (elt)) != SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1708 || REGNO (SET_SRC (elt)) != src_regno + i
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1709 || GET_CODE (SET_DEST (elt)) != MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1710 || GET_MODE (SET_DEST (elt)) != SImode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1711 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1712 newaddr = XEXP (SET_DEST (elt), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1713 if (legitimate_indirect_address_p (newaddr, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1714 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1715 newoffset = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1716 addr_reg = newaddr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1717 }
111
kono
parents: 67
diff changeset
1718 else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1719 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1720 addr_reg = XEXP (newaddr, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1721 newoffset = INTVAL (XEXP (newaddr, 1));
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 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1724 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1725 if (REGNO (addr_reg) != base_regno
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1726 || newoffset != offset + 4 * i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1727 return 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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1730 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1731 })
111
kono
parents: 67
diff changeset
1732
kono
parents: 67
diff changeset
1733 ;; Return 1 if OP is a stack tie operand.
kono
parents: 67
diff changeset
1734 (define_predicate "tie_operand"
kono
parents: 67
diff changeset
1735 (match_code "parallel")
kono
parents: 67
diff changeset
1736 {
kono
parents: 67
diff changeset
1737 return (GET_CODE (XVECEXP (op, 0, 0)) == SET
kono
parents: 67
diff changeset
1738 && GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) == MEM
kono
parents: 67
diff changeset
1739 && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode
kono
parents: 67
diff changeset
1740 && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx);
kono
parents: 67
diff changeset
1741 })
kono
parents: 67
diff changeset
1742
kono
parents: 67
diff changeset
1743 ;; Match a small code model toc reference (or medium and large
kono
parents: 67
diff changeset
1744 ;; model toc references before reload).
kono
parents: 67
diff changeset
1745 (define_predicate "small_toc_ref"
kono
parents: 67
diff changeset
1746 (match_code "unspec,plus")
kono
parents: 67
diff changeset
1747 {
kono
parents: 67
diff changeset
1748 if (GET_CODE (op) == PLUS && add_cint_operand (XEXP (op, 1), mode))
kono
parents: 67
diff changeset
1749 op = XEXP (op, 0);
kono
parents: 67
diff changeset
1750
kono
parents: 67
diff changeset
1751 return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL;
kono
parents: 67
diff changeset
1752 })
kono
parents: 67
diff changeset
1753
kono
parents: 67
diff changeset
1754 ;; Match the TOC memory operand that can be fused with an addis instruction.
kono
parents: 67
diff changeset
1755 ;; This is used in matching a potential fused address before register
kono
parents: 67
diff changeset
1756 ;; allocation.
kono
parents: 67
diff changeset
1757 (define_predicate "toc_fusion_mem_raw"
kono
parents: 67
diff changeset
1758 (match_code "mem")
kono
parents: 67
diff changeset
1759 {
kono
parents: 67
diff changeset
1760 if (!TARGET_TOC_FUSION_INT || !can_create_pseudo_p ())
kono
parents: 67
diff changeset
1761 return false;
kono
parents: 67
diff changeset
1762
kono
parents: 67
diff changeset
1763 return small_toc_ref (XEXP (op, 0), Pmode);
kono
parents: 67
diff changeset
1764 })
kono
parents: 67
diff changeset
1765
kono
parents: 67
diff changeset
1766 ;; Match the memory operand that has been fused with an addis instruction and
kono
parents: 67
diff changeset
1767 ;; wrapped inside of an (unspec [...] UNSPEC_FUSION_ADDIS) wrapper.
kono
parents: 67
diff changeset
1768 (define_predicate "toc_fusion_mem_wrapped"
kono
parents: 67
diff changeset
1769 (match_code "mem")
kono
parents: 67
diff changeset
1770 {
kono
parents: 67
diff changeset
1771 rtx addr;
kono
parents: 67
diff changeset
1772
kono
parents: 67
diff changeset
1773 if (!TARGET_TOC_FUSION_INT)
kono
parents: 67
diff changeset
1774 return false;
kono
parents: 67
diff changeset
1775
kono
parents: 67
diff changeset
1776 if (!MEM_P (op))
kono
parents: 67
diff changeset
1777 return false;
kono
parents: 67
diff changeset
1778
kono
parents: 67
diff changeset
1779 addr = XEXP (op, 0);
kono
parents: 67
diff changeset
1780 return (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_FUSION_ADDIS);
kono
parents: 67
diff changeset
1781 })
kono
parents: 67
diff changeset
1782
kono
parents: 67
diff changeset
1783 ;; Match the first insn (addis) in fusing the combination of addis and loads to
kono
parents: 67
diff changeset
1784 ;; GPR registers on power8.
kono
parents: 67
diff changeset
1785 (define_predicate "fusion_gpr_addis"
kono
parents: 67
diff changeset
1786 (match_code "const_int,high,plus")
kono
parents: 67
diff changeset
1787 {
kono
parents: 67
diff changeset
1788 HOST_WIDE_INT value;
kono
parents: 67
diff changeset
1789 rtx int_const;
kono
parents: 67
diff changeset
1790
kono
parents: 67
diff changeset
1791 if (GET_CODE (op) == HIGH)
kono
parents: 67
diff changeset
1792 return 1;
kono
parents: 67
diff changeset
1793
kono
parents: 67
diff changeset
1794 if (CONST_INT_P (op))
kono
parents: 67
diff changeset
1795 int_const = op;
kono
parents: 67
diff changeset
1796
kono
parents: 67
diff changeset
1797 else if (GET_CODE (op) == PLUS
kono
parents: 67
diff changeset
1798 && base_reg_operand (XEXP (op, 0), Pmode)
kono
parents: 67
diff changeset
1799 && CONST_INT_P (XEXP (op, 1)))
kono
parents: 67
diff changeset
1800 int_const = XEXP (op, 1);
kono
parents: 67
diff changeset
1801
kono
parents: 67
diff changeset
1802 else
kono
parents: 67
diff changeset
1803 return 0;
kono
parents: 67
diff changeset
1804
kono
parents: 67
diff changeset
1805 value = INTVAL (int_const);
kono
parents: 67
diff changeset
1806 if ((value & (HOST_WIDE_INT)0xffff) != 0)
kono
parents: 67
diff changeset
1807 return 0;
kono
parents: 67
diff changeset
1808
kono
parents: 67
diff changeset
1809 if ((value & (HOST_WIDE_INT)0xffff0000) == 0)
kono
parents: 67
diff changeset
1810 return 0;
kono
parents: 67
diff changeset
1811
kono
parents: 67
diff changeset
1812 /* Power8 currently will only do the fusion if the top 11 bits of the addis
kono
parents: 67
diff changeset
1813 value are all 1's or 0's. Ignore this restriction if we are testing
kono
parents: 67
diff changeset
1814 advanced fusion. */
kono
parents: 67
diff changeset
1815 if (TARGET_P9_FUSION)
kono
parents: 67
diff changeset
1816 return 1;
kono
parents: 67
diff changeset
1817
kono
parents: 67
diff changeset
1818 return (IN_RANGE (value >> 16, -32, 31));
kono
parents: 67
diff changeset
1819 })
kono
parents: 67
diff changeset
1820
kono
parents: 67
diff changeset
1821 ;; Match the second insn (lbz, lhz, lwz, ld) in fusing the combination of addis
kono
parents: 67
diff changeset
1822 ;; and loads to GPR registers on power8.
kono
parents: 67
diff changeset
1823 (define_predicate "fusion_gpr_mem_load"
kono
parents: 67
diff changeset
1824 (match_code "mem,sign_extend,zero_extend")
kono
parents: 67
diff changeset
1825 {
kono
parents: 67
diff changeset
1826 rtx addr, base, offset;
kono
parents: 67
diff changeset
1827
kono
parents: 67
diff changeset
1828 /* Handle sign/zero extend. */
kono
parents: 67
diff changeset
1829 if (GET_CODE (op) == ZERO_EXTEND
kono
parents: 67
diff changeset
1830 || (TARGET_P8_FUSION_SIGN && GET_CODE (op) == SIGN_EXTEND))
kono
parents: 67
diff changeset
1831 {
kono
parents: 67
diff changeset
1832 op = XEXP (op, 0);
kono
parents: 67
diff changeset
1833 mode = GET_MODE (op);
kono
parents: 67
diff changeset
1834 }
kono
parents: 67
diff changeset
1835
kono
parents: 67
diff changeset
1836 if (!MEM_P (op))
kono
parents: 67
diff changeset
1837 return 0;
kono
parents: 67
diff changeset
1838
kono
parents: 67
diff changeset
1839 switch (mode)
kono
parents: 67
diff changeset
1840 {
kono
parents: 67
diff changeset
1841 case E_QImode:
kono
parents: 67
diff changeset
1842 case E_HImode:
kono
parents: 67
diff changeset
1843 case E_SImode:
kono
parents: 67
diff changeset
1844 break;
kono
parents: 67
diff changeset
1845
kono
parents: 67
diff changeset
1846 case E_DImode:
kono
parents: 67
diff changeset
1847 if (!TARGET_POWERPC64)
kono
parents: 67
diff changeset
1848 return 0;
kono
parents: 67
diff changeset
1849 break;
kono
parents: 67
diff changeset
1850
kono
parents: 67
diff changeset
1851 default:
kono
parents: 67
diff changeset
1852 return 0;
kono
parents: 67
diff changeset
1853 }
kono
parents: 67
diff changeset
1854
kono
parents: 67
diff changeset
1855 addr = XEXP (op, 0);
kono
parents: 67
diff changeset
1856 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
kono
parents: 67
diff changeset
1857 return 0;
kono
parents: 67
diff changeset
1858
kono
parents: 67
diff changeset
1859 base = XEXP (addr, 0);
kono
parents: 67
diff changeset
1860 if (!base_reg_operand (base, GET_MODE (base)))
kono
parents: 67
diff changeset
1861 return 0;
kono
parents: 67
diff changeset
1862
kono
parents: 67
diff changeset
1863 offset = XEXP (addr, 1);
kono
parents: 67
diff changeset
1864
kono
parents: 67
diff changeset
1865 if (GET_CODE (addr) == PLUS)
kono
parents: 67
diff changeset
1866 return satisfies_constraint_I (offset);
kono
parents: 67
diff changeset
1867
kono
parents: 67
diff changeset
1868 else if (GET_CODE (addr) == LO_SUM)
kono
parents: 67
diff changeset
1869 {
kono
parents: 67
diff changeset
1870 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
kono
parents: 67
diff changeset
1871 return small_toc_ref (offset, GET_MODE (offset));
kono
parents: 67
diff changeset
1872
kono
parents: 67
diff changeset
1873 else if (TARGET_ELF && !TARGET_POWERPC64)
kono
parents: 67
diff changeset
1874 return CONSTANT_P (offset);
kono
parents: 67
diff changeset
1875 }
kono
parents: 67
diff changeset
1876
kono
parents: 67
diff changeset
1877 return 0;
kono
parents: 67
diff changeset
1878 })
kono
parents: 67
diff changeset
1879
kono
parents: 67
diff changeset
1880 ;; Match a GPR load (lbz, lhz, lwz, ld) that uses a combined address in the
kono
parents: 67
diff changeset
1881 ;; memory field with both the addis and the memory offset. Sign extension
kono
parents: 67
diff changeset
1882 ;; is not handled here, since lha and lwa are not fused.
kono
parents: 67
diff changeset
1883 ;; With P9 fusion, also match a fpr/vector load and float_extend
kono
parents: 67
diff changeset
1884 (define_predicate "fusion_addis_mem_combo_load"
kono
parents: 67
diff changeset
1885 (match_code "mem,zero_extend,float_extend")
kono
parents: 67
diff changeset
1886 {
kono
parents: 67
diff changeset
1887 rtx addr, base, offset;
kono
parents: 67
diff changeset
1888
kono
parents: 67
diff changeset
1889 /* Handle zero/float extend. */
kono
parents: 67
diff changeset
1890 if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND)
kono
parents: 67
diff changeset
1891 {
kono
parents: 67
diff changeset
1892 op = XEXP (op, 0);
kono
parents: 67
diff changeset
1893 mode = GET_MODE (op);
kono
parents: 67
diff changeset
1894 }
kono
parents: 67
diff changeset
1895
kono
parents: 67
diff changeset
1896 if (!MEM_P (op))
kono
parents: 67
diff changeset
1897 return 0;
kono
parents: 67
diff changeset
1898
kono
parents: 67
diff changeset
1899 switch (mode)
kono
parents: 67
diff changeset
1900 {
kono
parents: 67
diff changeset
1901 case E_QImode:
kono
parents: 67
diff changeset
1902 case E_HImode:
kono
parents: 67
diff changeset
1903 case E_SImode:
kono
parents: 67
diff changeset
1904 break;
kono
parents: 67
diff changeset
1905
kono
parents: 67
diff changeset
1906 /* Do not fuse 64-bit DImode in 32-bit since it splits into two
kono
parents: 67
diff changeset
1907 separate instructions. */
kono
parents: 67
diff changeset
1908 case E_DImode:
kono
parents: 67
diff changeset
1909 if (!TARGET_POWERPC64)
kono
parents: 67
diff changeset
1910 return 0;
kono
parents: 67
diff changeset
1911 break;
kono
parents: 67
diff changeset
1912
kono
parents: 67
diff changeset
1913 /* ISA 2.08/power8 only had fusion of GPR loads. */
kono
parents: 67
diff changeset
1914 case E_SFmode:
kono
parents: 67
diff changeset
1915 if (!TARGET_P9_FUSION)
kono
parents: 67
diff changeset
1916 return 0;
kono
parents: 67
diff changeset
1917 break;
kono
parents: 67
diff changeset
1918
kono
parents: 67
diff changeset
1919 /* ISA 2.08/power8 only had fusion of GPR loads. Do not allow 64-bit
kono
parents: 67
diff changeset
1920 DFmode in 32-bit if -msoft-float since it splits into two separate
kono
parents: 67
diff changeset
1921 instructions. */
kono
parents: 67
diff changeset
1922 case E_DFmode:
kono
parents: 67
diff changeset
1923 if ((!TARGET_POWERPC64 && !TARGET_DF_FPR) || !TARGET_P9_FUSION)
kono
parents: 67
diff changeset
1924 return 0;
kono
parents: 67
diff changeset
1925 break;
kono
parents: 67
diff changeset
1926
kono
parents: 67
diff changeset
1927 default:
kono
parents: 67
diff changeset
1928 return 0;
kono
parents: 67
diff changeset
1929 }
kono
parents: 67
diff changeset
1930
kono
parents: 67
diff changeset
1931 addr = XEXP (op, 0);
kono
parents: 67
diff changeset
1932 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
kono
parents: 67
diff changeset
1933 return 0;
kono
parents: 67
diff changeset
1934
kono
parents: 67
diff changeset
1935 base = XEXP (addr, 0);
kono
parents: 67
diff changeset
1936 if (!fusion_gpr_addis (base, GET_MODE (base)))
kono
parents: 67
diff changeset
1937 return 0;
kono
parents: 67
diff changeset
1938
kono
parents: 67
diff changeset
1939 offset = XEXP (addr, 1);
kono
parents: 67
diff changeset
1940 if (GET_CODE (addr) == PLUS)
kono
parents: 67
diff changeset
1941 return satisfies_constraint_I (offset);
kono
parents: 67
diff changeset
1942
kono
parents: 67
diff changeset
1943 else if (GET_CODE (addr) == LO_SUM)
kono
parents: 67
diff changeset
1944 {
kono
parents: 67
diff changeset
1945 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
kono
parents: 67
diff changeset
1946 return small_toc_ref (offset, GET_MODE (offset));
kono
parents: 67
diff changeset
1947
kono
parents: 67
diff changeset
1948 else if (TARGET_ELF && !TARGET_POWERPC64)
kono
parents: 67
diff changeset
1949 return CONSTANT_P (offset);
kono
parents: 67
diff changeset
1950 }
kono
parents: 67
diff changeset
1951
kono
parents: 67
diff changeset
1952 return 0;
kono
parents: 67
diff changeset
1953 })
kono
parents: 67
diff changeset
1954
kono
parents: 67
diff changeset
1955 ;; Like fusion_addis_mem_combo_load, but for stores
kono
parents: 67
diff changeset
1956 (define_predicate "fusion_addis_mem_combo_store"
kono
parents: 67
diff changeset
1957 (match_code "mem")
kono
parents: 67
diff changeset
1958 {
kono
parents: 67
diff changeset
1959 rtx addr, base, offset;
kono
parents: 67
diff changeset
1960
kono
parents: 67
diff changeset
1961 if (!MEM_P (op) || !TARGET_P9_FUSION)
kono
parents: 67
diff changeset
1962 return 0;
kono
parents: 67
diff changeset
1963
kono
parents: 67
diff changeset
1964 switch (mode)
kono
parents: 67
diff changeset
1965 {
kono
parents: 67
diff changeset
1966 case E_QImode:
kono
parents: 67
diff changeset
1967 case E_HImode:
kono
parents: 67
diff changeset
1968 case E_SImode:
kono
parents: 67
diff changeset
1969 case E_SFmode:
kono
parents: 67
diff changeset
1970 break;
kono
parents: 67
diff changeset
1971
kono
parents: 67
diff changeset
1972 /* Do not fuse 64-bit DImode in 32-bit since it splits into two
kono
parents: 67
diff changeset
1973 separate instructions. */
kono
parents: 67
diff changeset
1974 case E_DImode:
kono
parents: 67
diff changeset
1975 if (!TARGET_POWERPC64)
kono
parents: 67
diff changeset
1976 return 0;
kono
parents: 67
diff changeset
1977 break;
kono
parents: 67
diff changeset
1978
kono
parents: 67
diff changeset
1979 /* Do not allow 64-bit DFmode in 32-bit if -msoft-float since it splits
kono
parents: 67
diff changeset
1980 into two separate instructions. Do allow fusion if we have hardware
kono
parents: 67
diff changeset
1981 floating point. */
kono
parents: 67
diff changeset
1982 case E_DFmode:
kono
parents: 67
diff changeset
1983 if (!TARGET_POWERPC64 && !TARGET_DF_FPR)
kono
parents: 67
diff changeset
1984 return 0;
kono
parents: 67
diff changeset
1985 break;
kono
parents: 67
diff changeset
1986
kono
parents: 67
diff changeset
1987 default:
kono
parents: 67
diff changeset
1988 return 0;
kono
parents: 67
diff changeset
1989 }
kono
parents: 67
diff changeset
1990
kono
parents: 67
diff changeset
1991 addr = XEXP (op, 0);
kono
parents: 67
diff changeset
1992 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
kono
parents: 67
diff changeset
1993 return 0;
kono
parents: 67
diff changeset
1994
kono
parents: 67
diff changeset
1995 base = XEXP (addr, 0);
kono
parents: 67
diff changeset
1996 if (!fusion_gpr_addis (base, GET_MODE (base)))
kono
parents: 67
diff changeset
1997 return 0;
kono
parents: 67
diff changeset
1998
kono
parents: 67
diff changeset
1999 offset = XEXP (addr, 1);
kono
parents: 67
diff changeset
2000 if (GET_CODE (addr) == PLUS)
kono
parents: 67
diff changeset
2001 return satisfies_constraint_I (offset);
kono
parents: 67
diff changeset
2002
kono
parents: 67
diff changeset
2003 else if (GET_CODE (addr) == LO_SUM)
kono
parents: 67
diff changeset
2004 {
kono
parents: 67
diff changeset
2005 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
kono
parents: 67
diff changeset
2006 return small_toc_ref (offset, GET_MODE (offset));
kono
parents: 67
diff changeset
2007
kono
parents: 67
diff changeset
2008 else if (TARGET_ELF && !TARGET_POWERPC64)
kono
parents: 67
diff changeset
2009 return CONSTANT_P (offset);
kono
parents: 67
diff changeset
2010 }
kono
parents: 67
diff changeset
2011
kono
parents: 67
diff changeset
2012 return 0;
kono
parents: 67
diff changeset
2013 })
kono
parents: 67
diff changeset
2014
kono
parents: 67
diff changeset
2015 ;; Return true if the operand is a float_extend or zero extend of an
kono
parents: 67
diff changeset
2016 ;; offsettable memory operand suitable for use in fusion
kono
parents: 67
diff changeset
2017 (define_predicate "fusion_offsettable_mem_operand"
kono
parents: 67
diff changeset
2018 (match_code "mem,zero_extend,float_extend")
kono
parents: 67
diff changeset
2019 {
kono
parents: 67
diff changeset
2020 if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND)
kono
parents: 67
diff changeset
2021 {
kono
parents: 67
diff changeset
2022 op = XEXP (op, 0);
kono
parents: 67
diff changeset
2023 mode = GET_MODE (op);
kono
parents: 67
diff changeset
2024 }
kono
parents: 67
diff changeset
2025
kono
parents: 67
diff changeset
2026 if (!memory_operand (op, mode))
kono
parents: 67
diff changeset
2027 return 0;
kono
parents: 67
diff changeset
2028
kono
parents: 67
diff changeset
2029 return offsettable_nonstrict_memref_p (op);
kono
parents: 67
diff changeset
2030 })