Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/m32c/cond.md @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 ;; Machine Descriptions for R8C/M16C/M32C |
2 ;; Copyright (C) 2005, 2007, 2008 | |
3 ;; Free Software Foundation, Inc. | |
4 ;; Contributed by Red Hat. | |
5 ;; | |
6 ;; This file is part of GCC. | |
7 ;; | |
8 ;; GCC is free software; you can redistribute it and/or modify it | |
9 ;; under the terms of the GNU General Public License as published | |
10 ;; by the Free Software Foundation; either version 3, or (at your | |
11 ;; option) any later version. | |
12 ;; | |
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
15 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
16 ;; License for more details. | |
17 ;; | |
18 ;; You should have received a copy of the GNU General Public License | |
19 ;; along with GCC; see the file COPYING3. If not see | |
20 ;; <http://www.gnu.org/licenses/>. | |
21 | |
22 ; conditionals - cmp, jcc, setcc, etc. | |
23 | |
24 ; Special note about conditional instructions: GCC always emits the | |
25 ; compare right before the insn, which is good, because m32c's mov | |
26 ; insns modify the flags. However, this means that any conditional | |
27 ; insn that may require reloading must be kept with its compare until | |
28 ; after reload finishes, else the reload insns might clobber the | |
29 ; flags. Thus, these rules: | |
30 ; | |
31 ; * the cmp* expanders just save the operands in compare_op0 and | |
32 ; compare_op1 via m32c_pend_compare. | |
33 ; * conditional insns that won't need reload can call | |
34 ; m32c_unpend_compare before their expansion. | |
35 ; * other insns must expand to include the compare operands within, | |
36 ; then split after reload to a separate compare and conditional. | |
37 | |
38 ; Until support for relaxing is supported in gas, we must assume that | |
39 ; short labels won't reach, so we must use long labels. | |
40 ; Unfortunately, there aren't any conditional jumps with long labels, | |
41 ; so instead we invert the conditional and jump around a regular jump. | |
42 | |
43 ; Note that we can, at some point in the future, add code to omit the | |
44 ; "cmp" portion of the insn if the preceding insn happened to set the | |
45 ; right flags already. For example, a mov followed by a "cmp *,0" is | |
46 ; redundant; the move already set the Z flag. | |
47 | |
48 (define_insn_and_split "cbranch<mode>4" | |
49 [(set (pc) (if_then_else | |
50 (match_operator 0 "m32c_cmp_operator" | |
51 [(match_operand:QHPSI 1 "mra_operand" "RraSd") | |
52 (match_operand:QHPSI 2 "mrai_operand" "iRraSd")]) | |
53 (label_ref (match_operand 3 "" "")) | |
54 (pc)))] | |
55 "" | |
56 "#" | |
57 "reload_completed" | |
58 [(set (reg:CC FLG_REGNO) | |
59 (compare (match_dup 1) | |
60 (match_dup 2))) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
61 (set (pc) (if_then_else (match_op_dup 0 [(reg:CC FLG_REGNO) (const_int 0)]) |
0 | 62 (label_ref (match_dup 3)) |
63 (pc)))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
64 "" |
0 | 65 ) |
66 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
67 (define_insn "bcc_op" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
68 [(set (pc) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
69 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
70 [(reg:CC FLG_REGNO) (const_int 0)]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
71 (label_ref (match_operand 1 "")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
72 (pc)))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
73 "" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
74 "j%c0\t%l1" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
75 [(set_attr "flags" "n")] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
76 ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
77 |
0 | 78 (define_insn "stzx_16" |
79 [(set (match_operand:QI 0 "mrai_operand" "=R0w,R0w,R0w") | |
80 (if_then_else:QI (eq (reg:CC FLG_REGNO) (const_int 0)) | |
81 (match_operand:QI 1 "const_int_operand" "i,i,0") | |
82 (match_operand:QI 2 "const_int_operand" "i,0,i")))] | |
83 "TARGET_A16 && reload_completed" | |
84 "@ | |
85 stzx\t%1,%2,%0 | |
86 stz\t%1,%0 | |
87 stnz\t%2,%0" | |
88 [(set_attr "flags" "n,n,n")] | |
89 ) | |
90 | |
91 (define_insn "stzx_24_<mode>" | |
92 [(set (match_operand:QHI 0 "mrai_operand" "=RraSd,RraSd,RraSd") | |
93 (if_then_else:QHI (eq (reg:CC FLG_REGNO) (const_int 0)) | |
94 (match_operand:QHI 1 "const_int_operand" "i,i,0") | |
95 (match_operand:QHI 2 "const_int_operand" "i,0,i")))] | |
96 "TARGET_A24 && reload_completed" | |
97 "@ | |
98 stzx.<bwl>\t%1,%2,%0 | |
99 stz.<bwl>\t%1,%0 | |
100 stnz.<bwl>\t%2,%0" | |
101 [(set_attr "flags" "n,n,n")]) | |
102 | |
103 (define_insn_and_split "stzx_reversed_<mode>" | |
104 [(set (match_operand:QHI 0 "m32c_r0_operand" "=R0w") | |
105 (if_then_else:QHI (ne (reg:CC FLG_REGNO) (const_int 0)) | |
106 (match_operand:QHI 1 "const_int_operand" "") | |
107 (match_operand:QHI 2 "const_int_operand" "")))] | |
108 "(TARGET_A24 || GET_MODE (operands[0]) == QImode) && reload_completed" | |
109 "#" | |
110 "" | |
111 [(set (match_dup 0) | |
112 (if_then_else:QHI (eq (reg:CC FLG_REGNO) (const_int 0)) | |
113 (match_dup 2) | |
114 (match_dup 1)))] | |
115 "" | |
116 ) | |
117 | |
118 | |
119 (define_insn "cmp<mode>_op" | |
120 [(set (reg:CC FLG_REGNO) | |
121 (compare (match_operand:QHPSI 0 "mra_operand" "RraSd") | |
122 (match_operand:QHPSI 1 "mrai_operand" "RraSdi")))] | |
123 "" | |
124 "* return m32c_output_compare(insn, operands); " | |
125 [(set_attr "flags" "oszc")]) | |
126 | |
127 ;; m32c_conditional_register_usage changes the setcc_gen_code array to | |
128 ;; point to the _24 variants if needed. | |
129 | |
130 ;; We need to keep the compare and conditional sets together through | |
131 ;; reload, because reload might need to add address reloads to the | |
132 ;; set, which would clobber the flags. By keeping them together, the | |
133 ;; reloads get put before the compare, thus preserving the flags. | |
134 | |
135 ;; These are the post-split patterns for the conditional sets. | |
136 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
137 (define_insn "scc_op" |
0 | 138 [(set (match_operand:QI 0 "register_operand" "=Rqi") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
139 (match_operator:QI 1 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
140 [(reg:CC FLG_REGNO) (const_int 0)]))] |
0 | 141 "TARGET_A16 && reload_completed" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
142 "* return m32c_scc_pattern(operands, GET_CODE (operands[1]));") |
0 | 143 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
144 (define_insn "scc_24_op" |
0 | 145 [(set (match_operand:HI 0 "mra_operand" "=RhiSd") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
146 (match_operator:HI 1 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
147 [(reg:CC FLG_REGNO) (const_int 0)]))] |
0 | 148 "TARGET_A24 && reload_completed" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
149 "sc%c1\t%0" |
0 | 150 [(set_attr "flags" "n")] |
151 ) | |
152 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
153 ;; These are the pre-split patterns for the conditional sets. |
0 | 154 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
155 (define_insn_and_split "cstore<mode>4" |
0 | 156 [(set (match_operand:QI 0 "register_operand" "=Rqi") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
157 (match_operator:QI 1 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
158 [(match_operand:QHPSI 2 "mra_operand" "RraSd") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
159 (match_operand:QHPSI 3 "mrai_operand" "RraSdi")]))] |
0 | 160 "TARGET_A16" |
161 "#" | |
162 "reload_completed" | |
163 [(set (reg:CC FLG_REGNO) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
164 (compare (match_dup 2) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
165 (match_dup 3))) |
0 | 166 (set (match_dup 0) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
167 (match_op_dup 1 [(reg:CC FLG_REGNO) (const_int 0)]))] |
0 | 168 "" |
169 [(set_attr "flags" "x")] | |
170 ) | |
171 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
172 (define_insn_and_split "cstore<mode>4_24" |
0 | 173 [(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
174 (match_operator:HI 1 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
175 [(match_operand:QHPSI 2 "mra_operand" "RraSd") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
176 (match_operand:QHPSI 3 "mrai_operand" "RraSdi")]))] |
0 | 177 "TARGET_A24" |
178 "#" | |
179 "reload_completed" | |
180 [(set (reg:CC FLG_REGNO) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
181 (compare (match_dup 2) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
182 (match_dup 3))) |
0 | 183 (set (match_dup 0) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
184 (match_op_dup 1 [(reg:CC FLG_REGNO) (const_int 0)]))] |
0 | 185 "" |
186 [(set_attr "flags" "x")] | |
187 ) | |
188 | |
189 (define_insn_and_split "movqicc_<code>_<mode>" | |
190 [(set (match_operand:QI 0 "register_operand" "=R0w") | |
191 (if_then_else:QI (eqne_cond:QI (match_operand:QHPSI 1 "mra_operand" "RraSd") | |
192 (match_operand:QHPSI 2 "mrai_operand" "RraSdi")) | |
193 (match_operand:QI 3 "const_int_operand" "") | |
194 (match_operand:QI 4 "const_int_operand" "")))] | |
195 "" | |
196 "#" | |
197 "reload_completed" | |
198 [(set (reg:CC FLG_REGNO) | |
199 (compare (match_dup 1) | |
200 (match_dup 2))) | |
201 (set (match_dup 0) | |
202 (if_then_else:QI (eqne_cond:QI (reg:CC FLG_REGNO) (const_int 0)) | |
203 (match_dup 3) | |
204 (match_dup 4)))] | |
205 "" | |
206 [(set_attr "flags" "x")] | |
207 ) | |
208 | |
209 (define_insn_and_split "movhicc_<code>_<mode>" | |
210 [(set (match_operand:HI 0 "register_operand" "=R0w") | |
211 (if_then_else:HI (eqne_cond:HI (match_operand:QHPSI 1 "mra_operand" "RraSd") | |
212 (match_operand:QHPSI 2 "mrai_operand" "RraSdi")) | |
213 (match_operand:QI 3 "const_int_operand" "") | |
214 (match_operand:QI 4 "const_int_operand" "")))] | |
215 "TARGET_A24" | |
216 "#" | |
217 "reload_completed" | |
218 [(set (reg:CC FLG_REGNO) | |
219 (compare (match_dup 1) | |
220 (match_dup 2))) | |
221 (set (match_dup 0) | |
222 (if_then_else:HI (eqne_cond:HI (reg:CC FLG_REGNO) (const_int 0)) | |
223 (match_dup 3) | |
224 (match_dup 4)))] | |
225 "" | |
226 [(set_attr "flags" "x")] | |
227 ) | |
228 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
229 ;; And these are the expanders. |
0 | 230 |
231 (define_expand "movqicc" | |
232 [(set (match_operand:QI 0 "register_operand" "") | |
233 (if_then_else:QI (match_operand 1 "m32c_eqne_operator" "") | |
234 (match_operand:QI 2 "const_int_operand" "") | |
235 (match_operand:QI 3 "const_int_operand" "")))] | |
236 "" | |
237 "if (m32c_expand_movcc(operands)) | |
238 FAIL; | |
239 DONE;" | |
240 ) | |
241 | |
242 (define_expand "movhicc" | |
243 [(set (match_operand:HI 0 "mra_operand" "") | |
244 (if_then_else:HI (match_operand 1 "m32c_eqne_operator" "") | |
245 (match_operand:HI 2 "const_int_operand" "") | |
246 (match_operand:HI 3 "const_int_operand" "")))] | |
247 "TARGET_A24" | |
248 "if (m32c_expand_movcc(operands)) | |
249 FAIL; | |
250 DONE;" | |
251 ) | |
252 | |
253 | |
254 ;; CMP opcodes subtract two values, set the flags, and discard the | |
255 ;; value. This pattern recovers the sign of the discarded value based | |
256 ;; on the flags. Operand 0 is set to -1, 0, or 1. This is used for | |
257 ;; the cmpstr pattern. For optimal code, this should be removed if | |
258 ;; followed by a suitable CMP insn (see the peephole following). This | |
259 ;; pattern is 7 bytes and 5 cycles. If you don't need specific | |
260 ;; values, a 5/4 pattern can be made with SCGT and BMLT to set the | |
261 ;; appropriate bits. | |
262 | |
263 (define_insn "cond_to_int" | |
264 [(set (match_operand:HI 0 "mra_qi_operand" "=Rqi") | |
265 (if_then_else:HI (lt (reg:CC FLG_REGNO) (const_int 0)) | |
266 (const_int -1) | |
267 (if_then_else:HI (eq (reg:CC FLG_REGNO) (const_int 0)) | |
268 (const_int 0) | |
269 (const_int -1))))] | |
270 "TARGET_A24" | |
271 "sceq\t%0\n\tbmgt\t1,%h0\n\tdec.w\t%0" | |
272 [(set_attr "flags" "x")] | |
273 ) | |
274 | |
275 ;; A cond_to_int followed by a compare against zero is essentially a | |
276 ;; no-op. However, the result of the cond_to_int may be used by later | |
277 ;; insns, so make sure it's dead before deleting its set. | |
278 | |
279 (define_peephole2 | |
280 [(set (match_operand:HI 0 "mra_qi_operand" "") | |
281 (if_then_else:HI (lt (reg:CC FLG_REGNO) (const_int 0)) | |
282 (const_int -1) | |
283 (if_then_else:HI (eq (reg:CC FLG_REGNO) (const_int 0)) | |
284 (const_int 0) | |
285 (const_int -1)))) | |
286 (set (reg:CC FLG_REGNO) | |
287 (compare (match_operand:HI 1 "mra_qi_operand" "") | |
288 (const_int 0))) | |
289 ] | |
290 "rtx_equal_p (operands[0], operands[1]) | |
291 && dead_or_set_p (peep2_next_insn (1), operands[0])" | |
292 [(const_int 1)] | |
293 "") |