Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/rx/rx.md @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 ;; Machine Description for Renesas RX processors | 1 ;; Machine Description for Renesas RX processors |
2 ;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. | 2 ;; Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
3 ;; Contributed by Red Hat. | 3 ;; Contributed by Red Hat. |
4 | 4 |
5 ;; This file is part of GCC. | 5 ;; This file is part of GCC. |
6 | 6 |
7 ;; GCC is free software; you can redistribute it and/or modify | 7 ;; GCC is free software; you can redistribute it and/or modify |
16 | 16 |
17 ;; You should have received a copy of the GNU General Public License | 17 ;; You should have received a copy of the GNU General Public License |
18 ;; along with GCC; see the file COPYING3. If not see | 18 ;; along with GCC; see the file COPYING3. If not see |
19 ;; <http://www.gnu.org/licenses/>. | 19 ;; <http://www.gnu.org/licenses/>. |
20 | 20 |
21 | |
22 ;; This code iterator allows all branch instructions to | |
23 ;; be generated from a single define_expand template. | |
24 (define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu | |
25 unordered ordered ]) | |
26 | 21 |
27 ;; This code iterator is used for sign- and zero- extensions. | 22 ;; This code iterator is used for sign- and zero- extensions. |
28 (define_mode_iterator small_int_modes [(HI "") (QI "")]) | 23 (define_mode_iterator small_int_modes [(HI "") (QI "")]) |
29 | 24 |
30 ;; We do not handle DFmode here because it is either | 25 ;; We do not handle DFmode here because it is either |
32 ;; then all operations on doubles have to be handled by | 27 ;; then all operations on doubles have to be handled by |
33 ;; library functions. | 28 ;; library functions. |
34 (define_mode_iterator register_modes | 29 (define_mode_iterator register_modes |
35 [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")]) | 30 [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")]) |
36 | 31 |
37 | |
38 ;; Used to map RX condition names to GCC | |
39 ;; condition names for builtin instructions. | |
40 (define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu | |
41 unge unlt uneq ltgt]) | |
42 (define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt") | |
43 (le "le") (gtu "gtu") (geu "geu") (ltu "ltu") | |
44 (leu "leu") (unge "pz") (unlt "n") (uneq "o") | |
45 (ltgt "no")]) | |
46 | |
47 (define_constants | 32 (define_constants |
48 [ | 33 [ |
49 (SP_REG 0) | 34 (SP_REG 0) |
35 (CC_REG 16) | |
50 | 36 |
51 (UNSPEC_LOW_REG 0) | 37 (UNSPEC_LOW_REG 0) |
52 (UNSPEC_HIGH_REG 1) | 38 (UNSPEC_HIGH_REG 1) |
53 | 39 |
54 (UNSPEC_RTE 10) | 40 (UNSPEC_RTE 10) |
55 (UNSPEC_RTFI 11) | 41 (UNSPEC_RTFI 11) |
56 (UNSPEC_NAKED 12) | 42 (UNSPEC_NAKED 12) |
43 (UNSPEC_CONST 13) | |
57 | 44 |
58 (UNSPEC_MOVSTR 20) | 45 (UNSPEC_MOVSTR 20) |
59 (UNSPEC_MOVMEM 21) | 46 (UNSPEC_MOVMEM 21) |
60 (UNSPEC_SETMEM 22) | 47 (UNSPEC_SETMEM 22) |
61 (UNSPEC_STRLEN 23) | 48 (UNSPEC_STRLEN 23) |
83 (UNSPEC_BUILTIN_SAT 49) | 70 (UNSPEC_BUILTIN_SAT 49) |
84 (UNSPEC_BUILTIN_SETPSW 50) | 71 (UNSPEC_BUILTIN_SETPSW 50) |
85 (UNSPEC_BUILTIN_WAIT 51) | 72 (UNSPEC_BUILTIN_WAIT 51) |
86 ] | 73 ] |
87 ) | 74 ) |
88 | |
89 ;; Condition code settings: | |
90 ;; none - insn does not affect the condition code bits | |
91 ;; set_zs - insn sets z,s to usable values; | |
92 ;; set_zso - insn sets z,s,o to usable values; | |
93 ;; set_zsoc - insn sets z,s,o,c to usable values; | |
94 ;; clobber - value of cc0 is unknown | |
95 (define_attr "cc" "none,set_zs,set_zso,set_zsoc,clobber" (const_string "none")) | |
96 | 75 |
97 (define_attr "length" "" (const_int 8)) | 76 (define_attr "length" "" (const_int 8)) |
98 | 77 |
99 (include "predicates.md") | 78 (include "predicates.md") |
100 (include "constraints.md") | 79 (include "constraints.md") |
152 (define_insn_reservation "throughput_16_latency_16" 1 | 131 (define_insn_reservation "throughput_16_latency_16" 1 |
153 (eq_attr "timings" "1616") "throughput*16") | 132 (eq_attr "timings" "1616") "throughput*16") |
154 (define_insn_reservation "throughput_18_latency_18" 1 | 133 (define_insn_reservation "throughput_18_latency_18" 1 |
155 (eq_attr "timings" "1818") "throughput*18") | 134 (eq_attr "timings" "1818") "throughput*18") |
156 | 135 |
136 ;; ---------------------------------------------------------------------------- | |
137 | |
157 ;; Comparisons | 138 ;; Comparisons |
158 | 139 |
140 ;; Note - we do not specify the two instructions necessary to perform | |
141 ;; a compare-and-branch in the cbranchsi4 pattern because that would | |
142 ;; allow the comparison to be moved away from the jump before the reload | |
143 ;; pass has completed. That would be problematical because reload can | |
144 ;; generate ADDSI3 instructions which would corrupt the PSW flags. | |
145 | |
159 (define_expand "cbranchsi4" | 146 (define_expand "cbranchsi4" |
160 [(set (cc0) (compare:CC (match_operand:SI 1 "register_operand") | 147 [(set (pc) |
161 (match_operand:SI 2 "rx_source_operand"))) | 148 (if_then_else |
162 (set (pc) | 149 (match_operator 0 "comparison_operator" |
163 (if_then_else (match_operator:SI 0 "comparison_operator" | 150 [(match_operand:SI 1 "register_operand") |
164 [(cc0) (const_int 0)]) | 151 (match_operand:SI 2 "rx_source_operand")]) |
165 (label_ref (match_operand 3 "")) | 152 (label_ref (match_operand 3 "")) |
166 (pc)))] | 153 (pc)))] |
167 "" | 154 "" |
168 "" | 155 ) |
156 | |
157 (define_insn_and_split "*cbranchsi4" | |
158 [(set (pc) | |
159 (if_then_else | |
160 (match_operator 3 "comparison_operator" | |
161 [(match_operand:SI 0 "register_operand" "r") | |
162 (match_operand:SI 1 "rx_source_operand" "riQ")]) | |
163 (match_operand 2 "label_ref_operand" "") | |
164 (pc)))] | |
165 "" | |
166 "#" | |
167 "reload_completed" | |
168 [(const_int 0)] | |
169 { | |
170 rx_split_cbranch (CCmode, GET_CODE (operands[3]), | |
171 operands[0], operands[1], operands[2]); | |
172 DONE; | |
173 }) | |
174 | |
175 (define_insn "*cmpsi" | |
176 [(set (reg:CC CC_REG) | |
177 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r") | |
178 (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))] | |
179 "reload_completed" | |
180 "cmp\t%Q1, %0" | |
181 [(set_attr "timings" "11,11,11,11,11,11,33") | |
182 (set_attr "length" "2,2,3,4,5,6,5")] | |
183 ) | |
184 | |
185 ;; Canonical method for representing TST. | |
186 (define_insn_and_split "*cbranchsi4_tst" | |
187 [(set (pc) | |
188 (if_then_else | |
189 (match_operator 3 "rx_zs_comparison_operator" | |
190 [(and:SI (match_operand:SI 0 "register_operand" "r") | |
191 (match_operand:SI 1 "rx_source_operand" "riQ")) | |
192 (const_int 0)]) | |
193 (match_operand 2 "label_ref_operand" "") | |
194 (pc)))] | |
195 "" | |
196 "#" | |
197 "reload_completed" | |
198 [(const_int 0)] | |
199 { | |
200 rx_split_cbranch (CC_ZSmode, GET_CODE (operands[3]), | |
201 XEXP (operands[3], 0), XEXP (operands[3], 1), | |
202 operands[2]); | |
203 DONE; | |
204 }) | |
205 | |
206 ;; Various other ways that GCC codes "var & const" | |
207 (define_insn_and_split "*cbranchsi4_tst_ext" | |
208 [(set (pc) | |
209 (if_then_else | |
210 (match_operator 4 "rx_z_comparison_operator" | |
211 [(zero_extract:SI | |
212 (match_operand:SI 0 "register_operand" "r") | |
213 (match_operand:SI 1 "rx_constshift_operand" "") | |
214 (match_operand:SI 2 "rx_constshift_operand" "")) | |
215 (const_int 0)]) | |
216 (match_operand 3 "label_ref_operand" "") | |
217 (pc)))] | |
218 "" | |
219 "#" | |
220 "reload_completed" | |
221 [(const_int 0)] | |
222 { | |
223 HOST_WIDE_INT mask; | |
224 rtx x; | |
225 | |
226 mask = 1; | |
227 mask <<= INTVAL (operands[1]); | |
228 mask -= 1; | |
229 mask <<= INTVAL (operands[2]); | |
230 x = gen_rtx_AND (SImode, operands[0], gen_int_mode (mask, SImode)); | |
231 | |
232 rx_split_cbranch (CC_ZSmode, GET_CODE (operands[4]), | |
233 x, const0_rtx, operands[3]); | |
234 DONE; | |
235 }) | |
236 | |
237 (define_insn "*tstsi" | |
238 [(set (reg:CC_ZS CC_REG) | |
239 (compare:CC_ZS | |
240 (and:SI (match_operand:SI 0 "register_operand" "r,r,r") | |
241 (match_operand:SI 1 "rx_source_operand" "r,i,Q")) | |
242 (const_int 0)))] | |
243 "reload_completed" | |
244 "tst\t%Q1, %0" | |
245 [(set_attr "timings" "11,11,33") | |
246 (set_attr "length" "3,7,6")] | |
169 ) | 247 ) |
170 | 248 |
171 (define_expand "cbranchsf4" | 249 (define_expand "cbranchsf4" |
172 [(set (cc0) (compare:CC (match_operand:SF 1 "register_operand") | 250 [(set (pc) |
173 (match_operand:SF 2 "rx_source_operand"))) | 251 (if_then_else |
174 (set (pc) | 252 (match_operator 0 "rx_fp_comparison_operator" |
175 (if_then_else (match_operator:SI 0 "comparison_operator" | 253 [(match_operand:SF 1 "register_operand") |
176 [(cc0) (const_int 0)]) | 254 (match_operand:SF 2 "rx_source_operand")]) |
177 (label_ref (match_operand 3 "")) | 255 (label_ref (match_operand 3 "")) |
178 (pc)))] | 256 (pc)))] |
179 "ALLOW_RX_FPU_INSNS && ! flag_non_call_exceptions" | 257 "ALLOW_RX_FPU_INSNS" |
180 "" | 258 ) |
181 ) | 259 |
182 | 260 (define_insn_and_split "*cbranchsf4" |
183 ;; The TST instruction is not used as it does not set the Carry flag, | 261 [(set (pc) |
184 ;; so for example, the LessThan comparison cannot be tested. | 262 (if_then_else |
185 ;; | 263 (match_operator 3 "rx_fp_comparison_operator" |
186 ;; (define_insn "tstsi" | 264 [(match_operand:SF 0 "register_operand" "r") |
187 ;; [(set (cc0) | 265 (match_operand:SF 1 "rx_source_operand" "rFQ")]) |
188 ;; (match_operand:SI 0 "rx_source_operand" "r,i,Q")))] | 266 (match_operand 2 "label_ref_operand" "") |
189 ;; "" | 267 (pc)))] |
190 ;; { | 268 "ALLOW_RX_FPU_INSNS" |
191 ;; rx_float_compare_mode = false; | 269 "#" |
192 ;; return "tst\t%Q0"; | 270 "&& reload_completed" |
193 ;; } | 271 [(const_int 0)] |
194 ;; [(set_attr "cc" "set_zs") | 272 { |
195 ;; (set_attr "timings" "11,11,33") | 273 rx_split_cbranch (CC_Fmode, GET_CODE (operands[3]), |
196 ;; (set_attr "length" "3,7,6")] | 274 operands[0], operands[1], operands[2]); |
197 ;; ) | 275 DONE; |
198 | 276 }) |
199 (define_insn "cmpsi" | 277 |
200 [(set (cc0) (compare:CC | 278 (define_insn "*cmpsf" |
201 (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r") | 279 [(set (reg:CC_F CC_REG) |
202 (match_operand:SI 1 "rx_source_operand" | 280 (compare:CC_F |
203 "r,Uint04,Int08,Sint16,Sint24,i,Q")))] | 281 (match_operand:SF 0 "register_operand" "r,r,r") |
204 "" | 282 (match_operand:SF 1 "rx_source_operand" "r,F,Q")))] |
205 { | 283 "ALLOW_RX_FPU_INSNS && reload_completed" |
206 rx_float_compare_mode = false; | 284 "fcmp\t%1, %0" |
207 return "cmp\t%Q1, %Q0"; | 285 [(set_attr "timings" "11,11,33") |
208 } | |
209 [(set_attr "cc" "set_zsoc") | |
210 (set_attr "timings" "11,11,11,11,11,11,33") | |
211 (set_attr "length" "2,2,3,4,5,6,5")] | |
212 ) | |
213 | |
214 ;; This pattern is disabled when -fnon-call-exceptions is active because | |
215 ;; it could generate a floating point exception, which would introduce an | |
216 ;; edge into the flow graph between this insn and the conditional branch | |
217 ;; insn to follow, thus breaking the cc0 relationship. Run the g++ test | |
218 ;; g++.dg/eh/080514-1.C to see this happen. | |
219 (define_insn "cmpsf" | |
220 [(set (cc0) | |
221 (compare:CC (match_operand:SF 0 "register_operand" "r,r,r") | |
222 (match_operand:SF 1 "rx_source_operand" "r,i,Q")))] | |
223 "ALLOW_RX_FPU_INSNS && ! flag_non_call_exceptions" | |
224 { | |
225 rx_float_compare_mode = true; | |
226 return "fcmp\t%1, %0"; | |
227 } | |
228 [(set_attr "cc" "set_zso") | |
229 (set_attr "timings" "11,11,33") | |
230 (set_attr "length" "3,7,5")] | 286 (set_attr "length" "3,7,5")] |
231 ) | 287 ) |
232 | 288 |
233 ;; Flow Control Instructions: | 289 ;; Flow Control Instructions: |
234 | |
235 (define_expand "b<code>" | |
236 [(set (pc) | |
237 (if_then_else (most_cond (cc0) (const_int 0)) | |
238 (label_ref (match_operand 0)) | |
239 (pc)))] | |
240 "" | |
241 "" | |
242 ) | |
243 | 290 |
244 (define_insn "*conditional_branch" | 291 (define_insn "*conditional_branch" |
245 [(set (pc) | 292 [(set (pc) |
246 (if_then_else (match_operator 1 "comparison_operator" | 293 (if_then_else |
247 [(cc0) (const_int 0)]) | 294 (match_operator 1 "comparison_operator" |
248 (label_ref (match_operand 0 "" "")) | 295 [(reg CC_REG) (const_int 0)]) |
249 (pc)))] | 296 (label_ref (match_operand 0 "" "")) |
250 "" | 297 (pc)))] |
251 { | 298 "reload_completed" |
252 return rx_gen_cond_branch_template (operands[1], false); | 299 "b%B1\t%0" |
253 } | |
254 [(set_attr "length" "8") ;; This length is wrong, but it is | 300 [(set_attr "length" "8") ;; This length is wrong, but it is |
255 ;; too hard to compute statically. | 301 ;; too hard to compute statically. |
256 (set_attr "timings" "33") ;; The timing assumes that the branch is taken. | 302 (set_attr "timings" "33")] ;; The timing assumes that the branch is taken. |
257 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. | 303 ) |
258 ) | 304 |
259 | 305 ;; ---------------------------------------------------------------------------- |
260 (define_insn "*reveresed_conditional_branch" | 306 |
307 (define_insn "jump" | |
261 [(set (pc) | 308 [(set (pc) |
262 (if_then_else (match_operator 1 "comparison_operator" | 309 (label_ref (match_operand 0 "" "")))] |
263 [(cc0) (const_int 0)]) | |
264 (pc) | |
265 (label_ref (match_operand 0 "" ""))))] | |
266 "" | |
267 { | |
268 return rx_gen_cond_branch_template (operands[1], true); | |
269 } | |
270 [(set_attr "length" "8") ;; This length is wrong, but it is | |
271 ;; too hard to compute statically. | |
272 (set_attr "timings" "33") ;; The timing assumes that the branch is taken. | |
273 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. | |
274 ) | |
275 | |
276 (define_insn "jump" | |
277 [(set (pc) (label_ref (match_operand 0 "" "")))] | |
278 "" | 310 "" |
279 "bra\t%0" | 311 "bra\t%0" |
280 [(set_attr "length" "4") | 312 [(set_attr "length" "4") |
281 (set_attr "timings" "33") | 313 (set_attr "timings" "33")] |
282 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. | |
283 ) | 314 ) |
284 | 315 |
285 (define_insn "indirect_jump" | 316 (define_insn "indirect_jump" |
286 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] | 317 [(set (pc) |
318 (match_operand:SI 0 "register_operand" "r"))] | |
287 "" | 319 "" |
288 "jmp\t%0" | 320 "jmp\t%0" |
289 [(set_attr "length" "2") | 321 [(set_attr "length" "2") |
290 (set_attr "timings" "33") | 322 (set_attr "timings" "33")] |
291 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. | |
292 ) | 323 ) |
293 | 324 |
294 (define_insn "tablejump" | 325 (define_insn "tablejump" |
295 [(set (pc) (match_operand:SI 0 "register_operand" "r")) | 326 [(set (pc) |
327 (match_operand:SI 0 "register_operand" "r")) | |
296 (use (label_ref (match_operand 1 "" "")))] | 328 (use (label_ref (match_operand 1 "" "")))] |
297 "" | 329 "" |
298 { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0" | 330 { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0" |
299 : "\n1:\tbra\t%0") | 331 : "\n1:\tbra\t%0") |
300 : "jmp\t%0"; | 332 : "jmp\t%0"; |
301 } | 333 } |
302 [(set_attr "cc" "clobber") ;; FIXME: This clobber is wrong. | 334 [(set_attr "timings" "33") |
303 (set_attr "timings" "33") | |
304 (set_attr "length" "2")] | 335 (set_attr "length" "2")] |
305 ) | 336 ) |
306 | 337 |
307 (define_insn "simple_return" | 338 (define_insn "simple_return" |
308 [(return)] | 339 [(return)] |
310 "rts" | 341 "rts" |
311 [(set_attr "length" "1") | 342 [(set_attr "length" "1") |
312 (set_attr "timings" "55")] | 343 (set_attr "timings" "55")] |
313 ) | 344 ) |
314 | 345 |
346 ;; Unspec used so that the constant will not be invalid | |
347 ;; if -mmax-constant-size has been specified. | |
315 (define_insn "deallocate_and_return" | 348 (define_insn "deallocate_and_return" |
316 [(set (reg:SI SP_REG) | 349 [(set (reg:SI SP_REG) |
317 (plus:SI (reg:SI SP_REG) | 350 (plus:SI (reg:SI SP_REG) |
318 (match_operand:SI 0 "immediate_operand" "i"))) | 351 (const:SI (unspec:SI [(match_operand 0 "const_int_operand" "n")] UNSPEC_CONST)))) |
319 (return)] | 352 (return)] |
320 "" | 353 "" |
321 "rtsd\t%0" | 354 "rtsd\t%0" |
322 [(set_attr "length" "2") | 355 [(set_attr "length" "2") |
323 (set_attr "timings" "55")] | 356 (set_attr "timings" "55")] |
324 ) | 357 ) |
325 | 358 |
326 (define_insn "pop_and_return" | 359 (define_insn "pop_and_return" |
327 [(match_parallel 1 "rx_rtsd_vector" | 360 [(match_parallel 1 "rx_rtsd_vector" |
328 [(set:SI (reg:SI SP_REG) | 361 [(set (reg:SI SP_REG) |
329 (plus:SI (reg:SI SP_REG) | 362 (plus:SI (reg:SI SP_REG) |
330 (match_operand:SI | 363 (match_operand:SI 0 "const_int_operand" "n")))]) |
331 0 "const_int_operand" "n")))])] | 364 (return)] |
332 "reload_completed" | 365 "reload_completed" |
333 { | 366 { |
334 rx_emit_stack_popm (operands, false); | 367 rx_emit_stack_popm (operands, false); |
335 return ""; | 368 return ""; |
336 } | 369 } |
376 { | 409 { |
377 rtx dest = XEXP (operands[0], 0); | 410 rtx dest = XEXP (operands[0], 0); |
378 | 411 |
379 if (! rx_call_operand (dest, Pmode)) | 412 if (! rx_call_operand (dest, Pmode)) |
380 dest = force_reg (Pmode, dest); | 413 dest = force_reg (Pmode, dest); |
381 emit_call_insn (gen_call_internal (dest, operands[1])); | 414 emit_call_insn (gen_call_internal (dest)); |
382 DONE; | 415 DONE; |
383 } | 416 } |
384 ) | 417 ) |
385 | 418 |
386 (define_insn "call_internal" | 419 (define_insn "call_internal" |
387 [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol")) | 420 [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol")) |
388 (match_operand:SI 1 "general_operand" "g,g"))] | 421 (const_int 0)) |
422 (clobber (reg:CC CC_REG))] | |
389 "" | 423 "" |
390 "@ | 424 "@ |
391 jsr\t%0 | 425 jsr\t%0 |
392 bsr\t%A0" | 426 bsr\t%A0" |
393 [(set_attr "length" "2,4") | 427 [(set_attr "length" "2,4") |
402 { | 436 { |
403 rtx dest = XEXP (operands[1], 0); | 437 rtx dest = XEXP (operands[1], 0); |
404 | 438 |
405 if (! rx_call_operand (dest, Pmode)) | 439 if (! rx_call_operand (dest, Pmode)) |
406 dest = force_reg (Pmode, dest); | 440 dest = force_reg (Pmode, dest); |
407 emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2])); | 441 emit_call_insn (gen_call_value_internal (operands[0], dest)); |
408 DONE; | 442 DONE; |
409 } | 443 } |
410 ) | 444 ) |
411 | 445 |
412 (define_insn "call_value_internal" | 446 (define_insn "call_value_internal" |
413 [(set (match_operand 0 "register_operand" "=r,r") | 447 [(set (match_operand 0 "register_operand" "=r,r") |
414 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol")) | 448 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol")) |
415 (match_operand:SI 2 "general_operand" "g,g")))] | 449 (const_int 0))) |
450 (clobber (reg:CC CC_REG))] | |
416 "" | 451 "" |
417 "@ | 452 "@ |
418 jsr\t%1 | 453 jsr\t%1 |
419 bsr\t%A1" | 454 bsr\t%A1" |
420 [(set_attr "length" "2,4") | 455 [(set_attr "length" "2,4") |
433 (return)])] | 468 (return)])] |
434 "" | 469 "" |
435 { | 470 { |
436 if (MEM_P (operands[0])) | 471 if (MEM_P (operands[0])) |
437 operands[0] = XEXP (operands[0], 0); | 472 operands[0] = XEXP (operands[0], 0); |
473 emit_call_insn (gen_sibcall_internal (operands[0])); | |
474 DONE; | |
438 } | 475 } |
439 ) | 476 ) |
440 | 477 |
441 (define_insn "sibcall_internal" | 478 (define_insn "sibcall_internal" |
442 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol")) | 479 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol")) |
443 (match_operand:SI 1 "general_operand" "g")) | 480 (const_int 0)) |
444 (return)] | 481 (return)] |
445 "" | 482 "" |
446 "bra\t%A0" | 483 "bra\t%A0" |
447 [(set_attr "length" "4") | 484 [(set_attr "length" "4") |
448 (set_attr "timings" "33")] | 485 (set_attr "timings" "33")] |
456 (return)])] | 493 (return)])] |
457 "" | 494 "" |
458 { | 495 { |
459 if (MEM_P (operands[1])) | 496 if (MEM_P (operands[1])) |
460 operands[1] = XEXP (operands[1], 0); | 497 operands[1] = XEXP (operands[1], 0); |
498 emit_call_insn (gen_sibcall_value_internal (operands[0], operands[1])); | |
499 DONE; | |
461 } | 500 } |
462 ) | 501 ) |
463 | 502 |
464 (define_insn "sibcall_value_internal" | 503 (define_insn "sibcall_value_internal" |
465 [(set (match_operand 0 "register_operand" "=r") | 504 [(set (match_operand 0 "register_operand" "=r") |
466 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol")) | 505 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol")) |
467 (match_operand:SI 2 "general_operand" "g"))) | 506 (const_int 0))) |
468 (return)] | 507 (return)] |
469 "" | 508 "" |
470 "bra\t%A1" | 509 "bra\t%A1" |
471 [(set_attr "length" "4") | 510 [(set_attr "length" "4") |
472 (set_attr "timings" "33")] | 511 (set_attr "timings" "33")] |
514 (match_operand:register_modes 1 "general_operand"))] | 553 (match_operand:register_modes 1 "general_operand"))] |
515 "" | 554 "" |
516 { | 555 { |
517 if (MEM_P (operand0) && MEM_P (operand1)) | 556 if (MEM_P (operand0) && MEM_P (operand1)) |
518 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1); | 557 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1); |
558 if (CONST_INT_P (operand1) | |
559 && ! rx_is_legitimate_constant (operand1)) | |
560 FAIL; | |
519 } | 561 } |
520 ) | 562 ) |
521 | 563 |
522 (define_insn "*mov<register_modes:mode>_internal" | 564 (define_insn "*mov<register_modes:mode>_internal" |
523 [(set (match_operand:register_modes | 565 [(set (match_operand:register_modes |
549 [(set_attr "length" "2,4") | 591 [(set_attr "length" "2,4") |
550 (set_attr "timings" "11,12")] | 592 (set_attr "timings" "11,12")] |
551 ) | 593 ) |
552 | 594 |
553 (define_insn "stack_push" | 595 (define_insn "stack_push" |
554 [(set:SI (reg:SI SP_REG) | 596 [(set (reg:SI SP_REG) |
555 (minus:SI (reg:SI SP_REG) | 597 (minus:SI (reg:SI SP_REG) |
556 (const_int 4))) | 598 (const_int 4))) |
557 (set:SI (mem:SI (reg:SI SP_REG)) | 599 (set (mem:SI (reg:SI SP_REG)) |
558 (match_operand:SI 0 "register_operand" "r"))] | 600 (match_operand:SI 0 "register_operand" "r"))] |
559 "" | 601 "" |
560 "push.l\t%0" | 602 "push.l\t%0" |
561 [(set_attr "length" "2")] | 603 [(set_attr "length" "2")] |
562 ) | 604 ) |
563 | 605 |
564 (define_insn "stack_pushm" | 606 (define_insn "stack_pushm" |
565 [(match_parallel 1 "rx_store_multiple_vector" | 607 [(match_parallel 1 "rx_store_multiple_vector" |
566 [(set:SI (reg:SI SP_REG) | 608 [(set (reg:SI SP_REG) |
567 (minus:SI (reg:SI SP_REG) | 609 (minus:SI (reg:SI SP_REG) |
568 (match_operand:SI | 610 (match_operand:SI 0 "const_int_operand" "n")))])] |
569 0 "const_int_operand" "n")))])] | |
570 "reload_completed" | 611 "reload_completed" |
571 { | 612 { |
572 rx_emit_stack_pushm (operands); | 613 rx_emit_stack_pushm (operands); |
573 return ""; | 614 return ""; |
574 } | 615 } |
575 [(set_attr "length" "2") | 616 [(set_attr "length" "2") |
576 (set_attr "timings" "44")] ;; The timing is a guesstimate average timing. | 617 (set_attr "timings" "44")] ;; The timing is a guesstimate average timing. |
577 ) | 618 ) |
578 | 619 |
579 (define_insn "stack_pop" | 620 (define_insn "stack_pop" |
580 [(set:SI (match_operand:SI 0 "register_operand" "=r") | 621 [(set (match_operand:SI 0 "register_operand" "=r") |
581 (mem:SI (reg:SI SP_REG))) | 622 (mem:SI (reg:SI SP_REG))) |
582 (set:SI (reg:SI SP_REG) | 623 (set (reg:SI SP_REG) |
583 (plus:SI (reg:SI SP_REG) | 624 (plus:SI (reg:SI SP_REG) |
584 (const_int 4)))] | 625 (const_int 4)))] |
585 "" | 626 "" |
586 "pop\t%0" | 627 "pop\t%0" |
587 [(set_attr "length" "2") | 628 [(set_attr "length" "2") |
588 (set_attr "timings" "12")] | 629 (set_attr "timings" "12")] |
589 ) | 630 ) |
590 | 631 |
591 (define_insn "stack_popm" | 632 (define_insn "stack_popm" |
592 [(match_parallel 1 "rx_load_multiple_vector" | 633 [(match_parallel 1 "rx_load_multiple_vector" |
593 [(set:SI (reg:SI SP_REG) | 634 [(set (reg:SI SP_REG) |
594 (plus:SI (reg:SI SP_REG) | 635 (plus:SI (reg:SI SP_REG) |
595 (match_operand:SI | 636 (match_operand:SI 0 "const_int_operand" "n")))])] |
596 0 "const_int_operand" "n")))])] | |
597 "reload_completed" | 637 "reload_completed" |
598 { | 638 { |
599 rx_emit_stack_popm (operands, true); | 639 rx_emit_stack_popm (operands, true); |
600 return ""; | 640 return ""; |
601 } | 641 } |
602 [(set_attr "length" "2") | 642 [(set_attr "length" "2") |
603 (set_attr "timings" "45")] ;; The timing is a guesstimate average timing. | 643 (set_attr "timings" "45")] ;; The timing is a guesstimate average timing. |
604 ) | 644 ) |
605 | 645 |
606 (define_insn "cstoresi4" | 646 (define_insn_and_split "cstoresi4" |
607 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") | 647 [(set (match_operand:SI 0 "register_operand" "=r") |
608 (match_operator:SI | 648 (match_operator:SI 1 "comparison_operator" |
609 1 "comparison_operator" | 649 [(match_operand:SI 2 "register_operand" "r") |
610 [(match_operand:SI | 650 (match_operand:SI 3 "rx_source_operand" "riQ")])) |
611 2 "register_operand" "r,r,r,r,r,r,r") | 651 (clobber (reg:CC CC_REG))] |
612 (match_operand:SI | 652 "" |
613 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))] | 653 "#" |
614 "" | 654 "reload_completed" |
615 { | 655 [(const_int 0)] |
616 rx_float_compare_mode = false; | 656 { |
617 return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0"; | 657 rtx flags, x; |
618 } | 658 |
619 [(set_attr "cc" "set_zsoc") | 659 flags = gen_rtx_REG (CCmode, CC_REG); |
620 (set_attr "timings" "22,22,22,22,22,22,44") | 660 x = gen_rtx_COMPARE (CCmode, operands[2], operands[3]); |
621 (set_attr "length" "5,5,6,7,8,9,8")] | 661 x = gen_rtx_SET (VOIDmode, flags, x); |
622 ) | 662 emit_insn (x); |
663 | |
664 x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx); | |
665 x = gen_rtx_SET (VOIDmode, operands[0], x); | |
666 emit_insn (x); | |
667 DONE; | |
668 }) | |
669 | |
670 (define_insn "*sccc" | |
671 [(set (match_operand:SI 0 "register_operand" "=r") | |
672 (match_operator:SI 1 "comparison_operator" | |
673 [(reg CC_REG) (const_int 0)]))] | |
674 "reload_completed" | |
675 "sc%B1.L\t%0" | |
676 [(set_attr "length" "3")] | |
677 ) | |
678 | |
679 (define_insn_and_split "cstoresf4" | |
680 [(set (match_operand:SI 0 "register_operand" "=r") | |
681 (match_operator:SI 1 "rx_fp_comparison_operator" | |
682 [(match_operand:SF 2 "register_operand" "r") | |
683 (match_operand:SF 3 "rx_source_operand" "rFQ")]))] | |
684 "ALLOW_RX_FPU_INSNS" | |
685 "#" | |
686 "reload_completed" | |
687 [(const_int 0)] | |
688 { | |
689 rtx flags, x; | |
690 | |
691 flags = gen_rtx_REG (CC_Fmode, CC_REG); | |
692 x = gen_rtx_COMPARE (CC_Fmode, operands[2], operands[3]); | |
693 x = gen_rtx_SET (VOIDmode, flags, x); | |
694 emit_insn (x); | |
695 | |
696 x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx); | |
697 x = gen_rtx_SET (VOIDmode, operands[0], x); | |
698 emit_insn (x); | |
699 DONE; | |
700 }) | |
623 | 701 |
624 (define_expand "movsicc" | 702 (define_expand "movsicc" |
625 [(set (match_operand:SI 0 "register_operand") | 703 [(parallel |
626 (if_then_else:SI (match_operand:SI 1 "comparison_operator") | 704 [(set (match_operand:SI 0 "register_operand") |
627 (match_operand:SI 2 "nonmemory_operand") | 705 (if_then_else:SI (match_operand:SI 1 "comparison_operator") |
628 (match_operand:SI 3 "immediate_operand")))] | 706 (match_operand:SI 2 "nonmemory_operand") |
629 "" | 707 (match_operand:SI 3 "nonmemory_operand"))) |
630 { | 708 (clobber (reg:CC CC_REG))])] |
631 if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE) | 709 "" |
632 FAIL; | 710 { |
633 if (! CONST_INT_P (operands[3])) | 711 /* ??? Support other conditions via cstore into a temporary? */ |
634 FAIL; | 712 if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE) |
635 } | 713 FAIL; |
636 ) | 714 /* One operand must be a constant. */ |
637 | 715 if (!CONSTANT_P (operands[2]) && !CONSTANT_P (operands[3])) |
638 (define_insn "*movsieq" | 716 FAIL; |
639 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | 717 }) |
640 (if_then_else:SI (eq (match_operand:SI | 718 |
641 3 "register_operand" "r,r,r") | 719 (define_insn_and_split "*movsicc" |
642 (match_operand:SI | 720 [(set (match_operand:SI 0 "register_operand" "=r,r") |
643 4 "rx_source_operand" "riQ,riQ,riQ")) | 721 (if_then_else:SI |
644 (match_operand:SI | 722 (match_operator 5 "rx_z_comparison_operator" |
645 1 "nonmemory_operand" "0,i,r") | 723 [(match_operand:SI 3 "register_operand" "r,r") |
646 (match_operand:SI | 724 (match_operand:SI 4 "rx_source_operand" "riQ,riQ")]) |
647 2 "immediate_operand" "i,i,i")))] | 725 (match_operand:SI 1 "nonmemory_operand" "i,ri") |
648 "" | 726 (match_operand:SI 2 "nonmemory_operand" "ri,i"))) |
649 "@ | 727 (clobber (reg:CC CC_REG))] |
650 cmp\t%Q4, %Q3\n\tstnz\t%2, %0 | 728 "CONSTANT_P (operands[1]) || CONSTANT_P (operands[2])" |
651 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0 | 729 "#" |
652 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0" | 730 "&& reload_completed" |
653 [(set_attr "cc" "set_zsoc") | 731 [(const_int 0)] |
654 (set_attr "length" "13,19,15") | 732 { |
655 (set_attr "timings" "22,33,33")] | 733 rtx x, flags, op0, op1, op2; |
656 ) | 734 enum rtx_code cmp_code; |
657 | 735 |
658 (define_insn "*movsine" | 736 flags = gen_rtx_REG (CCmode, CC_REG); |
659 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | 737 x = gen_rtx_COMPARE (CCmode, operands[3], operands[4]); |
660 (if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r") | 738 emit_insn (gen_rtx_SET (VOIDmode, flags, x)); |
661 (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ")) | 739 |
662 (match_operand:SI 1 "nonmemory_operand" "0,i,r") | 740 cmp_code = GET_CODE (operands[5]); |
663 (match_operand:SI 2 "immediate_operand" "i,i,i")))] | 741 op0 = operands[0]; |
664 "" | 742 op1 = operands[1]; |
665 "@ | 743 op2 = operands[2]; |
666 cmp\t%Q4, %Q3\n\tstz\t%2, %0 | 744 |
667 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0 | 745 /* If OP2 is the constant, reverse the sense of the move. */ |
668 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0" | 746 if (!CONSTANT_P (operands[1])) |
669 [(set_attr "cc" "set_zsoc") | 747 { |
670 (set_attr "length" "13,19,15") | 748 x = op1, op1 = op2, op2 = x; |
671 (set_attr "timings" "22,33,33")] | 749 cmp_code = reverse_condition (cmp_code); |
750 } | |
751 | |
752 /* If OP2 does not match the output, copy it into place. We have allowed | |
753 these alternatives so that the destination can legitimately be one of | |
754 the comparison operands without increasing register pressure. */ | |
755 if (!rtx_equal_p (op0, op2)) | |
756 emit_move_insn (op0, op2); | |
757 | |
758 x = gen_rtx_fmt_ee (cmp_code, VOIDmode, flags, const0_rtx); | |
759 x = gen_rtx_IF_THEN_ELSE (SImode, x, op1, op0); | |
760 emit_insn (gen_rtx_SET (VOIDmode, op0, x)); | |
761 DONE; | |
762 }) | |
763 | |
764 (define_insn "*stcc" | |
765 [(set (match_operand:SI 0 "register_operand" "+r,r,r,r") | |
766 (if_then_else:SI | |
767 (match_operator 2 "rx_z_comparison_operator" | |
768 [(reg CC_REG) (const_int 0)]) | |
769 (match_operand:SI 1 "immediate_operand" "Sint08,Sint16,Sint24,i") | |
770 (match_dup 0)))] | |
771 "reload_completed" | |
772 { | |
773 if (GET_CODE (operands[2]) == EQ) | |
774 return "stz\t%1, %0"; | |
775 else | |
776 return "stnz\t%1, %0"; | |
777 } | |
778 [(set_attr "length" "4,5,6,7")] | |
672 ) | 779 ) |
673 | 780 |
674 ;; Arithmetic Instructions | 781 ;; Arithmetic Instructions |
675 | 782 |
676 (define_insn "abssi2" | 783 (define_insn "abssi2" |
677 [(set (match_operand:SI 0 "register_operand" "=r,r") | 784 [(set (match_operand:SI 0 "register_operand" "=r,r") |
678 (abs:SI (match_operand:SI 1 "register_operand" "0,r")))] | 785 (abs:SI (match_operand:SI 1 "register_operand" "0,r"))) |
786 (clobber (reg:CC CC_REG))] | |
679 "" | 787 "" |
680 "@ | 788 "@ |
681 abs\t%0 | 789 abs\t%0 |
682 abs\t%1, %0" | 790 abs\t%1, %0" |
683 [(set_attr "cc" "set_zso") | 791 [(set_attr "length" "2,3")] |
684 (set_attr "length" "2,3")] | 792 ) |
793 | |
794 (define_insn "*abssi2_flags" | |
795 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
796 (abs:SI (match_operand:SI 1 "register_operand" "0,r"))) | |
797 (set (reg CC_REG) | |
798 (compare (abs:SI (match_dup 1)) | |
799 (const_int 0)))] | |
800 ;; Note - although the ABS instruction does set the O bit in the processor | |
801 ;; status word, it does not do so in a way that is comparable with the CMP | |
802 ;; instruction. Hence we use CC_ZSmode rather than CC_ZSOmode. | |
803 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
804 "@ | |
805 abs\t%0 | |
806 abs\t%1, %0" | |
807 [(set_attr "length" "2,3")] | |
685 ) | 808 ) |
686 | 809 |
687 (define_insn "addsi3" | 810 (define_insn "addsi3" |
688 [(set (match_operand:SI 0 "register_operand" | 811 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r") |
689 "=r,r,r,r,r,r,r,r,r,r,r,r") | 812 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0") |
690 (plus:SI (match_operand:SI | 813 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q"))) |
691 1 "register_operand" | 814 (clobber (reg:CC CC_REG))] |
692 "%0,0,0,0,0,0,r,r,r,r,r,0") | |
693 (match_operand:SI | |
694 2 "rx_source_operand" | |
695 "r,Uint04,Sint08,Sint16,Sint24,i,r,Sint08,Sint16,Sint24,i,Q")))] | |
696 "" | 815 "" |
697 "@ | 816 "@ |
817 add\t%2, %0 | |
818 add\t%2, %0 | |
819 sub\t%N2, %0 | |
698 add\t%2, %0 | 820 add\t%2, %0 |
699 add\t%2, %0 | 821 add\t%2, %0 |
700 add\t%2, %0 | 822 add\t%2, %0 |
701 add\t%2, %0 | 823 add\t%2, %0 |
702 add\t%2, %0 | 824 add\t%1, %0 |
703 add\t%2, %0 | |
704 add\t%2, %1, %0 | 825 add\t%2, %1, %0 |
705 add\t%2, %1, %0 | 826 add\t%2, %1, %0 |
706 add\t%2, %1, %0 | 827 add\t%2, %1, %0 |
707 add\t%2, %1, %0 | 828 add\t%2, %1, %0 |
708 add\t%2, %1, %0 | 829 add\t%2, %1, %0 |
709 add\t%Q2, %0" | 830 add\t%Q2, %0" |
710 [(set_attr "cc" "set_zsoc") | 831 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33") |
711 (set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,33") | 832 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")] |
712 (set_attr "length" "2,2,3,4,5,6,3,3,4,5,6,5")] | 833 ) |
713 ) | 834 |
714 | 835 (define_insn "*addsi3_flags" |
715 (define_insn "adddi3" | 836 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r") |
716 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") | 837 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0") |
717 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0") | 838 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q"))) |
718 (match_operand:DI 2 "rx_source_operand" | 839 (set (reg CC_REG) |
719 "r,Sint08,Sint16,Sint24,i,Q")))] | 840 (compare (plus:SI (match_dup 1) (match_dup 2)) |
720 "" | 841 (const_int 0)))] |
721 "add\t%L2, %L0\n\tadc\t%H2, %H0" | 842 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)" |
722 [(set_attr "cc" "set_zsoc") | 843 "@ |
723 (set_attr "timings" "22,22,22,22,22,44") | 844 add\t%2, %0 |
724 (set_attr "length" "5,7,9,11,13,11")] | 845 add\t%2, %0 |
725 ) | 846 sub\t%N2, %0 |
847 add\t%2, %0 | |
848 add\t%2, %0 | |
849 add\t%2, %0 | |
850 add\t%2, %0 | |
851 add\t%1, %0 | |
852 add\t%2, %1, %0 | |
853 add\t%2, %1, %0 | |
854 add\t%2, %1, %0 | |
855 add\t%2, %1, %0 | |
856 add\t%2, %1, %0 | |
857 add\t%Q2, %0" | |
858 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33") | |
859 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")] | |
860 ) | |
861 | |
862 ;; A helper to expand the above with the CC_MODE filled in. | |
863 (define_expand "addsi3_flags" | |
864 [(parallel [(set (match_operand:SI 0 "register_operand") | |
865 (plus:SI (match_operand:SI 1 "register_operand") | |
866 (match_operand:SI 2 "rx_source_operand"))) | |
867 (set (reg:CC_ZSC CC_REG) | |
868 (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2)) | |
869 (const_int 0)))])] | |
870 ) | |
871 | |
872 (define_insn "adc_internal" | |
873 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") | |
874 (plus:SI | |
875 (plus:SI | |
876 (ltu:SI (reg:CC CC_REG) (const_int 0)) | |
877 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")) | |
878 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))) | |
879 (clobber (reg:CC CC_REG))] | |
880 "reload_completed" | |
881 "adc %2,%0" | |
882 [(set_attr "timings" "11,11,11,11,11,33") | |
883 (set_attr "length" "3,4,5,6,7,6")] | |
884 ) | |
885 | |
886 (define_insn "*adc_flags" | |
887 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") | |
888 (plus:SI | |
889 (plus:SI | |
890 (ltu:SI (reg:CC CC_REG) (const_int 0)) | |
891 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")) | |
892 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))) | |
893 (set (reg CC_REG) | |
894 (compare | |
895 (plus:SI | |
896 (plus:SI | |
897 (ltu:SI (reg:CC CC_REG) (const_int 0)) | |
898 (match_dup 1)) | |
899 (match_dup 2)) | |
900 (const_int 0)))] | |
901 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)" | |
902 "adc %2,%0" | |
903 [(set_attr "timings" "11,11,11,11,11,33") | |
904 (set_attr "length" "3,4,5,6,7,6")] | |
905 ) | |
906 | |
907 (define_expand "adddi3" | |
908 [(set (match_operand:DI 0 "register_operand") | |
909 (plus:DI (match_operand:DI 1 "register_operand") | |
910 (match_operand:DI 2 "rx_source_operand")))] | |
911 "" | |
912 { | |
913 rtx op0l, op0h, op1l, op1h, op2l, op2h; | |
914 | |
915 op0l = gen_lowpart (SImode, operands[0]); | |
916 op1l = gen_lowpart (SImode, operands[1]); | |
917 op2l = gen_lowpart (SImode, operands[2]); | |
918 op0h = gen_highpart (SImode, operands[0]); | |
919 op1h = gen_highpart (SImode, operands[1]); | |
920 op2h = gen_highpart_mode (SImode, DImode, operands[2]); | |
921 | |
922 emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h)); | |
923 DONE; | |
924 }) | |
925 | |
926 (define_insn_and_split "adddi3_internal" | |
927 [(set (match_operand:SI 0 "register_operand" "=r") | |
928 (plus:SI (match_operand:SI 2 "register_operand" "r") | |
929 (match_operand:SI 3 "rx_source_operand" "riQ"))) | |
930 (set (match_operand:SI 1 "register_operand" "=r") | |
931 (plus:SI | |
932 (plus:SI | |
933 (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2)) | |
934 (match_operand:SI 4 "register_operand" "%1")) | |
935 (match_operand:SI 5 "rx_source_operand" "riQ"))) | |
936 (clobber (match_scratch:SI 6 "=&r")) | |
937 (clobber (reg:CC CC_REG))] | |
938 "" | |
939 "#" | |
940 "reload_completed" | |
941 [(const_int 0)] | |
942 { | |
943 rtx op0l = operands[0]; | |
944 rtx op0h = operands[1]; | |
945 rtx op1l = operands[2]; | |
946 rtx op2l = operands[3]; | |
947 rtx op1h = operands[4]; | |
948 rtx op2h = operands[5]; | |
949 rtx scratch = operands[6]; | |
950 rtx x; | |
951 | |
952 if (reg_overlap_mentioned_p (op0l, op1h)) | |
953 { | |
954 emit_move_insn (scratch, op0l); | |
955 op1h = scratch; | |
956 if (reg_overlap_mentioned_p (op0l, op2h)) | |
957 op2h = scratch; | |
958 } | |
959 else if (reg_overlap_mentioned_p (op0l, op2h)) | |
960 { | |
961 emit_move_insn (scratch, op0l); | |
962 op2h = scratch; | |
963 } | |
964 | |
965 if (rtx_equal_p (op0l, op1l)) | |
966 ; | |
967 /* It is preferable that op0l == op1l... */ | |
968 else if (rtx_equal_p (op0l, op2l)) | |
969 x = op1l, op1l = op2l, op2l = x; | |
970 /* ... but it is only a requirement if op2l == MEM. */ | |
971 else if (MEM_P (op2l)) | |
972 { | |
973 /* Let's hope that we still have a scratch register free. */ | |
974 gcc_assert (op1h != scratch); | |
975 emit_move_insn (scratch, op2l); | |
976 op2l = scratch; | |
977 } | |
978 | |
979 emit_insn (gen_addsi3_flags (op0l, op1l, op2l)); | |
980 | |
981 if (rtx_equal_p (op0h, op1h)) | |
982 ; | |
983 else if (rtx_equal_p (op0h, op2h)) | |
984 x = op1h, op1h = op2h, op2h = x; | |
985 else | |
986 { | |
987 emit_move_insn (op0h, op1h); | |
988 op1h = op0h; | |
989 } | |
990 emit_insn (gen_adc_internal (op0h, op1h, op2h)); | |
991 DONE; | |
992 }) | |
726 | 993 |
727 (define_insn "andsi3" | 994 (define_insn "andsi3" |
728 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") | 995 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") |
729 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,0,Q") | 996 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") |
730 (match_operand:SI | 997 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))) |
731 2 "rx_source_operand" | 998 (clobber (reg:CC CC_REG))] |
732 "r,Uint04,Sint08,Sint16,Sint24,i,r,Q,0")))] | |
733 "" | 999 "" |
734 "@ | 1000 "@ |
735 and\t%2, %0 | 1001 and\t%2, %0 |
736 and\t%2, %0 | 1002 and\t%2, %0 |
737 and\t%2, %0 | 1003 and\t%2, %0 |
738 and\t%2, %0 | 1004 and\t%2, %0 |
739 and\t%2, %0 | 1005 and\t%2, %0 |
740 and\t%2, %0 | 1006 and\t%2, %0 |
1007 and\t%1, %0 | |
741 and\t%2, %1, %0 | 1008 and\t%2, %1, %0 |
742 and\t%Q2, %0 | 1009 and\t%Q2, %0" |
743 and\t%Q1, %0" | 1010 [(set_attr "timings" "11,11,11,11,11,11,11,11,33") |
744 [(set_attr "cc" "set_zs") | 1011 (set_attr "length" "2,2,3,4,5,6,2,5,5")] |
745 (set_attr "timings" "11,11,11,11,11,11,11,33,33") | 1012 ) |
746 (set_attr "length" "2,2,3,4,5,6,3,5,5")] | 1013 |
1014 (define_insn "*andsi3_flags" | |
1015 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") | |
1016 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") | |
1017 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))) | |
1018 (set (reg CC_REG) | |
1019 (compare (and:SI (match_dup 1) (match_dup 2)) | |
1020 (const_int 0)))] | |
1021 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1022 "@ | |
1023 and\t%2, %0 | |
1024 and\t%2, %0 | |
1025 and\t%2, %0 | |
1026 and\t%2, %0 | |
1027 and\t%2, %0 | |
1028 and\t%2, %0 | |
1029 and\t%1, %0 | |
1030 and\t%2, %1, %0 | |
1031 and\t%Q2, %0" | |
1032 [(set_attr "timings" "11,11,11,11,11,11,11,11,33") | |
1033 (set_attr "length" "2,2,3,4,5,6,2,5,5")] | |
747 ) | 1034 ) |
748 | 1035 |
749 ;; Byte swap (single 32-bit value). | 1036 ;; Byte swap (single 32-bit value). |
750 (define_insn "bswapsi2" | 1037 (define_insn "bswapsi2" |
751 [(set (match_operand:SI 0 "register_operand" "+r") | 1038 [(set (match_operand:SI 0 "register_operand" "=r") |
752 (bswap:SI (match_operand:SI 1 "register_operand" "r")))] | 1039 (bswap:SI (match_operand:SI 1 "register_operand" "r")))] |
753 "" | 1040 "" |
754 "revl\t%1, %0" | 1041 "revl\t%1, %0" |
755 [(set_attr "length" "3")] | 1042 [(set_attr "length" "3")] |
756 ) | 1043 ) |
757 | 1044 |
758 ;; Byte swap (single 16-bit value). Note - we ignore the swapping of the high 16-bits. | 1045 ;; Byte swap (single 16-bit value). Note - we ignore the swapping of the high 16-bits. |
759 (define_insn "bswaphi2" | 1046 (define_insn "bswaphi2" |
760 [(set (match_operand:HI 0 "register_operand" "+r") | 1047 [(set (match_operand:HI 0 "register_operand" "=r") |
761 (bswap:HI (match_operand:HI 1 "register_operand" "r")))] | 1048 (bswap:HI (match_operand:HI 1 "register_operand" "r")))] |
762 "" | 1049 "" |
763 "revw\t%1, %0" | 1050 "revw\t%1, %0" |
764 [(set_attr "length" "3")] | 1051 [(set_attr "length" "3")] |
765 ) | 1052 ) |
766 | 1053 |
767 (define_insn "divsi3" | 1054 (define_insn "divsi3" |
768 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") | 1055 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") |
769 (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0") | 1056 (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0") |
770 (match_operand:SI | 1057 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))) |
771 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))] | 1058 (clobber (reg:CC CC_REG))] |
772 "" | 1059 "" |
773 "div\t%Q2, %0" | 1060 "div\t%Q2, %0" |
774 [(set_attr "cc" "clobber") | 1061 [(set_attr "timings" "1111") ;; Strictly speaking the timing should be |
775 (set_attr "timings" "1111") ;; Strictly speaking the timing should be | |
776 ;; 2222, but that is a worst case sceanario. | 1062 ;; 2222, but that is a worst case sceanario. |
777 (set_attr "length" "3,4,5,6,7,6")] | 1063 (set_attr "length" "3,4,5,6,7,6")] |
778 ) | 1064 ) |
779 | 1065 |
780 (define_insn "udivsi3" | 1066 (define_insn "udivsi3" |
781 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") | 1067 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") |
782 (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0") | 1068 (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0") |
783 (match_operand:SI | 1069 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))) |
784 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))] | 1070 (clobber (reg:CC CC_REG))] |
785 "" | 1071 "" |
786 "divu\t%Q2, %0" | 1072 "divu\t%Q2, %0" |
787 [(set_attr "cc" "clobber") | 1073 [(set_attr "timings" "1010") ;; Strictly speaking the timing should be |
788 (set_attr "timings" "1010") ;; Strictly speaking the timing should be | |
789 ;; 2020, but that is a worst case sceanario. | 1074 ;; 2020, but that is a worst case sceanario. |
790 (set_attr "length" "3,4,5,6,7,6")] | 1075 (set_attr "length" "3,4,5,6,7,6")] |
791 ) | 1076 ) |
792 | 1077 |
793 ;; Note - these patterns are suppressed in big-endian mode because they | 1078 ;; Note - these patterns are suppressed in big-endian mode because they |
801 1 "register_operand" "%0,0,0,0,0,0")) | 1086 1 "register_operand" "%0,0,0,0,0,0")) |
802 (sign_extend:DI (match_operand:SI | 1087 (sign_extend:DI (match_operand:SI |
803 2 "rx_source_operand" | 1088 2 "rx_source_operand" |
804 "r,Sint08,Sint16,Sint24,i,Q"))))] | 1089 "r,Sint08,Sint16,Sint24,i,Q"))))] |
805 "! TARGET_BIG_ENDIAN_DATA" | 1090 "! TARGET_BIG_ENDIAN_DATA" |
806 "@ | 1091 "emul\t%Q2, %0" |
807 emul\t%Q2, %0 | |
808 emul\t%Q2, %0 | |
809 emul\t%Q2, %0 | |
810 emul\t%Q2, %0 | |
811 emul\t%Q2, %0 | |
812 emul\t%Q2, %0" | |
813 [(set_attr "length" "3,4,5,6,7,6") | 1092 [(set_attr "length" "3,4,5,6,7,6") |
814 (set_attr "timings" "22,22,22,22,22,44")] | 1093 (set_attr "timings" "22,22,22,22,22,44")] |
815 ) | 1094 ) |
816 | 1095 |
817 ;; See comment for mulsidi3. | 1096 ;; See comment for mulsidi3. |
818 ;; Note - the zero_extends are to distinguish this pattern from the | 1097 ;; Note - the zero_extends are to distinguish this pattern from the |
819 ;; mulsidi3 pattern. Immediate mode addressing is not supported | 1098 ;; mulsidi3 pattern. Immediate mode addressing is not supported |
820 ;; because gcc cannot handle the expression: (zero_extend (const_int)). | 1099 ;; because gcc cannot handle the expression: (zero_extend (const_int)). |
821 (define_insn "umulsidi3" | 1100 (define_insn "umulsidi3" |
822 [(set (match_operand:DI 0 "register_operand" | 1101 [(set (match_operand:DI 0 "register_operand" "=r,r") |
823 "=r,r") | 1102 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0")) |
824 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" | 1103 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))] |
825 "%0,0")) | |
826 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" | |
827 "r,Q"))))] | |
828 "! TARGET_BIG_ENDIAN_DATA" | 1104 "! TARGET_BIG_ENDIAN_DATA" |
829 "@ | 1105 "emulu\t%Q2, %0" |
830 emulu\t%Q2, %0 | |
831 emulu\t%Q2, %0" | |
832 [(set_attr "length" "3,6") | 1106 [(set_attr "length" "3,6") |
833 (set_attr "timings" "22,44")] | 1107 (set_attr "timings" "22,44")] |
834 ) | 1108 ) |
835 | 1109 |
836 (define_insn "smaxsi3" | 1110 (define_insn "smaxsi3" |
848 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") | 1122 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") |
849 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") | 1123 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") |
850 (match_operand:SI 2 "rx_source_operand" | 1124 (match_operand:SI 2 "rx_source_operand" |
851 "r,Sint08,Sint16,Sint24,i,Q")))] | 1125 "r,Sint08,Sint16,Sint24,i,Q")))] |
852 "" | 1126 "" |
853 "@ | 1127 "min\t%Q2, %0" |
854 min\t%Q2, %0 | |
855 min\t%Q2, %0 | |
856 min\t%Q2, %0 | |
857 min\t%Q2, %0 | |
858 min\t%Q2, %0 | |
859 min\t%Q2, %0" | |
860 [(set_attr "length" "3,4,5,6,7,6") | 1128 [(set_attr "length" "3,4,5,6,7,6") |
861 (set_attr "timings" "11,11,11,11,11,33")] | 1129 (set_attr "timings" "11,11,11,11,11,33")] |
862 ) | 1130 ) |
863 | 1131 |
864 (define_insn "mulsi3" | 1132 (define_insn "mulsi3" |
865 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") | 1133 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") |
866 (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,Q,r") | 1134 (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r") |
867 (match_operand:SI 2 "rx_source_operand" | 1135 (match_operand:SI 2 "rx_source_operand" |
868 "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))] | 1136 "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))] |
869 "" | 1137 "" |
870 "@ | 1138 "@ |
1139 mul\t%2, %0 | |
1140 mul\t%2, %0 | |
1141 mul\t%2, %0 | |
1142 mul\t%2, %0 | |
1143 mul\t%2, %0 | |
871 mul\t%Q2, %0 | 1144 mul\t%Q2, %0 |
872 mul\t%Q2, %0 | 1145 mul\t%Q2, %0 |
873 mul\t%Q2, %0 | 1146 mul\t%1, %0 |
874 mul\t%Q2, %0 | 1147 mul\t%2, %1, %0" |
875 mul\t%Q2, %0 | 1148 [(set_attr "length" "2,2,3,4,5,6,5,2,3") |
876 mul\t%Q2, %0 | 1149 (set_attr "timings" "11,11,11,11,11,11,33,11,11")] |
877 mul\t%Q2, %0 | |
878 mul\t%Q1, %0 | |
879 mul\t%Q2, %1, %0" | |
880 [(set_attr "length" "2,2,3,4,5,6,5,5,3") | |
881 (set_attr "timings" "11,11,11,11,11,11,33,33,11")] | |
882 ) | 1150 ) |
883 | 1151 |
884 (define_insn "negsi2" | 1152 (define_insn "negsi2" |
885 [(set (match_operand:SI 0 "register_operand" "=r,r") | 1153 [(set (match_operand:SI 0 "register_operand" "=r,r") |
886 (neg:SI (match_operand:SI 1 "register_operand" "0,r")))] | 1154 (neg:SI (match_operand:SI 1 "register_operand" "0,r"))) |
887 ;; The NEG instruction does not comply with -fwrapv semantics. | 1155 (clobber (reg:CC CC_REG))] |
888 ;; See gcc.c-torture/execute/pr22493-1.c for an example of this. | 1156 "" |
889 "! flag_wrapv" | |
890 "@ | 1157 "@ |
891 neg\t%0 | 1158 neg\t%0 |
892 neg\t%1, %0" | 1159 neg\t%1, %0" |
893 [(set_attr "length" "2,3")] | 1160 [(set_attr "length" "2,3")] |
894 ) | 1161 ) |
895 | 1162 |
1163 ;; Note that the O and C flags are not set as per a normal compare, | |
1164 ;; and thus are unusable in that context. | |
1165 (define_insn "*negsi2_flags" | |
1166 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1167 (neg:SI (match_operand:SI 1 "register_operand" "0,r"))) | |
1168 (set (reg CC_REG) | |
1169 (compare (neg:SI (match_dup 1)) | |
1170 (const_int 0)))] | |
1171 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1172 "@ | |
1173 neg\t%0 | |
1174 neg\t%1, %0" | |
1175 [(set_attr "length" "2,3")] | |
1176 ) | |
1177 | |
896 (define_insn "one_cmplsi2" | 1178 (define_insn "one_cmplsi2" |
897 [(set (match_operand:SI 0 "register_operand" "=r,r") | 1179 [(set (match_operand:SI 0 "register_operand" "=r,r") |
898 (not:SI (match_operand:SI 1 "register_operand" "0,r")))] | 1180 (not:SI (match_operand:SI 1 "register_operand" "0,r"))) |
1181 (clobber (reg:CC CC_REG))] | |
899 "" | 1182 "" |
900 "@ | 1183 "@ |
901 not\t%0 | 1184 not\t%0 |
902 not\t%1, %0" | 1185 not\t%1, %0" |
903 [(set_attr "cc" "set_zs") | 1186 [(set_attr "length" "2,3")] |
904 (set_attr "length" "2,3")] | 1187 ) |
1188 | |
1189 (define_insn "*one_cmplsi2_flags" | |
1190 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1191 (not:SI (match_operand:SI 1 "register_operand" "0,r"))) | |
1192 (set (reg CC_REG) | |
1193 (compare (not:SI (match_dup 1)) | |
1194 (const_int 0)))] | |
1195 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1196 "@ | |
1197 not\t%0 | |
1198 not\t%1, %0" | |
1199 [(set_attr "length" "2,3")] | |
905 ) | 1200 ) |
906 | 1201 |
907 (define_insn "iorsi3" | 1202 (define_insn "iorsi3" |
908 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") | 1203 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") |
909 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,0,Q") | 1204 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") |
910 (match_operand:SI 2 "rx_source_operand" | 1205 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))) |
911 "r,Uint04,Sint08,Sint16,Sint24,i,r,Q,0")))] | 1206 (clobber (reg:CC CC_REG))] |
912 "" | 1207 "" |
913 "@ | 1208 "@ |
914 or\t%2, %0 | 1209 or\t%2, %0 |
915 or\t%2, %0 | 1210 or\t%2, %0 |
916 or\t%2, %0 | 1211 or\t%2, %0 |
917 or\t%2, %0 | 1212 or\t%2, %0 |
918 or\t%2, %0 | 1213 or\t%2, %0 |
1214 or\t%Q2, %0 | |
1215 or\t%1, %0 | |
1216 or\t%2, %1, %0 | |
1217 or\t%Q2, %0" | |
1218 [(set_attr "timings" "11,11,11,11,11,11,11,11,33") | |
1219 (set_attr "length" "2,2,3,4,5,6,2,3,5")] | |
1220 ) | |
1221 | |
1222 (define_insn "*iorsi3_flags" | |
1223 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") | |
1224 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") | |
1225 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))) | |
1226 (set (reg CC_REG) | |
1227 (compare (ior:SI (match_dup 1) (match_dup 2)) | |
1228 (const_int 0)))] | |
1229 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1230 "@ | |
919 or\t%2, %0 | 1231 or\t%2, %0 |
1232 or\t%2, %0 | |
1233 or\t%2, %0 | |
1234 or\t%2, %0 | |
1235 or\t%2, %0 | |
1236 or\t%Q2, %0 | |
1237 or\t%1, %0 | |
920 or\t%2, %1, %0 | 1238 or\t%2, %1, %0 |
921 or\t%Q2, %0 | 1239 or\t%Q2, %0" |
922 or\t%Q1, %0" | 1240 [(set_attr "timings" "11,11,11,11,11,11,11,11,33") |
923 [(set_attr "cc" "set_zs") | 1241 (set_attr "length" "2,2,3,4,5,6,2,3,5")] |
924 (set_attr "timings" "11,11,11,11,11,11,11,33,33") | |
925 (set_attr "length" "2,2,3,4,5,6,3,5,5")] | |
926 ) | 1242 ) |
927 | 1243 |
928 (define_insn "rotlsi3" | 1244 (define_insn "rotlsi3" |
929 [(set (match_operand:SI 0 "register_operand" "=r") | 1245 [(set (match_operand:SI 0 "register_operand" "=r") |
930 (rotate:SI (match_operand:SI 1 "register_operand" "0") | 1246 (rotate:SI (match_operand:SI 1 "register_operand" "0") |
931 (match_operand:SI 2 "rx_shift_operand" "rn")))] | 1247 (match_operand:SI 2 "rx_shift_operand" "rn"))) |
1248 (clobber (reg:CC CC_REG))] | |
932 "" | 1249 "" |
933 "rotl\t%2, %0" | 1250 "rotl\t%2, %0" |
934 [(set_attr "cc" "set_zs") | 1251 [(set_attr "length" "3")] |
935 (set_attr "length" "3")] | 1252 ) |
1253 | |
1254 (define_insn "*rotlsi3_flags" | |
1255 [(set (match_operand:SI 0 "register_operand" "=r") | |
1256 (rotate:SI (match_operand:SI 1 "register_operand" "0") | |
1257 (match_operand:SI 2 "rx_shift_operand" "rn"))) | |
1258 (set (reg CC_REG) | |
1259 (compare (rotate:SI (match_dup 1) (match_dup 2)) | |
1260 (const_int 0)))] | |
1261 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1262 "rotl\t%2, %0" | |
1263 [(set_attr "length" "3")] | |
936 ) | 1264 ) |
937 | 1265 |
938 (define_insn "rotrsi3" | 1266 (define_insn "rotrsi3" |
939 [(set (match_operand:SI 0 "register_operand" "=r") | 1267 [(set (match_operand:SI 0 "register_operand" "=r") |
940 (rotatert:SI (match_operand:SI 1 "register_operand" "0") | 1268 (rotatert:SI (match_operand:SI 1 "register_operand" "0") |
941 (match_operand:SI 2 "rx_shift_operand" "rn")))] | 1269 (match_operand:SI 2 "rx_shift_operand" "rn"))) |
1270 (clobber (reg:CC CC_REG))] | |
942 "" | 1271 "" |
943 "rotr\t%2, %0" | 1272 "rotr\t%2, %0" |
944 [(set_attr "cc" "set_zs") | 1273 [(set_attr "length" "3")] |
945 (set_attr "length" "3")] | 1274 ) |
1275 | |
1276 (define_insn "*rotrsi3_flags" | |
1277 [(set (match_operand:SI 0 "register_operand" "=r") | |
1278 (rotatert:SI (match_operand:SI 1 "register_operand" "0") | |
1279 (match_operand:SI 2 "rx_shift_operand" "rn"))) | |
1280 (set (reg CC_REG) | |
1281 (compare (rotatert:SI (match_dup 1) (match_dup 2)) | |
1282 (const_int 0)))] | |
1283 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1284 "rotr\t%2, %0" | |
1285 [(set_attr "length" "3")] | |
946 ) | 1286 ) |
947 | 1287 |
948 (define_insn "ashrsi3" | 1288 (define_insn "ashrsi3" |
949 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | 1289 [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
950 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") | 1290 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") |
951 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))] | 1291 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) |
1292 (clobber (reg:CC CC_REG))] | |
952 "" | 1293 "" |
953 "@ | 1294 "@ |
954 shar\t%2, %0 | 1295 shar\t%2, %0 |
955 shar\t%2, %0 | 1296 shar\t%2, %0 |
956 shar\t%2, %1, %0" | 1297 shar\t%2, %1, %0" |
957 [(set_attr "cc" "set_zsoc") | 1298 [(set_attr "length" "3,2,3")] |
958 (set_attr "length" "3,2,3")] | 1299 ) |
1300 | |
1301 (define_insn "*ashrsi3_flags" | |
1302 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1303 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") | |
1304 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) | |
1305 (set (reg CC_REG) | |
1306 (compare (ashiftrt:SI (match_dup 1) (match_dup 2)) | |
1307 (const_int 0)))] | |
1308 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1309 "@ | |
1310 shar\t%2, %0 | |
1311 shar\t%2, %0 | |
1312 shar\t%2, %1, %0" | |
1313 [(set_attr "length" "3,2,3")] | |
959 ) | 1314 ) |
960 | 1315 |
961 (define_insn "lshrsi3" | 1316 (define_insn "lshrsi3" |
962 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | 1317 [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
963 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") | 1318 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") |
964 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))] | 1319 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) |
1320 (clobber (reg:CC CC_REG))] | |
965 "" | 1321 "" |
966 "@ | 1322 "@ |
967 shlr\t%2, %0 | 1323 shlr\t%2, %0 |
968 shlr\t%2, %0 | 1324 shlr\t%2, %0 |
969 shlr\t%2, %1, %0" | 1325 shlr\t%2, %1, %0" |
970 [(set_attr "cc" "set_zsoc") | 1326 [(set_attr "length" "3,2,3")] |
971 (set_attr "length" "3,2,3")] | 1327 ) |
1328 | |
1329 (define_insn "*lshrsi3_flags" | |
1330 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1331 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") | |
1332 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) | |
1333 (set (reg CC_REG) | |
1334 (compare (lshiftrt:SI (match_dup 1) (match_dup 2)) | |
1335 (const_int 0)))] | |
1336 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1337 "@ | |
1338 shlr\t%2, %0 | |
1339 shlr\t%2, %0 | |
1340 shlr\t%2, %1, %0" | |
1341 [(set_attr "length" "3,2,3")] | |
972 ) | 1342 ) |
973 | 1343 |
974 (define_insn "ashlsi3" | 1344 (define_insn "ashlsi3" |
975 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | 1345 [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
976 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r") | 1346 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r") |
977 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))] | 1347 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) |
1348 (clobber (reg:CC CC_REG))] | |
978 "" | 1349 "" |
979 "@ | 1350 "@ |
980 shll\t%2, %0 | 1351 shll\t%2, %0 |
981 shll\t%2, %0 | 1352 shll\t%2, %0 |
982 shll\t%2, %1, %0" | 1353 shll\t%2, %1, %0" |
983 [(set_attr "cc" "set_zsoc") | 1354 [(set_attr "length" "3,2,3")] |
984 (set_attr "length" "3,2,3")] | 1355 ) |
1356 | |
1357 (define_insn "*ashlsi3_flags" | |
1358 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1359 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r") | |
1360 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) | |
1361 (set (reg CC_REG) | |
1362 (compare (ashift:SI (match_dup 1) (match_dup 2)) | |
1363 (const_int 0)))] | |
1364 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1365 "@ | |
1366 shll\t%2, %0 | |
1367 shll\t%2, %0 | |
1368 shll\t%2, %1, %0" | |
1369 [(set_attr "length" "3,2,3")] | |
1370 ) | |
1371 | |
1372 ;; Saturate to 32-bits | |
1373 (define_insn_and_split "ssaddsi3" | |
1374 [(set (match_operand:SI 0 "register_operand" "=r") | |
1375 (ss_plus:SI (match_operand:SI 1 "register_operand" "r") | |
1376 (match_operand:SI 2 "rx_source_operand" "riQ"))) | |
1377 (clobber (reg:CC CC_REG))] | |
1378 "" | |
1379 "#" | |
1380 "reload_completed" | |
1381 [(parallel [(set (match_dup 0) | |
1382 (plus:SI (match_dup 1) (match_dup 2))) | |
1383 (set (reg:CC_ZSC CC_REG) | |
1384 (compare:CC_ZSC | |
1385 (plus:SI (match_dup 1) (match_dup 2)) | |
1386 (const_int 0)))]) | |
1387 (set (match_dup 0) | |
1388 (unspec:SI [(match_dup 0) (reg:CC CC_REG)] | |
1389 UNSPEC_BUILTIN_SAT))] | |
1390 "" | |
1391 ) | |
1392 | |
1393 (define_insn "*sat" | |
1394 [(set (match_operand:SI 0 "register_operand" "=r") | |
1395 (unspec:SI [(match_operand:SI 1 "register_operand" "0") | |
1396 (reg:CC CC_REG)] | |
1397 UNSPEC_BUILTIN_SAT))] | |
1398 "reload_completed" | |
1399 "sat\t%0" | |
1400 [(set_attr "length" "2")] | |
985 ) | 1401 ) |
986 | 1402 |
987 (define_insn "subsi3" | 1403 (define_insn "subsi3" |
988 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") | 1404 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") |
989 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0") | 1405 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0") |
990 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))] | 1406 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q"))) |
1407 (clobber (reg:CC CC_REG))] | |
991 "" | 1408 "" |
992 "@ | 1409 "@ |
993 sub\t%2, %0 | 1410 sub\t%2, %0 |
994 sub\t%2, %0 | 1411 sub\t%2, %0 |
995 add\t%N2, %0 | 1412 add\t%N2, %0 |
996 sub\t%2, %1, %0 | 1413 sub\t%2, %1, %0 |
997 sub\t%Q2, %0" | 1414 sub\t%Q2, %0" |
998 [(set_attr "cc" "set_zsoc") | 1415 [(set_attr "timings" "11,11,11,11,33") |
999 (set_attr "timings" "11,11,11,11,33") | |
1000 (set_attr "length" "2,2,6,3,5")] | 1416 (set_attr "length" "2,2,6,3,5")] |
1001 ) | 1417 ) |
1002 | 1418 |
1003 (define_insn "subdi3" | 1419 ;; Note that the O flag is set as if (compare op1 op2) not for |
1004 [(set (match_operand:DI 0 "register_operand" "=r,r") | 1420 ;; what is described here, (compare op0 0). |
1005 (minus:DI (match_operand:DI 1 "register_operand" "0,0") | 1421 (define_insn "*subsi3_flags" |
1006 (match_operand:DI 2 "rx_source_operand" "r,Q")))] | 1422 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") |
1007 "" | 1423 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0") |
1008 "sub\t%L2, %L0\n\tsbb\t%H2, %H0" | 1424 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q"))) |
1009 [(set_attr "cc" "set_zsoc") | 1425 (set (reg CC_REG) |
1010 (set_attr "timings" "22,44") | 1426 (compare (minus:SI (match_dup 1) (match_dup 2)) |
1011 (set_attr "length" "5,11")] | 1427 (const_int 0)))] |
1012 ) | 1428 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)" |
1429 "@ | |
1430 sub\t%2, %0 | |
1431 sub\t%2, %0 | |
1432 add\t%N2, %0 | |
1433 sub\t%2, %1, %0 | |
1434 sub\t%Q2, %0" | |
1435 [(set_attr "timings" "11,11,11,11,33") | |
1436 (set_attr "length" "2,2,6,3,5")] | |
1437 ) | |
1438 | |
1439 ;; A helper to expand the above with the CC_MODE filled in. | |
1440 (define_expand "subsi3_flags" | |
1441 [(parallel [(set (match_operand:SI 0 "register_operand") | |
1442 (minus:SI (match_operand:SI 1 "register_operand") | |
1443 (match_operand:SI 2 "rx_source_operand"))) | |
1444 (set (reg:CC_ZSC CC_REG) | |
1445 (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2)) | |
1446 (const_int 0)))])] | |
1447 ) | |
1448 | |
1449 (define_insn "sbb_internal" | |
1450 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1451 (minus:SI | |
1452 (minus:SI | |
1453 (match_operand:SI 1 "register_operand" " 0,0") | |
1454 (match_operand:SI 2 "rx_compare_operand" " r,Q")) | |
1455 (geu:SI (reg:CC CC_REG) (const_int 0)))) | |
1456 (clobber (reg:CC CC_REG))] | |
1457 "reload_completed" | |
1458 "sbb\t%2, %0" | |
1459 [(set_attr "timings" "11,33") | |
1460 (set_attr "length" "3,6")] | |
1461 ) | |
1462 | |
1463 (define_insn "*sbb_flags" | |
1464 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1465 (minus:SI | |
1466 (minus:SI | |
1467 (match_operand:SI 1 "register_operand" " 0,0") | |
1468 (match_operand:SI 2 "rx_compare_operand" " r,Q")) | |
1469 (geu:SI (reg:CC CC_REG) (const_int 0)))) | |
1470 (set (reg CC_REG) | |
1471 (compare | |
1472 (minus:SI | |
1473 (minus:SI (match_dup 1) (match_dup 2)) | |
1474 (geu:SI (reg:CC CC_REG) (const_int 0))) | |
1475 (const_int 0)))] | |
1476 "reload_completed" | |
1477 "sbb\t%2, %0" | |
1478 [(set_attr "timings" "11,33") | |
1479 (set_attr "length" "3,6")] | |
1480 ) | |
1481 | |
1482 (define_expand "subdi3" | |
1483 [(set (match_operand:DI 0 "register_operand") | |
1484 (minus:DI (match_operand:DI 1 "register_operand") | |
1485 (match_operand:DI 2 "rx_compare_operand")))] | |
1486 "" | |
1487 { | |
1488 rtx op0l, op0h, op1l, op1h, op2l, op2h; | |
1489 | |
1490 op0l = gen_lowpart (SImode, operands[0]); | |
1491 op1l = gen_lowpart (SImode, operands[1]); | |
1492 op2l = gen_lowpart (SImode, operands[2]); | |
1493 op0h = gen_highpart (SImode, operands[0]); | |
1494 op1h = gen_highpart (SImode, operands[1]); | |
1495 op2h = gen_highpart_mode (SImode, DImode, operands[2]); | |
1496 | |
1497 emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op2l, op1h, op2h)); | |
1498 DONE; | |
1499 }) | |
1500 | |
1501 (define_insn_and_split "subdi3_internal" | |
1502 [(set (match_operand:SI 0 "register_operand" "=&r,&r") | |
1503 (minus:SI (match_operand:SI 2 "register_operand" " 0, r") | |
1504 (match_operand:SI 3 "rx_compare_operand" "rQ, r"))) | |
1505 (set (match_operand:SI 1 "register_operand" "= r, r") | |
1506 (minus:SI | |
1507 (minus:SI | |
1508 (match_operand:SI 4 "register_operand" " 1, 1") | |
1509 (match_operand:SI 5 "rx_compare_operand" " rQ,rQ")) | |
1510 (geu:SI (match_dup 2) (match_dup 3)))) | |
1511 (clobber (reg:CC CC_REG))] | |
1512 "" | |
1513 "#" | |
1514 "reload_completed" | |
1515 [(const_int 0)] | |
1516 { | |
1517 emit_insn (gen_subsi3_flags (operands[0], operands[2], operands[3])); | |
1518 emit_insn (gen_sbb_internal (operands[1], operands[4], operands[5])); | |
1519 DONE; | |
1520 }) | |
1013 | 1521 |
1014 (define_insn "xorsi3" | 1522 (define_insn "xorsi3" |
1015 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") | 1523 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") |
1016 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") | 1524 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") |
1017 (match_operand:SI 2 "rx_source_operand" | 1525 (match_operand:SI 2 "rx_source_operand" |
1018 "r,Sint08,Sint16,Sint24,i,Q")))] | 1526 "r,Sint08,Sint16,Sint24,i,Q"))) |
1019 "" | 1527 (clobber (reg:CC CC_REG))] |
1020 "@ | 1528 "" |
1021 xor\t%Q2, %0 | 1529 "xor\t%Q2, %0" |
1022 xor\t%Q2, %0 | 1530 [(set_attr "timings" "11,11,11,11,11,33") |
1023 xor\t%Q2, %0 | 1531 (set_attr "length" "3,4,5,6,7,6")] |
1024 xor\t%Q2, %0 | 1532 ) |
1025 xor\t%Q2, %0 | 1533 |
1026 xor\t%Q2, %0" | 1534 (define_insn "*xorsi3_flags" |
1027 [(set_attr "cc" "set_zs") | 1535 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") |
1028 (set_attr "timings" "11,11,11,11,11,33") | 1536 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") |
1537 (match_operand:SI 2 "rx_source_operand" | |
1538 "r,Sint08,Sint16,Sint24,i,Q"))) | |
1539 (set (reg CC_REG) | |
1540 (compare (xor:SI (match_dup 1) (match_dup 2)) | |
1541 (const_int 0)))] | |
1542 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)" | |
1543 "xor\t%Q2, %0" | |
1544 [(set_attr "timings" "11,11,11,11,11,33") | |
1029 (set_attr "length" "3,4,5,6,7,6")] | 1545 (set_attr "length" "3,4,5,6,7,6")] |
1030 ) | 1546 ) |
1031 | 1547 |
1032 ;; Floating Point Instructions | 1548 ;; Floating Point Instructions |
1033 | 1549 |
1034 (define_insn "addsf3" | 1550 (define_insn "addsf3" |
1035 [(set (match_operand:SF 0 "register_operand" "=r,r,r") | 1551 [(set (match_operand:SF 0 "register_operand" "=r,r,r") |
1036 (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0") | 1552 (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0") |
1037 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] | 1553 (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) |
1554 (clobber (reg:CC CC_REG))] | |
1038 "ALLOW_RX_FPU_INSNS" | 1555 "ALLOW_RX_FPU_INSNS" |
1039 "@ | 1556 "fadd\t%2, %0" |
1040 fadd\t%2, %0 | 1557 [(set_attr "timings" "44,44,66") |
1041 fadd\t%2, %0 | |
1042 fadd\t%2, %0" | |
1043 [(set_attr "cc" "set_zs") | |
1044 (set_attr "timings" "44,44,66") | |
1045 (set_attr "length" "3,7,5")] | 1558 (set_attr "length" "3,7,5")] |
1046 ) | 1559 ) |
1047 | 1560 |
1048 (define_insn "divsf3" | 1561 (define_insn "divsf3" |
1049 [(set (match_operand:SF 0 "register_operand" "=r,r,r") | 1562 [(set (match_operand:SF 0 "register_operand" "=r,r,r") |
1050 (div:SF (match_operand:SF 1 "register_operand" "0,0,0") | 1563 (div:SF (match_operand:SF 1 "register_operand" "0,0,0") |
1051 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] | 1564 (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) |
1565 (clobber (reg:CC CC_REG))] | |
1052 "ALLOW_RX_FPU_INSNS" | 1566 "ALLOW_RX_FPU_INSNS" |
1053 "fdiv\t%2, %0" | 1567 "fdiv\t%2, %0" |
1054 [(set_attr "cc" "set_zs") | 1568 [(set_attr "timings" "1616,1616,1818") |
1055 (set_attr "timings" "1616,1616,1818") | |
1056 (set_attr "length" "3,7,5")] | 1569 (set_attr "length" "3,7,5")] |
1057 ) | 1570 ) |
1058 | 1571 |
1059 (define_insn "mulsf3" | 1572 (define_insn "mulsf3" |
1060 [(set (match_operand:SF 0 "register_operand" "=r,r,r") | 1573 [(set (match_operand:SF 0 "register_operand" "=r,r,r") |
1061 (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0") | 1574 (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0") |
1062 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] | 1575 (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) |
1576 (clobber (reg:CC CC_REG))] | |
1063 "ALLOW_RX_FPU_INSNS" | 1577 "ALLOW_RX_FPU_INSNS" |
1064 "@ | 1578 "fmul\t%2, %0" |
1065 fmul\t%2, %0 | 1579 [(set_attr "timings" "33,33,55") |
1066 fmul\t%2, %0 | |
1067 fmul\t%2, %0" | |
1068 [(set_attr "cc" "set_zs") | |
1069 (set_attr "timings" "33,33,55") | |
1070 (set_attr "length" "3,7,5")] | 1580 (set_attr "length" "3,7,5")] |
1071 ) | 1581 ) |
1072 | 1582 |
1073 (define_insn "subsf3" | 1583 (define_insn "subsf3" |
1074 [(set (match_operand:SF 0 "register_operand" "=r,r,r") | 1584 [(set (match_operand:SF 0 "register_operand" "=r,r,r") |
1075 (minus:SF (match_operand:SF 1 "register_operand" "0,0,0") | 1585 (minus:SF (match_operand:SF 1 "register_operand" "0,0,0") |
1076 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] | 1586 (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) |
1587 (clobber (reg:CC CC_REG))] | |
1077 "ALLOW_RX_FPU_INSNS" | 1588 "ALLOW_RX_FPU_INSNS" |
1078 "fsub\t%2, %0" | 1589 "fsub\t%Q2, %0" |
1079 [(set_attr "cc" "set_zs") | 1590 [(set_attr "timings" "44,44,66") |
1080 (set_attr "timings" "44,44,66") | |
1081 (set_attr "length" "3,7,5")] | 1591 (set_attr "length" "3,7,5")] |
1082 ) | 1592 ) |
1083 | 1593 |
1084 (define_insn "fix_truncsfsi2" | 1594 (define_insn "fix_truncsfsi2" |
1085 [(set (match_operand:SI 0 "register_operand" "=r,r") | 1595 [(set (match_operand:SI 0 "register_operand" "=r,r") |
1086 (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))] | 1596 (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q"))) |
1597 (clobber (reg:CC CC_REG))] | |
1087 "ALLOW_RX_FPU_INSNS" | 1598 "ALLOW_RX_FPU_INSNS" |
1088 "ftoi\t%1, %0" | 1599 "ftoi\t%Q1, %0" |
1089 [(set_attr "cc" "set_zs") | 1600 [(set_attr "timings" "22,44") |
1090 (set_attr "timings" "22,44") | |
1091 (set_attr "length" "3,5")] | 1601 (set_attr "length" "3,5")] |
1092 ) | 1602 ) |
1093 | 1603 |
1094 (define_insn "floatsisf2" | 1604 (define_insn "floatsisf2" |
1095 [(set (match_operand:SF 0 "register_operand" "=r,r") | 1605 [(set (match_operand:SF 0 "register_operand" "=r,r") |
1096 (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))] | 1606 (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q"))) |
1607 (clobber (reg:CC CC_REG))] | |
1097 "ALLOW_RX_FPU_INSNS" | 1608 "ALLOW_RX_FPU_INSNS" |
1098 "itof\t%1, %0" | 1609 "itof\t%Q1, %0" |
1099 [(set_attr "cc" "set_zs") | 1610 [(set_attr "timings" "22,44") |
1100 (set_attr "timings" "22,44") | |
1101 (set_attr "length" "3,6")] | 1611 (set_attr "length" "3,6")] |
1102 ) | 1612 ) |
1103 | 1613 |
1104 ;; Bit manipulation instructions. | 1614 ;; Bit manipulation instructions. |
1105 ;; Note - there are two versions of each pattern because the memory | 1615 |
1106 ;; accessing versions use QImode whilst the register accessing | 1616 ;; ??? The *_in_memory patterns will not be matched without further help. |
1107 ;; versions use SImode. | 1617 ;; At one time we had the insv expander generate them, but I suspect that |
1108 ;; The peephole are here because the combiner only looks at a maximum | 1618 ;; in general we get better performance by exposing the register load to |
1109 ;; of three instructions at a time. | 1619 ;; the optimizers. |
1110 | 1620 ;; |
1111 (define_insn "bitset" | 1621 ;; An alternate solution would be to re-organize these patterns such |
1112 [(set:SI (match_operand:SI 0 "register_operand" "+r") | 1622 ;; that allow both register and memory operands. This would allow the |
1113 (ior:SI (match_operand:SI 1 "register_operand" "0") | 1623 ;; register allocator to spill and not load the register operand. This |
1114 (ashift:SI (const_int 1) | 1624 ;; would be possible only for operations for which we have a constant |
1115 (match_operand:SI 2 "nonmemory_operand" "ri"))))] | 1625 ;; bit offset, so that we can adjust the address by ofs/8 and replace |
1116 "" | 1626 ;; the offset in the insn by ofs%8. |
1117 "bset\t%2, %0" | 1627 |
1118 [(set_attr "length" "3")] | 1628 (define_insn "*bitset" |
1119 ) | 1629 [(set (match_operand:SI 0 "register_operand" "=r") |
1120 | 1630 (ior:SI (ashift:SI (const_int 1) |
1121 (define_insn "bitset_in_memory" | 1631 (match_operand:SI 1 "rx_shift_operand" "ri")) |
1122 [(set:QI (match_operand:QI 0 "memory_operand" "+m") | 1632 (match_operand:SI 2 "register_operand" "0")))] |
1123 (ior:QI (match_operand:QI 1 "memory_operand" "0") | 1633 "" |
1124 (ashift:QI (const_int 1) | 1634 "bset\t%1, %0" |
1125 (match_operand:QI 2 "nonmemory_operand" "ri"))))] | 1635 [(set_attr "length" "3")] |
1126 "" | 1636 ) |
1127 "bset\t%2, %0.B" | 1637 |
1638 (define_insn "*bitset_in_memory" | |
1639 [(set (match_operand:QI 0 "memory_operand" "+Q") | |
1640 (ior:QI (ashift:QI (const_int 1) | |
1641 (match_operand:QI 1 "nonmemory_operand" "ri")) | |
1642 (match_dup 0)))] | |
1643 "" | |
1644 "bset\t%1, %0.B" | |
1128 [(set_attr "length" "3") | 1645 [(set_attr "length" "3") |
1129 (set_attr "timings" "34")] | 1646 (set_attr "timings" "33")] |
1130 ) | 1647 ) |
1131 | 1648 |
1132 ;; (set (reg A) (const_int 1)) | 1649 (define_insn "*bitinvert" |
1133 ;; (set (reg A) (ashift (reg A) (reg B))) | 1650 [(set (match_operand:SI 0 "register_operand" "=r") |
1134 ;; (set (reg C) (ior (reg A) (reg C))) | 1651 (xor:SI (ashift:SI (const_int 1) |
1135 (define_peephole2 | 1652 (match_operand:SI 1 "rx_shift_operand" "ri")) |
1136 [(set:SI (match_operand:SI 0 "register_operand" "") | 1653 (match_operand:SI 2 "register_operand" "0")))] |
1137 (const_int 1)) | 1654 "" |
1138 (set:SI (match_dup 0) | 1655 "bnot\t%1, %0" |
1139 (ashift:SI (match_dup 0) | 1656 [(set_attr "length" "3")] |
1140 (match_operand:SI 1 "register_operand" ""))) | 1657 ) |
1141 (set:SI (match_operand:SI 2 "register_operand" "") | 1658 |
1142 (ior:SI (match_dup 0) | 1659 (define_insn "*bitinvert_in_memory" |
1143 (match_dup 2)))] | 1660 [(set (match_operand:QI 0 "memory_operand" "+Q") |
1144 "dead_or_set_p (insn, operands[0])" | 1661 (xor:QI (ashift:QI (const_int 1) |
1145 [(set:SI (match_dup 2) | 1662 (match_operand:QI 1 "nonmemory_operand" "ri")) |
1146 (ior:SI (match_dup 2) | 1663 (match_dup 0)))] |
1147 (ashift:SI (const_int 1) | 1664 "" |
1148 (match_dup 1))))] | 1665 "bnot\t%1, %0.B" |
1149 ) | |
1150 | |
1151 ;; (set (reg A) (const_int 1)) | |
1152 ;; (set (reg A) (ashift (reg A) (reg B))) | |
1153 ;; (set (reg A) (ior (reg A) (reg C))) | |
1154 ;; (set (reg C) (reg A) | |
1155 (define_peephole2 | |
1156 [(set:SI (match_operand:SI 0 "register_operand" "") | |
1157 (const_int 1)) | |
1158 (set:SI (match_dup 0) | |
1159 (ashift:SI (match_dup 0) | |
1160 (match_operand:SI 1 "register_operand" ""))) | |
1161 (set:SI (match_dup 0) | |
1162 (ior:SI (match_dup 0) | |
1163 (match_operand:SI 2 "register_operand" ""))) | |
1164 (set:SI (match_dup 2) (match_dup 0))] | |
1165 "dead_or_set_p (insn, operands[0])" | |
1166 [(set:SI (match_dup 2) | |
1167 (ior:SI (match_dup 2) | |
1168 (ashift:SI (const_int 1) | |
1169 (match_dup 1))))] | |
1170 ) | |
1171 | |
1172 (define_insn "bitinvert" | |
1173 [(set:SI (match_operand:SI 0 "register_operand" "+r") | |
1174 (xor:SI (match_operand:SI 1 "register_operand" "0") | |
1175 (ashift:SI (const_int 1) | |
1176 (match_operand:SI 2 "nonmemory_operand" "ri"))))] | |
1177 "" | |
1178 "bnot\t%2, %0" | |
1179 [(set_attr "length" "3")] | |
1180 ) | |
1181 | |
1182 (define_insn "bitinvert_in_memory" | |
1183 [(set:QI (match_operand:QI 0 "memory_operand" "+m") | |
1184 (xor:QI (match_operand:QI 1 "register_operand" "0") | |
1185 (ashift:QI (const_int 1) | |
1186 (match_operand:QI 2 "nonmemory_operand" "ri"))))] | |
1187 "" | |
1188 "bnot\t%2, %0.B" | |
1189 [(set_attr "length" "5") | 1666 [(set_attr "length" "5") |
1190 (set_attr "timings" "33")] | 1667 (set_attr "timings" "33")] |
1191 ) | 1668 ) |
1192 | 1669 |
1193 ;; (set (reg A) (const_int 1)) | 1670 (define_insn "*bitclr" |
1194 ;; (set (reg A) (ashift (reg A) (reg B))) | 1671 [(set (match_operand:SI 0 "register_operand" "=r") |
1195 ;; (set (reg C) (xor (reg A) (reg C))) | 1672 (and:SI (not:SI |
1196 (define_peephole2 | 1673 (ashift:SI |
1197 [(set:SI (match_operand:SI 0 "register_operand" "") | 1674 (const_int 1) |
1198 (const_int 1)) | 1675 (match_operand:SI 1 "rx_shift_operand" "ri"))) |
1199 (set:SI (match_dup 0) | 1676 (match_operand:SI 2 "register_operand" "0")))] |
1200 (ashift:SI (match_dup 0) | 1677 "" |
1201 (match_operand:SI 1 "register_operand" ""))) | 1678 "bclr\t%1, %0" |
1202 (set:SI (match_operand:SI 2 "register_operand" "") | 1679 [(set_attr "length" "3")] |
1203 (xor:SI (match_dup 0) | 1680 ) |
1204 (match_dup 2)))] | 1681 |
1205 "dead_or_set_p (insn, operands[0])" | 1682 (define_insn "*bitclr_in_memory" |
1206 [(set:SI (match_dup 2) | 1683 [(set (match_operand:QI 0 "memory_operand" "+Q") |
1207 (xor:SI (match_dup 2) | 1684 (and:QI (not:QI |
1208 (ashift:SI (const_int 1) | 1685 (ashift:QI |
1209 (match_dup 1))))] | 1686 (const_int 1) |
1210 "" | 1687 (match_operand:QI 1 "nonmemory_operand" "ri"))) |
1211 ) | 1688 (match_dup 0)))] |
1212 | 1689 "" |
1213 ;; (set (reg A) (const_int 1)) | 1690 "bclr\t%1, %0.B" |
1214 ;; (set (reg A) (ashift (reg A) (reg B))) | |
1215 ;; (set (reg A) (xor (reg A) (reg C))) | |
1216 ;; (set (reg C) (reg A)) | |
1217 (define_peephole2 | |
1218 [(set:SI (match_operand:SI 0 "register_operand" "") | |
1219 (const_int 1)) | |
1220 (set:SI (match_dup 0) | |
1221 (ashift:SI (match_dup 0) | |
1222 (match_operand:SI 1 "register_operand" ""))) | |
1223 (set:SI (match_dup 0) | |
1224 (xor:SI (match_dup 0) | |
1225 (match_operand:SI 2 "register_operand" ""))) | |
1226 (set:SI (match_dup 2) (match_dup 0))] | |
1227 "dead_or_set_p (insn, operands[0])" | |
1228 [(set:SI (match_dup 2) | |
1229 (xor:SI (match_dup 2) | |
1230 (ashift:SI (const_int 1) | |
1231 (match_dup 1))))] | |
1232 "" | |
1233 ) | |
1234 | |
1235 (define_insn "bitclr" | |
1236 [(set:SI (match_operand:SI 0 "register_operand" "+r") | |
1237 (and:SI (match_operand:SI 1 "register_operand" "0") | |
1238 (not:SI (ashift:SI (const_int 1) | |
1239 (match_operand:SI 2 "nonmemory_operand" "ri")))))] | |
1240 "" | |
1241 "bclr\t%2, %0" | |
1242 [(set_attr "length" "3")] | |
1243 ) | |
1244 | |
1245 (define_insn "bitclr_in_memory" | |
1246 [(set:QI (match_operand:QI 0 "memory_operand" "+m") | |
1247 (and:QI (match_operand:QI 1 "memory_operand" "0") | |
1248 (not:QI (ashift:QI (const_int 1) | |
1249 (match_operand:QI 2 "nonmemory_operand" "ri")))))] | |
1250 "" | |
1251 "bclr\t%2, %0.B" | |
1252 [(set_attr "length" "3") | 1691 [(set_attr "length" "3") |
1253 (set_attr "timings" "34")] | 1692 (set_attr "timings" "33")] |
1254 ) | 1693 ) |
1255 | 1694 |
1256 ;; (set (reg A) (const_int -2)) | 1695 (define_insn "*insv_imm" |
1257 ;; (set (reg A) (rotate (reg A) (reg B))) | 1696 [(set (zero_extract:SI |
1258 ;; (set (reg C) (and (reg A) (reg C))) | 1697 (match_operand:SI 0 "register_operand" "+r") |
1259 (define_peephole2 | 1698 (const_int 1) |
1260 [(set:SI (match_operand:SI 0 "register_operand" "") | 1699 (match_operand:SI 1 "rx_shift_operand" "ri")) |
1261 (const_int -2)) | 1700 (match_operand:SI 2 "const_int_operand" ""))] |
1262 (set:SI (match_dup 0) | 1701 "" |
1263 (rotate:SI (match_dup 0) | 1702 { |
1264 (match_operand:SI 1 "register_operand" ""))) | 1703 if (INTVAL (operands[2]) & 1) |
1265 (set:SI (match_operand:SI 2 "register_operand" "") | 1704 return "bset\t%1, %0"; |
1266 (and:SI (match_dup 0) | 1705 else |
1267 (match_dup 2)))] | 1706 return "bclr\t%1, %0"; |
1268 "dead_or_set_p (insn, operands[0])" | 1707 } |
1269 [(set:SI (match_dup 2) | 1708 [(set_attr "length" "3")] |
1270 (and:SI (match_dup 2) | 1709 ) |
1271 (not:SI (ashift:SI (const_int 1) | 1710 |
1272 (match_dup 1)))))] | 1711 (define_insn_and_split "rx_insv_reg" |
1273 ) | 1712 [(set (zero_extract:SI |
1274 | 1713 (match_operand:SI 0 "register_operand" "+r") |
1275 ;; (set (reg A) (const_int -2)) | 1714 (const_int 1) |
1276 ;; (set (reg A) (rotate (reg A) (reg B))) | 1715 (match_operand:SI 1 "const_int_operand" "")) |
1277 ;; (set (reg A) (and (reg A) (reg C))) | 1716 (match_operand:SI 2 "register_operand" "r")) |
1278 ;; (set (reg C) (reg A) | 1717 (clobber (reg:CC CC_REG))] |
1279 (define_peephole2 | 1718 "" |
1280 [(set:SI (match_operand:SI 0 "register_operand" "") | 1719 "#" |
1281 (const_int -2)) | 1720 "reload_completed" |
1282 (set:SI (match_dup 0) | 1721 [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)) |
1283 (rotate:SI (match_dup 0) | 1722 (match_dup 3))] |
1284 (match_operand:SI 1 "register_operand" ""))) | 1723 { |
1285 (set:SI (match_dup 0) | 1724 rtx flags, x; |
1286 (and:SI (match_dup 0) | 1725 |
1287 (match_operand:SI 2 "register_operand" ""))) | 1726 /* Emit tst #1, op2. */ |
1288 (set:SI (match_dup 2) (match_dup 0))] | 1727 flags = gen_rtx_REG (CC_ZSmode, CC_REG); |
1289 "dead_or_set_p (insn, operands[0])" | 1728 x = gen_rtx_AND (SImode, operands[2], const1_rtx); |
1290 [(set:SI (match_dup 2) | 1729 x = gen_rtx_COMPARE (CC_ZSmode, x, const0_rtx); |
1291 (and:SI (match_dup 2) | 1730 x = gen_rtx_SET (VOIDmode, flags, x); |
1292 (not:SI (ashift:SI (const_int 1) | 1731 emit_insn (x); |
1293 (match_dup 1)))))] | 1732 |
1733 /* Emit bmne. */ | |
1734 operands[3] = gen_rtx_NE (SImode, flags, const0_rtx); | |
1735 }) | |
1736 | |
1737 (define_insn_and_split "*insv_cond" | |
1738 [(set (zero_extract:SI | |
1739 (match_operand:SI 0 "register_operand" "+r") | |
1740 (const_int 1) | |
1741 (match_operand:SI 1 "const_int_operand" "")) | |
1742 (match_operator:SI 4 "comparison_operator" | |
1743 [(match_operand:SI 2 "register_operand" "r") | |
1744 (match_operand:SI 3 "rx_source_operand" "riQ")])) | |
1745 (clobber (reg:CC CC_REG))] | |
1746 "" | |
1747 "#" | |
1748 "reload_completed" | |
1749 [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)) | |
1750 (match_dup 4))] | |
1751 { | |
1752 rtx flags, x; | |
1753 | |
1754 flags = gen_rtx_REG (CCmode, CC_REG); | |
1755 x = gen_rtx_COMPARE (CCmode, operands[2], operands[3]); | |
1756 x = gen_rtx_SET (VOIDmode, flags, x); | |
1757 emit_insn (x); | |
1758 | |
1759 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode, | |
1760 flags, const0_rtx); | |
1761 }) | |
1762 | |
1763 (define_insn "*bmcc" | |
1764 [(set (zero_extract:SI | |
1765 (match_operand:SI 0 "register_operand" "+r") | |
1766 (const_int 1) | |
1767 (match_operand:SI 1 "const_int_operand" "")) | |
1768 (match_operator:SI 2 "comparison_operator" | |
1769 [(reg CC_REG) (const_int 0)]))] | |
1770 "reload_completed" | |
1771 "bm%B2\t%1, %0" | |
1772 [(set_attr "length" "3")] | |
1773 ) | |
1774 | |
1775 ;; Work around the fact that X=Y<0 is preferentially expanded as a shift. | |
1776 (define_insn_and_split "*insv_cond_lt" | |
1777 [(set (zero_extract:SI | |
1778 (match_operand:SI 0 "register_operand" "+r") | |
1779 (const_int 1) | |
1780 (match_operand:SI 1 "const_int_operand" "")) | |
1781 (match_operator:SI 3 "rshift_operator" | |
1782 [(match_operand:SI 2 "register_operand" "r") | |
1783 (const_int 31)])) | |
1784 (clobber (reg:CC CC_REG))] | |
1785 "" | |
1786 "#" | |
1787 "" | |
1788 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)) | |
1789 (lt:SI (match_dup 2) (const_int 0))) | |
1790 (clobber (reg:CC CC_REG))])] | |
1791 "" | |
1294 ) | 1792 ) |
1295 | 1793 |
1296 (define_expand "insv" | 1794 (define_expand "insv" |
1297 [(set:SI (zero_extract:SI (match_operand:SI | 1795 [(set (zero_extract:SI |
1298 0 "nonimmediate_operand") ;; Destination | 1796 (match_operand:SI 0 "register_operand") ;; Destination |
1299 (match_operand | 1797 (match_operand:SI 1 "const_int_operand") ;; # of bits to set |
1300 1 "immediate_operand") ;; # of bits to set | 1798 (match_operand:SI 2 "nonmemory_operand")) ;; Starting bit |
1301 (match_operand | 1799 (match_operand:SI 3 "nonmemory_operand"))] ;; Bits to insert |
1302 2 "immediate_operand")) ;; Starting bit | 1800 "" |
1303 (match_operand | 1801 { |
1304 3 "immediate_operand"))] ;; Bits to insert | 1802 /* We only handle single-bit inserts. */ |
1305 "" | 1803 if (!CONST_INT_P (operands[1]) || INTVAL (operands[1]) != 1) |
1306 { | 1804 FAIL; |
1307 if (rx_expand_insv (operands)) | 1805 |
1806 /* Either the bit to insert or the position must be constant. */ | |
1807 if (CONST_INT_P (operands[3])) | |
1808 operands[3] = GEN_INT (INTVAL (operands[3]) & 1); | |
1809 else if (CONST_INT_P (operands[2])) | |
1810 { | |
1811 emit_insn (gen_rx_insv_reg (operands[0], operands[2], operands[3])); | |
1308 DONE; | 1812 DONE; |
1813 } | |
1814 else | |
1309 FAIL; | 1815 FAIL; |
1310 } | 1816 }) |
1311 ) | |
1312 | 1817 |
1313 ;; Atomic exchange operation. | 1818 ;; Atomic exchange operation. |
1314 | 1819 |
1315 (define_insn "sync_lock_test_and_setsi" | 1820 (define_insn "sync_lock_test_and_setsi" |
1316 [(set:SI (match_operand:SI 0 "register_operand" "=r,r") | 1821 [(set (match_operand:SI 0 "register_operand" "=r,r") |
1317 (match_operand:SI 1 "rx_compare_operand" "=r,Q")) | 1822 (match_operand:SI 1 "rx_compare_operand" "=r,Q")) |
1318 (set:SI (match_dup 1) | 1823 (set (match_dup 1) |
1319 (match_operand:SI 2 "register_operand" "0,0"))] | 1824 (match_operand:SI 2 "register_operand" "0,0"))] |
1320 "" | 1825 "" |
1321 "xchg\t%1, %0" | 1826 "xchg\t%1, %0" |
1322 [(set_attr "length" "3,6") | 1827 [(set_attr "length" "3,6") |
1323 (set_attr "timings" "22")] | 1828 (set_attr "timings" "22")] |
1324 ) | 1829 ) |
1325 | 1830 |
1326 ;; Block move functions. | 1831 ;; Block move functions. |
1327 | 1832 |
1328 (define_expand "movstr" | 1833 (define_expand "movstr" |
1329 [(set:SI (match_operand:BLK 1 "memory_operand") ;; Dest | 1834 [(set (match_operand:BLK 1 "memory_operand") ;; Dest |
1330 (match_operand:BLK 2 "memory_operand")) ;; Source | 1835 (match_operand:BLK 2 "memory_operand")) ;; Source |
1331 (use (match_operand:SI 0 "register_operand")) ;; Updated Dest | 1836 (use (match_operand:SI 0 "register_operand")) ;; Updated Dest |
1332 ] | 1837 ] |
1333 "" | 1838 "" |
1334 { | 1839 { |
1335 rtx addr1 = gen_rtx_REG (SImode, 1); | 1840 rtx addr1 = gen_rtx_REG (SImode, 1); |
1336 rtx addr2 = gen_rtx_REG (SImode, 2); | 1841 rtx addr2 = gen_rtx_REG (SImode, 2); |
1349 DONE; | 1854 DONE; |
1350 } | 1855 } |
1351 ) | 1856 ) |
1352 | 1857 |
1353 (define_insn "rx_movstr" | 1858 (define_insn "rx_movstr" |
1354 [(set:SI (mem:BLK (reg:SI 1)) | 1859 [(set (mem:BLK (reg:SI 1)) |
1355 (mem:BLK (reg:SI 2))) | 1860 (mem:BLK (reg:SI 2))) |
1356 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR) | 1861 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR) |
1357 (clobber (reg:SI 1)) | 1862 (clobber (reg:SI 1)) |
1358 (clobber (reg:SI 2)) | 1863 (clobber (reg:SI 2)) |
1359 (clobber (reg:SI 3)) | 1864 (clobber (reg:SI 3))] |
1360 ] | |
1361 "" | 1865 "" |
1362 "smovu" | 1866 "smovu" |
1363 [(set_attr "length" "2") | 1867 [(set_attr "length" "2") |
1364 (set_attr "timings" "1111")] ;; The timing is a guesstimate. | 1868 (set_attr "timings" "1111")] ;; The timing is a guesstimate. |
1365 ) | 1869 ) |
1366 | 1870 |
1367 (define_insn "rx_strend" | 1871 (define_insn "rx_strend" |
1368 [(set:SI (match_operand:SI 0 "register_operand" "=r") | 1872 [(set (match_operand:SI 0 "register_operand" "=r") |
1369 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") | 1873 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") |
1370 (reg:SI 3)] UNSPEC_STRLEN)) | 1874 (reg:SI 3)] UNSPEC_STRLEN)) |
1371 (clobber (reg:SI 1)) | 1875 (clobber (reg:SI 1)) |
1372 (clobber (reg:SI 2)) | 1876 (clobber (reg:SI 2)) |
1373 (clobber (reg:SI 3)) | 1877 (clobber (reg:SI 3)) |
1374 ] | 1878 (clobber (reg:CC CC_REG)) |
1879 ] | |
1375 "" | 1880 "" |
1376 "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0" | 1881 "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0" |
1377 [(set_attr "length" "10") | 1882 [(set_attr "length" "10") |
1378 (set_attr "cc" "clobber") | |
1379 (set_attr "timings" "1111")] ;; The timing is a guesstimate. | 1883 (set_attr "timings" "1111")] ;; The timing is a guesstimate. |
1380 ) | 1884 ) |
1381 | 1885 |
1382 (define_expand "movmemsi" | 1886 (define_expand "movmemsi" |
1383 [(parallel | 1887 [(parallel |
1390 "" | 1894 "" |
1391 { | 1895 { |
1392 rtx addr1 = gen_rtx_REG (SImode, 1); | 1896 rtx addr1 = gen_rtx_REG (SImode, 1); |
1393 rtx addr2 = gen_rtx_REG (SImode, 2); | 1897 rtx addr2 = gen_rtx_REG (SImode, 2); |
1394 rtx len = gen_rtx_REG (SImode, 3); | 1898 rtx len = gen_rtx_REG (SImode, 3); |
1899 | |
1900 /* Do not use when the source or destination are volatile - the SMOVF | |
1901 instruction will read and write in word sized blocks, which may be | |
1902 outside of the valid address range. */ | |
1903 if (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) | |
1904 FAIL; | |
1905 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1])) | |
1906 FAIL; | |
1395 | 1907 |
1396 if (REG_P (operands[0]) && (REGNO (operands[0]) == 2 | 1908 if (REG_P (operands[0]) && (REGNO (operands[0]) == 2 |
1397 || REGNO (operands[0]) == 3)) | 1909 || REGNO (operands[0]) == 3)) |
1398 FAIL; | 1910 FAIL; |
1399 if (REG_P (operands[1]) && (REGNO (operands[1]) == 1 | 1911 if (REG_P (operands[1]) && (REGNO (operands[1]) == 1 |
1400 || REGNO (operands[1]) == 3)) | 1912 || REGNO (operands[1]) == 3)) |
1401 FAIL; | 1913 FAIL; |
1402 if (REG_P (operands[2]) && (REGNO (operands[2]) == 1 | 1914 if (REG_P (operands[2]) && (REGNO (operands[2]) == 1 |
1403 || REGNO (operands[2]) == 2)) | 1915 || REGNO (operands[2]) == 2)) |
1404 FAIL; | 1916 FAIL; |
1917 | |
1405 emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX)); | 1918 emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX)); |
1406 emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX)); | 1919 emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX)); |
1407 emit_move_insn (len, force_operand (operands[2], NULL_RTX)); | 1920 emit_move_insn (len, force_operand (operands[2], NULL_RTX)); |
1408 operands[0] = replace_equiv_address_nv (operands[0], addr1); | 1921 operands[0] = replace_equiv_address_nv (operands[0], addr1); |
1409 operands[1] = replace_equiv_address_nv (operands[1], addr2); | 1922 operands[1] = replace_equiv_address_nv (operands[1], addr2); |
1445 DONE; | 1958 DONE; |
1446 } | 1959 } |
1447 ) | 1960 ) |
1448 | 1961 |
1449 (define_insn "rx_setmem" | 1962 (define_insn "rx_setmem" |
1450 [(set:BLK (mem:BLK (reg:SI 1)) (reg 2)) | 1963 [(set (mem:BLK (reg:SI 1)) |
1451 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM) | 1964 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)) |
1452 (clobber (reg:SI 1)) | 1965 (clobber (reg:SI 1)) |
1453 (clobber (reg:SI 3))] | 1966 (clobber (reg:SI 3))] |
1454 "" | 1967 "" |
1455 "sstr.b" | 1968 "sstr.b" |
1456 [(set_attr "length" "2") | 1969 [(set_attr "length" "2") |
1457 (set_attr "timings" "1111")] ;; The timing is a guesstimate. | 1970 (set_attr "timings" "1111")] ;; The timing is a guesstimate. |
1458 ) | 1971 ) |
1459 | 1972 |
1460 (define_expand "cmpstrnsi" | 1973 (define_expand "cmpstrnsi" |
1461 [(set (match_operand:SI | 1974 [(set (match_operand:SI 0 "register_operand") ;; Result |
1462 0 "register_operand") ;; Result | 1975 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1 |
1463 (unspec_volatile:SI [(match_operand:BLK | 1976 (match_operand:BLK 2 "memory_operand")] ;; String2 |
1464 1 "memory_operand") ;; String1 | |
1465 (match_operand:BLK | |
1466 2 "memory_operand")] ;; String2 | |
1467 UNSPEC_CMPSTRN)) | 1977 UNSPEC_CMPSTRN)) |
1468 (use (match_operand:SI | 1978 (use (match_operand:SI 3 "register_operand")) ;; Max Length |
1469 3 "register_operand")) ;; Max Length | 1979 (match_operand:SI 4 "immediate_operand")] ;; Known Align |
1470 (match_operand:SI | |
1471 4 "immediate_operand")] ;; Known Align | |
1472 "" | 1980 "" |
1473 { | 1981 { |
1474 rtx str1 = gen_rtx_REG (SImode, 1); | 1982 rtx str1 = gen_rtx_REG (SImode, 1); |
1475 rtx str2 = gen_rtx_REG (SImode, 2); | 1983 rtx str2 = gen_rtx_REG (SImode, 2); |
1476 rtx len = gen_rtx_REG (SImode, 3); | 1984 rtx len = gen_rtx_REG (SImode, 3); |
1483 DONE; | 1991 DONE; |
1484 } | 1992 } |
1485 ) | 1993 ) |
1486 | 1994 |
1487 (define_expand "cmpstrsi" | 1995 (define_expand "cmpstrsi" |
1488 [(set (match_operand:SI | 1996 [(set (match_operand:SI 0 "register_operand") ;; Result |
1489 0 "register_operand") ;; Result | 1997 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1 |
1490 (unspec_volatile:SI [(match_operand:BLK | 1998 (match_operand:BLK 2 "memory_operand")] ;; String2 |
1491 1 "memory_operand") ;; String1 | |
1492 (match_operand:BLK | |
1493 2 "memory_operand")] ;; String2 | |
1494 UNSPEC_CMPSTRN)) | 1999 UNSPEC_CMPSTRN)) |
1495 (match_operand:SI | 2000 (match_operand:SI 3 "immediate_operand")] ;; Known Align |
1496 3 "immediate_operand")] ;; Known Align | |
1497 "" | 2001 "" |
1498 { | 2002 { |
1499 rtx str1 = gen_rtx_REG (SImode, 1); | 2003 rtx str1 = gen_rtx_REG (SImode, 1); |
1500 rtx str2 = gen_rtx_REG (SImode, 2); | 2004 rtx str2 = gen_rtx_REG (SImode, 2); |
1501 rtx len = gen_rtx_REG (SImode, 3); | 2005 rtx len = gen_rtx_REG (SImode, 3); |
1508 DONE; | 2012 DONE; |
1509 } | 2013 } |
1510 ) | 2014 ) |
1511 | 2015 |
1512 (define_insn "rx_cmpstrn" | 2016 (define_insn "rx_cmpstrn" |
1513 [(set:SI (match_operand:SI 0 "register_operand" "=r") | 2017 [(set (match_operand:SI 0 "register_operand" "=r") |
1514 (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)] | 2018 (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)] |
1515 UNSPEC_CMPSTRN)) | 2019 UNSPEC_CMPSTRN)) |
1516 (use (match_operand:BLK 1 "memory_operand" "m")) | 2020 (use (match_operand:BLK 1 "memory_operand" "m")) |
1517 (use (match_operand:BLK 2 "memory_operand" "m")) | 2021 (use (match_operand:BLK 2 "memory_operand" "m")) |
1518 (clobber (reg:SI 1)) | 2022 (clobber (reg:SI 1)) |
1519 (clobber (reg:SI 2)) | 2023 (clobber (reg:SI 2)) |
1520 (clobber (reg:SI 3))] | 2024 (clobber (reg:SI 3)) |
2025 (clobber (reg:CC CC_REG))] | |
1521 "" | 2026 "" |
1522 "scmpu ; Perform the string comparison | 2027 "scmpu ; Perform the string comparison |
1523 mov #-1, %0 ; Set up -1 result (which cannot be created | 2028 mov #-1, %0 ; Set up -1 result (which cannot be created |
1524 ; by the SC insn) | 2029 ; by the SC insn) |
1525 bnc ?+ ; If Carry is not set skip over | 2030 bnc ?+ ; If Carry is not set skip over |
1644 | 2149 |
1645 ;;---------- Arithmetic ------------------------ | 2150 ;;---------- Arithmetic ------------------------ |
1646 | 2151 |
1647 ;; Byte swap (two 16-bit values). | 2152 ;; Byte swap (two 16-bit values). |
1648 (define_insn "revw" | 2153 (define_insn "revw" |
1649 [(set (match_operand:SI 0 "register_operand" "+r") | 2154 [(set (match_operand:SI 0 "register_operand" "=r") |
1650 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] | 2155 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] |
1651 UNSPEC_BUILTIN_REVW))] | 2156 UNSPEC_BUILTIN_REVW))] |
1652 "" | 2157 "" |
1653 "revw\t%1, %0" | 2158 "revw\t%1, %0" |
1654 [(set_attr "length" "3")] | 2159 [(set_attr "length" "3")] |
1656 | 2161 |
1657 ;; Round to integer. | 2162 ;; Round to integer. |
1658 (define_insn "lrintsf2" | 2163 (define_insn "lrintsf2" |
1659 [(set (match_operand:SI 0 "register_operand" "=r,r") | 2164 [(set (match_operand:SI 0 "register_operand" "=r,r") |
1660 (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")] | 2165 (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")] |
1661 UNSPEC_BUILTIN_ROUND))] | 2166 UNSPEC_BUILTIN_ROUND)) |
2167 (clobber (reg:CC CC_REG))] | |
1662 "" | 2168 "" |
1663 "round\t%1, %0" | 2169 "round\t%1, %0" |
1664 [(set_attr "cc" "set_zs") | 2170 [(set_attr "timings" "22,44") |
1665 (set_attr "timings" "22,44") | |
1666 (set_attr "length" "3,5")] | 2171 (set_attr "length" "3,5")] |
1667 ) | |
1668 | |
1669 ;; Saturate to 32-bits | |
1670 (define_insn "sat" | |
1671 [(set (match_operand:SI 0 "register_operand" "=r") | |
1672 (unspec:SI [(match_operand:SI 1 "register_operand" "0")] | |
1673 UNSPEC_BUILTIN_SAT))] | |
1674 "" | |
1675 "sat\t%0" | |
1676 [(set_attr "length" "2")] | |
1677 ) | 2172 ) |
1678 | 2173 |
1679 ;;---------- Control Registers ------------------------ | 2174 ;;---------- Control Registers ------------------------ |
1680 | 2175 |
1681 ;; Clear Processor Status Word | 2176 ;; Clear Processor Status Word |
1682 (define_insn "clrpsw" | 2177 (define_insn "clrpsw" |
1683 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")] | 2178 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] |
1684 UNSPEC_BUILTIN_CLRPSW) | 2179 UNSPEC_BUILTIN_CLRPSW) |
1685 (clobber (cc0))] | 2180 (clobber (reg:CC CC_REG))] |
1686 "" | 2181 "" |
1687 "clrpsw\t%F0" | 2182 "clrpsw\t%F0" |
1688 [(set_attr "length" "2") | 2183 [(set_attr "length" "2")] |
1689 (set_attr "cc" "clobber")] | |
1690 ) | 2184 ) |
1691 | 2185 |
1692 ;; Set Processor Status Word | 2186 ;; Set Processor Status Word |
1693 (define_insn "setpsw" | 2187 (define_insn "setpsw" |
1694 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")] | 2188 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] |
1695 UNSPEC_BUILTIN_SETPSW) | 2189 UNSPEC_BUILTIN_SETPSW) |
1696 (clobber (cc0))] | 2190 (clobber (reg:CC CC_REG))] |
1697 "" | 2191 "" |
1698 "setpsw\t%F0" | 2192 "setpsw\t%F0" |
1699 [(set_attr "length" "2") | 2193 [(set_attr "length" "2")] |
1700 (set_attr "cc" "clobber")] | |
1701 ) | 2194 ) |
1702 | 2195 |
1703 ;; Move from control register | 2196 ;; Move from control register |
1704 (define_insn "mvfc" | 2197 (define_insn "mvfc" |
1705 [(set (match_operand:SI 0 "register_operand" "=r") | 2198 [(set (match_operand:SI 0 "register_operand" "=r") |
1706 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] | 2199 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] |
1707 UNSPEC_BUILTIN_MVFC))] | 2200 UNSPEC_BUILTIN_MVFC))] |
1708 "" | 2201 "" |
1709 "mvfc\t%C1, %0" | 2202 "mvfc\t%C1, %0" |
1710 [(set_attr "length" "3")] | 2203 [(set_attr "length" "3")] |
1711 ) | 2204 ) |
1712 | 2205 |
1713 ;; Move to control register | 2206 ;; Move to control register |
1714 (define_insn "mvtc" | 2207 (define_insn "mvtc" |
1715 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i") | 2208 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i,i") |
1716 (match_operand:SI 1 "nonmemory_operand" "r,i")] | 2209 (match_operand:SI 1 "nonmemory_operand" "r,i")] |
1717 UNSPEC_BUILTIN_MVTC)] | 2210 UNSPEC_BUILTIN_MVTC)] |
1718 "" | 2211 "" |
1719 "mvtc\t%1, %C0" | 2212 "mvtc\t%1, %C0" |
1720 [(set_attr "length" "3,7")] | 2213 [(set_attr "length" "3,7")] |
1725 ;; them. | 2218 ;; them. |
1726 ) | 2219 ) |
1727 | 2220 |
1728 ;; Move to interrupt priority level | 2221 ;; Move to interrupt priority level |
1729 (define_insn "mvtipl" | 2222 (define_insn "mvtipl" |
1730 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")] | 2223 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "Uint04")] |
1731 UNSPEC_BUILTIN_MVTIPL)] | 2224 UNSPEC_BUILTIN_MVTIPL)] |
1732 "" | 2225 "" |
1733 "mvtipl\t%0" | 2226 "mvtipl\t%0" |
1734 [(set_attr "length" "3")] | 2227 [(set_attr "length" "3")] |
1735 ) | 2228 ) |