d0ce5963c8370145dc014195f7e009967f7b816c
[gcc.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;; t -- T
46 ;; x -- mac
47 ;; l -- pr
48 ;; z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73 (AP_REG 145)
74 (PR_REG 146)
75 (T_REG 147)
76 (GBR_REG 144)
77 (MACH_REG 148)
78 (MACL_REG 149)
79 (FPUL_REG 150)
80 (RAP_REG 152)
81
82 (FPSCR_REG 151)
83
84 (PIC_REG 12)
85 (FP_REG 14)
86 (SP_REG 15)
87
88 (PR_MEDIA_REG 18)
89 (T_MEDIA_REG 19)
90
91 (R0_REG 0)
92 (R1_REG 1)
93 (R2_REG 2)
94 (R3_REG 3)
95 (R4_REG 4)
96 (R5_REG 5)
97 (R6_REG 6)
98 (R7_REG 7)
99 (R8_REG 8)
100 (R9_REG 9)
101 (R10_REG 10)
102 (R20_REG 20)
103 (R21_REG 21)
104 (R22_REG 22)
105 (R23_REG 23)
106
107 (DR0_REG 64)
108 (DR2_REG 66)
109 (DR4_REG 68)
110 (FR23_REG 87)
111
112 (TR0_REG 128)
113 (TR1_REG 129)
114 (TR2_REG 130)
115
116 (XD0_REG 136)
117
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
120 (UNSPEC_MOVA 1)
121 (UNSPEC_CASESI 2)
122 (UNSPEC_DATALABEL 3)
123 (UNSPEC_BBR 4)
124 (UNSPEC_SFUNC 5)
125 (UNSPEC_PIC 6)
126 (UNSPEC_GOT 7)
127 (UNSPEC_GOTOFF 8)
128 (UNSPEC_PLT 9)
129 (UNSPEC_CALLER 10)
130 (UNSPEC_GOTPLT 11)
131 (UNSPEC_ICACHE 12)
132 (UNSPEC_INIT_TRAMP 13)
133 (UNSPEC_FCOSA 14)
134 (UNSPEC_FSRRA 15)
135 (UNSPEC_FSINA 16)
136 (UNSPEC_NSB 17)
137 (UNSPEC_ALLOCO 18)
138 (UNSPEC_EH_RETURN 19)
139 (UNSPEC_TLSGD 20)
140 (UNSPEC_TLSLDM 21)
141 (UNSPEC_TLSIE 22)
142 (UNSPEC_DTPOFF 23)
143 (UNSPEC_GOTTPOFF 24)
144 (UNSPEC_TPOFF 25)
145 (UNSPEC_RA 26)
146 (UNSPEC_DIV_INV_M0 30)
147 (UNSPEC_DIV_INV_M1 31)
148 (UNSPEC_DIV_INV_M2 32)
149 (UNSPEC_DIV_INV_M3 33)
150 (UNSPEC_DIV_INV20 34)
151 (UNSPEC_ASHIFTRT 35)
152 (UNSPEC_THUNK 36)
153 (UNSPEC_SP_SET 40)
154 (UNSPEC_SP_TEST 41)
155
156 ;; These are used with unspec_volatile.
157 (UNSPECV_BLOCKAGE 0)
158 (UNSPECV_ALIGN 1)
159 (UNSPECV_CONST2 2)
160 (UNSPECV_CONST4 4)
161 (UNSPECV_CONST8 6)
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
164 ])
165
166 ;; -------------------------------------------------------------------------
167 ;; Attributes
168 ;; -------------------------------------------------------------------------
169
170 ;; Target CPU.
171
172 (define_attr "cpu"
173 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174 (const (symbol_ref "sh_cpu_attr")))
175
176 (define_attr "endian" "big,little"
177 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178 (const_string "little") (const_string "big"))))
179
180 ;; Indicate if the default fpu mode is single precision.
181 (define_attr "fpu_single" "yes,no"
182 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183 (const_string "yes") (const_string "no"))))
184
185 (define_attr "fmovd" "yes,no"
186 (const (if_then_else (symbol_ref "TARGET_FMOVD")
187 (const_string "yes") (const_string "no"))))
188 ;; pipeline model
189 (define_attr "pipe_model" "sh1,sh4,sh5media"
190 (const
191 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193 (const_string "sh1"))))
194
195 ;; cbranch conditional branch instructions
196 ;; jump unconditional jumps
197 ;; arith ordinary arithmetic
198 ;; arith3 a compound insn that behaves similarly to a sequence of
199 ;; three insns of type arith
200 ;; arith3b like above, but might end with a redirected branch
201 ;; load from memory
202 ;; load_si Likewise, SImode variant for general register.
203 ;; fload Likewise, but load to fp register.
204 ;; store to memory
205 ;; move general purpose register to register
206 ;; mt_group other sh4 mt instructions
207 ;; fmove register to register, floating point
208 ;; smpy word precision integer multiply
209 ;; dmpy longword or doublelongword precision integer multiply
210 ;; return rts
211 ;; pload load of pr reg, which can't be put into delay slot of rts
212 ;; prset copy register to pr reg, ditto
213 ;; pstore store of pr reg, which can't be put into delay slot of jsr
214 ;; prget copy pr to register, ditto
215 ;; pcload pc relative load of constant value
216 ;; pcfload Likewise, but load to fp register.
217 ;; pcload_si Likewise, SImode variant for general register.
218 ;; rte return from exception
219 ;; sfunc special function call with known used registers
220 ;; call function call
221 ;; fp floating point
222 ;; fdiv floating point divide (or square root)
223 ;; gp_fpul move from general purpose register to fpul
224 ;; fpul_gp move from fpul to general purpose register
225 ;; mac_gp move from mac[lh] to general purpose register
226 ;; dfp_arith, dfp_cmp,dfp_conv
227 ;; ftrc_s fix_truncsfsi2_i4
228 ;; dfdiv double precision floating point divide (or square root)
229 ;; cwb ic_invalidate_line_i
230 ;; movua SH4a unaligned load
231 ;; fsrra square root reciprocal approximate
232 ;; fsca sine and cosine approximate
233 ;; tls_load load TLS related address
234 ;; arith_media SHmedia arithmetic, logical, and shift instructions
235 ;; cbranch_media SHmedia conditional branch instructions
236 ;; cmp_media SHmedia compare instructions
237 ;; dfdiv_media SHmedia double precision divide and square root
238 ;; dfmul_media SHmedia double precision multiply instruction
239 ;; dfparith_media SHmedia double precision floating point arithmetic
240 ;; dfpconv_media SHmedia double precision floating point conversions
241 ;; dmpy_media SHmedia longword multiply
242 ;; fcmp_media SHmedia floating point compare instructions
243 ;; fdiv_media SHmedia single precision divide and square root
244 ;; fload_media SHmedia floating point register load instructions
245 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
246 ;; fparith_media SHmedia single precision floating point arithmetic
247 ;; fpconv_media SHmedia single precision floating point conversions
248 ;; fstore_media SHmedia floating point register store instructions
249 ;; gettr_media SHmedia gettr instruction
250 ;; invalidate_line_media SHmedia invalidate_line sequence
251 ;; jump_media SHmedia unconditional branch instructions
252 ;; load_media SHmedia general register load instructions
253 ;; pt_media SHmedia pt instruction (expanded by assembler)
254 ;; ptabs_media SHmedia ptabs instruction
255 ;; store_media SHmedia general register store instructions
256 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
257 ;; mac_media SHmedia mac-style fixed point operations
258 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
259 ;; atrans_media SHmedia approximate transcendental functions
260 ;; ustore_media SHmedia unaligned stores
261 ;; nil no-op move, will be deleted.
262
263 (define_attr "type"
264 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
265 (const_string "other"))
266
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
269 ;;
270 ;; mt_group SH4 "mt" group instructions.
271 ;;
272 ;; ex_group SH4 "ex" group instructions.
273 ;;
274 ;; ls_group SH4 "ls" group instructions.
275 ;;
276
277 (define_attr "insn_class"
278 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282 (eq_attr "type" "cbranch,jump") (const_string "br_group")
283 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284 (const_string "fe_group")
285 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
286 (const_string "none")))
287 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288 ;; so these do not belong in an insn group, although they are modeled
289 ;; with their own define_insn_reservations.
290
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
292
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
294
295 ;; Indicate if the fpu mode is set by this instruction
296 ;; "unknown" must have the value as "none" in fp_mode, and means
297 ;; that the instruction/abi has left the processor in an unknown
298 ;; state.
299 ;; "none" means that nothing has changed and no mode is set.
300 ;; This attribute is only used for the Renesas ABI.
301 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
302
303 ; If a conditional branch destination is within -252..258 bytes away
304 ; from the instruction it can be 2 bytes long. Something in the
305 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
306 ; branches are initially assumed to be 16 bytes long.
307 ; In machine_dependent_reorg, we split all branches that are longer than
308 ; 2 bytes.
309
310 ;; The maximum range used for SImode constant pool entries is 1018. A final
311 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
313 ;; instruction around the pool table, 2 bytes of alignment before the table,
314 ;; and 30 bytes of alignment after the table. That gives a maximum total
315 ;; pool size of 1058 bytes.
316 ;; Worst case code/pool content size ratio is 1:2 (using asms).
317 ;; Thus, in the worst case, there is one instruction in front of a maximum
318 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
320 ;; If we have a forward branch, the initial table will be put after the
321 ;; unconditional branch.
322 ;;
323 ;; ??? We could do much better by keeping track of the actual pcloads within
324 ;; the branch range and in the pcload range in front of the branch range.
325
326 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
327 ;; inside an le.
328 (define_attr "short_cbranch_p" "no,yes"
329 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
330 (const_string "no")
331 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
332 (const_string "yes")
333 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
334 (const_string "no")
335 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
336 (const_string "yes")
337 ] (const_string "no")))
338
339 (define_attr "med_branch_p" "no,yes"
340 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
341 (const_int 1988))
342 (const_string "yes")
343 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344 (const_string "no")
345 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
346 (const_int 8186))
347 (const_string "yes")
348 ] (const_string "no")))
349
350 (define_attr "med_cbranch_p" "no,yes"
351 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
352 (const_int 1986))
353 (const_string "yes")
354 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
355 (const_string "no")
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
357 (const_int 8184))
358 (const_string "yes")
359 ] (const_string "no")))
360
361 (define_attr "braf_branch_p" "no,yes"
362 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
363 (const_string "no")
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
365 (const_int 20660))
366 (const_string "yes")
367 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
368 (const_string "no")
369 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
370 (const_int 65530))
371 (const_string "yes")
372 ] (const_string "no")))
373
374 (define_attr "braf_cbranch_p" "no,yes"
375 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
376 (const_string "no")
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
378 (const_int 20658))
379 (const_string "yes")
380 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
381 (const_string "no")
382 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
383 (const_int 65528))
384 (const_string "yes")
385 ] (const_string "no")))
386
387 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
388 ; For wider ranges, we need a combination of a code and a data part.
389 ; If we can get a scratch register for a long range jump, the code
390 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
392 ; long; otherwise, it must be 6 bytes long.
393
394 ; All other instructions are two bytes long by default.
395
396 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397 ;; but getattrtab doesn't understand this.
398 (define_attr "length" ""
399 (cond [(eq_attr "type" "cbranch")
400 (cond [(eq_attr "short_cbranch_p" "yes")
401 (const_int 2)
402 (eq_attr "med_cbranch_p" "yes")
403 (const_int 6)
404 (eq_attr "braf_cbranch_p" "yes")
405 (const_int 12)
406 ;; ??? using pc is not computed transitively.
407 (ne (match_dup 0) (match_dup 0))
408 (const_int 14)
409 (ne (symbol_ref ("flag_pic")) (const_int 0))
410 (const_int 24)
411 ] (const_int 16))
412 (eq_attr "type" "jump")
413 (cond [(eq_attr "med_branch_p" "yes")
414 (const_int 2)
415 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
416 (symbol_ref "INSN"))
417 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
418 (symbol_ref "code_for_indirect_jump_scratch")))
419 (cond [(eq_attr "braf_branch_p" "yes")
420 (const_int 6)
421 (eq (symbol_ref "flag_pic") (const_int 0))
422 (const_int 10)
423 (ne (symbol_ref "TARGET_SH2") (const_int 0))
424 (const_int 10)] (const_int 18))
425 (eq_attr "braf_branch_p" "yes")
426 (const_int 10)
427 ;; ??? using pc is not computed transitively.
428 (ne (match_dup 0) (match_dup 0))
429 (const_int 12)
430 (ne (symbol_ref ("flag_pic")) (const_int 0))
431 (const_int 22)
432 ] (const_int 14))
433 (eq_attr "type" "pt_media")
434 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
435 (const_int 20) (const_int 12))
436 (and (eq_attr "type" "jump_media")
437 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
438 (const_int 8)
439 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
440 (const_int 4)
441 (const_int 2))))
442
443 ;; DFA descriptions for the pipelines
444
445 (include "sh1.md")
446 (include "shmedia.md")
447 (include "sh4.md")
448
449 (include "predicates.md")
450
451 ;; Definitions for filling delay slots
452
453 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
454
455 ;; ??? This should be (nil) instead of (const_int 0)
456 (define_attr "hit_stack" "yes,no"
457 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
458 (const_int 0))
459 (const_string "no")]
460 (const_string "yes")))
461
462 (define_attr "interrupt_function" "no,yes"
463 (const (symbol_ref "current_function_interrupt")))
464
465 (define_attr "in_delay_slot" "yes,no"
466 (cond [(eq_attr "type" "cbranch") (const_string "no")
467 (eq_attr "type" "pcload,pcload_si") (const_string "no")
468 (eq_attr "needs_delay_slot" "yes") (const_string "no")
469 (eq_attr "length" "2") (const_string "yes")
470 ] (const_string "no")))
471
472 (define_attr "cond_delay_slot" "yes,no"
473 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474 ] (const_string "no")))
475
476 (define_attr "is_sfunc" ""
477 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
478
479 (define_attr "is_mac_media" ""
480 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
481
482 (define_attr "branch_zero" "yes,no"
483 (cond [(eq_attr "type" "!cbranch") (const_string "no")
484 (ne (symbol_ref "(next_active_insn (insn)\
485 == (prev_active_insn\
486 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
487 && get_attr_length (next_active_insn (insn)) == 2")
488 (const_int 0))
489 (const_string "yes")]
490 (const_string "no")))
491
492 ;; SH4 Double-precision computation with double-precision result -
493 ;; the two halves are ready at different times.
494 (define_attr "dfp_comp" "yes,no"
495 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
496 (const_string "no")))
497
498 ;; Insns for which the latency of a preceding fp insn is decreased by one.
499 (define_attr "late_fp_use" "yes,no" (const_string "no"))
500 ;; And feeding insns for which this relevant.
501 (define_attr "any_fp_comp" "yes,no"
502 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
503 (const_string "yes")]
504 (const_string "no")))
505
506 (define_attr "any_int_load" "yes,no"
507 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
508 (const_string "yes")]
509 (const_string "no")))
510
511 (define_attr "highpart" "user, ignore, extend, depend, must_split"
512 (const_string "user"))
513
514 (define_delay
515 (eq_attr "needs_delay_slot" "yes")
516 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
517
518 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
519 ;; and thus we can't put a pop instruction in its delay slot.
520 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
521 ;; instruction can go in the delay slot.
522
523 ;; Since a normal return (rts) implicitly uses the PR register,
524 ;; we can't allow PR register loads in an rts delay slot.
525
526 (define_delay
527 (eq_attr "type" "return")
528 [(and (eq_attr "in_delay_slot" "yes")
529 (ior (and (eq_attr "interrupt_function" "no")
530 (eq_attr "type" "!pload,prset"))
531 (and (eq_attr "interrupt_function" "yes")
532 (ior
533 (ne (symbol_ref "TARGET_SH3") (const_int 0))
534 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
535
536 ;; Since a call implicitly uses the PR register, we can't allow
537 ;; a PR register store in a jsr delay slot.
538
539 (define_delay
540 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
541 [(and (eq_attr "in_delay_slot" "yes")
542 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
543
544 ;; Say that we have annulled true branches, since this gives smaller and
545 ;; faster code when branches are predicted as not taken.
546
547 ;; ??? The non-annulled condition should really be "in_delay_slot",
548 ;; but insns that can be filled in non-annulled get priority over insns
549 ;; that can only be filled in anulled.
550
551 (define_delay
552 (and (eq_attr "type" "cbranch")
553 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
554 ;; SH2e has a hardware bug that pretty much prohibits the use of
555 ;; annuled delay slots.
556 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
557 (not (eq_attr "cpu" "sh2e"))) (nil)])
558 \f
559 ;; -------------------------------------------------------------------------
560 ;; SImode signed integer comparisons
561 ;; -------------------------------------------------------------------------
562
563 (define_insn ""
564 [(set (reg:SI T_REG)
565 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
566 (match_operand:SI 1 "arith_operand" "K08,r"))
567 (const_int 0)))]
568 "TARGET_SH1"
569 "tst %1,%0"
570 [(set_attr "type" "mt_group")])
571
572 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
573 ;; That would still allow reload to create cmpi instructions, but would
574 ;; perhaps allow forcing the constant into a register when that is better.
575 ;; Probably should use r0 for mem/imm compares, but force constant into a
576 ;; register for pseudo/imm compares.
577
578 (define_insn "cmpeqsi_t"
579 [(set (reg:SI T_REG)
580 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
581 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
582 "TARGET_SH1"
583 "@
584 tst %0,%0
585 cmp/eq %1,%0
586 cmp/eq %1,%0"
587 [(set_attr "type" "mt_group")])
588
589 (define_insn "cmpgtsi_t"
590 [(set (reg:SI T_REG)
591 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
592 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
593 "TARGET_SH1"
594 "@
595 cmp/gt %1,%0
596 cmp/pl %0"
597 [(set_attr "type" "mt_group")])
598
599 (define_insn "cmpgesi_t"
600 [(set (reg:SI T_REG)
601 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
602 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
603 "TARGET_SH1"
604 "@
605 cmp/ge %1,%0
606 cmp/pz %0"
607 [(set_attr "type" "mt_group")])
608
609 ;; -------------------------------------------------------------------------
610 ;; SImode unsigned integer comparisons
611 ;; -------------------------------------------------------------------------
612
613 (define_insn "cmpgeusi_t"
614 [(set (reg:SI T_REG)
615 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
616 (match_operand:SI 1 "arith_reg_operand" "r")))]
617 "TARGET_SH1"
618 "cmp/hs %1,%0"
619 [(set_attr "type" "mt_group")])
620
621 (define_insn "cmpgtusi_t"
622 [(set (reg:SI T_REG)
623 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
624 (match_operand:SI 1 "arith_reg_operand" "r")))]
625 "TARGET_SH1"
626 "cmp/hi %1,%0"
627 [(set_attr "type" "mt_group")])
628
629 ;; We save the compare operands in the cmpxx patterns and use them when
630 ;; we generate the branch.
631
632 (define_expand "cmpsi"
633 [(set (reg:SI T_REG)
634 (compare (match_operand:SI 0 "cmpsi_operand" "")
635 (match_operand:SI 1 "arith_operand" "")))]
636 "TARGET_SH1 || TARGET_SHMEDIA"
637 "
638 {
639 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
640 && GET_CODE (operands[1]) != CONST_INT)
641 operands[0] = copy_to_mode_reg (SImode, operands[0]);
642 sh_compare_op0 = operands[0];
643 sh_compare_op1 = operands[1];
644 DONE;
645 }")
646 \f
647 ;; -------------------------------------------------------------------------
648 ;; DImode signed integer comparisons
649 ;; -------------------------------------------------------------------------
650
651 ;; ??? Could get better scheduling by splitting the initial test from the
652 ;; rest of the insn after reload. However, the gain would hardly justify
653 ;; the sh.md size increase necessary to do that.
654
655 (define_insn ""
656 [(set (reg:SI T_REG)
657 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
658 (match_operand:DI 1 "arith_operand" "r"))
659 (const_int 0)))]
660 "TARGET_SH1"
661 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
662 insn, operands);"
663 [(set_attr "length" "6")
664 (set_attr "type" "arith3b")])
665
666 (define_insn "cmpeqdi_t"
667 [(set (reg:SI T_REG)
668 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
669 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
670 "TARGET_SH1"
671 "@
672 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
673 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
674 [(set_attr "length" "6")
675 (set_attr "type" "arith3b")])
676
677 (define_split
678 [(set (reg:SI T_REG)
679 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
680 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
681 ;; If we applied this split when not optimizing, it would only be
682 ;; applied during the machine-dependent reorg, when no new basic blocks
683 ;; may be created.
684 "TARGET_SH1 && reload_completed && optimize"
685 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
686 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
687 (label_ref (match_dup 6))
688 (pc)))
689 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
690 (match_dup 6)]
691 "
692 {
693 operands[2]
694 = gen_rtx_REG (SImode,
695 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
696 operands[3]
697 = (operands[1] == const0_rtx
698 ? const0_rtx
699 : gen_rtx_REG (SImode,
700 true_regnum (operands[1])
701 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
702 operands[4] = gen_lowpart (SImode, operands[0]);
703 operands[5] = gen_lowpart (SImode, operands[1]);
704 operands[6] = gen_label_rtx ();
705 }")
706
707 (define_insn "cmpgtdi_t"
708 [(set (reg:SI T_REG)
709 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
710 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
711 "TARGET_SH2"
712 "@
713 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
714 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
715 [(set_attr "length" "8")
716 (set_attr "type" "arith3")])
717
718 (define_insn "cmpgedi_t"
719 [(set (reg:SI T_REG)
720 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
722 "TARGET_SH2"
723 "@
724 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
725 cmp/pz\\t%S0"
726 [(set_attr "length" "8,2")
727 (set_attr "type" "arith3,mt_group")])
728 \f
729 ;; -------------------------------------------------------------------------
730 ;; DImode unsigned integer comparisons
731 ;; -------------------------------------------------------------------------
732
733 (define_insn "cmpgeudi_t"
734 [(set (reg:SI T_REG)
735 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
736 (match_operand:DI 1 "arith_reg_operand" "r")))]
737 "TARGET_SH2"
738 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
739 [(set_attr "length" "8")
740 (set_attr "type" "arith3")])
741
742 (define_insn "cmpgtudi_t"
743 [(set (reg:SI T_REG)
744 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
745 (match_operand:DI 1 "arith_reg_operand" "r")))]
746 "TARGET_SH2"
747 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
748 [(set_attr "length" "8")
749 (set_attr "type" "arith3")])
750
751 (define_insn "cmpeqsi_media"
752 [(set (match_operand:DI 0 "register_operand" "=r")
753 (eq:DI (match_operand:SI 1 "logical_operand" "%r")
754 (match_operand:SI 2 "cmp_operand" "Nr")))]
755 "TARGET_SHMEDIA"
756 "cmpeq %1, %N2, %0"
757 [(set_attr "type" "cmp_media")])
758
759 (define_insn "cmpeqdi_media"
760 [(set (match_operand:DI 0 "register_operand" "=r")
761 (eq:DI (match_operand:DI 1 "register_operand" "%r")
762 (match_operand:DI 2 "cmp_operand" "Nr")))]
763 "TARGET_SHMEDIA"
764 "cmpeq %1, %N2, %0"
765 [(set_attr "type" "cmp_media")])
766
767 (define_insn "cmpgtsi_media"
768 [(set (match_operand:DI 0 "register_operand" "=r")
769 (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
770 (match_operand:SI 2 "cmp_operand" "rN")))]
771 "TARGET_SHMEDIA"
772 "cmpgt %N1, %N2, %0"
773 [(set_attr "type" "cmp_media")])
774
775 (define_insn "cmpgtdi_media"
776 [(set (match_operand:DI 0 "register_operand" "=r")
777 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
778 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
779 "TARGET_SHMEDIA"
780 "cmpgt %N1, %N2, %0"
781 [(set_attr "type" "cmp_media")])
782
783 (define_insn "cmpgtusi_media"
784 [(set (match_operand:DI 0 "register_operand" "=r")
785 (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
786 (match_operand:SI 2 "cmp_operand" "rN")))]
787 "TARGET_SHMEDIA"
788 "cmpgtu %N1, %N2, %0"
789 [(set_attr "type" "cmp_media")])
790
791 (define_insn "cmpgtudi_media"
792 [(set (match_operand:DI 0 "register_operand" "=r")
793 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
794 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
795 "TARGET_SHMEDIA"
796 "cmpgtu %N1, %N2, %0"
797 [(set_attr "type" "cmp_media")])
798
799 (define_insn "cmpsieqsi_media"
800 [(set (match_operand:SI 0 "register_operand" "=r")
801 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
802 (match_operand:SI 2 "cmp_operand" "Nr")))]
803 "TARGET_SHMEDIA"
804 "cmpeq %1, %N2, %0"
805 [(set_attr "type" "cmp_media")])
806
807 (define_insn "cmpsieqdi_media"
808 [(set (match_operand:SI 0 "register_operand" "=r")
809 (eq:SI (match_operand:DI 1 "register_operand" "%r")
810 (match_operand:DI 2 "cmp_operand" "Nr")))]
811 "TARGET_SHMEDIA"
812 "cmpeq %1, %N2, %0"
813 [(set_attr "type" "cmp_media")])
814
815 (define_insn "cmpsigtsi_media"
816 [(set (match_operand:SI 0 "register_operand" "=r")
817 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
818 (match_operand:SI 2 "cmp_operand" "rN")))]
819 "TARGET_SHMEDIA"
820 "cmpgt %N1, %N2, %0"
821 [(set_attr "type" "cmp_media")])
822
823 (define_insn "cmpsigtdi_media"
824 [(set (match_operand:SI 0 "register_operand" "=r")
825 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
826 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827 "TARGET_SHMEDIA"
828 "cmpgt %N1, %N2, %0"
829 [(set_attr "type" "cmp_media")])
830
831 (define_insn "cmpsigtusi_media"
832 [(set (match_operand:SI 0 "register_operand" "=r")
833 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
834 (match_operand:SI 2 "cmp_operand" "rN")))]
835 "TARGET_SHMEDIA"
836 "cmpgtu %N1, %N2, %0"
837 [(set_attr "type" "cmp_media")])
838
839 (define_insn "cmpsigtudi_media"
840 [(set (match_operand:SI 0 "register_operand" "=r")
841 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
842 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
843 "TARGET_SHMEDIA"
844 "cmpgtu %N1, %N2, %0"
845 [(set_attr "type" "cmp_media")])
846
847 ; These two patterns are for combine.
848 (define_insn "*cmpne0si_media"
849 [(set (match_operand:DI 0 "register_operand" "=r")
850 (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
851 "TARGET_SHMEDIA"
852 "cmpgtu %1,r63,%0"
853 [(set_attr "type" "cmp_media")])
854
855 (define_insn "*cmpne0sisi_media"
856 [(set (match_operand:SI 0 "register_operand" "=r")
857 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
858 "TARGET_SHMEDIA"
859 "cmpgtu %1,r63,%0"
860 [(set_attr "type" "cmp_media")])
861
862 ;; We save the compare operands in the cmpxx patterns and use them when
863 ;; we generate the branch.
864
865 (define_expand "cmpdi"
866 [(set (reg:SI T_REG)
867 (compare (match_operand:DI 0 "arith_operand" "")
868 (match_operand:DI 1 "arith_operand" "")))]
869 "TARGET_SH2 || TARGET_SHMEDIA"
870 "
871 {
872 sh_compare_op0 = operands[0];
873 sh_compare_op1 = operands[1];
874 DONE;
875 }")
876 ;; -------------------------------------------------------------------------
877 ;; Conditional move instructions
878 ;; -------------------------------------------------------------------------
879
880 ;; The insn names may seem reversed, but note that cmveq performs the move
881 ;; if op1 == 0, and cmvne does it if op1 != 0.
882
883 (define_insn "movdicc_false"
884 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
885 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
886 (const_int 0))
887 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
888 (match_operand:DI 3 "arith_reg_operand" "0")))]
889 "TARGET_SHMEDIA"
890 "cmveq %1, %N2, %0"
891 [(set_attr "type" "arith_media")])
892
893 (define_insn "movdicc_true"
894 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
895 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
896 (const_int 0))
897 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
898 (match_operand:DI 3 "arith_reg_operand" "0")))]
899 "TARGET_SHMEDIA"
900 "cmvne %1, %N2, %0"
901 [(set_attr "type" "arith_media")])
902
903 (define_peephole2
904 [(set (match_operand:DI 0 "arith_reg_dest" "")
905 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
906 [(match_operand:DI 1 "arith_reg_operand" "")
907 (const_int 0)])
908 (match_operand:DI 2 "arith_reg_dest" "")
909 (match_dup 0)))
910 (set (match_dup 2) (match_dup 0))]
911 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
912 [(set (match_dup 2)
913 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
914 "
915 {
916 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917 VOIDmode, operands[1], CONST0_RTX (DImode));
918 }")
919
920 (define_peephole2
921 [(set (match_operand:DI 0 "general_movdst_operand" "")
922 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
923 (set (match_operand:DI 2 "arith_reg_dest" "")
924 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
925 [(match_operand:DI 3 "arith_reg_operand" "")
926 (const_int 0)])
927 (match_dup 0)
928 (match_dup 2)))]
929 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
930 [(set (match_dup 2)
931 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
932 "")
933
934 (define_expand "movdicc"
935 [(set (match_operand:DI 0 "register_operand" "")
936 (if_then_else:DI (match_operand 1 "comparison_operator" "")
937 (match_operand:DI 2 "register_operand" "")
938 (match_operand:DI 3 "register_operand" "")))]
939 "TARGET_SHMEDIA"
940 "
941 {
942 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
943 && GET_MODE (sh_compare_op0) == DImode
944 && sh_compare_op1 == const0_rtx)
945 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
946 sh_compare_op0, sh_compare_op1);
947 else
948 {
949 rtx tmp;
950
951 if (no_new_pseudos)
952 FAIL;
953
954 tmp = gen_reg_rtx (DImode);
955
956 switch (GET_CODE (operands[1]))
957 {
958 case EQ:
959 emit_insn (gen_seq (tmp));
960 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
961 break;
962
963 case NE:
964 emit_insn (gen_seq (tmp));
965 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
966 break;
967
968 case GT:
969 emit_insn (gen_sgt (tmp));
970 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
971 break;
972
973 case LT:
974 emit_insn (gen_slt (tmp));
975 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
976 break;
977
978 case GE:
979 emit_insn (gen_slt (tmp));
980 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
981 break;
982
983 case LE:
984 emit_insn (gen_sgt (tmp));
985 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
986 break;
987
988 case GTU:
989 emit_insn (gen_sgtu (tmp));
990 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
991 break;
992
993 case LTU:
994 emit_insn (gen_sltu (tmp));
995 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
996 break;
997
998 case GEU:
999 emit_insn (gen_sltu (tmp));
1000 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1001 break;
1002
1003 case LEU:
1004 emit_insn (gen_sgtu (tmp));
1005 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006 break;
1007
1008 case UNORDERED:
1009 emit_insn (gen_sunordered (tmp));
1010 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011 break;
1012
1013 case ORDERED:
1014 emit_insn (gen_sunordered (tmp));
1015 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016 break;
1017
1018 case UNEQ:
1019 case UNGE:
1020 case UNGT:
1021 case UNLE:
1022 case UNLT:
1023 case LTGT:
1024 FAIL;
1025
1026 default:
1027 gcc_unreachable ();
1028 }
1029 }
1030 }")
1031
1032 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1033 ;; SImode to DImode.
1034 (define_insn "movsicc_false"
1035 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1036 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1037 (const_int 0))
1038 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1039 (match_operand:SI 3 "arith_reg_operand" "0")))]
1040 "TARGET_SHMEDIA"
1041 "cmveq %1, %N2, %0"
1042 [(set_attr "type" "arith_media")])
1043
1044 (define_insn "movsicc_true"
1045 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1046 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1047 (const_int 0))
1048 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1049 (match_operand:SI 3 "arith_reg_operand" "0")))]
1050 "TARGET_SHMEDIA"
1051 "cmvne %1, %N2, %0"
1052 [(set_attr "type" "arith_media")])
1053
1054 (define_peephole2
1055 [(set (match_operand:SI 0 "arith_reg_dest" "")
1056 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1057 [(match_operand:SI 1 "arith_reg_operand" "")
1058 (const_int 0)])
1059 (match_operand:SI 2 "arith_reg_dest" "")
1060 (match_dup 0)))
1061 (set (match_dup 2) (match_dup 0))]
1062 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1063 [(set (match_dup 2)
1064 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1065 "
1066 {
1067 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068 VOIDmode, operands[1], CONST0_RTX (SImode));
1069 }")
1070
1071 (define_peephole2
1072 [(set (match_operand:SI 0 "general_movdst_operand" "")
1073 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1074 (set (match_operand:SI 2 "arith_reg_dest" "")
1075 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1076 [(match_operand:SI 3 "arith_reg_operand" "")
1077 (const_int 0)])
1078 (match_dup 0)
1079 (match_dup 2)))]
1080 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1081 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1082 [(set (match_dup 2)
1083 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1084 "
1085 {
1086 replace_rtx (operands[4], operands[0], operands[1]);
1087 }")
1088
1089 (define_peephole2
1090 [(set (match_operand 0 "any_register_operand" "")
1091 (match_operand 1 "any_register_operand" ""))
1092 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1093 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1094 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1095 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1096 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1097 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1098 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1099 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1100 && (REGNO_REG_CLASS (REGNO (operands[0]))
1101 == REGNO_REG_CLASS (REGNO (operands[2])))
1102 && (REGNO_REG_CLASS (REGNO (operands[1]))
1103 == REGNO_REG_CLASS (REGNO (operands[0])))"
1104 [(set (match_dup 0) (match_dup 3))
1105 (set (match_dup 4) (match_dup 5))]
1106 "
1107 {
1108 rtx set1, set2;
1109 rtx replacements[4];
1110
1111 /* We want to replace occurrences of operands[0] with operands[1] and
1112 operands[2] with operands[0] in operands[4]/operands[5].
1113 Doing just two replace_rtx calls naively would result in the second
1114 replacement undoing all that the first did if operands[1] and operands[2]
1115 are identical, so we must do this simultaneously. */
1116 replacements[0] = operands[0];
1117 replacements[1] = operands[1];
1118 replacements[2] = operands[2];
1119 replacements[3] = operands[0];
1120 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1121 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1122 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1123 FAIL;
1124
1125 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1126 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1127 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1128 /* The operands array is aliased to recog_data.operand, which gets
1129 clobbered by extract_insn, so finish with it now. */
1130 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1131 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1132 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1133 always uses emit_insn. */
1134 /* Check that we don't violate matching constraints or earlyclobbers. */
1135 extract_insn (emit_insn (set1));
1136 if (! constrain_operands (1))
1137 goto failure;
1138 extract_insn (emit (set2));
1139 if (! constrain_operands (1))
1140 {
1141 rtx tmp;
1142 failure:
1143 tmp = replacements[0];
1144 replacements[0] = replacements[1];
1145 replacements[1] = tmp;
1146 tmp = replacements[2];
1147 replacements[2] = replacements[3];
1148 replacements[3] = tmp;
1149 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1150 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1151 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1152 FAIL;
1153 }
1154 DONE;
1155 }")
1156
1157 ;; The register allocator is rather clumsy in handling multi-way conditional
1158 ;; moves, so allow the combiner to make them, and we split them up after
1159 ;; reload. */
1160 (define_insn_and_split "*movsicc_umin"
1161 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1162 (umin:SI (if_then_else:SI
1163 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1164 (const_int 0))
1165 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1166 (match_operand:SI 3 "register_operand" "0"))
1167 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1168 (clobber (match_scratch:SI 5 "=&r"))]
1169 "TARGET_SHMEDIA && no_new_pseudos"
1170 "#"
1171 "TARGET_SHMEDIA && reload_completed"
1172 [(pc)]
1173 "
1174 {
1175 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1176 operands[3]));
1177 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1178 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1179 operands[0]));
1180 DONE;
1181 }")
1182
1183 (define_expand "movsicc"
1184 [(set (match_operand:SI 0 "register_operand" "")
1185 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1186 (match_operand:SI 2 "register_operand" "")
1187 (match_operand:SI 3 "register_operand" "")))]
1188 "TARGET_SHMEDIA"
1189 "
1190 {
1191 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1192 && GET_MODE (sh_compare_op0) == SImode
1193 && sh_compare_op1 == const0_rtx)
1194 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1195 sh_compare_op0, sh_compare_op1);
1196 else
1197 {
1198 rtx tmp;
1199
1200 if (no_new_pseudos)
1201 FAIL;
1202
1203 tmp = gen_reg_rtx (SImode);
1204
1205 switch (GET_CODE (operands[1]))
1206 {
1207 case EQ:
1208 emit_insn (gen_seq (tmp));
1209 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1210 break;
1211
1212 case NE:
1213 emit_insn (gen_seq (tmp));
1214 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1215 break;
1216
1217 case GT:
1218 emit_insn (gen_sgt (tmp));
1219 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1220 break;
1221
1222 case LT:
1223 emit_insn (gen_slt (tmp));
1224 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1225 break;
1226
1227 case GE:
1228 emit_insn (gen_slt (tmp));
1229 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1230 break;
1231
1232 case LE:
1233 emit_insn (gen_sgt (tmp));
1234 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1235 break;
1236
1237 case GTU:
1238 emit_insn (gen_sgtu (tmp));
1239 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1240 break;
1241
1242 case LTU:
1243 emit_insn (gen_sltu (tmp));
1244 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1245 break;
1246
1247 case GEU:
1248 emit_insn (gen_sltu (tmp));
1249 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1250 break;
1251
1252 case LEU:
1253 emit_insn (gen_sgtu (tmp));
1254 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1255 break;
1256
1257 case UNORDERED:
1258 emit_insn (gen_sunordered (tmp));
1259 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1260 break;
1261
1262 case ORDERED:
1263 emit_insn (gen_sunordered (tmp));
1264 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1265 break;
1266
1267 case UNEQ:
1268 case UNGE:
1269 case UNGT:
1270 case UNLE:
1271 case UNLT:
1272 case LTGT:
1273 FAIL;
1274
1275 default:
1276 abort ();
1277 }
1278 }
1279 }")
1280
1281 (define_expand "movqicc"
1282 [(set (match_operand:QI 0 "register_operand" "")
1283 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1284 (match_operand:QI 2 "register_operand" "")
1285 (match_operand:QI 3 "register_operand" "")))]
1286 "TARGET_SHMEDIA"
1287 "
1288 {
1289 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1290 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1291 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1292 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1293 DONE;
1294 }")
1295 \f
1296 ;; -------------------------------------------------------------------------
1297 ;; Addition instructions
1298 ;; -------------------------------------------------------------------------
1299
1300 (define_expand "adddi3"
1301 [(set (match_operand:DI 0 "arith_reg_operand" "")
1302 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1303 (match_operand:DI 2 "arith_operand" "")))]
1304 ""
1305 "
1306 {
1307 if (TARGET_SH1)
1308 {
1309 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1310 FAIL;
1311 operands[2] = force_reg (DImode, operands[2]);
1312 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1313 DONE;
1314 }
1315 }")
1316
1317 (define_insn "*adddi3_media"
1318 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1319 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1320 (match_operand:DI 2 "arith_operand" "r,I10")))]
1321 "TARGET_SHMEDIA"
1322 "@
1323 add %1, %2, %0
1324 addi %1, %2, %0"
1325 [(set_attr "type" "arith_media")])
1326
1327 (define_insn "*adddisi3_media"
1328 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1329 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1330 (match_operand:DI 2 "arith_operand" "r,I10")))]
1331 "TARGET_SHMEDIA"
1332 "@
1333 add.l %1, %2, %0
1334 addi.l %1, %2, %0"
1335 [(set_attr "type" "arith_media")
1336 (set_attr "highpart" "ignore")])
1337
1338 (define_insn "adddi3z_media"
1339 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1340 (zero_extend:DI
1341 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1342 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1343 "TARGET_SHMEDIA"
1344 "addz.l %1, %N2, %0"
1345 [(set_attr "type" "arith_media")
1346 (set_attr "highpart" "ignore")])
1347
1348 (define_insn "adddi3_compact"
1349 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1350 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1351 (match_operand:DI 2 "arith_reg_operand" "r")))
1352 (clobber (reg:SI T_REG))]
1353 "TARGET_SH1"
1354 "#"
1355 [(set_attr "length" "6")])
1356
1357 (define_split
1358 [(set (match_operand:DI 0 "arith_reg_dest" "")
1359 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1360 (match_operand:DI 2 "arith_reg_operand" "")))
1361 (clobber (reg:SI T_REG))]
1362 "TARGET_SH1 && reload_completed"
1363 [(const_int 0)]
1364 "
1365 {
1366 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1367 high0 = gen_rtx_REG (SImode,
1368 true_regnum (operands[0])
1369 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1370 high2 = gen_rtx_REG (SImode,
1371 true_regnum (operands[2])
1372 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1373 emit_insn (gen_clrt ());
1374 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1375 emit_insn (gen_addc1 (high0, high0, high2));
1376 DONE;
1377 }")
1378
1379 (define_insn "addc"
1380 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1381 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1382 (match_operand:SI 2 "arith_reg_operand" "r"))
1383 (reg:SI T_REG)))
1384 (set (reg:SI T_REG)
1385 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1386 "TARGET_SH1"
1387 "addc %2,%0"
1388 [(set_attr "type" "arith")])
1389
1390 (define_insn "addc1"
1391 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1393 (match_operand:SI 2 "arith_reg_operand" "r"))
1394 (reg:SI T_REG)))
1395 (clobber (reg:SI T_REG))]
1396 "TARGET_SH1"
1397 "addc %2,%0"
1398 [(set_attr "type" "arith")])
1399
1400 (define_expand "addsi3"
1401 [(set (match_operand:SI 0 "arith_reg_operand" "")
1402 (plus:SI (match_operand:SI 1 "arith_operand" "")
1403 (match_operand:SI 2 "arith_operand" "")))]
1404 ""
1405 "
1406 {
1407 if (TARGET_SHMEDIA)
1408 operands[1] = force_reg (SImode, operands[1]);
1409 }")
1410
1411 (define_insn "addsi3_media"
1412 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1413 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1414 (match_operand:SI 2 "arith_operand" "r,I10")))]
1415 "TARGET_SHMEDIA"
1416 "@
1417 add.l %1, %2, %0
1418 addi.l %1, %2, %0"
1419 [(set_attr "type" "arith_media")
1420 (set_attr "highpart" "ignore")])
1421
1422 (define_insn "addsidi3_media"
1423 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1424 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1425 "%r,r")
1426 (match_operand:SI 2 "arith_operand"
1427 "r,I10"))))]
1428 "TARGET_SHMEDIA"
1429 "@
1430 add.l %1, %2, %0
1431 addi.l %1, %2, %0"
1432 [(set_attr "type" "arith_media")
1433 (set_attr "highpart" "ignore")])
1434
1435 (define_insn "*addsi3_compact"
1436 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1438 (match_operand:SI 2 "arith_operand" "rI08")))]
1439 "TARGET_SH1"
1440 "add %2,%0"
1441 [(set_attr "type" "arith")])
1442
1443 ;; -------------------------------------------------------------------------
1444 ;; Subtraction instructions
1445 ;; -------------------------------------------------------------------------
1446
1447 (define_expand "subdi3"
1448 [(set (match_operand:DI 0 "arith_reg_operand" "")
1449 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1450 (match_operand:DI 2 "arith_reg_operand" "")))]
1451 ""
1452 "
1453 {
1454 if (TARGET_SH1)
1455 {
1456 operands[1] = force_reg (DImode, operands[1]);
1457 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1458 DONE;
1459 }
1460 }")
1461
1462 (define_insn "*subdi3_media"
1463 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1464 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1465 (match_operand:DI 2 "arith_reg_operand" "r")))]
1466 "TARGET_SHMEDIA"
1467 "sub %N1, %2, %0"
1468 [(set_attr "type" "arith_media")])
1469
1470 (define_insn "subdisi3_media"
1471 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1472 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1473 (match_operand:DI 2 "arith_reg_operand" "r")))]
1474 "TARGET_SHMEDIA"
1475 "sub.l %N1, %2, %0"
1476 [(set_attr "type" "arith_media")
1477 (set_attr "highpart" "ignore")])
1478
1479 (define_insn "subdi3_compact"
1480 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1481 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1482 (match_operand:DI 2 "arith_reg_operand" "r")))
1483 (clobber (reg:SI T_REG))]
1484 "TARGET_SH1"
1485 "#"
1486 [(set_attr "length" "6")])
1487
1488 (define_split
1489 [(set (match_operand:DI 0 "arith_reg_dest" "")
1490 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1491 (match_operand:DI 2 "arith_reg_operand" "")))
1492 (clobber (reg:SI T_REG))]
1493 "TARGET_SH1 && reload_completed"
1494 [(const_int 0)]
1495 "
1496 {
1497 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1498 high0 = gen_rtx_REG (SImode,
1499 true_regnum (operands[0])
1500 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1501 high2 = gen_rtx_REG (SImode,
1502 true_regnum (operands[2])
1503 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1504 emit_insn (gen_clrt ());
1505 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1506 emit_insn (gen_subc1 (high0, high0, high2));
1507 DONE;
1508 }")
1509
1510 (define_insn "subc"
1511 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1512 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1513 (match_operand:SI 2 "arith_reg_operand" "r"))
1514 (reg:SI T_REG)))
1515 (set (reg:SI T_REG)
1516 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1517 (reg:SI T_REG))
1518 (match_dup 1)))]
1519 "TARGET_SH1"
1520 "subc %2,%0"
1521 [(set_attr "type" "arith")])
1522
1523 (define_insn "subc1"
1524 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1525 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1526 (match_operand:SI 2 "arith_reg_operand" "r"))
1527 (reg:SI T_REG)))
1528 (clobber (reg:SI T_REG))]
1529 "TARGET_SH1"
1530 "subc %2,%0"
1531 [(set_attr "type" "arith")])
1532
1533 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1534 ;; pattern for this case. This helps multimedia applications that compute
1535 ;; the sum of absolute differences.
1536 (define_insn "mov_neg_si_t"
1537 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1538 "TARGET_SH1"
1539 "subc %0,%0"
1540 [(set_attr "type" "arith")])
1541
1542 (define_insn "*subsi3_internal"
1543 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1544 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1545 (match_operand:SI 2 "arith_reg_operand" "r")))]
1546 "TARGET_SH1"
1547 "sub %2,%0"
1548 [(set_attr "type" "arith")])
1549
1550 (define_insn_and_split "*subsi3_media"
1551 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1552 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1553 (match_operand:SI 2 "extend_reg_operand" "r")))]
1554 "TARGET_SHMEDIA
1555 && (operands[1] != constm1_rtx
1556 || (GET_CODE (operands[2]) != TRUNCATE
1557 && GET_CODE (operands[2]) != SUBREG))"
1558 "sub.l %N1, %2, %0"
1559 "operands[1] == constm1_rtx"
1560 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1561 ""
1562 [(set_attr "type" "arith_media")
1563 (set_attr "highpart" "ignore")])
1564
1565 (define_split
1566 [(set (match_operand:SI 0 "arith_reg_dest" "")
1567 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1568 "general_extend_operand"
1569 "") 0)) 0)))]
1570 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1571 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1572 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1573 "")
1574
1575 (define_split
1576 [(set (match_operand:SI 0 "arith_reg_dest" "")
1577 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1578 "general_extend_operand"
1579 "") 0)) 3)))]
1580 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1581 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1582 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1583 "")
1584 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1585 ;; will sometimes save one instruction. Otherwise we might get
1586 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1587 ;; are the same.
1588
1589 (define_expand "subsi3"
1590 [(set (match_operand:SI 0 "arith_reg_operand" "")
1591 (minus:SI (match_operand:SI 1 "arith_operand" "")
1592 (match_operand:SI 2 "arith_reg_operand" "")))]
1593 ""
1594 "
1595 {
1596 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1597 {
1598 emit_insn (gen_negsi2 (operands[0], operands[2]));
1599 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1600 DONE;
1601 }
1602 if (TARGET_SHMEDIA)
1603 {
1604 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1605 FAIL;
1606 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1607 operands[1] = force_reg (SImode, operands[1]);
1608 }
1609 }")
1610 \f
1611 ;; -------------------------------------------------------------------------
1612 ;; Division instructions
1613 ;; -------------------------------------------------------------------------
1614
1615 ;; We take advantage of the library routines which don't clobber as many
1616 ;; registers as a normal function call would.
1617
1618 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1619 ;; also has an effect on the register that holds the address of the sfunc.
1620 ;; To make this work, we have an extra dummy insn that shows the use
1621 ;; of this register for reorg.
1622
1623 (define_insn "use_sfunc_addr"
1624 [(set (reg:SI PR_REG)
1625 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1626 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1627 ""
1628 [(set_attr "length" "0")])
1629
1630 (define_insn "udivsi3_sh2a"
1631 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1632 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1633 (match_operand:SI 2 "arith_reg_operand" "z")))]
1634 "TARGET_SH2A"
1635 "divu %2,%1"
1636 [(set_attr "type" "arith")
1637 (set_attr "in_delay_slot" "no")])
1638
1639 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1640 ;; hard register 0. If we used hard register 0, then the next instruction
1641 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1642 ;; gets allocated to a stack slot that needs its address reloaded, then
1643 ;; there is nothing to prevent reload from using r0 to reload the address.
1644 ;; This reload would clobber the value in r0 we are trying to store.
1645 ;; If we let reload allocate r0, then this problem can never happen.
1646
1647 (define_insn "udivsi3_i1"
1648 [(set (match_operand:SI 0 "register_operand" "=z")
1649 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1650 (clobber (reg:SI T_REG))
1651 (clobber (reg:SI PR_REG))
1652 (clobber (reg:SI R4_REG))
1653 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1654 "TARGET_SH1 && ! TARGET_SH4"
1655 "jsr @%1%#"
1656 [(set_attr "type" "sfunc")
1657 (set_attr "needs_delay_slot" "yes")])
1658
1659 ; Since shmedia-nofpu code could be linked against shcompact code, and
1660 ; the udivsi3 libcall has the same name, we must consider all registers
1661 ; clobbered that are in the union of the registers clobbered by the
1662 ; shmedia and the shcompact implementation. Note, if the shcompact
1663 ; implementation actually used shcompact code, we'd need to clobber
1664 ; also r23 and fr23.
1665 (define_insn "udivsi3_i1_media"
1666 [(set (match_operand:SI 0 "register_operand" "=z")
1667 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1668 (clobber (reg:SI T_MEDIA_REG))
1669 (clobber (reg:SI PR_MEDIA_REG))
1670 (clobber (reg:SI R20_REG))
1671 (clobber (reg:SI R21_REG))
1672 (clobber (reg:SI R22_REG))
1673 (clobber (reg:DI TR0_REG))
1674 (clobber (reg:DI TR1_REG))
1675 (clobber (reg:DI TR2_REG))
1676 (use (match_operand 1 "target_operand" "b"))]
1677 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1678 "blink %1, r18"
1679 [(set_attr "type" "sfunc")
1680 (set_attr "needs_delay_slot" "yes")])
1681
1682 (define_expand "udivsi3_i4_media"
1683 [(set (match_dup 3)
1684 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1685 (set (match_dup 4)
1686 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1687 (set (match_dup 5) (float:DF (match_dup 3)))
1688 (set (match_dup 6) (float:DF (match_dup 4)))
1689 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1690 (set (match_dup 8) (fix:DI (match_dup 7)))
1691 (set (match_operand:SI 0 "register_operand" "")
1692 (truncate:SI (match_dup 8)))]
1693 "TARGET_SHMEDIA_FPU"
1694 "
1695 {
1696 operands[3] = gen_reg_rtx (DImode);
1697 operands[4] = gen_reg_rtx (DImode);
1698 operands[5] = gen_reg_rtx (DFmode);
1699 operands[6] = gen_reg_rtx (DFmode);
1700 operands[7] = gen_reg_rtx (DFmode);
1701 operands[8] = gen_reg_rtx (DImode);
1702 }")
1703
1704 (define_insn "udivsi3_i4"
1705 [(set (match_operand:SI 0 "register_operand" "=y")
1706 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1707 (clobber (reg:SI T_REG))
1708 (clobber (reg:SI PR_REG))
1709 (clobber (reg:DF DR0_REG))
1710 (clobber (reg:DF DR2_REG))
1711 (clobber (reg:DF DR4_REG))
1712 (clobber (reg:SI R0_REG))
1713 (clobber (reg:SI R1_REG))
1714 (clobber (reg:SI R4_REG))
1715 (clobber (reg:SI R5_REG))
1716 (use (reg:PSI FPSCR_REG))
1717 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1718 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1719 "jsr @%1%#"
1720 [(set_attr "type" "sfunc")
1721 (set_attr "fp_mode" "double")
1722 (set_attr "needs_delay_slot" "yes")])
1723
1724 (define_insn "udivsi3_i4_single"
1725 [(set (match_operand:SI 0 "register_operand" "=y")
1726 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1727 (clobber (reg:SI T_REG))
1728 (clobber (reg:SI PR_REG))
1729 (clobber (reg:DF DR0_REG))
1730 (clobber (reg:DF DR2_REG))
1731 (clobber (reg:DF DR4_REG))
1732 (clobber (reg:SI R0_REG))
1733 (clobber (reg:SI R1_REG))
1734 (clobber (reg:SI R4_REG))
1735 (clobber (reg:SI R5_REG))
1736 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1737 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1738 "jsr @%1%#"
1739 [(set_attr "type" "sfunc")
1740 (set_attr "needs_delay_slot" "yes")])
1741
1742 (define_expand "udivsi3"
1743 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1744 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1745 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1746 (parallel [(set (match_operand:SI 0 "register_operand" "")
1747 (udiv:SI (reg:SI R4_REG)
1748 (reg:SI R5_REG)))
1749 (clobber (reg:SI T_REG))
1750 (clobber (reg:SI PR_REG))
1751 (clobber (reg:SI R4_REG))
1752 (use (match_dup 3))])]
1753 ""
1754 "
1755 {
1756 rtx first, last;
1757
1758 operands[3] = gen_reg_rtx (Pmode);
1759 /* Emit the move of the address to a pseudo outside of the libcall. */
1760 if (TARGET_HARD_SH4 && TARGET_SH2E)
1761 {
1762 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1763 if (TARGET_FPU_SINGLE)
1764 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1765 else
1766 last = gen_udivsi3_i4 (operands[0], operands[3]);
1767 }
1768 else if (TARGET_SHMEDIA_FPU)
1769 {
1770 operands[1] = force_reg (SImode, operands[1]);
1771 operands[2] = force_reg (SImode, operands[2]);
1772 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1773 DONE;
1774 }
1775 else if (TARGET_SH2A)
1776 {
1777 operands[1] = force_reg (SImode, operands[1]);
1778 operands[2] = force_reg (SImode, operands[2]);
1779 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1780 DONE;
1781 }
1782 else if (TARGET_SH5)
1783 {
1784 function_symbol (operands[3],
1785 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1786 SFUNC_STATIC);
1787
1788 if (TARGET_SHMEDIA)
1789 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1790 else if (TARGET_FPU_ANY)
1791 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1792 else
1793 last = gen_udivsi3_i1 (operands[0], operands[3]);
1794 }
1795 else
1796 {
1797 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1798 last = gen_udivsi3_i1 (operands[0], operands[3]);
1799 }
1800 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1801 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1802 last = emit_insn (last);
1803 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1804 invariant code motion can move it. */
1805 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1806 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1807 DONE;
1808 }")
1809
1810 (define_insn "divsi3_sh2a"
1811 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1812 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1813 (match_operand:SI 2 "arith_reg_operand" "z")))]
1814 "TARGET_SH2A"
1815 "divs %2,%1"
1816 [(set_attr "type" "arith")
1817 (set_attr "in_delay_slot" "no")])
1818
1819 (define_insn "divsi3_i1"
1820 [(set (match_operand:SI 0 "register_operand" "=z")
1821 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1822 (clobber (reg:SI T_REG))
1823 (clobber (reg:SI PR_REG))
1824 (clobber (reg:SI R1_REG))
1825 (clobber (reg:SI R2_REG))
1826 (clobber (reg:SI R3_REG))
1827 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1828 "TARGET_SH1 && ! TARGET_SH4"
1829 "jsr @%1%#"
1830 [(set_attr "type" "sfunc")
1831 (set_attr "needs_delay_slot" "yes")])
1832
1833 (define_insn "divsi3_i1_media"
1834 [(set (match_operand:SI 0 "register_operand" "=z")
1835 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1836 (clobber (reg:SI T_MEDIA_REG))
1837 (clobber (reg:SI PR_MEDIA_REG))
1838 (clobber (reg:SI R1_REG))
1839 (clobber (reg:SI R20_REG))
1840 (clobber (reg:SI R21_REG))
1841 (clobber (reg:SI TR0_REG))
1842 (use (match_operand 1 "target_operand" "b"))]
1843 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1844 "blink %1, r18"
1845 [(set_attr "type" "sfunc")])
1846
1847 (define_insn "divsi3_media_2"
1848 [(set (match_operand:SI 0 "register_operand" "=z")
1849 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1850 (clobber (reg:SI T_MEDIA_REG))
1851 (clobber (reg:SI PR_MEDIA_REG))
1852 (clobber (reg:SI R1_REG))
1853 (clobber (reg:SI R21_REG))
1854 (clobber (reg:SI TR0_REG))
1855 (use (reg:SI R20_REG))
1856 (use (match_operand 1 "target_operand" "b"))]
1857 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1858 "blink %1, r18"
1859 [(set_attr "type" "sfunc")])
1860
1861 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1862 ;; hard reg clobbers and data dependencies that we need when we want
1863 ;; to rematerialize the division into a call.
1864 (define_insn_and_split "divsi_inv_call"
1865 [(set (match_operand:SI 0 "register_operand" "=r")
1866 (div:SI (match_operand:SI 1 "register_operand" "r")
1867 (match_operand:SI 2 "register_operand" "r")))
1868 (clobber (reg:SI R4_REG))
1869 (clobber (reg:SI R5_REG))
1870 (clobber (reg:SI T_MEDIA_REG))
1871 (clobber (reg:SI PR_MEDIA_REG))
1872 (clobber (reg:SI R1_REG))
1873 (clobber (reg:SI R21_REG))
1874 (clobber (reg:SI TR0_REG))
1875 (clobber (reg:SI R20_REG))
1876 (use (match_operand:SI 3 "register_operand" "r"))]
1877 "TARGET_SHMEDIA"
1878 "#"
1879 "&& (high_life_started || reload_completed)"
1880 [(set (match_dup 0) (match_dup 3))]
1881 ""
1882 [(set_attr "highpart" "must_split")])
1883
1884 ;; This is the combiner pattern for -mdiv=inv:call .
1885 (define_insn_and_split "*divsi_inv_call_combine"
1886 [(set (match_operand:SI 0 "register_operand" "=z")
1887 (div:SI (match_operand:SI 1 "register_operand" "r")
1888 (match_operand:SI 2 "register_operand" "r")))
1889 (clobber (reg:SI R4_REG))
1890 (clobber (reg:SI R5_REG))
1891 (clobber (reg:SI T_MEDIA_REG))
1892 (clobber (reg:SI PR_MEDIA_REG))
1893 (clobber (reg:SI R1_REG))
1894 (clobber (reg:SI R21_REG))
1895 (clobber (reg:SI TR0_REG))
1896 (clobber (reg:SI R20_REG))
1897 (use (unspec:SI [(match_dup 1)
1898 (match_operand:SI 3 "" "")
1899 (unspec:SI [(match_operand:SI 4 "" "")
1900 (match_dup 3)
1901 (match_operand:DI 5 "" "")]
1902 UNSPEC_DIV_INV_M2)
1903 (match_operand:DI 6 "" "")
1904 (const_int 0)
1905 (const_int 0)]
1906 UNSPEC_DIV_INV_M3))]
1907 "TARGET_SHMEDIA"
1908 "#"
1909 "&& (high_life_started || reload_completed)"
1910 [(pc)]
1911 "
1912 {
1913 const char *name = sh_divsi3_libfunc;
1914 enum sh_function_kind kind = SFUNC_GOT;
1915 rtx sym;
1916
1917 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1918 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1919 while (TARGET_DIVIDE_INV_CALL2)
1920 {
1921 rtx x = operands[3];
1922
1923 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1924 break;
1925 x = XVECEXP (x, 0, 0);
1926 name = \"__sdivsi3_2\";
1927 kind = SFUNC_STATIC;
1928 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1929 break;
1930 }
1931 sym = function_symbol (NULL, name, kind);
1932 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1933 DONE;
1934 }"
1935 [(set_attr "highpart" "must_split")])
1936
1937 (define_expand "divsi3_i4_media"
1938 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1939 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1940 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1941 (set (match_operand:SI 0 "register_operand" "=r")
1942 (fix:SI (match_dup 5)))]
1943 "TARGET_SHMEDIA_FPU"
1944 "
1945 {
1946 operands[3] = gen_reg_rtx (DFmode);
1947 operands[4] = gen_reg_rtx (DFmode);
1948 operands[5] = gen_reg_rtx (DFmode);
1949 }")
1950
1951 (define_insn "divsi3_i4"
1952 [(set (match_operand:SI 0 "register_operand" "=y")
1953 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1954 (clobber (reg:SI PR_REG))
1955 (clobber (reg:DF DR0_REG))
1956 (clobber (reg:DF DR2_REG))
1957 (use (reg:PSI FPSCR_REG))
1958 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1959 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1960 "jsr @%1%#"
1961 [(set_attr "type" "sfunc")
1962 (set_attr "fp_mode" "double")
1963 (set_attr "needs_delay_slot" "yes")])
1964
1965 (define_insn "divsi3_i4_single"
1966 [(set (match_operand:SI 0 "register_operand" "=y")
1967 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1968 (clobber (reg:SI PR_REG))
1969 (clobber (reg:DF DR0_REG))
1970 (clobber (reg:DF DR2_REG))
1971 (clobber (reg:SI R2_REG))
1972 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1973 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1974 "jsr @%1%#"
1975 [(set_attr "type" "sfunc")
1976 (set_attr "needs_delay_slot" "yes")])
1977
1978 (define_expand "divsi3"
1979 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1980 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1981 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1982 (parallel [(set (match_operand:SI 0 "register_operand" "")
1983 (div:SI (reg:SI R4_REG)
1984 (reg:SI R5_REG)))
1985 (clobber (reg:SI T_REG))
1986 (clobber (reg:SI PR_REG))
1987 (clobber (reg:SI R1_REG))
1988 (clobber (reg:SI R2_REG))
1989 (clobber (reg:SI R3_REG))
1990 (use (match_dup 3))])]
1991 ""
1992 "
1993 {
1994 rtx first, last;
1995
1996 operands[3] = gen_reg_rtx (Pmode);
1997 /* Emit the move of the address to a pseudo outside of the libcall. */
1998 if (TARGET_HARD_SH4 && TARGET_SH2E)
1999 {
2000 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2001 if (TARGET_FPU_SINGLE)
2002 last = gen_divsi3_i4_single (operands[0], operands[3]);
2003 else
2004 last = gen_divsi3_i4 (operands[0], operands[3]);
2005 }
2006 else if (TARGET_SH2A)
2007 {
2008 operands[1] = force_reg (SImode, operands[1]);
2009 operands[2] = force_reg (SImode, operands[2]);
2010 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2011 DONE;
2012 }
2013 else if (TARGET_DIVIDE_INV)
2014 {
2015 rtx dividend = operands[1];
2016 rtx divisor = operands[2];
2017 rtx tab_base;
2018 rtx nsb_res = gen_reg_rtx (DImode);
2019 rtx norm64 = gen_reg_rtx (DImode);
2020 rtx tab_ix = gen_reg_rtx (DImode);
2021 rtx norm32 = gen_reg_rtx (SImode);
2022 rtx i92 = force_reg (DImode, GEN_INT (92));
2023 rtx scratch0a = gen_reg_rtx (DImode);
2024 rtx scratch0b = gen_reg_rtx (DImode);
2025 rtx inv0 = gen_reg_rtx (SImode);
2026 rtx scratch1a = gen_reg_rtx (DImode);
2027 rtx scratch1b = gen_reg_rtx (DImode);
2028 rtx shift = gen_reg_rtx (DImode);
2029 rtx i2p27, i43;
2030 rtx inv1 = gen_reg_rtx (SImode);
2031 rtx scratch2a = gen_reg_rtx (DImode);
2032 rtx scratch2b = gen_reg_rtx (SImode);
2033 rtx inv2 = gen_reg_rtx (SImode);
2034 rtx scratch3a = gen_reg_rtx (DImode);
2035 rtx scratch3b = gen_reg_rtx (DImode);
2036 rtx scratch3c = gen_reg_rtx (DImode);
2037 rtx scratch3d = gen_reg_rtx (SImode);
2038 rtx scratch3e = gen_reg_rtx (DImode);
2039 rtx result = gen_reg_rtx (SImode);
2040
2041 if (! arith_reg_or_0_operand (dividend, SImode))
2042 dividend = force_reg (SImode, dividend);
2043 if (! arith_reg_operand (divisor, SImode))
2044 divisor = force_reg (SImode, divisor);
2045 if (flag_pic && Pmode != DImode)
2046 {
2047 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2048 tab_base = gen_datalabel_ref (tab_base);
2049 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2050 }
2051 else
2052 {
2053 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2054 tab_base = gen_datalabel_ref (tab_base);
2055 tab_base = force_reg (DImode, tab_base);
2056 }
2057 if (TARGET_DIVIDE_INV20U)
2058 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2059 else
2060 i2p27 = GEN_INT (0);
2061 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2062 i43 = force_reg (DImode, GEN_INT (43));
2063 else
2064 i43 = GEN_INT (0);
2065 emit_insn (gen_nsbdi (nsb_res,
2066 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2067 emit_insn (gen_ashldi3_media (norm64,
2068 gen_rtx_SUBREG (DImode, divisor, 0),
2069 nsb_res));
2070 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2071 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2072 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2073 inv0, scratch0a, scratch0b,
2074 scratch1a, scratch1b));
2075 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2076 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2077 scratch2a));
2078 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2079 i2p27, i43,
2080 scratch3a, scratch3b, scratch3c,
2081 scratch2a, scratch2b, scratch3d, scratch3e));
2082 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2083 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2084 else if (TARGET_DIVIDE_INV_FP)
2085 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2086 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2087 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2088 gen_reg_rtx (DFmode)));
2089 else
2090 emit_move_insn (operands[0], result);
2091 DONE;
2092 }
2093 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2094 {
2095 operands[1] = force_reg (SImode, operands[1]);
2096 operands[2] = force_reg (SImode, operands[2]);
2097 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2098 DONE;
2099 }
2100 else if (TARGET_SH5)
2101 {
2102 if (TARGET_DIVIDE_CALL2)
2103 {
2104 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2105 tab_base = gen_datalabel_ref (tab_base);
2106 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2107 }
2108 if (TARGET_FPU_ANY && TARGET_SH1)
2109 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2110 else if (TARGET_DIVIDE_CALL2)
2111 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2112 else
2113 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2114
2115 if (TARGET_SHMEDIA)
2116 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2117 (operands[0], operands[3]));
2118 else if (TARGET_FPU_ANY)
2119 last = gen_divsi3_i4_single (operands[0], operands[3]);
2120 else
2121 last = gen_divsi3_i1 (operands[0], operands[3]);
2122 }
2123 else
2124 {
2125 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2126 last = gen_divsi3_i1 (operands[0], operands[3]);
2127 }
2128 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2129 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2130 last = emit_insn (last);
2131 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2132 invariant code motion can move it. */
2133 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2134 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2135 DONE;
2136 }")
2137
2138 ;; operands: inv0, tab_base, tab_ix, norm32
2139 ;; scratch equiv in sdivsi3_2: r19, r21
2140 (define_expand "divsi_inv_m0"
2141 [(set (match_operand:SI 0 "register_operand" "=r")
2142 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2143 (match_operand:DI 2 "register_operand" "r")
2144 (match_operand:SI 3 "register_operand" "r")]
2145 UNSPEC_DIV_INV_M0))
2146 (clobber (match_operand:DI 4 "register_operand" "=r"))
2147 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2148 "TARGET_SHMEDIA"
2149 "
2150 {
2151 /*
2152 tab_base: r20
2153 tab_ix: r21
2154 norm32: r25
2155 ldx.ub r20, r21, r19 // u0.8
2156 shlli r21, 1, r21
2157 muls.l r25, r19, r19 // s2.38
2158 ldx.w r20, r21, r21 // s2.14
2159 shari r19, 24, r19 // truncate to s2.14
2160 sub r21, r19, r19 // some 11 bit inverse in s1.14
2161 */
2162
2163 rtx inv0 = operands[0];
2164 rtx tab_base = operands[1];
2165 rtx tab_ix = operands[2];
2166 rtx norm32 = operands[3];
2167 rtx scratch0 = operands[4];
2168 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2169 rtx scratch1 = operands[5];
2170 rtx mem;
2171
2172 mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2173 emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2174 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2175 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2176 mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2177 emit_insn (gen_extendhidi2 (scratch1, mem));
2178 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2179 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2180 DONE;
2181 }")
2182
2183 ;; operands: inv1, tab_base, tab_ix, norm32
2184 (define_insn_and_split "divsi_inv_m1"
2185 [(set (match_operand:SI 0 "register_operand" "=r")
2186 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2187 (match_operand:DI 2 "register_operand" "r")
2188 (match_operand:SI 3 "register_operand" "r")]
2189 UNSPEC_DIV_INV_M1))
2190 (clobber (match_operand:SI 4 "register_operand" "=r"))
2191 (clobber (match_operand:DI 5 "register_operand" "=r"))
2192 (clobber (match_operand:DI 6 "register_operand" "=r"))
2193 (clobber (match_operand:DI 7 "register_operand" "=r"))
2194 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2195 "TARGET_SHMEDIA"
2196 "#"
2197 "&& no_new_pseudos"
2198 [(pc)]
2199 "
2200 {
2201 /* inv0: r19
2202 muls.l r19, r19, r18 // u0.28
2203 muls.l r25, r18, r18 // s2.58
2204 shlli r19, 45, r0 // multiply by two and convert to s2.58
2205 sub r0, r18, r18
2206 shari r18, 28, r18 // some 18 bit inverse in s1.30
2207 */
2208
2209 rtx inv1 = operands[0];
2210 rtx tab_base = operands[1];
2211 rtx tab_ix = operands[2];
2212 rtx norm32 = operands[3];
2213 rtx inv0 = operands[4];
2214 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2215 rtx scratch0a = operands[5];
2216 rtx scratch0b = operands[6];
2217 rtx scratch0 = operands[7];
2218 rtx scratch1 = operands[8];
2219 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2220
2221 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2222 scratch0a, scratch0b));
2223 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2224 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2225 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2226 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2227 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2228 DONE;
2229 }")
2230
2231 ;; operands: inv2, norm32, inv1, i92
2232 (define_insn_and_split "divsi_inv_m2"
2233 [(set (match_operand:SI 0 "register_operand" "=r")
2234 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2235 (match_operand:SI 2 "register_operand" "r")
2236 (match_operand:DI 3 "register_operand" "r")]
2237 UNSPEC_DIV_INV_M2))
2238 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2239 "TARGET_SHMEDIA"
2240 "#"
2241 "&& no_new_pseudos"
2242 [(pc)]
2243 "
2244 {
2245 /*
2246 muls.l r18, r25, r0 // s2.60
2247 shari r0, 16, r0 // s-16.44
2248 sub
2249 muls.l r0, r18, r19 // s-16.74
2250 shari r19, 30, r19 // s-16.44
2251 */
2252 rtx inv2 = operands[0];
2253 rtx norm32 = operands[1];
2254 rtx inv1 = operands[2];
2255 rtx i92 = operands[3];
2256 rtx scratch0 = operands[4];
2257 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2258
2259 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2260 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2261 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2262 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2263 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2264 DONE;
2265 }")
2266
2267 (define_insn_and_split "divsi_inv_m3"
2268 [(set (match_operand:SI 0 "register_operand" "=r")
2269 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2270 (match_operand:SI 2 "register_operand" "r")
2271 (match_operand:SI 3 "register_operand" "r")
2272 (match_operand:DI 4 "register_operand" "r")
2273 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2274 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2275 UNSPEC_DIV_INV_M3))
2276 (clobber (match_operand:DI 7 "register_operand" "=r"))
2277 (clobber (match_operand:DI 8 "register_operand" "=r"))
2278 (clobber (match_operand:DI 9 "register_operand" "=r"))
2279 (clobber (match_operand:DI 10 "register_operand" "=r"))
2280 (clobber (match_operand:SI 11 "register_operand" "=r"))
2281 (clobber (match_operand:SI 12 "register_operand" "=r"))
2282 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2283 "TARGET_SHMEDIA"
2284 "#"
2285 "&& no_new_pseudos"
2286 [(pc)]
2287 "
2288 {
2289 /*
2290 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2291 r0: scratch0 r19: scratch1 r21: scratch2
2292
2293 muls.l r18, r4, r25 // s32.30
2294 muls.l r19, r4, r19 // s15.30
2295 shari r25, 63, r21
2296 shari r19, 14, r19 // s18.-14
2297 sub r25, r19, r0
2298 shard r0, r1, r0
2299 sub r0, r21, r0
2300 */
2301
2302 rtx result = operands[0];
2303 rtx dividend = operands[1];
2304 rtx inv1 = operands[2];
2305 rtx inv2 = operands[3];
2306 rtx shift = operands[4];
2307 rtx scratch0 = operands[7];
2308 rtx scratch1 = operands[8];
2309 rtx scratch2 = operands[9];
2310
2311 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2312 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2313 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2314 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2315 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2316 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2317 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2318 DONE;
2319 }")
2320
2321 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2322 ;; inv1: tab_base, tab_ix, norm32
2323 ;; inv2: norm32, inv1, i92
2324 (define_insn_and_split "divsi_inv_m1_3"
2325 [(set (match_operand:SI 0 "register_operand" "=r")
2326 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2327 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2328 (match_operand:DI 3 "register_operand" "r")
2329 (match_operand:SI 4 "register_operand" "r")]
2330 UNSPEC_DIV_INV_M1)
2331 (unspec:SI [(match_dup 4)
2332 (unspec:SI [(match_dup 2)
2333 (match_dup 3)
2334 (match_dup 4)] UNSPEC_DIV_INV_M1)
2335 (match_operand:SI 5 "" "")]
2336 UNSPEC_DIV_INV_M2)
2337 (match_operand:DI 6 "register_operand" "r")
2338 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2339 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2340 UNSPEC_DIV_INV_M3))
2341 (clobber (match_operand:DI 9 "register_operand" "=r"))
2342 (clobber (match_operand:DI 10 "register_operand" "=r"))
2343 (clobber (match_operand:DI 11 "register_operand" "=r"))
2344 (clobber (match_operand:DI 12 "register_operand" "=r"))
2345 (clobber (match_operand:SI 13 "register_operand" "=r"))
2346 (clobber (match_operand:SI 14 "register_operand" "=r"))
2347 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2348 "TARGET_SHMEDIA
2349 && (TARGET_DIVIDE_INV_MINLAT
2350 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2351 "#"
2352 "&& no_new_pseudos"
2353 [(pc)]
2354 "
2355 {
2356 rtx result = operands[0];
2357 rtx dividend = operands[1];
2358 rtx tab_base = operands[2];
2359 rtx tab_ix = operands[3];
2360 rtx norm32 = operands[4];
2361 /* rtx i92 = operands[5]; */
2362 rtx shift = operands[6];
2363 rtx i2p27 = operands[7];
2364 rtx i43 = operands[8];
2365 rtx scratch0 = operands[9];
2366 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2367 rtx scratch1 = operands[10];
2368 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2369 rtx scratch2 = operands[11];
2370 rtx scratch3 = operands[12];
2371 rtx scratch4 = operands[13];
2372 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2373 rtx scratch5 = operands[14];
2374 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2375 rtx scratch6 = operands[15];
2376
2377 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2378 scratch0, scratch1));
2379 /* inv0 == scratch4 */
2380 if (! TARGET_DIVIDE_INV20U)
2381 {
2382 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2383 i2p27 = scratch0;
2384 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2385 }
2386 else
2387 {
2388 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2389 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2390 }
2391 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2392 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2393 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2394 /* inv1 == scratch4 */
2395
2396 if (TARGET_DIVIDE_INV_MINLAT)
2397 {
2398 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2399 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2400 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2401 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2402 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2403 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2404 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2405 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2406 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2407 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2408 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2409 }
2410 else
2411 {
2412 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2413 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2414 emit_insn (gen_nsbdi (scratch6,
2415 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2416 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2417 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2418 emit_insn (gen_divsi_inv20 (scratch2,
2419 norm32, scratch4, dividend,
2420 scratch6, scratch3, i43,
2421 /* scratch0 may be shared with i2p27. */
2422 scratch0, scratch1, scratch5,
2423 label, label, i2p27));
2424 }
2425 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2426 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2427 DONE;
2428 }")
2429
2430 (define_insn "divsi_inv20"
2431 [(set (match_operand:DI 0 "register_operand" "=&r")
2432 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2433 (match_operand:SI 2 "register_operand" "r")
2434 (match_operand:SI 3 "register_operand" "r")
2435 (match_operand:DI 4 "register_operand" "r")
2436 (match_operand:DI 5 "register_operand" "r")
2437 (match_operand:DI 6 "register_operand" "r")
2438 (match_operand:DI 12 "register_operand" "r")
2439 (match_operand 10 "target_operand" "b")
2440 (match_operand 11 "immediate_operand" "i")]
2441 UNSPEC_DIV_INV20))
2442 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2443 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2444 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2445 "TARGET_SHMEDIA
2446 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2447 "*
2448 {
2449 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2450 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2451 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2452 %10 label (tr), %11 label (imm)
2453
2454 muls.l inv1, norm32, scratch0 // s2.60
2455 muls.l inv1, dividend, result // s32.30
2456 xor i2p27, result_sign, round_scratch
2457 bge/u dividend_nsb, i43, tr.. (label)
2458 shari scratch0, 16, scratch0 // s-16.44
2459 muls.l sratch0_si, inv1, scratch0 // s-16.74
2460 sub result, round_scratch, result
2461 shari dividend, 14, scratch1 // s19.-14
2462 shari scratch0, 30, scratch0 // s-16.44
2463 muls.l scratch0, scratch1, round_scratch // s15.30
2464 label:
2465 sub result, round_scratch, result */
2466
2467 int likely = TARGET_DIVIDE_INV20L;
2468
2469 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2470 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2471 output_asm_insn (likely
2472 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2473 : \"bge/u\t%4, %6, %10\", operands);
2474 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2475 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2476 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2477 return (likely
2478 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2479 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2480 }")
2481
2482 (define_insn_and_split "divsi_inv_fp"
2483 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2484 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2485 (match_operand:SI 2 "register_operand" "rf")))
2486 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2487 (clobber (match_operand:SI 4 "register_operand" "=r"))
2488 (clobber (match_operand:SI 5 "register_operand" "=r"))
2489 (clobber (match_operand:DF 6 "register_operand" "=r"))
2490 (clobber (match_operand:DF 7 "register_operand" "=r"))
2491 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2492 "TARGET_SHMEDIA_FPU"
2493 "#"
2494 "&& (high_life_started || reload_completed)"
2495 [(set (match_dup 0) (match_dup 3))]
2496 ""
2497 [(set_attr "highpart" "must_split")])
2498
2499 ;; If a matching group of divide-by-inverse instructions is in the same
2500 ;; basic block after gcse & loop optimizations, we want to transform them
2501 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2502 (define_insn_and_split "*divsi_inv_fp_combine"
2503 [(set (match_operand:SI 0 "register_operand" "=f")
2504 (div:SI (match_operand:SI 1 "register_operand" "f")
2505 (match_operand:SI 2 "register_operand" "f")))
2506 (use (unspec:SI [(match_dup 1)
2507 (match_operand:SI 3 "" "")
2508 (unspec:SI [(match_operand:SI 4 "" "")
2509 (match_dup 3)
2510 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2511 (match_operand:DI 6 "" "")
2512 (const_int 0)
2513 (const_int 0)] UNSPEC_DIV_INV_M3))
2514 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2515 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2516 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2517 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2518 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2519 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2520 "#"
2521 "&& 1"
2522 [(set (match_dup 9) (float:DF (match_dup 1)))
2523 (set (match_dup 10) (float:DF (match_dup 2)))
2524 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2525 (set (match_dup 8)
2526 (fix:SI (match_dup 11)))
2527 (set (match_dup 0) (match_dup 8))]
2528 "
2529 {
2530 if (! fp_arith_reg_operand (operands[1], SImode))
2531 {
2532 emit_move_insn (operands[7], operands[1]);
2533 operands[1] = operands[7];
2534 }
2535 if (! fp_arith_reg_operand (operands[2], SImode))
2536 {
2537 emit_move_insn (operands[8], operands[2]);
2538 operands[2] = operands[8];
2539 }
2540 }"
2541 [(set_attr "highpart" "must_split")])
2542 \f
2543 ;; -------------------------------------------------------------------------
2544 ;; Multiplication instructions
2545 ;; -------------------------------------------------------------------------
2546
2547 (define_insn "umulhisi3_i"
2548 [(set (reg:SI MACL_REG)
2549 (mult:SI (zero_extend:SI
2550 (match_operand:HI 0 "arith_reg_operand" "r"))
2551 (zero_extend:SI
2552 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2553 "TARGET_SH1"
2554 "mulu.w %1,%0"
2555 [(set_attr "type" "smpy")])
2556
2557 (define_insn "mulhisi3_i"
2558 [(set (reg:SI MACL_REG)
2559 (mult:SI (sign_extend:SI
2560 (match_operand:HI 0 "arith_reg_operand" "r"))
2561 (sign_extend:SI
2562 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2563 "TARGET_SH1"
2564 "muls.w %1,%0"
2565 [(set_attr "type" "smpy")])
2566
2567 (define_expand "mulhisi3"
2568 [(set (reg:SI MACL_REG)
2569 (mult:SI (sign_extend:SI
2570 (match_operand:HI 1 "arith_reg_operand" ""))
2571 (sign_extend:SI
2572 (match_operand:HI 2 "arith_reg_operand" ""))))
2573 (set (match_operand:SI 0 "arith_reg_operand" "")
2574 (reg:SI MACL_REG))]
2575 "TARGET_SH1"
2576 "
2577 {
2578 rtx first, last;
2579
2580 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2581 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2582 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2583 invariant code motion can move it. */
2584 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2585 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2586 /* expand_binop can't find a suitable code in umul_widen_optab to
2587 make a REG_EQUAL note from, so make one here.
2588 See also smulsi3_highpart.
2589 ??? Alternatively, we could put this at the calling site of expand_binop,
2590 i.e. expand_expr. */
2591 REG_NOTES (last)
2592 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2593 REG_NOTES (last));
2594 DONE;
2595 }")
2596
2597 (define_expand "umulhisi3"
2598 [(set (reg:SI MACL_REG)
2599 (mult:SI (zero_extend:SI
2600 (match_operand:HI 1 "arith_reg_operand" ""))
2601 (zero_extend:SI
2602 (match_operand:HI 2 "arith_reg_operand" ""))))
2603 (set (match_operand:SI 0 "arith_reg_operand" "")
2604 (reg:SI MACL_REG))]
2605 "TARGET_SH1"
2606 "
2607 {
2608 rtx first, last;
2609
2610 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2611 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2612 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2613 invariant code motion can move it. */
2614 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2615 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2616 /* expand_binop can't find a suitable code in umul_widen_optab to
2617 make a REG_EQUAL note from, so make one here.
2618 See also smulsi3_highpart.
2619 ??? Alternatively, we could put this at the calling site of expand_binop,
2620 i.e. expand_expr. */
2621 REG_NOTES (last)
2622 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2623 REG_NOTES (last));
2624 DONE;
2625 }")
2626
2627 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2628 ;; a call to a routine which clobbers known registers.
2629
2630 (define_insn ""
2631 [(set (match_operand:SI 1 "register_operand" "=z")
2632 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2633 (clobber (reg:SI MACL_REG))
2634 (clobber (reg:SI T_REG))
2635 (clobber (reg:SI PR_REG))
2636 (clobber (reg:SI R3_REG))
2637 (clobber (reg:SI R2_REG))
2638 (clobber (reg:SI R1_REG))
2639 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2640 "TARGET_SH1"
2641 "jsr @%0%#"
2642 [(set_attr "type" "sfunc")
2643 (set_attr "needs_delay_slot" "yes")])
2644
2645 (define_expand "mulsi3_call"
2646 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2647 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2648 (parallel[(set (match_operand:SI 0 "register_operand" "")
2649 (mult:SI (reg:SI R4_REG)
2650 (reg:SI R5_REG)))
2651 (clobber (reg:SI MACL_REG))
2652 (clobber (reg:SI T_REG))
2653 (clobber (reg:SI PR_REG))
2654 (clobber (reg:SI R3_REG))
2655 (clobber (reg:SI R2_REG))
2656 (clobber (reg:SI R1_REG))
2657 (use (match_operand:SI 3 "register_operand" ""))])]
2658 "TARGET_SH1"
2659 "")
2660
2661 (define_insn "mul_r"
2662 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2663 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2664 (match_operand:SI 2 "arith_reg_operand" "z")))]
2665 "TARGET_SH2A"
2666 "mulr %2,%0"
2667 [(set_attr "type" "dmpy")])
2668
2669 (define_insn "mul_l"
2670 [(set (reg:SI MACL_REG)
2671 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2672 (match_operand:SI 1 "arith_reg_operand" "r")))]
2673 "TARGET_SH2"
2674 "mul.l %1,%0"
2675 [(set_attr "type" "dmpy")])
2676
2677 (define_expand "mulsi3"
2678 [(set (reg:SI MACL_REG)
2679 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2680 (match_operand:SI 2 "arith_reg_operand" "")))
2681 (set (match_operand:SI 0 "arith_reg_operand" "")
2682 (reg:SI MACL_REG))]
2683 "TARGET_SH1"
2684 "
2685 {
2686 rtx first, last;
2687
2688 if (!TARGET_SH2)
2689 {
2690 /* The address must be set outside the libcall,
2691 since it goes into a pseudo. */
2692 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2693 rtx addr = force_reg (SImode, sym);
2694 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2695 operands[2], addr);
2696 first = insns;
2697 last = emit_insn (insns);
2698 }
2699 else
2700 {
2701 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2702
2703 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2704 /* consec_sets_giv can only recognize the first insn that sets a
2705 giv as the giv insn. So we must tag this also with a REG_EQUAL
2706 note. */
2707 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2708 }
2709 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2710 invariant code motion can move it. */
2711 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2712 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2713 DONE;
2714 }")
2715
2716 (define_insn "mulsidi3_i"
2717 [(set (reg:SI MACH_REG)
2718 (truncate:SI
2719 (lshiftrt:DI
2720 (mult:DI
2721 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2722 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2723 (const_int 32))))
2724 (set (reg:SI MACL_REG)
2725 (mult:SI (match_dup 0)
2726 (match_dup 1)))]
2727 "TARGET_SH2"
2728 "dmuls.l %1,%0"
2729 [(set_attr "type" "dmpy")])
2730
2731 (define_expand "mulsidi3"
2732 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2733 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2734 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2735 "TARGET_SH2 || TARGET_SHMEDIA"
2736 "
2737 {
2738 if (TARGET_SH2)
2739 {
2740 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2741 operands[2]));
2742 DONE;
2743 }
2744 }")
2745
2746 (define_insn "mulsidi3_media"
2747 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2748 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2749 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2750 "TARGET_SHMEDIA"
2751 "muls.l %1, %2, %0"
2752 [(set_attr "type" "dmpy_media")
2753 (set_attr "highpart" "ignore")])
2754
2755 (define_insn "mulsidi3_compact"
2756 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2757 (mult:DI
2758 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2759 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2760 (clobber (reg:SI MACH_REG))
2761 (clobber (reg:SI MACL_REG))]
2762 "TARGET_SH2"
2763 "#")
2764
2765 (define_split
2766 [(set (match_operand:DI 0 "arith_reg_dest" "")
2767 (mult:DI
2768 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2769 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2770 (clobber (reg:SI MACH_REG))
2771 (clobber (reg:SI MACL_REG))]
2772 "TARGET_SH2"
2773 [(const_int 0)]
2774 "
2775 {
2776 rtx low_dst = gen_lowpart (SImode, operands[0]);
2777 rtx high_dst = gen_highpart (SImode, operands[0]);
2778
2779 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2780
2781 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2782 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2783 /* We need something to tag the possible REG_EQUAL notes on to. */
2784 emit_move_insn (operands[0], operands[0]);
2785 DONE;
2786 }")
2787
2788 (define_insn "umulsidi3_i"
2789 [(set (reg:SI MACH_REG)
2790 (truncate:SI
2791 (lshiftrt:DI
2792 (mult:DI
2793 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2794 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2795 (const_int 32))))
2796 (set (reg:SI MACL_REG)
2797 (mult:SI (match_dup 0)
2798 (match_dup 1)))]
2799 "TARGET_SH2"
2800 "dmulu.l %1,%0"
2801 [(set_attr "type" "dmpy")])
2802
2803 (define_expand "umulsidi3"
2804 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2805 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2806 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2807 "TARGET_SH2 || TARGET_SHMEDIA"
2808 "
2809 {
2810 if (TARGET_SH2)
2811 {
2812 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2813 operands[2]));
2814 DONE;
2815 }
2816 }")
2817
2818 (define_insn "umulsidi3_media"
2819 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2820 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2821 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2822 "TARGET_SHMEDIA"
2823 "mulu.l %1, %2, %0"
2824 [(set_attr "type" "dmpy_media")
2825 (set_attr "highpart" "ignore")])
2826
2827 (define_insn "umulsidi3_compact"
2828 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2829 (mult:DI
2830 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2831 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2832 (clobber (reg:SI MACH_REG))
2833 (clobber (reg:SI MACL_REG))]
2834 "TARGET_SH2"
2835 "#")
2836
2837 (define_split
2838 [(set (match_operand:DI 0 "arith_reg_dest" "")
2839 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2840 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2841 (clobber (reg:SI MACH_REG))
2842 (clobber (reg:SI MACL_REG))]
2843 "TARGET_SH2"
2844 [(const_int 0)]
2845 "
2846 {
2847 rtx low_dst = gen_lowpart (SImode, operands[0]);
2848 rtx high_dst = gen_highpart (SImode, operands[0]);
2849
2850 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2851
2852 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2853 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2854 /* We need something to tag the possible REG_EQUAL notes on to. */
2855 emit_move_insn (operands[0], operands[0]);
2856 DONE;
2857 }")
2858
2859 (define_insn "smulsi3_highpart_i"
2860 [(set (reg:SI MACH_REG)
2861 (truncate:SI
2862 (lshiftrt:DI
2863 (mult:DI
2864 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2865 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2866 (const_int 32))))
2867 (clobber (reg:SI MACL_REG))]
2868 "TARGET_SH2"
2869 "dmuls.l %1,%0"
2870 [(set_attr "type" "dmpy")])
2871
2872 (define_expand "smulsi3_highpart"
2873 [(parallel
2874 [(set (reg:SI MACH_REG)
2875 (truncate:SI
2876 (lshiftrt:DI
2877 (mult:DI
2878 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2879 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2880 (const_int 32))))
2881 (clobber (reg:SI MACL_REG))])
2882 (set (match_operand:SI 0 "arith_reg_operand" "")
2883 (reg:SI MACH_REG))]
2884 "TARGET_SH2"
2885 "
2886 {
2887 rtx first, last;
2888
2889 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2890 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2891 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2892 invariant code motion can move it. */
2893 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2894 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2895 /* expand_binop can't find a suitable code in mul_highpart_optab to
2896 make a REG_EQUAL note from, so make one here.
2897 See also {,u}mulhisi.
2898 ??? Alternatively, we could put this at the calling site of expand_binop,
2899 i.e. expand_mult_highpart. */
2900 REG_NOTES (last)
2901 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2902 REG_NOTES (last));
2903 DONE;
2904 }")
2905
2906 (define_insn "umulsi3_highpart_i"
2907 [(set (reg:SI MACH_REG)
2908 (truncate:SI
2909 (lshiftrt:DI
2910 (mult:DI
2911 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2912 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2913 (const_int 32))))
2914 (clobber (reg:SI MACL_REG))]
2915 "TARGET_SH2"
2916 "dmulu.l %1,%0"
2917 [(set_attr "type" "dmpy")])
2918
2919 (define_expand "umulsi3_highpart"
2920 [(parallel
2921 [(set (reg:SI MACH_REG)
2922 (truncate:SI
2923 (lshiftrt:DI
2924 (mult:DI
2925 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2926 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2927 (const_int 32))))
2928 (clobber (reg:SI MACL_REG))])
2929 (set (match_operand:SI 0 "arith_reg_operand" "")
2930 (reg:SI MACH_REG))]
2931 "TARGET_SH2"
2932 "
2933 {
2934 rtx first, last;
2935
2936 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2937 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2938 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2939 invariant code motion can move it. */
2940 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2941 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2942 DONE;
2943 }")
2944
2945 (define_insn_and_split "muldi3"
2946 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2947 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2948 (match_operand:DI 2 "arith_reg_operand" "r")))
2949 (clobber (match_scratch:DI 3 "=&r"))
2950 (clobber (match_scratch:DI 4 "=r"))]
2951 "TARGET_SHMEDIA"
2952 "#"
2953 "reload_completed"
2954 [(const_int 0)]
2955 "
2956 {
2957 rtx op3_v2si, op2_v2si;
2958
2959 op3_v2si = operands[3];
2960 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2961 {
2962 op3_v2si = XEXP (op3_v2si, 0);
2963 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2964 }
2965 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2966 op2_v2si = operands[2];
2967 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2968 {
2969 op2_v2si = XEXP (op2_v2si, 0);
2970 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2971 }
2972 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2973 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2974 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2975 emit_insn (gen_umulsidi3_media (operands[4],
2976 sh_gen_truncate (SImode, operands[1], 0),
2977 sh_gen_truncate (SImode, operands[2], 0)));
2978 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2979 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2980 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2981 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2982 DONE;
2983 }")
2984
2985 \f
2986 ;; -------------------------------------------------------------------------
2987 ;; Logical operations
2988 ;; -------------------------------------------------------------------------
2989
2990 (define_insn "*andsi3_compact"
2991 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2992 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2993 (match_operand:SI 2 "logical_operand" "r,K08")))]
2994 "TARGET_SH1"
2995 "and %2,%0"
2996 [(set_attr "type" "arith")])
2997
2998 (define_insn "*andsi3_media"
2999 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3000 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3001 (match_operand:SI 2 "logical_operand" "r,I10")))]
3002 "TARGET_SHMEDIA"
3003 "@
3004 and %1, %2, %0
3005 andi %1, %2, %0"
3006 [(set_attr "type" "arith_media")])
3007
3008 ;; If the constant is 255, then emit an extu.b instruction instead of an
3009 ;; and, since that will give better code.
3010
3011 (define_expand "andsi3"
3012 [(set (match_operand:SI 0 "arith_reg_operand" "")
3013 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3014 (match_operand:SI 2 "logical_operand" "")))]
3015 ""
3016 "
3017 {
3018 if (TARGET_SH1
3019 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3020 {
3021 emit_insn (gen_zero_extendqisi2 (operands[0],
3022 gen_lowpart (QImode, operands[1])));
3023 DONE;
3024 }
3025 }")
3026
3027 (define_insn_and_split "anddi3"
3028 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3029 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3030 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3031 "TARGET_SHMEDIA"
3032 "@
3033 and %1, %2, %0
3034 andi %1, %2, %0
3035 #"
3036 "reload_completed
3037 && ! logical_operand (operands[2], DImode)"
3038 [(const_int 0)]
3039 "
3040 {
3041 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3042 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3043 else
3044 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3045 DONE;
3046 }"
3047 [(set_attr "type" "arith_media")])
3048
3049 (define_insn "andcsi3"
3050 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3051 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3052 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3053 "TARGET_SHMEDIA"
3054 "andc %1,%2,%0"
3055 [(set_attr "type" "arith_media")])
3056
3057 (define_insn "andcdi3"
3058 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3059 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3060 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3061 "TARGET_SHMEDIA"
3062 "andc %1,%2,%0"
3063 [(set_attr "type" "arith_media")])
3064
3065 (define_expand "iorsi3"
3066 [(set (match_operand:SI 0 "arith_reg_operand" "")
3067 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3068 (match_operand:SI 2 "logical_operand" "")))]
3069 ""
3070 "")
3071
3072 (define_insn "*iorsi3_compact"
3073 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3074 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3075 (match_operand:SI 2 "logical_operand" "r,K08")))]
3076 "TARGET_SH1"
3077 "or %2,%0"
3078 [(set_attr "type" "arith")])
3079
3080 (define_insn "*iorsi3_media"
3081 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3082 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3083 (match_operand:SI 2 "logical_operand" "r,I10")))]
3084 "TARGET_SHMEDIA"
3085 "@
3086 or %1, %2, %0
3087 ori %1, %2, %0"
3088 [(set_attr "type" "arith_media")])
3089
3090 (define_insn "iordi3"
3091 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3092 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3093 (match_operand:DI 2 "logical_operand" "r,I10")))]
3094 "TARGET_SHMEDIA"
3095 "@
3096 or %1, %2, %0
3097 ori %1, %2, %0"
3098 [(set_attr "type" "arith_media")])
3099
3100 (define_insn_and_split "*logical_sidi3"
3101 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3102 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3103 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3104 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3105 "TARGET_SHMEDIA"
3106 "#"
3107 "&& reload_completed"
3108 [(set (match_dup 0) (match_dup 3))]
3109 "
3110 {
3111 operands[3]
3112 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3113 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3114 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3115 }")
3116
3117 (define_insn_and_split "*logical_sidisi3"
3118 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3119 (truncate:SI (sign_extend:DI
3120 (match_operator:SI 3 "logical_operator"
3121 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3122 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3123 "TARGET_SHMEDIA"
3124 "#"
3125 "&& 1"
3126 [(set (match_dup 0) (match_dup 3))])
3127
3128 (define_insn_and_split "*logical_sidi3_2"
3129 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3130 (sign_extend:DI (truncate:SI (sign_extend:DI
3131 (match_operator:SI 3 "logical_operator"
3132 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3133 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3134 "TARGET_SHMEDIA"
3135 "#"
3136 "&& 1"
3137 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3138
3139 (define_expand "xorsi3"
3140 [(set (match_operand:SI 0 "arith_reg_operand" "")
3141 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3142 (match_operand:SI 2 "xor_operand" "")))]
3143 ""
3144 "")
3145
3146 (define_insn "*xorsi3_compact"
3147 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3148 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3149 (match_operand:SI 2 "logical_operand" "K08,r")))]
3150 "TARGET_SH1"
3151 "xor %2,%0"
3152 [(set_attr "type" "arith")])
3153
3154 (define_insn "*xorsi3_media"
3155 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3156 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3157 (match_operand:SI 2 "xor_operand" "r,I06")))]
3158 "TARGET_SHMEDIA"
3159 "@
3160 xor %1, %2, %0
3161 xori %1, %2, %0"
3162 [(set_attr "type" "arith_media")])
3163
3164 (define_insn "xordi3"
3165 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3166 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3167 (match_operand:DI 2 "xor_operand" "r,I06")))]
3168 "TARGET_SHMEDIA"
3169 "@
3170 xor %1, %2, %0
3171 xori %1, %2, %0"
3172 [(set_attr "type" "arith_media")])
3173
3174 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3175 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3176 (define_split
3177 [(set (match_operand:DI 0 "arith_reg_dest" "")
3178 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3179 [(match_operand 1 "any_register_operand" "")
3180 (match_operand 2 "any_register_operand" "")])))]
3181 "TARGET_SHMEDIA"
3182 [(set (match_dup 5) (match_dup 4))
3183 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3184 "
3185 {
3186 enum machine_mode inmode = GET_MODE (operands[1]);
3187 int offset = 0;
3188
3189 if (GET_CODE (operands[0]) == SUBREG)
3190 {
3191 offset = SUBREG_BYTE (operands[0]);
3192 operands[0] = SUBREG_REG (operands[0]);
3193 }
3194 gcc_assert (GET_CODE (operands[0]) == REG);
3195 if (! TARGET_LITTLE_ENDIAN)
3196 offset += 8 - GET_MODE_SIZE (inmode);
3197 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3198 }")
3199 \f
3200 ;; -------------------------------------------------------------------------
3201 ;; Shifts and rotates
3202 ;; -------------------------------------------------------------------------
3203
3204 (define_expand "rotldi3"
3205 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3206 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3207 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3208 "TARGET_SHMEDIA"
3209 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3210
3211 (define_insn "rotldi3_mextr"
3212 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3213 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3214 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3215 "TARGET_SHMEDIA"
3216 "*
3217 {
3218 static char templ[16];
3219
3220 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3221 8 - (int) (INTVAL (operands[2]) >> 3));
3222 return templ;
3223 }"
3224 [(set_attr "type" "arith_media")])
3225
3226 (define_expand "rotrdi3"
3227 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3228 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3229 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3230 "TARGET_SHMEDIA"
3231 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3232
3233 (define_insn "rotrdi3_mextr"
3234 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3235 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3236 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3237 "TARGET_SHMEDIA"
3238 "*
3239 {
3240 static char templ[16];
3241
3242 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3243 return templ;
3244 }"
3245 [(set_attr "type" "arith_media")])
3246
3247 (define_split
3248 [(set (match_operand:DI 0 "arith_reg_dest" "")
3249 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3250 "ua_address_operand" "")))
3251 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3252 (const_int 8))))
3253 (clobber (match_operand:DI 3 "register_operand" ""))]
3254 "TARGET_SHMEDIA"
3255 [(match_dup 4) (match_dup 5)]
3256 "
3257 {
3258 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3259 (operands[3], operands[1]));
3260 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3261 GEN_INT (56), GEN_INT (8));
3262 }")
3263
3264 (define_insn "rotlsi3_1"
3265 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3266 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3267 (const_int 1)))
3268 (set (reg:SI T_REG)
3269 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3270 "TARGET_SH1"
3271 "rotl %0"
3272 [(set_attr "type" "arith")])
3273
3274 (define_insn "rotlsi3_31"
3275 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3276 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3277 (const_int 31)))
3278 (clobber (reg:SI T_REG))]
3279 "TARGET_SH1"
3280 "rotr %0"
3281 [(set_attr "type" "arith")])
3282
3283 (define_insn "rotlsi3_16"
3284 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3285 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3286 (const_int 16)))]
3287 "TARGET_SH1"
3288 "swap.w %1,%0"
3289 [(set_attr "type" "arith")])
3290
3291 (define_expand "rotlsi3"
3292 [(set (match_operand:SI 0 "arith_reg_dest" "")
3293 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3294 (match_operand:SI 2 "immediate_operand" "")))]
3295 "TARGET_SH1"
3296 "
3297 {
3298 static const char rot_tab[] = {
3299 000, 000, 000, 000, 000, 000, 010, 001,
3300 001, 001, 011, 013, 003, 003, 003, 003,
3301 003, 003, 003, 003, 003, 013, 012, 002,
3302 002, 002, 010, 000, 000, 000, 000, 000,
3303 };
3304
3305 int count, choice;
3306
3307 if (GET_CODE (operands[2]) != CONST_INT)
3308 FAIL;
3309 count = INTVAL (operands[2]);
3310 choice = rot_tab[count];
3311 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3312 FAIL;
3313 choice &= 7;
3314 switch (choice)
3315 {
3316 case 0:
3317 emit_move_insn (operands[0], operands[1]);
3318 count -= (count & 16) * 2;
3319 break;
3320 case 3:
3321 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3322 count -= 16;
3323 break;
3324 case 1:
3325 case 2:
3326 {
3327 rtx parts[2];
3328 parts[0] = gen_reg_rtx (SImode);
3329 parts[1] = gen_reg_rtx (SImode);
3330 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3331 emit_move_insn (parts[choice-1], operands[1]);
3332 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3333 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3334 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3335 count = (count & ~16) - 8;
3336 }
3337 }
3338
3339 for (; count > 0; count--)
3340 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3341 for (; count < 0; count++)
3342 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3343
3344 DONE;
3345 }")
3346
3347 (define_insn "*rotlhi3_8"
3348 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3349 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3350 (const_int 8)))]
3351 "TARGET_SH1"
3352 "swap.b %1,%0"
3353 [(set_attr "type" "arith")])
3354
3355 (define_expand "rotlhi3"
3356 [(set (match_operand:HI 0 "arith_reg_operand" "")
3357 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3358 (match_operand:HI 2 "immediate_operand" "")))]
3359 "TARGET_SH1"
3360 "
3361 {
3362 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3363 FAIL;
3364 }")
3365
3366 ;;
3367 ;; shift left
3368
3369 (define_insn "ashlsi3_sh2a"
3370 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3371 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3372 (match_operand:SI 2 "arith_reg_operand" "r")))]
3373 "TARGET_SH2A"
3374 "shad %2,%0"
3375 [(set_attr "type" "arith")
3376 (set_attr "length" "4")])
3377
3378 ;; This pattern is used by init_expmed for computing the costs of shift
3379 ;; insns.
3380
3381 (define_insn_and_split "ashlsi3_std"
3382 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3383 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3384 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3385 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3386 "TARGET_SH3
3387 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3388 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3389 "@
3390 shld %2,%0
3391 add %0,%0
3392 shll%O2 %0
3393 #"
3394 "TARGET_SH3
3395 && reload_completed
3396 && GET_CODE (operands[2]) == CONST_INT
3397 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3398 [(set (match_dup 3) (match_dup 2))
3399 (parallel
3400 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3401 (clobber (match_dup 4))])]
3402 "operands[4] = gen_rtx_SCRATCH (SImode);"
3403 [(set_attr "length" "*,*,*,4")
3404 (set_attr "type" "dyn_shift,arith,arith,arith")])
3405
3406 (define_insn "ashlhi3_k"
3407 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3408 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3409 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3410 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3411 "@
3412 add %0,%0
3413 shll%O2 %0"
3414 [(set_attr "type" "arith")])
3415
3416 (define_insn "ashlsi3_n"
3417 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3418 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3419 (match_operand:SI 2 "const_int_operand" "n")))
3420 (clobber (reg:SI T_REG))]
3421 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3422 "#"
3423 [(set (attr "length")
3424 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3425 (const_string "2")
3426 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3427 (const_string "4")
3428 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3429 (const_string "6")]
3430 (const_string "8")))
3431 (set_attr "type" "arith")])
3432
3433 (define_split
3434 [(set (match_operand:SI 0 "arith_reg_dest" "")
3435 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3436 (match_operand:SI 2 "const_int_operand" "")))
3437 (clobber (reg:SI T_REG))]
3438 "TARGET_SH1 && reload_completed"
3439 [(use (reg:SI R0_REG))]
3440 "
3441 {
3442 gen_shifty_op (ASHIFT, operands);
3443 DONE;
3444 }")
3445
3446 (define_insn "ashlsi3_media"
3447 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3448 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3449 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3450 "TARGET_SHMEDIA"
3451 "@
3452 shlld.l %1, %2, %0
3453 shlli.l %1, %2, %0"
3454 [(set_attr "type" "arith_media")
3455 (set_attr "highpart" "ignore")])
3456
3457 (define_expand "ashlsi3"
3458 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3459 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3460 (match_operand:SI 2 "nonmemory_operand" "")))
3461 (clobber (reg:SI T_REG))])]
3462 ""
3463 "
3464 {
3465 if (TARGET_SHMEDIA)
3466 {
3467 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3468 DONE;
3469 }
3470 if (GET_CODE (operands[2]) == CONST_INT
3471 && sh_dynamicalize_shift_p (operands[2]))
3472 operands[2] = force_reg (SImode, operands[2]);
3473 if (TARGET_SH3)
3474 {
3475 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3476 DONE;
3477 }
3478 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3479 FAIL;
3480 }")
3481
3482 (define_insn "*ashlhi3_n"
3483 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3484 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3485 (match_operand:HI 2 "const_int_operand" "n")))
3486 (clobber (reg:SI T_REG))]
3487 "TARGET_SH1"
3488 "#"
3489 [(set (attr "length")
3490 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3491 (const_string "2")
3492 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3493 (const_string "4")]
3494 (const_string "6")))
3495 (set_attr "type" "arith")])
3496
3497 (define_expand "ashlhi3"
3498 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3499 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3500 (match_operand:SI 2 "nonmemory_operand" "")))
3501 (clobber (reg:SI T_REG))])]
3502 "TARGET_SH1"
3503 "
3504 {
3505 if (GET_CODE (operands[2]) != CONST_INT)
3506 FAIL;
3507 /* It may be possible to call gen_ashlhi3 directly with more generic
3508 operands. Make sure operands[1] is a HImode register here. */
3509 if (!arith_reg_operand (operands[1], HImode))
3510 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3511 }")
3512
3513 (define_split
3514 [(set (match_operand:HI 0 "arith_reg_dest" "")
3515 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3516 (match_operand:HI 2 "const_int_operand" "")))
3517 (clobber (reg:SI T_REG))]
3518 "TARGET_SH1 && reload_completed"
3519 [(use (reg:SI R0_REG))]
3520 "
3521 {
3522 gen_shifty_hi_op (ASHIFT, operands);
3523 DONE;
3524 }")
3525
3526 ;
3527 ; arithmetic shift right
3528 ;
3529
3530 (define_insn "ashrsi3_sh2a"
3531 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3532 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3533 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3534 "TARGET_SH2A"
3535 "shad %2,%0"
3536 [(set_attr "type" "dyn_shift")
3537 (set_attr "length" "4")])
3538
3539 (define_insn "ashrsi3_k"
3540 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3541 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3542 (match_operand:SI 2 "const_int_operand" "M")))
3543 (clobber (reg:SI T_REG))]
3544 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3545 "shar %0"
3546 [(set_attr "type" "arith")])
3547
3548 ;; We can't do HImode right shifts correctly unless we start out with an
3549 ;; explicit zero / sign extension; doing that would result in worse overall
3550 ;; code, so just let the machine independent code widen the mode.
3551 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3552
3553
3554 ;; ??? This should be a define expand.
3555
3556 (define_insn "ashrsi2_16"
3557 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3558 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3559 (const_int 16)))]
3560 "TARGET_SH1"
3561 "#"
3562 [(set_attr "length" "4")])
3563
3564 (define_split
3565 [(set (match_operand:SI 0 "arith_reg_dest" "")
3566 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3567 (const_int 16)))]
3568 "TARGET_SH1"
3569 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3570 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3571 "operands[2] = gen_lowpart (HImode, operands[0]);")
3572
3573 ;; ??? This should be a define expand.
3574
3575 (define_insn "ashrsi2_31"
3576 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3577 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3578 (const_int 31)))
3579 (clobber (reg:SI T_REG))]
3580 "TARGET_SH1"
3581 "#"
3582 [(set_attr "length" "4")])
3583
3584 (define_split
3585 [(set (match_operand:SI 0 "arith_reg_dest" "")
3586 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3587 (const_int 31)))
3588 (clobber (reg:SI T_REG))]
3589 "TARGET_SH1"
3590 [(const_int 0)]
3591 "
3592 {
3593 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3594 emit_insn (gen_mov_neg_si_t (operands[0]));
3595 DONE;
3596 }")
3597
3598 (define_peephole2
3599 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3600 (set (reg:SI T_REG)
3601 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3602 "TARGET_SH1
3603 && peep2_reg_dead_p (2, operands[0])
3604 && peep2_reg_dead_p (2, operands[1])"
3605 [(const_int 0)]
3606 "
3607 {
3608 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3609 DONE;
3610 }")
3611
3612 (define_insn "ashlsi_c"
3613 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3614 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3615 (set (reg:SI T_REG)
3616 (lt:SI (match_dup 1) (const_int 0)))]
3617 "TARGET_SH1"
3618 "shll %0"
3619 [(set_attr "type" "arith")])
3620
3621 (define_insn "*ashlsi_c_void"
3622 [(set (reg:SI T_REG)
3623 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3624 (clobber (match_scratch:SI 1 "=0"))]
3625 "TARGET_SH1 && cse_not_expected"
3626 "shll %0"
3627 [(set_attr "type" "arith")])
3628
3629 (define_insn "ashrsi3_d"
3630 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3631 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3632 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3633 "TARGET_SH3"
3634 "shad %2,%0"
3635 [(set_attr "type" "dyn_shift")])
3636
3637 (define_insn "ashrsi3_n"
3638 [(set (reg:SI R4_REG)
3639 (ashiftrt:SI (reg:SI R4_REG)
3640 (match_operand:SI 0 "const_int_operand" "i")))
3641 (clobber (reg:SI T_REG))
3642 (clobber (reg:SI PR_REG))
3643 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3644 "TARGET_SH1"
3645 "jsr @%1%#"
3646 [(set_attr "type" "sfunc")
3647 (set_attr "needs_delay_slot" "yes")])
3648
3649 (define_insn "ashrsi3_media"
3650 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3651 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3652 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3653 "TARGET_SHMEDIA"
3654 "@
3655 shard.l %1, %2, %0
3656 shari.l %1, %2, %0"
3657 [(set_attr "type" "arith_media")
3658 (set_attr "highpart" "ignore")])
3659
3660 (define_expand "ashrsi3"
3661 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3662 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3663 (match_operand:SI 2 "nonmemory_operand" "")))
3664 (clobber (reg:SI T_REG))])]
3665 ""
3666 "
3667 {
3668 if (TARGET_SHMEDIA)
3669 {
3670 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3671 DONE;
3672 }
3673 if (expand_ashiftrt (operands))
3674 DONE;
3675 else
3676 FAIL;
3677 }")
3678
3679 ;; logical shift right
3680
3681 (define_insn "lshrsi3_sh2a"
3682 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3683 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3684 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3685 "TARGET_SH2A"
3686 "shld %2,%0"
3687 [(set_attr "type" "dyn_shift")
3688 (set_attr "length" "4")])
3689
3690 (define_insn "lshrsi3_d"
3691 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3692 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3693 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694 "TARGET_SH3"
3695 "shld %2,%0"
3696 [(set_attr "type" "dyn_shift")])
3697
3698 ;; Only the single bit shift clobbers the T bit.
3699
3700 (define_insn "lshrsi3_m"
3701 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3702 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3703 (match_operand:SI 2 "const_int_operand" "M")))
3704 (clobber (reg:SI T_REG))]
3705 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3706 "shlr %0"
3707 [(set_attr "type" "arith")])
3708
3709 (define_insn "lshrsi3_k"
3710 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3711 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3712 (match_operand:SI 2 "const_int_operand" "P27")))]
3713 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3714 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3715 "shlr%O2 %0"
3716 [(set_attr "type" "arith")])
3717
3718 (define_insn "lshrsi3_n"
3719 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3720 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3721 (match_operand:SI 2 "const_int_operand" "n")))
3722 (clobber (reg:SI T_REG))]
3723 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3724 "#"
3725 [(set (attr "length")
3726 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3727 (const_string "2")
3728 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3729 (const_string "4")
3730 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3731 (const_string "6")]
3732 (const_string "8")))
3733 (set_attr "type" "arith")])
3734
3735 (define_split
3736 [(set (match_operand:SI 0 "arith_reg_dest" "")
3737 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3738 (match_operand:SI 2 "const_int_operand" "")))
3739 (clobber (reg:SI T_REG))]
3740 "TARGET_SH1 && reload_completed"
3741 [(use (reg:SI R0_REG))]
3742 "
3743 {
3744 gen_shifty_op (LSHIFTRT, operands);
3745 DONE;
3746 }")
3747
3748 (define_insn "lshrsi3_media"
3749 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3750 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3751 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3752 "TARGET_SHMEDIA"
3753 "@
3754 shlrd.l %1, %2, %0
3755 shlri.l %1, %2, %0"
3756 [(set_attr "type" "arith_media")
3757 (set_attr "highpart" "ignore")])
3758
3759 (define_expand "lshrsi3"
3760 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3761 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3762 (match_operand:SI 2 "nonmemory_operand" "")))
3763 (clobber (reg:SI T_REG))])]
3764 ""
3765 "
3766 {
3767 if (TARGET_SHMEDIA)
3768 {
3769 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3770 DONE;
3771 }
3772 if (GET_CODE (operands[2]) == CONST_INT
3773 && sh_dynamicalize_shift_p (operands[2]))
3774 operands[2] = force_reg (SImode, operands[2]);
3775 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3776 {
3777 rtx count = copy_to_mode_reg (SImode, operands[2]);
3778 emit_insn (gen_negsi2 (count, count));
3779 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3780 DONE;
3781 }
3782 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3783 FAIL;
3784 }")
3785
3786 ;; ??? This should be a define expand.
3787
3788 (define_insn "ashldi3_k"
3789 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3790 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3791 (const_int 1)))
3792 (clobber (reg:SI T_REG))]
3793 "TARGET_SH1"
3794 "shll %R0\;rotcl %S0"
3795 [(set_attr "length" "4")
3796 (set_attr "type" "arith")])
3797
3798 (define_insn "ashldi3_media"
3799 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3800 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3801 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3802 "TARGET_SHMEDIA"
3803 "@
3804 shlld %1, %2, %0
3805 shlli %1, %2, %0"
3806 [(set_attr "type" "arith_media")])
3807
3808 (define_insn "*ashldisi3_media"
3809 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3810 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3811 (match_operand:DI 2 "const_int_operand" "n")))]
3812 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3813 "shlli.l %1, %2, %0"
3814 [(set_attr "type" "arith_media")
3815 (set_attr "highpart" "ignore")])
3816
3817 (define_expand "ashldi3"
3818 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3819 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3820 (match_operand:DI 2 "immediate_operand" "")))
3821 (clobber (reg:SI T_REG))])]
3822 ""
3823 "
3824 {
3825 if (TARGET_SHMEDIA)
3826 {
3827 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3828 DONE;
3829 }
3830 if (GET_CODE (operands[2]) != CONST_INT
3831 || INTVAL (operands[2]) != 1)
3832 FAIL;
3833 }")
3834
3835 ;; ??? This should be a define expand.
3836
3837 (define_insn "lshrdi3_k"
3838 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3839 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3840 (const_int 1)))
3841 (clobber (reg:SI T_REG))]
3842 "TARGET_SH1"
3843 "shlr %S0\;rotcr %R0"
3844 [(set_attr "length" "4")
3845 (set_attr "type" "arith")])
3846
3847 (define_insn "lshrdi3_media"
3848 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3849 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3850 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3851 "TARGET_SHMEDIA
3852 && (arith_reg_dest (operands[0], DImode)
3853 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3854 "@
3855 shlrd %1, %2, %0
3856 shlri %1, %2, %0"
3857 [(set_attr "type" "arith_media")])
3858
3859 (define_insn "*lshrdisi3_media"
3860 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3861 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3862 (match_operand:DI 2 "const_int_operand" "n")))]
3863 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3864 "shlri.l %1, %2, %0"
3865 [(set_attr "type" "arith_media")
3866 (set_attr "highpart" "ignore")])
3867
3868 (define_expand "lshrdi3"
3869 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3870 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3871 (match_operand:DI 2 "immediate_operand" "")))
3872 (clobber (reg:SI T_REG))])]
3873 ""
3874 "
3875 {
3876 if (TARGET_SHMEDIA)
3877 {
3878 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3879 DONE;
3880 }
3881 if (GET_CODE (operands[2]) != CONST_INT
3882 || INTVAL (operands[2]) != 1)
3883 FAIL;
3884 }")
3885
3886 ;; ??? This should be a define expand.
3887
3888 (define_insn "ashrdi3_k"
3889 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3890 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3891 (const_int 1)))
3892 (clobber (reg:SI T_REG))]
3893 "TARGET_SH1"
3894 "shar %S0\;rotcr %R0"
3895 [(set_attr "length" "4")
3896 (set_attr "type" "arith")])
3897
3898 (define_insn "ashrdi3_media"
3899 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3900 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3901 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3902 "TARGET_SHMEDIA
3903 && (arith_reg_dest (operands[0], DImode)
3904 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3905 "@
3906 shard %1, %2, %0
3907 shari %1, %2, %0"
3908 [(set_attr "type" "arith_media")])
3909
3910 (define_insn "*ashrdisi3_media"
3911 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3912 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3913 (match_operand:DI 2 "const_int_operand" "n")))]
3914 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3915 "shari.l %1, %2, %0"
3916 [(set_attr "type" "arith_media")
3917 (set_attr "highpart" "ignore")])
3918
3919 (define_insn "ashrdisi3_media_high"
3920 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921 (truncate:SI
3922 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3923 (match_operand:DI 2 "const_int_operand" "n"))))]
3924 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3925 "shari %1, %2, %0"
3926 [(set_attr "type" "arith_media")])
3927
3928 (define_insn "ashrdisi3_media_opaque"
3929 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3930 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3931 (match_operand:DI 2 "const_int_operand" "n")]
3932 UNSPEC_ASHIFTRT))]
3933 "TARGET_SHMEDIA"
3934 "shari %1, %2, %0"
3935 [(set_attr "type" "arith_media")])
3936
3937 (define_expand "ashrdi3"
3938 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3939 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3940 (match_operand:DI 2 "immediate_operand" "")))
3941 (clobber (reg:SI T_REG))])]
3942 ""
3943 "
3944 {
3945 if (TARGET_SHMEDIA)
3946 {
3947 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3948 DONE;
3949 }
3950 if (GET_CODE (operands[2]) != CONST_INT
3951 || INTVAL (operands[2]) != 1)
3952 FAIL;
3953 }")
3954
3955 ;; combined left/right shift
3956
3957 (define_split
3958 [(set (match_operand:SI 0 "register_operand" "")
3959 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3960 (match_operand:SI 2 "const_int_operand" ""))
3961 (match_operand:SI 3 "const_int_operand" "")))]
3962 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3963 [(use (reg:SI R0_REG))]
3964 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3965 DONE;")
3966
3967 (define_split
3968 [(set (match_operand:SI 0 "register_operand" "")
3969 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3970 (match_operand:SI 2 "const_int_operand" ""))
3971 (match_operand:SI 3 "const_int_operand" "")))
3972 (clobber (reg:SI T_REG))]
3973 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3974 [(use (reg:SI R0_REG))]
3975 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3976 DONE;")
3977
3978 (define_insn ""
3979 [(set (match_operand:SI 0 "register_operand" "=r")
3980 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3981 (match_operand:SI 2 "const_int_operand" "n"))
3982 (match_operand:SI 3 "const_int_operand" "n")))
3983 (clobber (reg:SI T_REG))]
3984 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3985 "#"
3986 [(set (attr "length")
3987 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3988 (const_string "4")
3989 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3990 (const_string "6")
3991 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3992 (const_string "8")
3993 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3994 (const_string "10")
3995 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3996 (const_string "12")
3997 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3998 (const_string "14")
3999 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4000 (const_string "16")]
4001 (const_string "18")))
4002 (set_attr "type" "arith")])
4003
4004 (define_insn ""
4005 [(set (match_operand:SI 0 "register_operand" "=z")
4006 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4007 (match_operand:SI 2 "const_int_operand" "n"))
4008 (match_operand:SI 3 "const_int_operand" "n")))
4009 (clobber (reg:SI T_REG))]
4010 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4011 "#"
4012 [(set (attr "length")
4013 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4014 (const_string "4")
4015 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4016 (const_string "6")
4017 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4018 (const_string "8")]
4019 (const_string "10")))
4020 (set_attr "type" "arith")])
4021
4022 ;; shift left / and combination with a scratch register: The combine pass
4023 ;; does not accept the individual instructions, even though they are
4024 ;; cheap. But it needs a precise description so that it is usable after
4025 ;; reload.
4026 (define_insn "and_shl_scratch"
4027 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4028 (lshiftrt:SI
4029 (ashift:SI
4030 (and:SI
4031 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4032 (match_operand:SI 2 "const_int_operand" "N,n"))
4033 (match_operand:SI 3 "" "0,r"))
4034 (match_operand:SI 4 "const_int_operand" "n,n"))
4035 (match_operand:SI 5 "const_int_operand" "n,n")))
4036 (clobber (reg:SI T_REG))]
4037 "TARGET_SH1"
4038 "#"
4039 [(set (attr "length")
4040 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4041 (const_string "4")
4042 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4043 (const_string "6")
4044 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4045 (const_string "8")
4046 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4047 (const_string "10")]
4048 (const_string "12")))
4049 (set_attr "type" "arith")])
4050
4051 (define_split
4052 [(set (match_operand:SI 0 "register_operand" "")
4053 (lshiftrt:SI
4054 (ashift:SI
4055 (and:SI
4056 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4057 (match_operand:SI 2 "const_int_operand" ""))
4058 (match_operand:SI 3 "register_operand" ""))
4059 (match_operand:SI 4 "const_int_operand" ""))
4060 (match_operand:SI 5 "const_int_operand" "")))
4061 (clobber (reg:SI T_REG))]
4062 "TARGET_SH1"
4063 [(use (reg:SI R0_REG))]
4064 "
4065 {
4066 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4067
4068 if (INTVAL (operands[2]))
4069 {
4070 gen_shifty_op (LSHIFTRT, operands);
4071 }
4072 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4073 operands[2] = operands[4];
4074 gen_shifty_op (ASHIFT, operands);
4075 if (INTVAL (operands[5]))
4076 {
4077 operands[2] = operands[5];
4078 gen_shifty_op (LSHIFTRT, operands);
4079 }
4080 DONE;
4081 }")
4082
4083 ;; signed left/right shift combination.
4084 (define_split
4085 [(set (match_operand:SI 0 "register_operand" "")
4086 (sign_extract:SI
4087 (ashift:SI (match_operand:SI 1 "register_operand" "")
4088 (match_operand:SI 2 "const_int_operand" ""))
4089 (match_operand:SI 3 "const_int_operand" "")
4090 (const_int 0)))
4091 (clobber (reg:SI T_REG))]
4092 "TARGET_SH1"
4093 [(use (reg:SI R0_REG))]
4094 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4095 DONE;")
4096
4097 (define_insn "shl_sext_ext"
4098 [(set (match_operand:SI 0 "register_operand" "=r")
4099 (sign_extract:SI
4100 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101 (match_operand:SI 2 "const_int_operand" "n"))
4102 (match_operand:SI 3 "const_int_operand" "n")
4103 (const_int 0)))
4104 (clobber (reg:SI T_REG))]
4105 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4106 "#"
4107 [(set (attr "length")
4108 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4109 (const_string "2")
4110 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4111 (const_string "4")
4112 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4113 (const_string "6")
4114 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4115 (const_string "8")
4116 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4117 (const_string "10")
4118 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4119 (const_string "12")
4120 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4121 (const_string "14")
4122 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4123 (const_string "16")]
4124 (const_string "18")))
4125 (set_attr "type" "arith")])
4126
4127 (define_insn "shl_sext_sub"
4128 [(set (match_operand:SI 0 "register_operand" "=z")
4129 (sign_extract:SI
4130 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4131 (match_operand:SI 2 "const_int_operand" "n"))
4132 (match_operand:SI 3 "const_int_operand" "n")
4133 (const_int 0)))
4134 (clobber (reg:SI T_REG))]
4135 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4136 "#"
4137 [(set (attr "length")
4138 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4139 (const_string "6")
4140 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4141 (const_string "8")
4142 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4143 (const_string "10")
4144 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4145 (const_string "12")]
4146 (const_string "14")))
4147 (set_attr "type" "arith")])
4148
4149 ;; These patterns are found in expansions of DImode shifts by 16, and
4150 ;; allow the xtrct instruction to be generated from C source.
4151
4152 (define_insn "xtrct_left"
4153 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4154 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4155 (const_int 16))
4156 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4157 (const_int 16))))]
4158 "TARGET_SH1"
4159 "xtrct %1,%0"
4160 [(set_attr "type" "arith")])
4161
4162 (define_insn "xtrct_right"
4163 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4164 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4165 (const_int 16))
4166 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4167 (const_int 16))))]
4168 "TARGET_SH1"
4169 "xtrct %2,%0"
4170 [(set_attr "type" "arith")])
4171
4172 ;; -------------------------------------------------------------------------
4173 ;; Unary arithmetic
4174 ;; -------------------------------------------------------------------------
4175
4176 (define_insn "negc"
4177 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4178 (neg:SI (plus:SI (reg:SI T_REG)
4179 (match_operand:SI 1 "arith_reg_operand" "r"))))
4180 (set (reg:SI T_REG)
4181 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4182 (const_int 0)))]
4183 "TARGET_SH1"
4184 "negc %1,%0"
4185 [(set_attr "type" "arith")])
4186
4187 (define_insn "*negdi_media"
4188 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4189 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4190 "TARGET_SHMEDIA"
4191 "sub r63, %1, %0"
4192 [(set_attr "type" "arith_media")])
4193
4194 (define_expand "negdi2"
4195 [(set (match_operand:DI 0 "arith_reg_operand" "")
4196 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4197 ""
4198 "
4199 {
4200 if (TARGET_SH1)
4201 {
4202 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4203 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4204
4205 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4206 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4207
4208 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4209 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4210
4211 emit_insn (gen_clrt ());
4212 emit_insn (gen_negc (low_dst, low_src));
4213 emit_insn (gen_negc (high_dst, high_src));
4214 DONE;
4215 }
4216 }")
4217
4218 (define_insn "negsi2"
4219 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4220 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4221 "TARGET_SH1"
4222 "neg %1,%0"
4223 [(set_attr "type" "arith")])
4224
4225 (define_insn "one_cmplsi2"
4226 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4227 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4228 "TARGET_SH1"
4229 "not %1,%0"
4230 [(set_attr "type" "arith")])
4231
4232 (define_expand "one_cmpldi2"
4233 [(set (match_operand:DI 0 "arith_reg_dest" "")
4234 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4235 (const_int -1)))]
4236 "TARGET_SHMEDIA" "")
4237
4238 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4239 This can be used as some kind of conditional execution, which is useful
4240 for abs. */
4241 (define_split
4242 [(set (match_operand:SI 0 "arith_reg_dest" "")
4243 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4244 (match_operand:SI 1 "arith_reg_operand" ""))
4245 (reg:SI T_REG)))]
4246 "TARGET_HARD_SH4"
4247 [(const_int 0)]
4248 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4249 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4250 DONE;")
4251
4252 (define_insn "cneg"
4253 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4254 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4255 (match_operand:SI 1 "arith_reg_operand" "0")
4256 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4257 "TARGET_HARD_SH4"
4258 "bf 0f\;neg %2,%0\\n0:"
4259 [(set_attr "type" "arith") ;; poor approximation
4260 (set_attr "length" "4")])
4261
4262 \f
4263 ;; -------------------------------------------------------------------------
4264 ;; Zero extension instructions
4265 ;; -------------------------------------------------------------------------
4266
4267 (define_insn "zero_extendsidi2"
4268 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4269 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4270 "TARGET_SHMEDIA"
4271 "addz.l %1, r63, %0"
4272 [(set_attr "type" "arith_media")
4273 (set_attr "highpart" "extend")])
4274
4275 (define_insn "zero_extendhidi2"
4276 [(set (match_operand:DI 0 "register_operand" "=r,r")
4277 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4278 "TARGET_SHMEDIA"
4279 "@
4280 #
4281 ld%M1.uw %m1, %0"
4282 [(set_attr "type" "*,load_media")
4283 (set (attr "highpart")
4284 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4285 (const_string "user")]
4286 (const_string "ignore")))])
4287
4288 (define_split
4289 [(set (match_operand:DI 0 "register_operand" "")
4290 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4291 "TARGET_SHMEDIA && reload_completed"
4292 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4293 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4294 "
4295 {
4296 if (GET_CODE (operands[1]) == TRUNCATE)
4297 operands[1] = XEXP (operands[1], 0);
4298 }")
4299
4300 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4301 ;; reload the entire truncate expression.
4302 (define_insn_and_split "*loaddi_trunc"
4303 [(set (match_operand 0 "any_register_operand" "=r")
4304 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4305 "TARGET_SHMEDIA && reload_completed"
4306 "#"
4307 "TARGET_SHMEDIA && reload_completed"
4308 [(set (match_dup 0) (match_dup 1))]
4309 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4310
4311 (define_insn "zero_extendqidi2"
4312 [(set (match_operand:DI 0 "register_operand" "=r,r")
4313 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4314 "TARGET_SHMEDIA"
4315 "@
4316 andi %1, 255, %0
4317 ld%M1.ub %m1, %0"
4318 [(set_attr "type" "arith_media,load_media")
4319 (set (attr "highpart")
4320 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4321 (const_string "user")]
4322 (const_string "ignore")))])
4323
4324 (define_expand "zero_extendhisi2"
4325 [(set (match_operand:SI 0 "arith_reg_operand" "")
4326 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4327 ""
4328 "
4329 {
4330 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4331 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4332 }")
4333
4334 (define_insn "*zero_extendhisi2_compact"
4335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4337 "TARGET_SH1"
4338 "extu.w %1,%0"
4339 [(set_attr "type" "arith")])
4340
4341 (define_insn "*zero_extendhisi2_media"
4342 [(set (match_operand:SI 0 "register_operand" "=r,r")
4343 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4344 "TARGET_SHMEDIA"
4345 "@
4346 #
4347 ld%M1.uw %m1, %0"
4348 [(set_attr "type" "arith_media,load_media")
4349 (set (attr "highpart")
4350 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4351 (const_string "user")]
4352 (const_string "ignore")))])
4353
4354 (define_split
4355 [(set (match_operand:SI 0 "register_operand" "")
4356 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4357 "TARGET_SHMEDIA && reload_completed"
4358 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4359 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4360 "
4361 {
4362 rtx op1 = operands[1];
4363
4364 if (GET_CODE (op1) == TRUNCATE)
4365 op1 = XEXP (op1, 0);
4366 operands[2]
4367 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4368 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4369 }")
4370
4371 (define_expand "zero_extendqisi2"
4372 [(set (match_operand:SI 0 "arith_reg_operand" "")
4373 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4374 ""
4375 "
4376 {
4377 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4378 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4379 }")
4380
4381 (define_insn "*zero_extendqisi2_compact"
4382 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4383 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4384 "TARGET_SH1"
4385 "extu.b %1,%0"
4386 [(set_attr "type" "arith")])
4387
4388 (define_insn "*zero_extendqisi2_media"
4389 [(set (match_operand:SI 0 "register_operand" "=r,r")
4390 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4391 "TARGET_SHMEDIA"
4392 "@
4393 andi %1, 255, %0
4394 ld%M1.ub %m1, %0"
4395 [(set_attr "type" "arith_media,load_media")
4396 (set (attr "highpart")
4397 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4398 (const_string "user")]
4399 (const_string "ignore")))])
4400
4401 (define_insn "zero_extendqihi2"
4402 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4403 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4404 "TARGET_SH1"
4405 "extu.b %1,%0"
4406 [(set_attr "type" "arith")])
4407
4408 ;; -------------------------------------------------------------------------
4409 ;; Sign extension instructions
4410 ;; -------------------------------------------------------------------------
4411
4412 ;; ??? This should be a define expand.
4413 ;; ??? Or perhaps it should be dropped?
4414
4415 ;; convert_move generates good code for SH[1-4].
4416 (define_insn "extendsidi2"
4417 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4418 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4419 "TARGET_SHMEDIA"
4420 "@
4421 add.l %1, r63, %0
4422 ld%M1.l %m1, %0
4423 fmov.sl %1, %0"
4424 [(set_attr "type" "arith_media,load_media,fpconv_media")
4425 (set (attr "highpart")
4426 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4427 (const_string "user")]
4428 (const_string "extend")))])
4429
4430 (define_insn "extendhidi2"
4431 [(set (match_operand:DI 0 "register_operand" "=r,r")
4432 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4433 "TARGET_SHMEDIA"
4434 "@
4435 #
4436 ld%M1.w %m1, %0"
4437 [(set_attr "type" "*,load_media")
4438 (set (attr "highpart")
4439 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4440 (const_string "user")]
4441 (const_string "ignore")))])
4442
4443 (define_split
4444 [(set (match_operand:DI 0 "register_operand" "")
4445 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4446 "TARGET_SHMEDIA && reload_completed"
4447 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4448 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4449 "
4450 {
4451 if (GET_CODE (operands[1]) == TRUNCATE)
4452 operands[1] = XEXP (operands[1], 0);
4453 }")
4454
4455 (define_insn "extendqidi2"
4456 [(set (match_operand:DI 0 "register_operand" "=r,r")
4457 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4458 "TARGET_SHMEDIA"
4459 "@
4460 #
4461 ld%M1.b %m1, %0"
4462 [(set_attr "type" "*,load_media")
4463 (set (attr "highpart")
4464 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4465 (const_string "user")]
4466 (const_string "ignore")))])
4467
4468 (define_split
4469 [(set (match_operand:DI 0 "register_operand" "")
4470 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4471 "TARGET_SHMEDIA && reload_completed"
4472 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4473 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4474 "
4475 {
4476 if (GET_CODE (operands[1]) == TRUNCATE)
4477 operands[1] = XEXP (operands[1], 0);
4478 }")
4479
4480 (define_expand "extendhisi2"
4481 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4482 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4483 ""
4484 "")
4485
4486 (define_insn "*extendhisi2_compact"
4487 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4488 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4489 "TARGET_SH1"
4490 "@
4491 exts.w %1,%0
4492 mov.w %1,%0"
4493 [(set_attr "type" "arith,load")])
4494
4495 (define_insn "*extendhisi2_media"
4496 [(set (match_operand:SI 0 "register_operand" "=r,r")
4497 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4498 "TARGET_SHMEDIA"
4499 "@
4500 #
4501 ld%M1.w %m1, %0"
4502 [(set_attr "type" "arith_media,load_media")
4503 (set (attr "highpart")
4504 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4505 (const_string "user")]
4506 (const_string "ignore")))])
4507
4508 (define_split
4509 [(set (match_operand:SI 0 "register_operand" "")
4510 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4511 "TARGET_SHMEDIA && reload_completed"
4512 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4513 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4514 "
4515 {
4516 rtx op1 = operands[1];
4517 if (GET_CODE (op1) == TRUNCATE)
4518 op1 = XEXP (op1, 0);
4519 operands[2]
4520 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4521 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4522 }")
4523
4524 (define_expand "extendqisi2"
4525 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4526 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4527 ""
4528 "")
4529
4530 (define_insn "*extendqisi2_compact"
4531 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4532 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4533 "TARGET_SH1"
4534 "@
4535 exts.b %1,%0
4536 mov.b %1,%0"
4537 [(set_attr "type" "arith,load")])
4538
4539 (define_insn "*extendqisi2_media"
4540 [(set (match_operand:SI 0 "register_operand" "=r,r")
4541 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4542 "TARGET_SHMEDIA"
4543 "@
4544 #
4545 ld%M1.b %m1, %0"
4546 [(set_attr "type" "arith_media,load_media")
4547 (set (attr "highpart")
4548 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4549 (const_string "user")]
4550 (const_string "ignore")))])
4551
4552 (define_split
4553 [(set (match_operand:SI 0 "register_operand" "")
4554 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4555 "TARGET_SHMEDIA && reload_completed"
4556 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4557 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4558 "
4559 {
4560 rtx op1 = operands[1];
4561 if (GET_CODE (op1) == TRUNCATE)
4562 op1 = XEXP (op1, 0);
4563 operands[2]
4564 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4565 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4566 }")
4567
4568 (define_insn "extendqihi2"
4569 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4570 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4571 "TARGET_SH1"
4572 "@
4573 exts.b %1,%0
4574 mov.b %1,%0"
4575 [(set_attr "type" "arith,load")])
4576
4577 /* It would seem useful to combine the truncXi patterns into the movXi
4578 patterns, but unary operators are ignored when matching constraints,
4579 so we need separate patterns. */
4580 (define_insn "truncdisi2"
4581 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4582 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4583 "TARGET_SHMEDIA"
4584 "@
4585 add.l %1, r63, %0
4586 st%M0.l %m0, %1
4587 fst%M0.s %m0, %T1
4588 fmov.ls %1, %0
4589 fmov.sl %T1, %0
4590 fmov.s %T1, %0"
4591 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4592 (set (attr "highpart")
4593 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4594 (const_string "user")]
4595 (const_string "extend")))])
4596
4597 (define_insn "truncdihi2"
4598 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4599 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4600 "TARGET_SHMEDIA"
4601 "@
4602 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4603 st%M0.w %m0, %1"
4604 [(set_attr "type" "arith_media,store_media")
4605 (set_attr "length" "8,4")
4606 (set (attr "highpart")
4607 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4608 (const_string "user")]
4609 (const_string "extend")))])
4610
4611 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4612 ; Because we use zero extension, we can't provide signed QImode compares
4613 ; using a simple compare or conditional banch insn.
4614 (define_insn "truncdiqi2"
4615 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4616 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4617 "TARGET_SHMEDIA"
4618 "@
4619 andi %1, 255, %0
4620 st%M0.b %m0, %1"
4621 [(set_attr "type" "arith_media,store")
4622 (set (attr "highpart")
4623 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4624 (const_string "user")]
4625 (const_string "extend")))])
4626 ;; -------------------------------------------------------------------------
4627 ;; Move instructions
4628 ;; -------------------------------------------------------------------------
4629
4630 ;; define push and pop so it is easy for sh.c
4631 ;; We can't use push and pop on SHcompact because the stack must always
4632 ;; be 8-byte aligned.
4633
4634 (define_expand "push"
4635 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4636 (match_operand:SI 0 "register_operand" "r,l,x"))]
4637 "TARGET_SH1 && ! TARGET_SH5"
4638 "")
4639
4640 (define_expand "pop"
4641 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4642 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4643 "TARGET_SH1 && ! TARGET_SH5"
4644 "")
4645
4646 (define_expand "push_e"
4647 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4648 (match_operand:SF 0 "" ""))
4649 (use (reg:PSI FPSCR_REG))
4650 (clobber (scratch:SI))])]
4651 "TARGET_SH1 && ! TARGET_SH5"
4652 "")
4653
4654 (define_insn "push_fpul"
4655 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4656 "TARGET_SH2E && ! TARGET_SH5"
4657 "sts.l fpul,@-r15"
4658 [(set_attr "type" "store")
4659 (set_attr "late_fp_use" "yes")
4660 (set_attr "hit_stack" "yes")])
4661
4662 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4663 ;; so use that.
4664 (define_expand "push_4"
4665 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4666 (match_operand:DF 0 "" ""))
4667 (use (reg:PSI FPSCR_REG))
4668 (clobber (scratch:SI))])]
4669 "TARGET_SH1 && ! TARGET_SH5"
4670 "")
4671
4672 (define_expand "pop_e"
4673 [(parallel [(set (match_operand:SF 0 "" "")
4674 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4675 (use (reg:PSI FPSCR_REG))
4676 (clobber (scratch:SI))])]
4677 "TARGET_SH1 && ! TARGET_SH5"
4678 "")
4679
4680 (define_insn "pop_fpul"
4681 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4682 "TARGET_SH2E && ! TARGET_SH5"
4683 "lds.l @r15+,fpul"
4684 [(set_attr "type" "load")
4685 (set_attr "hit_stack" "yes")])
4686
4687 (define_expand "pop_4"
4688 [(parallel [(set (match_operand:DF 0 "" "")
4689 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4690 (use (reg:PSI FPSCR_REG))
4691 (clobber (scratch:SI))])]
4692 "TARGET_SH1 && ! TARGET_SH5"
4693 "")
4694
4695 (define_expand "push_fpscr"
4696 [(const_int 0)]
4697 "TARGET_SH2E"
4698 "
4699 {
4700 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4701 gen_rtx_PRE_DEC (Pmode,
4702 stack_pointer_rtx)),
4703 get_fpscr_rtx ()));
4704 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4705 DONE;
4706 }")
4707
4708 (define_expand "pop_fpscr"
4709 [(const_int 0)]
4710 "TARGET_SH2E"
4711 "
4712 {
4713 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4714 gen_frame_mem (PSImode,
4715 gen_rtx_POST_INC (Pmode,
4716 stack_pointer_rtx))));
4717 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4718 DONE;
4719 }")
4720
4721 ;; These two patterns can happen as the result of optimization, when
4722 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4723 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4724
4725 (define_insn "clrt"
4726 [(set (reg:SI T_REG) (const_int 0))]
4727 "TARGET_SH1"
4728 "clrt")
4729
4730 (define_insn "sett"
4731 [(set (reg:SI T_REG) (const_int 1))]
4732 "TARGET_SH1"
4733 "sett")
4734
4735 ;; t/r must come after r/r, lest reload will try to reload stuff like
4736 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4737 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4738 (define_insn "movsi_i"
4739 [(set (match_operand:SI 0 "general_movdst_operand"
4740 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4741 (match_operand:SI 1 "general_movsrc_operand"
4742 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4743 "TARGET_SH1
4744 && ! TARGET_SH2E
4745 && ! TARGET_SH2A
4746 && (register_operand (operands[0], SImode)
4747 || register_operand (operands[1], SImode))"
4748 "@
4749 mov.l %1,%0
4750 mov %1,%0
4751 cmp/pl %1
4752 mov.l %1,%0
4753 sts %1,%0
4754 sts %1,%0
4755 movt %0
4756 mov.l %1,%0
4757 sts.l %1,%0
4758 sts.l %1,%0
4759 lds %1,%0
4760 lds %1,%0
4761 lds.l %1,%0
4762 lds.l %1,%0
4763 fake %1,%0"
4764 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4765 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4766
4767 ;; t/r must come after r/r, lest reload will try to reload stuff like
4768 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4769 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4770 ;; will require a reload.
4771 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4772 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4773 (define_insn "movsi_ie"
4774 [(set (match_operand:SI 0 "general_movdst_operand"
4775 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4776 (match_operand:SI 1 "general_movsrc_operand"
4777 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4778 "(TARGET_SH2E || TARGET_SH2A)
4779 && (register_operand (operands[0], SImode)
4780 || register_operand (operands[1], SImode))"
4781 "@
4782 mov.l %1,%0
4783 mov %1,%0
4784 movi20 %1,%0
4785 cmp/pl %1
4786 mov.l %1,%0
4787 sts %1,%0
4788 sts %1,%0
4789 movt %0
4790 mov.l %1,%0
4791 sts.l %1,%0
4792 sts.l %1,%0
4793 lds %1,%0
4794 lds %1,%0
4795 lds.l %1,%0
4796 lds.l %1,%0
4797 lds.l %1,%0
4798 sts.l %1,%0
4799 fake %1,%0
4800 lds %1,%0
4801 sts %1,%0
4802 fsts fpul,%0
4803 flds %1,fpul
4804 fmov %1,%0
4805 ! move optimized away"
4806 [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4807 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4808 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4809
4810 (define_insn "movsi_i_lowpart"
4811 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4812 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4813 "TARGET_SH1
4814 && (register_operand (operands[0], SImode)
4815 || register_operand (operands[1], SImode))"
4816 "@
4817 mov.l %1,%0
4818 mov %1,%0
4819 mov.l %1,%0
4820 sts %1,%0
4821 sts %1,%0
4822 movt %0
4823 mov.l %1,%0
4824 fake %1,%0"
4825 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4826
4827 (define_insn_and_split "load_ra"
4828 [(set (match_operand:SI 0 "general_movdst_operand" "")
4829 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4830 "TARGET_SH1"
4831 "#"
4832 "&& ! currently_expanding_to_rtl"
4833 [(set (match_dup 0) (match_dup 1))]
4834 "
4835 {
4836 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4837 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4838 }")
4839
4840 ;; The '?'s in the following constraints may not reflect the time taken
4841 ;; to perform the move. They are there to discourage the use of floating-
4842 ;; point registers for storing integer values.
4843 (define_insn "*movsi_media"
4844 [(set (match_operand:SI 0 "general_movdst_operand"
4845 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4846 (match_operand:SI 1 "general_movsrc_operand"
4847 "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4848 "TARGET_SHMEDIA_FPU
4849 && (register_operand (operands[0], SImode)
4850 || sh_register_operand (operands[1], SImode)
4851 || GET_CODE (operands[1]) == TRUNCATE)"
4852 "@
4853 add.l %1, r63, %0
4854 movi %1, %0
4855 #
4856 ld%M1.l %m1, %0
4857 st%M0.l %m0, %N1
4858 fld%M1.s %m1, %0
4859 fst%M0.s %m0, %1
4860 fmov.ls %N1, %0
4861 fmov.sl %1, %0
4862 fmov.s %1, %0
4863 ptabs %1, %0
4864 gettr %1, %0
4865 pt %1, %0"
4866 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
4867 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4868 (set (attr "highpart")
4869 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4870 (const_string "user")]
4871 (const_string "ignore")))])
4872
4873 (define_insn "*movsi_media_nofpu"
4874 [(set (match_operand:SI 0 "general_movdst_operand"
4875 "=r,r,r,r,m,*b,r,*b")
4876 (match_operand:SI 1 "general_movsrc_operand"
4877 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4878 "TARGET_SHMEDIA
4879 && (register_operand (operands[0], SImode)
4880 || sh_register_operand (operands[1], SImode)
4881 || GET_CODE (operands[1]) == TRUNCATE)"
4882 "@
4883 add.l %1, r63, %0
4884 movi %1, %0
4885 #
4886 ld%M1.l %m1, %0
4887 st%M0.l %m0, %N1
4888 ptabs %1, %0
4889 gettr %1, %0
4890 pt %1, %0"
4891 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4892 (set_attr "length" "4,4,8,4,4,4,4,12")
4893 (set (attr "highpart")
4894 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4895 (const_string "user")]
4896 (const_string "ignore")))])
4897
4898 (define_expand "movsi_const"
4899 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4900 (const:SI (sign_extend:SI
4901 (truncate:HI
4902 (ashiftrt:SI
4903 (match_operand:DI 1 "immediate_operand" "s")
4904 (const_int 16))))))
4905 (set (match_dup 0)
4906 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4907 (zero_extend:SI
4908 (truncate:HI
4909 (const:SI
4910 (sign_extend:SI
4911 (truncate:HI (match_dup 1))))))))]
4912 "TARGET_SHMEDIA && reload_completed
4913 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4914 "
4915 {
4916 if (GET_CODE (operands[1]) == LABEL_REF
4917 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4918 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4919 else if (GOTOFF_P (operands[1]))
4920 {
4921 rtx unspec = XEXP (operands[1], 0);
4922
4923 if (! UNSPEC_GOTOFF_P (unspec))
4924 {
4925 unspec = XEXP (unspec, 0);
4926 if (! UNSPEC_GOTOFF_P (unspec))
4927 abort ();
4928 }
4929 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4930 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4931 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4932 }
4933 }")
4934
4935 (define_expand "movsi_const_16bit"
4936 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4937 (const:SI (sign_extend:SI
4938 (truncate:HI
4939 (match_operand:DI 1 "immediate_operand" "s")))))]
4940 "TARGET_SHMEDIA && flag_pic && reload_completed
4941 && GET_CODE (operands[1]) == SYMBOL_REF"
4942 "")
4943
4944 (define_split
4945 [(set (match_operand:SI 0 "arith_reg_dest" "")
4946 (match_operand:SI 1 "immediate_operand" ""))]
4947 "TARGET_SHMEDIA && reload_completed
4948 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4949 [(const_int 0)]
4950 "
4951 {
4952 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4953
4954 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4955 REG_NOTES (insn));
4956
4957 DONE;
4958 }")
4959
4960 (define_split
4961 [(set (match_operand:SI 0 "register_operand" "")
4962 (match_operand:SI 1 "immediate_operand" ""))]
4963 "TARGET_SHMEDIA && reload_completed
4964 && ((GET_CODE (operands[1]) == CONST_INT
4965 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4966 || GET_CODE (operands[1]) == CONST_DOUBLE)"
4967 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4968
4969 (define_expand "movsi"
4970 [(set (match_operand:SI 0 "general_movdst_operand" "")
4971 (match_operand:SI 1 "general_movsrc_operand" ""))]
4972 ""
4973 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4974
4975 (define_expand "ic_invalidate_line"
4976 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4977 (match_dup 1)] UNSPEC_ICACHE)
4978 (clobber (scratch:SI))])]
4979 "TARGET_HARD_SH4 || TARGET_SH5"
4980 "
4981 {
4982 if (TARGET_SHMEDIA)
4983 {
4984 emit_insn (gen_ic_invalidate_line_media (operands[0]));
4985 DONE;
4986 }
4987 else if (TARGET_SHCOMPACT)
4988 {
4989 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4990 operands[1] = force_reg (Pmode, operands[1]);
4991 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4992 DONE;
4993 }
4994 else if (TARGET_SH4A_ARCH)
4995 {
4996 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4997 DONE;
4998 }
4999 operands[0] = force_reg (Pmode, operands[0]);
5000 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5001 Pmode)));
5002 }")
5003
5004 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5005 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5006 ;; the requirement *1*00 for associative address writes. The alignment of
5007 ;; %0 implies that its least significant bit is cleared,
5008 ;; thus we clear the V bit of a matching entry if there is one.
5009 (define_insn "ic_invalidate_line_i"
5010 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5011 (match_operand:SI 1 "register_operand" "r")]
5012 UNSPEC_ICACHE)
5013 (clobber (match_scratch:SI 2 "=&r"))]
5014 "TARGET_HARD_SH4"
5015 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5016 [(set_attr "length" "8")
5017 (set_attr "type" "cwb")])
5018
5019 (define_insn "ic_invalidate_line_sh4a"
5020 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5021 UNSPEC_ICACHE)]
5022 "TARGET_SH4A_ARCH"
5023 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5024 [(set_attr "length" "16")
5025 (set_attr "type" "cwb")])
5026
5027 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5028 ;; an add in the code that calculates the address.
5029 (define_insn "ic_invalidate_line_media"
5030 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5031 UNSPEC_ICACHE)]
5032 "TARGET_SHMEDIA"
5033 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5034 [(set_attr "length" "16")
5035 (set_attr "type" "invalidate_line_media")])
5036
5037 (define_insn "ic_invalidate_line_compact"
5038 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5039 (match_operand:SI 1 "register_operand" "r")]
5040 UNSPEC_ICACHE)
5041 (clobber (reg:SI PR_REG))]
5042 "TARGET_SHCOMPACT"
5043 "jsr @%1%#"
5044 [(set_attr "type" "sfunc")
5045 (set_attr "needs_delay_slot" "yes")])
5046
5047 (define_expand "initialize_trampoline"
5048 [(match_operand:SI 0 "" "")
5049 (match_operand:SI 1 "" "")
5050 (match_operand:SI 2 "" "")]
5051 "TARGET_SHCOMPACT"
5052 "
5053 {
5054 rtx sfun, tramp;
5055
5056 tramp = force_reg (Pmode, operands[0]);
5057 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5058 SFUNC_STATIC));
5059 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5060 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5061
5062 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5063 DONE;
5064 }")
5065
5066 (define_insn "initialize_trampoline_compact"
5067 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5068 (match_operand:SI 1 "register_operand" "r")
5069 (reg:SI R2_REG) (reg:SI R3_REG)]
5070 UNSPEC_INIT_TRAMP)
5071
5072 (clobber (reg:SI PR_REG))]
5073 "TARGET_SHCOMPACT"
5074 "jsr @%1%#"
5075 [(set_attr "type" "sfunc")
5076 (set_attr "needs_delay_slot" "yes")])
5077
5078 (define_insn "movqi_i"
5079 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5080 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
5081 "TARGET_SH1
5082 && (arith_reg_operand (operands[0], QImode)
5083 || arith_reg_operand (operands[1], QImode))"
5084 "@
5085 mov %1,%0
5086 mov.b %1,%0
5087 mov.b %1,%0
5088 movt %0
5089 sts %1,%0
5090 lds %1,%0"
5091 [(set_attr "type" "move,load,store,move,move,move")])
5092
5093 (define_insn "*movqi_media"
5094 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5095 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5096 "TARGET_SHMEDIA
5097 && (arith_reg_operand (operands[0], QImode)
5098 || extend_reg_or_0_operand (operands[1], QImode))"
5099 "@
5100 add.l %1, r63, %0
5101 movi %1, %0
5102 ld%M1.ub %m1, %0
5103 st%M0.b %m0, %N1"
5104 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5105 (set (attr "highpart")
5106 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5107 (const_string "user")]
5108 (const_string "ignore")))])
5109
5110 (define_expand "movqi"
5111 [(set (match_operand:QI 0 "general_operand" "")
5112 (match_operand:QI 1 "general_operand" ""))]
5113 ""
5114 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5115
5116 (define_expand "reload_inqi"
5117 [(set (match_operand:SI 2 "" "=&r")
5118 (match_operand:QI 1 "inqhi_operand" ""))
5119 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5120 (truncate:QI (match_dup 3)))]
5121 "TARGET_SHMEDIA"
5122 "
5123 {
5124 rtx inner = XEXP (operands[1], 0);
5125 int regno = REGNO (inner);
5126
5127 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5128 operands[1] = gen_rtx_REG (SImode, regno);
5129 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5130 }")
5131
5132 /* When storing r0, we have to avoid reg+reg addressing. */
5133 (define_insn "movhi_i"
5134 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5135 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5136 "TARGET_SH1
5137 && (arith_reg_operand (operands[0], HImode)
5138 || arith_reg_operand (operands[1], HImode))
5139 && (GET_CODE (operands[0]) != MEM
5140 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5141 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5142 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5143 "@
5144 mov.w %1,%0
5145 mov %1,%0
5146 mov.w %1,%0
5147 movt %0
5148 mov.w %1,%0
5149 sts %1,%0
5150 lds %1,%0
5151 fake %1,%0"
5152 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5153
5154 (define_insn "*movhi_media"
5155 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5156 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5157 "TARGET_SHMEDIA
5158 && (arith_reg_operand (operands[0], HImode)
5159 || arith_reg_or_0_operand (operands[1], HImode))"
5160 "@
5161 add.l %1, r63, %0
5162 movi %1, %0
5163 #
5164 ld%M1.w %m1, %0
5165 st%M0.w %m0, %N1"
5166 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5167 (set (attr "highpart")
5168 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5169 (const_string "user")]
5170 (const_string "ignore")))])
5171
5172 (define_split
5173 [(set (match_operand:HI 0 "register_operand" "")
5174 (match_operand:HI 1 "immediate_operand" ""))]
5175 "TARGET_SHMEDIA && reload_completed
5176 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5177 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5178
5179 (define_expand "movhi"
5180 [(set (match_operand:HI 0 "general_movdst_operand" "")
5181 (match_operand:HI 1 "general_movsrc_operand" ""))]
5182 ""
5183 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5184
5185 (define_expand "reload_inhi"
5186 [(set (match_operand:SI 2 "" "=&r")
5187 (match_operand:HI 1 "inqhi_operand" ""))
5188 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5189 (truncate:HI (match_dup 3)))]
5190 "TARGET_SHMEDIA"
5191 "
5192 {
5193 rtx inner = XEXP (operands[1], 0);
5194 int regno = REGNO (inner);
5195
5196 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5197 operands[1] = gen_rtx_REG (SImode, regno);
5198 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5199 }")
5200
5201 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5202 ;; compiled with -m2 -ml -O3 -funroll-loops
5203 (define_insn "*movdi_i"
5204 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5205 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5206 "TARGET_SH1
5207 && (arith_reg_operand (operands[0], DImode)
5208 || arith_reg_operand (operands[1], DImode))"
5209 "* return output_movedouble (insn, operands, DImode);"
5210 [(set_attr "length" "4")
5211 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5212
5213 ;; If the output is a register and the input is memory or a register, we have
5214 ;; to be careful and see which word needs to be loaded first.
5215
5216 (define_split
5217 [(set (match_operand:DI 0 "general_movdst_operand" "")
5218 (match_operand:DI 1 "general_movsrc_operand" ""))]
5219 "TARGET_SH1 && reload_completed"
5220 [(set (match_dup 2) (match_dup 3))
5221 (set (match_dup 4) (match_dup 5))]
5222 "
5223 {
5224 int regno;
5225
5226 if ((GET_CODE (operands[0]) == MEM
5227 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5228 || (GET_CODE (operands[1]) == MEM
5229 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5230 FAIL;
5231
5232 switch (GET_CODE (operands[0]))
5233 {
5234 case REG:
5235 regno = REGNO (operands[0]);
5236 break;
5237 case SUBREG:
5238 regno = subreg_regno (operands[0]);
5239 break;
5240 case MEM:
5241 regno = -1;
5242 break;
5243 default:
5244 gcc_unreachable ();
5245 }
5246
5247 if (regno == -1
5248 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5249 {
5250 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5251 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5252 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5253 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5254 }
5255 else
5256 {
5257 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5258 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5259 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5260 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5261 }
5262
5263 if (operands[2] == 0 || operands[3] == 0
5264 || operands[4] == 0 || operands[5] == 0)
5265 FAIL;
5266 }")
5267
5268 ;; The '?'s in the following constraints may not reflect the time taken
5269 ;; to perform the move. They are there to discourage the use of floating-
5270 ;; point registers for storing integer values.
5271 (define_insn "*movdi_media"
5272 [(set (match_operand:DI 0 "general_movdst_operand"
5273 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5274 (match_operand:DI 1 "general_movsrc_operand"
5275 "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5276 "TARGET_SHMEDIA_FPU
5277 && (register_operand (operands[0], DImode)
5278 || sh_register_operand (operands[1], DImode))"
5279 "@
5280 add %1, r63, %0
5281 movi %1, %0
5282 #
5283 ld%M1.q %m1, %0
5284 st%M0.q %m0, %N1
5285 fld%M1.d %m1, %0
5286 fst%M0.d %m0, %1
5287 fmov.qd %N1, %0
5288 fmov.dq %1, %0
5289 fmov.d %1, %0
5290 ptabs %1, %0
5291 gettr %1, %0
5292 pt %1, %0"
5293 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
5294 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5295
5296 (define_insn "*movdi_media_nofpu"
5297 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5298 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5299 "TARGET_SHMEDIA
5300 && (register_operand (operands[0], DImode)
5301 || sh_register_operand (operands[1], DImode))"
5302 "@
5303 add %1, r63, %0
5304 movi %1, %0
5305 #
5306 ld%M1.q %m1, %0
5307 st%M0.q %m0, %N1
5308 ptabs %1, %0
5309 gettr %1, %0
5310 pt %1, %0"
5311 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5312 (set_attr "length" "4,4,16,4,4,4,4,*")])
5313
5314 (define_insn "*movdi_media_I16"
5315 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5316 (match_operand:DI 1 "const_int_operand" "I16"))]
5317 "TARGET_SHMEDIA && reload_completed"
5318 "movi %1, %0"
5319 [(set_attr "type" "arith_media")
5320 (set_attr "length" "4")])
5321
5322 (define_split
5323 [(set (match_operand:DI 0 "arith_reg_dest" "")
5324 (match_operand:DI 1 "immediate_operand" ""))]
5325 "TARGET_SHMEDIA && reload_completed
5326 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5327 [(set (match_dup 0) (match_dup 1))]
5328 "
5329 {
5330 rtx insn;
5331
5332 if (TARGET_SHMEDIA64)
5333 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5334 else
5335 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5336
5337 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5338 REG_NOTES (insn));
5339
5340 DONE;
5341 }")
5342
5343 (define_expand "movdi_const"
5344 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5345 (const:DI (sign_extend:DI
5346 (truncate:HI
5347 (ashiftrt:DI
5348 (match_operand:DI 1 "immediate_operand" "s")
5349 (const_int 48))))))
5350 (set (match_dup 0)
5351 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5352 (zero_extend:DI
5353 (truncate:HI
5354 (const:DI
5355 (sign_extend:DI
5356 (truncate:HI
5357 (ashiftrt:SI
5358 (match_dup 1)
5359 (const_int 32)))))))))
5360 (set (match_dup 0)
5361 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5362 (zero_extend:DI
5363 (truncate:HI
5364 (const:DI
5365 (sign_extend:DI
5366 (truncate:HI
5367 (ashiftrt:SI
5368 (match_dup 1)
5369 (const_int 16)))))))))
5370 (set (match_dup 0)
5371 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5372 (zero_extend:DI
5373 (truncate:HI
5374 (const:DI
5375 (sign_extend:DI
5376 (truncate:HI
5377 (match_dup 1))))))))]
5378 "TARGET_SHMEDIA64 && reload_completed
5379 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5380 "
5381 {
5382 sh_mark_label (operands[1], 4);
5383 }")
5384
5385 (define_expand "movdi_const_32bit"
5386 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5387 (const:DI (sign_extend:DI
5388 (truncate:HI
5389 (ashiftrt:DI
5390 (match_operand:DI 1 "immediate_operand" "s")
5391 (const_int 16))))))
5392 (set (match_dup 0)
5393 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5394 (zero_extend:DI
5395 (truncate:HI
5396 (const:DI
5397 (sign_extend:DI
5398 (truncate:HI
5399 (match_dup 1))))))))]
5400 "TARGET_SHMEDIA32 && reload_completed
5401 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5402 "
5403 {
5404 sh_mark_label (operands[1], 2);
5405 }")
5406
5407 (define_expand "movdi_const_16bit"
5408 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5409 (const:DI (sign_extend:DI
5410 (truncate:HI
5411 (match_operand:DI 1 "immediate_operand" "s")))))]
5412 "TARGET_SHMEDIA && flag_pic && reload_completed
5413 && GET_CODE (operands[1]) == SYMBOL_REF"
5414 "")
5415
5416 (define_split
5417 [(set (match_operand:DI 0 "ext_dest_operand" "")
5418 (match_operand:DI 1 "immediate_operand" ""))]
5419 "TARGET_SHMEDIA && reload_completed
5420 && GET_CODE (operands[1]) == CONST_INT
5421 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5422 [(set (match_dup 0) (match_dup 2))
5423 (match_dup 1)]
5424 "
5425 {
5426 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5427 unsigned HOST_WIDE_INT low = val;
5428 unsigned HOST_WIDE_INT high = val;
5429 unsigned HOST_WIDE_INT sign;
5430 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5431
5432 /* Sign-extend the 16 least-significant bits. */
5433 low &= 0xffff;
5434 low ^= 0x8000;
5435 low -= 0x8000;
5436
5437 /* Arithmetic shift right the word by 16 bits. */
5438 high >>= 16;
5439 if (GET_CODE (operands[0]) == SUBREG
5440 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5441 {
5442 high &= 0xffff;
5443 high ^= 0x8000;
5444 high -= 0x8000;
5445 }
5446 else
5447 {
5448 sign = 1;
5449 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5450 high ^= sign;
5451 high -= sign;
5452 }
5453 do
5454 {
5455 /* If we can't generate the constant with a two-insn movi / shori
5456 sequence, try some other strategies. */
5457 if (! CONST_OK_FOR_I16 (high))
5458 {
5459 /* Try constant load / left shift. We know VAL != 0. */
5460 val2 = val ^ (val-1);
5461 if (val2 > 0x1ffff)
5462 {
5463 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5464
5465 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5466 || (! CONST_OK_FOR_I16 (high >> 16)
5467 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5468 {
5469 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5470 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5471 GEN_INT (trailing_zeroes));
5472 break;
5473 }
5474 }
5475 /* Try constant load / right shift. */
5476 val2 = (val >> 15) + 1;
5477 if (val2 == (val2 & -val2))
5478 {
5479 int shift = 49 - exact_log2 (val2);
5480
5481 val2 = trunc_int_for_mode (val << shift, DImode);
5482 if (CONST_OK_FOR_I16 (val2))
5483 {
5484 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5485 GEN_INT (shift));
5486 break;
5487 }
5488 }
5489 /* Try mperm.w . */
5490 val2 = val & 0xffff;
5491 if ((val >> 16 & 0xffff) == val2
5492 && (val >> 32 & 0xffff) == val2
5493 && (val >> 48 & 0xffff) == val2)
5494 {
5495 val2 = (HOST_WIDE_INT) val >> 48;
5496 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5497 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5498 break;
5499 }
5500 /* Try movi / mshflo.l */
5501 val2 = (HOST_WIDE_INT) val >> 32;
5502 if (val2 == ((unsigned HOST_WIDE_INT)
5503 trunc_int_for_mode (val, SImode)))
5504 {
5505 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5506 operands[0]);
5507 break;
5508 }
5509 /* Try movi / mshflo.l w/ r63. */
5510 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5511 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5512 {
5513 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5514 const0_rtx);
5515 break;
5516 }
5517 }
5518 val2 = high;
5519 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5520 }
5521 while (0);
5522 operands[2] = GEN_INT (val2);
5523 }")
5524
5525 (define_split
5526 [(set (match_operand:DI 0 "ext_dest_operand" "")
5527 (match_operand:DI 1 "immediate_operand" ""))]
5528 "TARGET_SHMEDIA && reload_completed
5529 && GET_CODE (operands[1]) == CONST_DOUBLE"
5530 [(set (match_dup 0) (match_dup 2))
5531 (set (match_dup 0)
5532 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5533 (zero_extend:DI (truncate:HI (match_dup 1)))))]
5534 "
5535 {
5536 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5537 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5538 unsigned HOST_WIDE_INT val = low;
5539 unsigned HOST_WIDE_INT sign;
5540
5541 /* Sign-extend the 16 least-significant bits. */
5542 val &= 0xffff;
5543 val ^= 0x8000;
5544 val -= 0x8000;
5545 operands[1] = GEN_INT (val);
5546
5547 /* Arithmetic shift right the double-word by 16 bits. */
5548 low >>= 16;
5549 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5550 high >>= 16;
5551 sign = 1;
5552 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5553 high ^= sign;
5554 high -= sign;
5555
5556 /* This will only be true if high is a sign-extension of low, i.e.,
5557 it must be either 0 or (unsigned)-1, and be zero iff the
5558 most-significant bit of low is set. */
5559 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5560 operands[2] = GEN_INT (low);
5561 else
5562 operands[2] = immed_double_const (low, high, DImode);
5563 }")
5564
5565 (define_insn "shori_media"
5566 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5567 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5568 (const_int 16))
5569 (zero_extend:DI
5570 (truncate:HI
5571 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5572 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5573 "@
5574 shori %u2, %0
5575 #"
5576 [(set_attr "type" "arith_media,*")])
5577
5578 (define_insn "*shori_media_si"
5579 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5580 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5581 (const_int 16))
5582 (zero_extend:SI
5583 (truncate:HI
5584 (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5585 "TARGET_SHMEDIA"
5586 "shori %u2, %0")
5587
5588 (define_expand "movdi"
5589 [(set (match_operand:DI 0 "general_movdst_operand" "")
5590 (match_operand:DI 1 "general_movsrc_operand" ""))]
5591 ""
5592 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5593
5594 (define_insn "movdf_media"
5595 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5596 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5597 "TARGET_SHMEDIA_FPU
5598 && (register_operand (operands[0], DFmode)
5599 || sh_register_operand (operands[1], DFmode))"
5600 "@
5601 fmov.d %1, %0
5602 fmov.qd %N1, %0
5603 fmov.dq %1, %0
5604 add %1, r63, %0
5605 #
5606 fld%M1.d %m1, %0
5607 fst%M0.d %m0, %1
5608 ld%M1.q %m1, %0
5609 st%M0.q %m0, %N1"
5610 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5611
5612 (define_insn "movdf_media_nofpu"
5613 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5614 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5615 "TARGET_SHMEDIA
5616 && (register_operand (operands[0], DFmode)
5617 || sh_register_operand (operands[1], DFmode))"
5618 "@
5619 add %1, r63, %0
5620 #
5621 ld%M1.q %m1, %0
5622 st%M0.q %m0, %N1"
5623 [(set_attr "type" "arith_media,*,load_media,store_media")])
5624
5625 (define_split
5626 [(set (match_operand:DF 0 "arith_reg_dest" "")
5627 (match_operand:DF 1 "immediate_operand" ""))]
5628 "TARGET_SHMEDIA && reload_completed"
5629 [(set (match_dup 3) (match_dup 2))]
5630 "
5631 {
5632 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5633 long values[2];
5634 REAL_VALUE_TYPE value;
5635
5636 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5637 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5638
5639 if (HOST_BITS_PER_WIDE_INT >= 64)
5640 operands[2] = immed_double_const ((unsigned long) values[endian]
5641 | ((HOST_WIDE_INT) values[1 - endian]
5642 << 32), 0, DImode);
5643 else
5644 {
5645 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5646 operands[2] = immed_double_const (values[endian], values[1 - endian],
5647 DImode);
5648 }
5649
5650 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5651 }")
5652
5653 ;; ??? This should be a define expand.
5654
5655 (define_insn "movdf_k"
5656 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5657 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5658 "TARGET_SH1
5659 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5660 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5661 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5662 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5663 && (arith_reg_operand (operands[0], DFmode)
5664 || arith_reg_operand (operands[1], DFmode))"
5665 "* return output_movedouble (insn, operands, DFmode);"
5666 [(set_attr "length" "4")
5667 (set_attr "type" "move,pcload,load,store")])
5668
5669 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5670 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5671 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5672 ;; the d/m/c/X alternative, which is split later into single-precision
5673 ;; instructions. And when not optimizing, no splits are done before fixing
5674 ;; up pcloads, so we need usable length information for that.
5675 (define_insn "movdf_i4"
5676 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5677 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5678 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5679 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5680 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5681 && (arith_reg_operand (operands[0], DFmode)
5682 || arith_reg_operand (operands[1], DFmode))"
5683 "@
5684 fmov %1,%0
5685 #
5686 #
5687 fmov.d %1,%0
5688 fmov.d %1,%0
5689 #
5690 #
5691 #
5692 #
5693 #"
5694 [(set_attr_alternative "length"
5695 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5696 (const_int 4)
5697 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5698 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5699 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5700 (const_int 4)
5701 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5702 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5703 ;; increment or decrement r15 explicitly.
5704 (if_then_else
5705 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5706 (const_int 10) (const_int 8))
5707 (if_then_else
5708 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5709 (const_int 10) (const_int 8))])
5710 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5711 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5712 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5713 (const_string "double")
5714 (const_string "none")))])
5715
5716 ;; Moving DFmode between fp/general registers through memory
5717 ;; (the top of the stack) is faster than moving through fpul even for
5718 ;; little endian. Because the type of an instruction is important for its
5719 ;; scheduling, it is beneficial to split these operations, rather than
5720 ;; emitting them in one single chunk, even if this will expose a stack
5721 ;; use that will prevent scheduling of other stack accesses beyond this
5722 ;; instruction.
5723 (define_split
5724 [(set (match_operand:DF 0 "register_operand" "")
5725 (match_operand:DF 1 "register_operand" ""))
5726 (use (match_operand:PSI 2 "fpscr_operand" ""))
5727 (clobber (match_scratch:SI 3 "=X"))]
5728 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5729 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5730 [(const_int 0)]
5731 "
5732 {
5733 rtx insn, tos;
5734
5735 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5736 {
5737 emit_move_insn (stack_pointer_rtx,
5738 plus_constant (stack_pointer_rtx, -8));
5739 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5740 }
5741 else
5742 tos = gen_tmp_stack_mem (DFmode,
5743 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5744 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5745 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5746 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5747 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5748 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5749 else
5750 tos = gen_tmp_stack_mem (DFmode,
5751 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5752 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5753 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5754 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5755 else
5756 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5757 DONE;
5758 }")
5759
5760 ;; local-alloc sometimes allocates scratch registers even when not required,
5761 ;; so we must be prepared to handle these.
5762
5763 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5764 (define_split
5765 [(set (match_operand:DF 0 "general_movdst_operand" "")
5766 (match_operand:DF 1 "general_movsrc_operand" ""))
5767 (use (match_operand:PSI 2 "fpscr_operand" ""))
5768 (clobber (match_scratch:SI 3 ""))]
5769 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5770 && reload_completed
5771 && true_regnum (operands[0]) < 16
5772 && true_regnum (operands[1]) < 16"
5773 [(set (match_dup 0) (match_dup 1))]
5774 "
5775 {
5776 /* If this was a reg <-> mem operation with base + index reg addressing,
5777 we have to handle this in a special way. */
5778 rtx mem = operands[0];
5779 int store_p = 1;
5780 if (! memory_operand (mem, DFmode))
5781 {
5782 mem = operands[1];
5783 store_p = 0;
5784 }
5785 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5786 mem = SUBREG_REG (mem);
5787 if (GET_CODE (mem) == MEM)
5788 {
5789 rtx addr = XEXP (mem, 0);
5790 if (GET_CODE (addr) == PLUS
5791 && GET_CODE (XEXP (addr, 0)) == REG
5792 && GET_CODE (XEXP (addr, 1)) == REG)
5793 {
5794 int offset;
5795 rtx reg0 = gen_rtx_REG (Pmode, 0);
5796 rtx regop = operands[store_p], word0 ,word1;
5797
5798 if (GET_CODE (regop) == SUBREG)
5799 alter_subreg (&regop);
5800 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5801 offset = 2;
5802 else
5803 offset = 4;
5804 mem = copy_rtx (mem);
5805 PUT_MODE (mem, SImode);
5806 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5807 alter_subreg (&word0);
5808 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5809 alter_subreg (&word1);
5810 if (store_p || ! refers_to_regno_p (REGNO (word0),
5811 REGNO (word0) + 1, addr, 0))
5812 {
5813 emit_insn (store_p
5814 ? gen_movsi_ie (mem, word0)
5815 : gen_movsi_ie (word0, mem));
5816 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5817 mem = copy_rtx (mem);
5818 emit_insn (store_p
5819 ? gen_movsi_ie (mem, word1)
5820 : gen_movsi_ie (word1, mem));
5821 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5822 }
5823 else
5824 {
5825 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5826 emit_insn (gen_movsi_ie (word1, mem));
5827 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5828 mem = copy_rtx (mem);
5829 emit_insn (gen_movsi_ie (word0, mem));
5830 }
5831 DONE;
5832 }
5833 }
5834 }")
5835
5836 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5837 (define_split
5838 [(set (match_operand:DF 0 "register_operand" "")
5839 (match_operand:DF 1 "memory_operand" ""))
5840 (use (match_operand:PSI 2 "fpscr_operand" ""))
5841 (clobber (reg:SI R0_REG))]
5842 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5843 [(parallel [(set (match_dup 0) (match_dup 1))
5844 (use (match_dup 2))
5845 (clobber (scratch:SI))])]
5846 "")
5847
5848 (define_expand "reload_indf"
5849 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5850 (match_operand:DF 1 "immediate_operand" "FQ"))
5851 (use (reg:PSI FPSCR_REG))
5852 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5853 "TARGET_SH1"
5854 "")
5855
5856 (define_expand "reload_outdf"
5857 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5858 (match_operand:DF 1 "register_operand" "af,r"))
5859 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5860 "TARGET_SH1"
5861 "")
5862
5863 ;; Simplify no-op moves.
5864 (define_split
5865 [(set (match_operand:SF 0 "register_operand" "")
5866 (match_operand:SF 1 "register_operand" ""))
5867 (use (match_operand:PSI 2 "fpscr_operand" ""))
5868 (clobber (match_scratch:SI 3 ""))]
5869 "TARGET_SH2E && reload_completed
5870 && true_regnum (operands[0]) == true_regnum (operands[1])"
5871 [(set (match_dup 0) (match_dup 0))]
5872 "")
5873
5874 ;; fmovd substitute post-reload splits
5875 (define_split
5876 [(set (match_operand:DF 0 "register_operand" "")
5877 (match_operand:DF 1 "register_operand" ""))
5878 (use (match_operand:PSI 2 "fpscr_operand" ""))
5879 (clobber (match_scratch:SI 3 ""))]
5880 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5881 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5882 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5883 [(const_int 0)]
5884 "
5885 {
5886 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5887 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5888 gen_rtx_REG (SFmode, src), operands[2]));
5889 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5890 gen_rtx_REG (SFmode, src + 1), operands[2]));
5891 DONE;
5892 }")
5893
5894 (define_split
5895 [(set (match_operand:DF 0 "register_operand" "")
5896 (mem:DF (match_operand:SI 1 "register_operand" "")))
5897 (use (match_operand:PSI 2 "fpscr_operand" ""))
5898 (clobber (match_scratch:SI 3 ""))]
5899 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5900 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5901 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5902 [(const_int 0)]
5903 "
5904 {
5905 int regno = true_regnum (operands[0]);
5906 rtx insn;
5907 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5908 rtx mem2
5909 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5910 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5911 regno + !! TARGET_LITTLE_ENDIAN),
5912 mem2, operands[2]));
5913 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5914 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5915 regno + ! TARGET_LITTLE_ENDIAN),
5916 change_address (mem, SFmode, NULL_RTX),
5917 operands[2]));
5918 DONE;
5919 }")
5920
5921 (define_split
5922 [(set (match_operand:DF 0 "register_operand" "")
5923 (match_operand:DF 1 "memory_operand" ""))
5924 (use (match_operand:PSI 2 "fpscr_operand" ""))
5925 (clobber (match_scratch:SI 3 ""))]
5926 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5927 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5928 [(const_int 0)]
5929 "
5930 {
5931 int regno = true_regnum (operands[0]);
5932 rtx addr, insn, adjust = NULL_RTX;
5933 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
5934 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5935 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5936
5937 operands[1] = copy_rtx (mem2);
5938 addr = XEXP (mem2, 0);
5939 if (GET_CODE (addr) != POST_INC)
5940 {
5941 /* If we have to modify the stack pointer, the value that we have
5942 read with post-increment might be modified by an interrupt,
5943 so write it back. */
5944 if (REGNO (addr) == STACK_POINTER_REGNUM)
5945 adjust = gen_push_e (reg0);
5946 else
5947 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5948 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5949 }
5950 addr = XEXP (addr, 0);
5951 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5952 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5953 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5954 if (adjust)
5955 emit_insn (adjust);
5956 else
5957 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5958 DONE;
5959 }")
5960
5961 (define_split
5962 [(set (match_operand:DF 0 "memory_operand" "")
5963 (match_operand:DF 1 "register_operand" ""))
5964 (use (match_operand:PSI 2 "fpscr_operand" ""))
5965 (clobber (match_scratch:SI 3 ""))]
5966 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5967 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5968 [(const_int 0)]
5969 "
5970 {
5971 int regno = true_regnum (operands[1]);
5972 rtx insn, addr, adjust = NULL_RTX;
5973
5974 operands[0] = copy_rtx (operands[0]);
5975 PUT_MODE (operands[0], SFmode);
5976 insn = emit_insn (gen_movsf_ie (operands[0],
5977 gen_rtx_REG (SFmode,
5978 regno + ! TARGET_LITTLE_ENDIAN),
5979 operands[2]));
5980 operands[0] = copy_rtx (operands[0]);
5981 addr = XEXP (operands[0], 0);
5982 if (GET_CODE (addr) != PRE_DEC)
5983 {
5984 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5985 emit_insn_before (adjust, insn);
5986 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5987 }
5988 addr = XEXP (addr, 0);
5989 if (! adjust)
5990 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5991 insn = emit_insn (gen_movsf_ie (operands[0],
5992 gen_rtx_REG (SFmode,
5993 regno + !! TARGET_LITTLE_ENDIAN),
5994 operands[2]));
5995 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5996 DONE;
5997 }")
5998
5999 ;; If the output is a register and the input is memory or a register, we have
6000 ;; to be careful and see which word needs to be loaded first.
6001
6002 (define_split
6003 [(set (match_operand:DF 0 "general_movdst_operand" "")
6004 (match_operand:DF 1 "general_movsrc_operand" ""))]
6005 "TARGET_SH1 && reload_completed"
6006 [(set (match_dup 2) (match_dup 3))
6007 (set (match_dup 4) (match_dup 5))]
6008 "
6009 {
6010 int regno;
6011
6012 if ((GET_CODE (operands[0]) == MEM
6013 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6014 || (GET_CODE (operands[1]) == MEM
6015 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6016 FAIL;
6017
6018 switch (GET_CODE (operands[0]))
6019 {
6020 case REG:
6021 regno = REGNO (operands[0]);
6022 break;
6023 case SUBREG:
6024 regno = subreg_regno (operands[0]);
6025 break;
6026 case MEM:
6027 regno = -1;
6028 break;
6029 default:
6030 gcc_unreachable ();
6031 }
6032
6033 if (regno == -1
6034 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6035 {
6036 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6037 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6038 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6039 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6040 }
6041 else
6042 {
6043 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6044 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6045 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6046 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6047 }
6048
6049 if (operands[2] == 0 || operands[3] == 0
6050 || operands[4] == 0 || operands[5] == 0)
6051 FAIL;
6052 }")
6053
6054 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6055 ;; used only once, let combine add in the index again.
6056
6057 (define_split
6058 [(set (match_operand:SI 0 "register_operand" "")
6059 (match_operand:SI 1 "" ""))
6060 (clobber (match_operand 2 "register_operand" ""))]
6061 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6062 && ALLOW_INDEXED_ADDRESS"
6063 [(use (reg:SI R0_REG))]
6064 "
6065 {
6066 rtx addr, reg, const_int;
6067
6068 if (GET_CODE (operands[1]) != MEM)
6069 FAIL;
6070 addr = XEXP (operands[1], 0);
6071 if (GET_CODE (addr) != PLUS)
6072 FAIL;
6073 reg = XEXP (addr, 0);
6074 const_int = XEXP (addr, 1);
6075 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6076 && GET_CODE (const_int) == CONST_INT))
6077 FAIL;
6078 emit_move_insn (operands[2], const_int);
6079 emit_move_insn (operands[0],
6080 change_address (operands[1], VOIDmode,
6081 gen_rtx_PLUS (SImode, reg, operands[2])));
6082 DONE;
6083 }")
6084
6085 (define_split
6086 [(set (match_operand:SI 1 "" "")
6087 (match_operand:SI 0 "register_operand" ""))
6088 (clobber (match_operand 2 "register_operand" ""))]
6089 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6090 && ALLOW_INDEXED_ADDRESS"
6091 [(use (reg:SI R0_REG))]
6092 "
6093 {
6094 rtx addr, reg, const_int;
6095
6096 if (GET_CODE (operands[1]) != MEM)
6097 FAIL;
6098 addr = XEXP (operands[1], 0);
6099 if (GET_CODE (addr) != PLUS)
6100 FAIL;
6101 reg = XEXP (addr, 0);
6102 const_int = XEXP (addr, 1);
6103 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6104 && GET_CODE (const_int) == CONST_INT))
6105 FAIL;
6106 emit_move_insn (operands[2], const_int);
6107 emit_move_insn (change_address (operands[1], VOIDmode,
6108 gen_rtx_PLUS (SImode, reg, operands[2])),
6109 operands[0]);
6110 DONE;
6111 }")
6112
6113 (define_expand "movdf"
6114 [(set (match_operand:DF 0 "general_movdst_operand" "")
6115 (match_operand:DF 1 "general_movsrc_operand" ""))]
6116 ""
6117 "
6118 {
6119 if (prepare_move_operands (operands, DFmode)) DONE;
6120 if (TARGET_SHMEDIA)
6121 {
6122 if (TARGET_SHMEDIA_FPU)
6123 emit_insn (gen_movdf_media (operands[0], operands[1]));
6124 else
6125 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6126 DONE;
6127 }
6128 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6129 {
6130 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6131 DONE;
6132 }
6133 }")
6134
6135 ;;This is incompatible with the way gcc uses subregs.
6136 ;;(define_insn "movv2sf_i"
6137 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6138 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6139 ;; "TARGET_SHMEDIA_FPU
6140 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6141 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6142 ;; "@
6143 ;; #
6144 ;; fld%M1.p %m1, %0
6145 ;; fst%M0.p %m0, %1"
6146 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6147
6148 (define_insn_and_split "movv2sf_i"
6149 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6150 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6151 "TARGET_SHMEDIA_FPU"
6152 "#"
6153 "TARGET_SHMEDIA_FPU && reload_completed"
6154 [(set (match_dup 0) (match_dup 1))]
6155 "
6156 {
6157 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6158 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6159 }")
6160
6161 (define_expand "movv2sf"
6162 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6163 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6164 "TARGET_SHMEDIA_FPU"
6165 "
6166 {
6167 if (prepare_move_operands (operands, V2SFmode))
6168 DONE;
6169 }")
6170
6171 (define_expand "addv2sf3"
6172 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6173 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6174 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6175 "TARGET_SHMEDIA_FPU"
6176 "
6177 {
6178 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6179 DONE;
6180 }")
6181
6182 (define_expand "subv2sf3"
6183 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6184 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6185 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6186 "TARGET_SHMEDIA_FPU"
6187 "
6188 {
6189 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6190 DONE;
6191 }")
6192
6193 (define_expand "mulv2sf3"
6194 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6195 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6196 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6197 "TARGET_SHMEDIA_FPU"
6198 "
6199 {
6200 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6201 DONE;
6202 }")
6203
6204 (define_expand "divv2sf3"
6205 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6206 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6207 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6208 "TARGET_SHMEDIA_FPU"
6209 "
6210 {
6211 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6212 DONE;
6213 }")
6214
6215 (define_insn_and_split "*movv4sf_i"
6216 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6217 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6218 "TARGET_SHMEDIA_FPU"
6219 "#"
6220 "&& reload_completed"
6221 [(const_int 0)]
6222 "
6223 {
6224 int i;
6225
6226 for (i = 0; i < 4/2; i++)
6227 {
6228 rtx x, y;
6229
6230 if (GET_CODE (operands[0]) == MEM)
6231 x = adjust_address (operands[0], V2SFmode,
6232 i * GET_MODE_SIZE (V2SFmode));
6233 else
6234 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6235
6236 if (GET_CODE (operands[1]) == MEM)
6237 y = adjust_address (operands[1], V2SFmode,
6238 i * GET_MODE_SIZE (V2SFmode));
6239 else
6240 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6241
6242 emit_insn (gen_movv2sf_i (x, y));
6243 }
6244
6245 DONE;
6246 }"
6247 [(set_attr "length" "8")])
6248
6249 (define_expand "movv4sf"
6250 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6251 (match_operand:V4SF 1 "general_operand" ""))]
6252 "TARGET_SHMEDIA_FPU"
6253 "
6254 {
6255 if (prepare_move_operands (operands, V4SFmode))
6256 DONE;
6257 }")
6258
6259 (define_insn_and_split "*movv16sf_i"
6260 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6261 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6262 "TARGET_SHMEDIA_FPU"
6263 "#"
6264 "&& reload_completed"
6265 [(const_int 0)]
6266 "
6267 {
6268 int i;
6269
6270 for (i = 0; i < 16/2; i++)
6271 {
6272 rtx x,y;
6273
6274 if (GET_CODE (operands[0]) == MEM)
6275 x = adjust_address (operands[0], V2SFmode,
6276 i * GET_MODE_SIZE (V2SFmode));
6277 else
6278 {
6279 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6280 alter_subreg (&x);
6281 }
6282
6283 if (GET_CODE (operands[1]) == MEM)
6284 y = adjust_address (operands[1], V2SFmode,
6285 i * GET_MODE_SIZE (V2SFmode));
6286 else
6287 {
6288 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6289 alter_subreg (&y);
6290 }
6291
6292 emit_insn (gen_movv2sf_i (x, y));
6293 }
6294
6295 DONE;
6296 }"
6297 [(set_attr "length" "32")])
6298
6299 (define_expand "movv16sf"
6300 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6301 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6302 "TARGET_SHMEDIA_FPU"
6303 "
6304 {
6305 if (prepare_move_operands (operands, V16SFmode))
6306 DONE;
6307 }")
6308
6309 (define_insn "movsf_media"
6310 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6311 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6312 "TARGET_SHMEDIA_FPU
6313 && (register_operand (operands[0], SFmode)
6314 || sh_register_operand (operands[1], SFmode))"
6315 "@
6316 fmov.s %1, %0
6317 fmov.ls %N1, %0
6318 fmov.sl %1, %0
6319 add.l %1, r63, %0
6320 #
6321 fld%M1.s %m1, %0
6322 fst%M0.s %m0, %1
6323 ld%M1.l %m1, %0
6324 st%M0.l %m0, %N1"
6325 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6326 (set (attr "highpart")
6327 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6328 (const_string "user")]
6329 (const_string "ignore")))])
6330
6331 (define_insn "movsf_media_nofpu"
6332 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6333 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6334 "TARGET_SHMEDIA
6335 && (register_operand (operands[0], SFmode)
6336 || sh_register_operand (operands[1], SFmode))"
6337 "@
6338 add.l %1, r63, %0
6339 #
6340 ld%M1.l %m1, %0
6341 st%M0.l %m0, %N1"
6342 [(set_attr "type" "arith_media,*,load_media,store_media")
6343 (set (attr "highpart")
6344 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6345 (const_string "user")]
6346 (const_string "ignore")))])
6347
6348 (define_split
6349 [(set (match_operand:SF 0 "arith_reg_dest" "")
6350 (match_operand:SF 1 "immediate_operand" ""))]
6351 "TARGET_SHMEDIA && reload_completed
6352 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6353 [(set (match_dup 3) (match_dup 2))]
6354 "
6355 {
6356 long values;
6357 REAL_VALUE_TYPE value;
6358
6359 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6360 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6361 operands[2] = GEN_INT (values);
6362
6363 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6364 }")
6365
6366 (define_insn "movsf_i"
6367 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6368 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6369 "TARGET_SH1
6370 && (! TARGET_SH2E
6371 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6372 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6373 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6374 && (arith_reg_operand (operands[0], SFmode)
6375 || arith_reg_operand (operands[1], SFmode))"
6376 "@
6377 mov %1,%0
6378 mov #0,%0
6379 mov.l %1,%0
6380 mov.l %1,%0
6381 mov.l %1,%0
6382 lds %1,%0
6383 sts %1,%0"
6384 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6385
6386 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6387 ;; update_flow_info would not know where to put REG_EQUAL notes
6388 ;; when the destination changes mode.
6389 (define_insn "movsf_ie"
6390 [(set (match_operand:SF 0 "general_movdst_operand"
6391 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6392 (match_operand:SF 1 "general_movsrc_operand"
6393 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6394 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
6395 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6396
6397 "TARGET_SH2E
6398 && (arith_reg_operand (operands[0], SFmode)
6399 || arith_reg_operand (operands[1], SFmode)
6400 || arith_reg_operand (operands[3], SImode)
6401 || (fpul_operand (operands[0], SFmode)
6402 && memory_operand (operands[1], SFmode)
6403 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6404 || (fpul_operand (operands[1], SFmode)
6405 && memory_operand (operands[0], SFmode)
6406 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6407 "@
6408 fmov %1,%0
6409 mov %1,%0
6410 fldi0 %0
6411 fldi1 %0
6412 #
6413 fmov.s %1,%0
6414 fmov.s %1,%0
6415 mov.l %1,%0
6416 mov.l %1,%0
6417 mov.l %1,%0
6418 fsts fpul,%0
6419 flds %1,fpul
6420 lds.l %1,%0
6421 #
6422 sts %1,%0
6423 lds %1,%0
6424 sts.l %1,%0
6425 lds.l %1,%0
6426 ! move optimized away"
6427 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6428 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6429 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6430 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6431 (const_string "single")
6432 (const_string "none")))])
6433
6434 (define_split
6435 [(set (match_operand:SF 0 "register_operand" "")
6436 (match_operand:SF 1 "register_operand" ""))
6437 (use (match_operand:PSI 2 "fpscr_operand" ""))
6438 (clobber (reg:SI FPUL_REG))]
6439 "TARGET_SH1"
6440 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6441 (use (match_dup 2))
6442 (clobber (scratch:SI))])
6443 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6444 (use (match_dup 2))
6445 (clobber (scratch:SI))])]
6446 "")
6447
6448 (define_expand "movsf"
6449 [(set (match_operand:SF 0 "general_movdst_operand" "")
6450 (match_operand:SF 1 "general_movsrc_operand" ""))]
6451 ""
6452 "
6453 {
6454 if (prepare_move_operands (operands, SFmode))
6455 DONE;
6456 if (TARGET_SHMEDIA)
6457 {
6458 if (TARGET_SHMEDIA_FPU)
6459 emit_insn (gen_movsf_media (operands[0], operands[1]));
6460 else
6461 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6462 DONE;
6463 }
6464 if (TARGET_SH2E)
6465 {
6466 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6467 DONE;
6468 }
6469 }")
6470
6471 (define_insn "mov_nop"
6472 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6473 "TARGET_SH2E"
6474 ""
6475 [(set_attr "length" "0")
6476 (set_attr "type" "nil")])
6477
6478 (define_expand "reload_insf"
6479 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6480 (match_operand:SF 1 "immediate_operand" "FQ"))
6481 (use (reg:PSI FPSCR_REG))
6482 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6483 "TARGET_SH1"
6484 "")
6485
6486 (define_expand "reload_insi"
6487 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6488 (match_operand:SI 1 "immediate_operand" "i"))
6489 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6490 "TARGET_SH1"
6491 "")
6492
6493 (define_expand "ptabs"
6494 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6495 "TARGET_SHMEDIA"
6496 "
6497 {
6498 if (!TARGET_PT_FIXED)
6499 {
6500 rtx eq = operands[1];
6501
6502 /* ??? For canonical RTL we really should remove any CONST from EQ
6503 before wrapping it in the AND, and finally wrap the EQ into a
6504 const if is constant. However, for reload we must expose the
6505 input register or symbolic constant, and we can't have
6506 different insn structures outside of the operands for different
6507 alternatives of the same pattern. */
6508 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6509 GEN_INT (3));
6510 operands[1]
6511 = (gen_rtx_IF_THEN_ELSE
6512 (PDImode,
6513 eq,
6514 gen_rtx_MEM (PDImode, operands[1]),
6515 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6516 PDImode, operands[1])));
6517 }
6518 }")
6519
6520 ;; expanded by ptabs expander.
6521 (define_insn "*extendsipdi_media"
6522 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6523 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6524 "r,Csy")
6525 (const_int 3))
6526 (const_int 3))
6527 (mem:PDI (match_dup 1))
6528 (sign_extend:PDI (match_dup 1))))]
6529 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6530 "@
6531 ptabs %1, %0
6532 pt %1, %0"
6533 [(set_attr "type" "ptabs_media,pt_media")
6534 (set_attr "length" "4,*")])
6535
6536 (define_insn "*truncdipdi_media"
6537 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6538 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6539 "r,Csy")
6540 (const_int 3))
6541 (const_int 3))
6542 (mem:PDI (match_dup 1))
6543 (truncate:PDI (match_dup 1))))]
6544 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6545 "@
6546 ptabs %1, %0
6547 pt %1, %0"
6548 [(set_attr "type" "ptabs_media,pt_media")
6549 (set_attr "length" "4,*")])
6550
6551 (define_insn "*movsi_y"
6552 [(set (match_operand:SI 0 "register_operand" "=y,y")
6553 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6554 (clobber (match_scratch:SI 2 "=&z,r"))]
6555 "TARGET_SH2E
6556 && (reload_in_progress || reload_completed)"
6557 "#"
6558 [(set_attr "length" "4")
6559 (set_attr "type" "pcload,move")])
6560
6561 (define_split
6562 [(set (match_operand:SI 0 "register_operand" "")
6563 (match_operand:SI 1 "immediate_operand" ""))
6564 (clobber (match_operand:SI 2 "register_operand" ""))]
6565 "TARGET_SH1"
6566 [(set (match_dup 2) (match_dup 1))
6567 (set (match_dup 0) (match_dup 2))]
6568 "")
6569
6570 (define_split
6571 [(set (match_operand:SI 0 "register_operand" "")
6572 (match_operand:SI 1 "memory_operand" ""))
6573 (clobber (reg:SI R0_REG))]
6574 "TARGET_SH1"
6575 [(set (match_dup 0) (match_dup 1))]
6576 "")
6577 \f
6578 ;; ------------------------------------------------------------------------
6579 ;; Define the real conditional branch instructions.
6580 ;; ------------------------------------------------------------------------
6581
6582 (define_insn "branch_true"
6583 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6584 (label_ref (match_operand 0 "" ""))
6585 (pc)))]
6586 "TARGET_SH1"
6587 "* return output_branch (1, insn, operands);"
6588 [(set_attr "type" "cbranch")])
6589
6590 (define_insn "branch_false"
6591 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6592 (label_ref (match_operand 0 "" ""))
6593 (pc)))]
6594 "TARGET_SH1"
6595 "* return output_branch (0, insn, operands);"
6596 [(set_attr "type" "cbranch")])
6597
6598 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6599 ;; which destination is too far away.
6600 ;; The const_int_operand is distinct for each branch target; it avoids
6601 ;; unwanted matches with redundant_insn.
6602 (define_insn "block_branch_redirect"
6603 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6604 "TARGET_SH1"
6605 ""
6606 [(set_attr "length" "0")])
6607
6608 ;; This one has the additional purpose to record a possible scratch register
6609 ;; for the following branch.
6610 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6611 ;; because the insn then might be deemed dead and deleted. And we can't
6612 ;; make the use in the jump insn explicit because that would disable
6613 ;; delay slot scheduling from the target.
6614 (define_insn "indirect_jump_scratch"
6615 [(set (match_operand:SI 0 "register_operand" "=r")
6616 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6617 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6618 "TARGET_SH1"
6619 ""
6620 [(set_attr "length" "0")])
6621
6622 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6623 ;; being pulled into the delay slot of a condbranch that has been made to
6624 ;; jump around the unconditional jump because it was out of range.
6625 (define_insn "stuff_delay_slot"
6626 [(set (pc)
6627 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6628 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6629 "TARGET_SH1"
6630 ""
6631 [(set_attr "length" "0")
6632 (set_attr "cond_delay_slot" "yes")])
6633 \f
6634 ;; Conditional branch insns
6635
6636 (define_expand "beq_media"
6637 [(set (pc)
6638 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6639 (match_operand:DI 2 "arith_operand" "r,I06"))
6640 (match_operand 0 "" "")
6641 (pc)))]
6642 "TARGET_SHMEDIA"
6643 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6644
6645 (define_insn "*beq_media_i"
6646 [(set (pc)
6647 (if_then_else (match_operator 3 "equality_comparison_operator"
6648 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6649 (match_operand:DI 2 "arith_operand" "r,I06")])
6650 (match_operand 0 "target_operand" "b,b")
6651 (pc)))]
6652 "TARGET_SHMEDIA"
6653 "@
6654 b%o3%' %1, %2, %0%>
6655 b%o3i%' %1, %2, %0%>"
6656 [(set_attr "type" "cbranch_media")])
6657
6658 (define_insn "*beq_media_i32"
6659 [(set (pc)
6660 (if_then_else (match_operator 3 "equality_comparison_operator"
6661 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6662 (match_operand:SI 2 "arith_operand" "r,I06")])
6663 (match_operand 0 "target_operand" "b,b")
6664 (pc)))]
6665 "TARGET_SHMEDIA"
6666 "@
6667 b%o3%' %1, %2, %0%>
6668 b%o3i%' %1, %2, %0%>"
6669 [(set_attr "type" "cbranch_media")])
6670
6671 (define_expand "bne_media"
6672 [(set (pc)
6673 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6674 (match_operand:DI 2 "arith_operand" "r,I06"))
6675 (match_operand 0 "" "")
6676 (pc)))]
6677 "TARGET_SHMEDIA"
6678 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6679
6680 (define_expand "bgt_media"
6681 [(set (pc)
6682 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6683 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6684 (match_operand 0 "" "")
6685 (pc)))]
6686 "TARGET_SHMEDIA"
6687 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6688
6689 (define_expand "bge_media"
6690 [(set (pc)
6691 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6692 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6693 (match_operand 0 "" "")
6694 (pc)))]
6695 "TARGET_SHMEDIA"
6696 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6697
6698 (define_expand "bgtu_media"
6699 [(set (pc)
6700 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6701 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6702 (match_operand 0 "" "")
6703 (pc)))]
6704 "TARGET_SHMEDIA"
6705 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6706
6707 (define_expand "bgeu_media"
6708 [(set (pc)
6709 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6710 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6711 (match_operand 0 "" "")
6712 (pc)))]
6713 "TARGET_SHMEDIA"
6714 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6715
6716 (define_insn "*bgt_media_i"
6717 [(set (pc)
6718 (if_then_else (match_operator 3 "greater_comparison_operator"
6719 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6720 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6721 (match_operand 0 "target_operand" "b")
6722 (pc)))]
6723 "TARGET_SHMEDIA"
6724 "b%o3%' %N1, %N2, %0%>"
6725 [(set_attr "type" "cbranch_media")])
6726
6727 (define_insn "*bgt_media_i32"
6728 [(set (pc)
6729 (if_then_else (match_operator 3 "greater_comparison_operator"
6730 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6731 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6732 (match_operand 0 "target_operand" "b")
6733 (pc)))]
6734 "TARGET_SHMEDIA"
6735 "b%o3%' %N1, %N2, %0%>"
6736 [(set_attr "type" "cbranch_media")])
6737
6738 ;; These are only needed to make invert_jump() happy - otherwise, jump
6739 ;; optimization will be silently disabled.
6740 (define_insn "*blt_media_i"
6741 [(set (pc)
6742 (if_then_else (match_operator 3 "less_comparison_operator"
6743 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6744 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6745 (match_operand 0 "target_operand" "b")
6746 (pc)))]
6747 "TARGET_SHMEDIA"
6748 "b%o3%' %N2, %N1, %0%>"
6749 [(set_attr "type" "cbranch_media")])
6750
6751 (define_insn "*blt_media_i32"
6752 [(set (pc)
6753 (if_then_else (match_operator 3 "less_comparison_operator"
6754 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6755 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6756 (match_operand 0 "target_operand" "b")
6757 (pc)))]
6758 "TARGET_SHMEDIA"
6759 "b%o3%' %N2, %N1, %0%>"
6760 [(set_attr "type" "cbranch_media")])
6761
6762 (define_expand "beq"
6763 [(set (pc)
6764 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6765 (label_ref (match_operand 0 "" ""))
6766 (pc)))]
6767 ""
6768 "
6769 {
6770 if (TARGET_SHMEDIA)
6771 {
6772 enum machine_mode mode = GET_MODE (sh_compare_op0);
6773
6774 if (mode != DImode && mode != SImode)
6775 {
6776 rtx tmp = gen_reg_rtx (DImode);
6777
6778 emit_insn (gen_seq (tmp));
6779 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6780 DONE;
6781 }
6782
6783 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6784 if (CONSTANT_P (sh_compare_op1)
6785 && (GET_CODE (sh_compare_op1) != CONST_INT
6786 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6787 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6788 emit_jump_insn (gen_beq_media (operands[0],
6789 sh_compare_op0, sh_compare_op1));
6790 DONE;
6791 }
6792
6793 from_compare (operands, EQ);
6794 }")
6795
6796 (define_expand "bne"
6797 [(set (pc)
6798 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6799 (label_ref (match_operand 0 "" ""))
6800 (pc)))]
6801 ""
6802 "
6803 {
6804 if (TARGET_SHMEDIA)
6805 {
6806 enum machine_mode mode = GET_MODE (sh_compare_op0);
6807
6808 if (mode != DImode && mode != SImode)
6809 {
6810 rtx tmp = gen_reg_rtx (DImode);
6811
6812 emit_insn (gen_seq (tmp));
6813 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6814 DONE;
6815 }
6816
6817 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6818 if (CONSTANT_P (sh_compare_op1)
6819 && (GET_CODE (sh_compare_op1) != CONST_INT
6820 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6821 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6822 emit_jump_insn (gen_bne_media (operands[0],
6823 sh_compare_op0, sh_compare_op1));
6824 DONE;
6825 }
6826
6827 from_compare (operands, EQ);
6828 }")
6829
6830 (define_expand "bgt"
6831 [(set (pc)
6832 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6833 (label_ref (match_operand 0 "" ""))
6834 (pc)))]
6835 ""
6836 "
6837 {
6838 if (TARGET_SHMEDIA)
6839 {
6840 enum machine_mode mode = GET_MODE (sh_compare_op0);
6841
6842 if (mode != DImode && mode != SImode)
6843 {
6844 rtx tmp = gen_reg_rtx (DImode);
6845
6846 emit_insn (gen_sgt (tmp));
6847 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6848 DONE;
6849 }
6850
6851 if (sh_compare_op0 != const0_rtx)
6852 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6853 if (sh_compare_op1 != const0_rtx)
6854 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6855 emit_jump_insn (gen_bgt_media (operands[0],
6856 sh_compare_op0, sh_compare_op1));
6857 DONE;
6858 }
6859
6860 from_compare (operands, GT);
6861 }")
6862
6863 (define_expand "blt"
6864 [(set (pc)
6865 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6866 (label_ref (match_operand 0 "" ""))
6867 (pc)))]
6868 ""
6869 "
6870 {
6871 if (TARGET_SHMEDIA)
6872 {
6873 enum machine_mode mode = GET_MODE (sh_compare_op0);
6874
6875 if (mode != DImode && mode != SImode)
6876 {
6877 rtx tmp = gen_reg_rtx (DImode);
6878
6879 emit_insn (gen_slt (tmp));
6880 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6881 DONE;
6882 }
6883
6884 if (sh_compare_op0 != const0_rtx)
6885 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6886 if (sh_compare_op1 != const0_rtx)
6887 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6888 emit_jump_insn (gen_bgt_media (operands[0],
6889 sh_compare_op1, sh_compare_op0));
6890 DONE;
6891 }
6892
6893 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6894 {
6895 rtx tmp = sh_compare_op0;
6896 sh_compare_op0 = sh_compare_op1;
6897 sh_compare_op1 = tmp;
6898 emit_insn (gen_bgt (operands[0]));
6899 DONE;
6900 }
6901 from_compare (operands, GE);
6902 }")
6903
6904 (define_expand "ble"
6905 [(set (pc)
6906 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6907 (label_ref (match_operand 0 "" ""))
6908 (pc)))]
6909 ""
6910 "
6911 {
6912 if (TARGET_SHMEDIA)
6913 {
6914 enum machine_mode mode = GET_MODE (sh_compare_op0);
6915
6916 if (mode != DImode && mode != SImode)
6917 {
6918 rtx tmp = gen_reg_rtx (DImode);
6919
6920 emit_insn (gen_sle (tmp));
6921 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6922 DONE;
6923 }
6924
6925 if (sh_compare_op0 != const0_rtx)
6926 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6927 if (sh_compare_op1 != const0_rtx)
6928 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6929 emit_jump_insn (gen_bge_media (operands[0],
6930 sh_compare_op1, sh_compare_op0));
6931 DONE;
6932 }
6933
6934 if (TARGET_SH2E
6935 && TARGET_IEEE
6936 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6937 {
6938 rtx tmp = sh_compare_op0;
6939 sh_compare_op0 = sh_compare_op1;
6940 sh_compare_op1 = tmp;
6941 emit_insn (gen_bge (operands[0]));
6942 DONE;
6943 }
6944 from_compare (operands, GT);
6945 }")
6946
6947 (define_expand "bge"
6948 [(set (pc)
6949 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6950 (label_ref (match_operand 0 "" ""))
6951 (pc)))]
6952 ""
6953 "
6954 {
6955 if (TARGET_SHMEDIA)
6956 {
6957 enum machine_mode mode = GET_MODE (sh_compare_op0);
6958
6959 if (mode != DImode && mode != SImode)
6960 {
6961 rtx tmp = gen_reg_rtx (DImode);
6962
6963 emit_insn (gen_sge (tmp));
6964 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6965 DONE;
6966 }
6967
6968 if (sh_compare_op0 != const0_rtx)
6969 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6970 if (sh_compare_op1 != const0_rtx)
6971 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6972 emit_jump_insn (gen_bge_media (operands[0],
6973 sh_compare_op0, sh_compare_op1));
6974 DONE;
6975 }
6976
6977 if (TARGET_SH2E
6978 && ! TARGET_IEEE
6979 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6980 {
6981 rtx tmp = sh_compare_op0;
6982 sh_compare_op0 = sh_compare_op1;
6983 sh_compare_op1 = tmp;
6984 emit_insn (gen_ble (operands[0]));
6985 DONE;
6986 }
6987 from_compare (operands, GE);
6988 }")
6989
6990 (define_expand "bgtu"
6991 [(set (pc)
6992 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6993 (label_ref (match_operand 0 "" ""))
6994 (pc)))]
6995 ""
6996 "
6997 {
6998 if (TARGET_SHMEDIA)
6999 {
7000 enum machine_mode mode = GET_MODE (sh_compare_op0);
7001
7002 if (sh_compare_op0 != const0_rtx)
7003 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7004 if (sh_compare_op1 != const0_rtx)
7005 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7006 emit_jump_insn (gen_bgtu_media (operands[0],
7007 sh_compare_op0, sh_compare_op1));
7008 DONE;
7009 }
7010
7011 from_compare (operands, GTU);
7012 }")
7013
7014 (define_expand "bltu"
7015 [(set (pc)
7016 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7017 (label_ref (match_operand 0 "" ""))
7018 (pc)))]
7019 ""
7020 "
7021 {
7022 if (TARGET_SHMEDIA)
7023 {
7024 enum machine_mode mode = GET_MODE (sh_compare_op0);
7025
7026 if (sh_compare_op0 != const0_rtx)
7027 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7028 if (sh_compare_op1 != const0_rtx)
7029 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030 emit_jump_insn (gen_bgtu_media (operands[0],
7031 sh_compare_op1, sh_compare_op0));
7032 DONE;
7033 }
7034
7035 from_compare (operands, GEU);
7036 }")
7037
7038 (define_expand "bgeu"
7039 [(set (pc)
7040 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7041 (label_ref (match_operand 0 "" ""))
7042 (pc)))]
7043 ""
7044 "
7045 {
7046 if (TARGET_SHMEDIA)
7047 {
7048 enum machine_mode mode = GET_MODE (sh_compare_op0);
7049
7050 if (sh_compare_op0 != const0_rtx)
7051 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7052 if (sh_compare_op1 != const0_rtx)
7053 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7054 emit_jump_insn (gen_bgeu_media (operands[0],
7055 sh_compare_op0, sh_compare_op1));
7056 DONE;
7057 }
7058
7059 from_compare (operands, GEU);
7060 }")
7061
7062 (define_expand "bleu"
7063 [(set (pc)
7064 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7065 (label_ref (match_operand 0 "" ""))
7066 (pc)))]
7067 ""
7068 "
7069 {
7070 if (TARGET_SHMEDIA)
7071 {
7072 enum machine_mode mode = GET_MODE (sh_compare_op0);
7073
7074 if (sh_compare_op0 != const0_rtx)
7075 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7076 if (sh_compare_op1 != const0_rtx)
7077 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7078 emit_jump_insn (gen_bgeu_media (operands[0],
7079 sh_compare_op1, sh_compare_op0));
7080 DONE;
7081 }
7082
7083 from_compare (operands, GTU);
7084 }")
7085
7086 (define_expand "bunordered"
7087 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7088 (set (pc)
7089 (if_then_else (ne (match_dup 1) (const_int 0))
7090 (match_operand 0 "" "")
7091 (pc)))]
7092 "TARGET_SHMEDIA"
7093 "
7094 {
7095 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7096 operands[1] = gen_reg_rtx (DImode);
7097 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7098 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7099 }")
7100
7101 ;; combiner splitter for test-and-branch on single bit in register. This
7102 ;; is endian dependent because the non-paradoxical subreg looks different
7103 ;; on big endian.
7104 (define_split
7105 [(set (pc)
7106 (if_then_else
7107 (match_operator 3 "equality_comparison_operator"
7108 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7109 "extend_reg_operand" "")
7110 0)
7111 (const_int 1)
7112 (match_operand 2
7113 "const_int_operand" "")) 0)
7114 (const_int 0)])
7115 (match_operand 0 "target_operand" "")
7116 (pc)))
7117 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7118 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7119 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7120 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7121
7122 "
7123 {
7124 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7125 operands[6] = (GET_CODE (operands[3]) == EQ
7126 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7127 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7128 }")
7129 \f
7130 ;; ------------------------------------------------------------------------
7131 ;; Jump and linkage insns
7132 ;; ------------------------------------------------------------------------
7133
7134 (define_insn "jump_compact"
7135 [(set (pc)
7136 (label_ref (match_operand 0 "" "")))]
7137 "TARGET_SH1"
7138 "*
7139 {
7140 /* The length is 16 if the delay slot is unfilled. */
7141 if (get_attr_length(insn) > 4)
7142 return output_far_jump(insn, operands[0]);
7143 else
7144 return \"bra %l0%#\";
7145 }"
7146 [(set_attr "type" "jump")
7147 (set_attr "needs_delay_slot" "yes")])
7148
7149 ;; ??? It would be much saner to explicitly use the scratch register
7150 ;; in the jump insn, and have indirect_jump_scratch only set it,
7151 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7152 ;; from the target then, as it uses simplejump_p.
7153 ;;(define_insn "jump_compact_far"
7154 ;; [(set (pc)
7155 ;; (label_ref (match_operand 0 "" "")))
7156 ;; (use (match_operand 1 "register_operand" "r")]
7157 ;; "TARGET_SH1"
7158 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7159 ;; [(set_attr "type" "jump")
7160 ;; (set_attr "needs_delay_slot" "yes")])
7161
7162 (define_insn "jump_media"
7163 [(set (pc)
7164 (match_operand 0 "target_operand" "b"))]
7165 "TARGET_SHMEDIA"
7166 "blink %0, r63%>"
7167 [(set_attr "type" "jump_media")])
7168
7169 (define_expand "jump"
7170 [(set (pc)
7171 (label_ref (match_operand 0 "" "")))]
7172 ""
7173 "
7174 {
7175 if (TARGET_SH1)
7176 emit_jump_insn (gen_jump_compact (operands[0]));
7177 else if (TARGET_SHMEDIA)
7178 {
7179 if (reload_in_progress || reload_completed)
7180 FAIL;
7181 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7182 operands[0])));
7183 }
7184 DONE;
7185 }")
7186
7187 (define_insn "force_mode_for_call"
7188 [(use (reg:PSI FPSCR_REG))]
7189 "TARGET_SHCOMPACT"
7190 ""
7191 [(set_attr "length" "0")
7192 (set (attr "fp_mode")
7193 (if_then_else (eq_attr "fpu_single" "yes")
7194 (const_string "single") (const_string "double")))])
7195
7196 (define_insn "calli"
7197 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7198 (match_operand 1 "" ""))
7199 (use (reg:PSI FPSCR_REG))
7200 (clobber (reg:SI PR_REG))]
7201 "TARGET_SH1"
7202 "jsr @%0%#"
7203 [(set_attr "type" "call")
7204 (set (attr "fp_mode")
7205 (if_then_else (eq_attr "fpu_single" "yes")
7206 (const_string "single") (const_string "double")))
7207 (set_attr "needs_delay_slot" "yes")
7208 (set_attr "fp_set" "unknown")])
7209
7210 ;; This is a pc-rel call, using bsrf, for use with PIC.
7211
7212 (define_insn "calli_pcrel"
7213 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7214 (match_operand 1 "" ""))
7215 (use (reg:PSI FPSCR_REG))
7216 (use (reg:SI PIC_REG))
7217 (use (match_operand 2 "" ""))
7218 (clobber (reg:SI PR_REG))]
7219 "TARGET_SH2"
7220 "bsrf %0\\n%O2:%#"
7221 [(set_attr "type" "call")
7222 (set (attr "fp_mode")
7223 (if_then_else (eq_attr "fpu_single" "yes")
7224 (const_string "single") (const_string "double")))
7225 (set_attr "needs_delay_slot" "yes")
7226 (set_attr "fp_set" "unknown")])
7227
7228 (define_insn_and_split "call_pcrel"
7229 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7230 (match_operand 1 "" ""))
7231 (use (reg:PSI FPSCR_REG))
7232 (use (reg:SI PIC_REG))
7233 (clobber (reg:SI PR_REG))
7234 (clobber (match_scratch:SI 2 "=r"))]
7235 "TARGET_SH2"
7236 "#"
7237 "reload_completed"
7238 [(const_int 0)]
7239 "
7240 {
7241 rtx lab = PATTERN (gen_call_site ());
7242
7243 if (SYMBOL_REF_LOCAL_P (operands[0]))
7244 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7245 else
7246 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7247 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7248 DONE;
7249 }"
7250 [(set_attr "type" "call")
7251 (set (attr "fp_mode")
7252 (if_then_else (eq_attr "fpu_single" "yes")
7253 (const_string "single") (const_string "double")))
7254 (set_attr "needs_delay_slot" "yes")
7255 (set_attr "fp_set" "unknown")])
7256
7257 (define_insn "call_compact"
7258 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7259 (match_operand 1 "" ""))
7260 (match_operand 2 "immediate_operand" "n")
7261 (use (reg:SI R0_REG))
7262 (use (reg:SI R1_REG))
7263 (use (reg:PSI FPSCR_REG))
7264 (clobber (reg:SI PR_REG))]
7265 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7266 "jsr @%0%#"
7267 [(set_attr "type" "call")
7268 (set (attr "fp_mode")
7269 (if_then_else (eq_attr "fpu_single" "yes")
7270 (const_string "single") (const_string "double")))
7271 (set_attr "needs_delay_slot" "yes")])
7272
7273 (define_insn "call_compact_rettramp"
7274 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7275 (match_operand 1 "" ""))
7276 (match_operand 2 "immediate_operand" "n")
7277 (use (reg:SI R0_REG))
7278 (use (reg:SI R1_REG))
7279 (use (reg:PSI FPSCR_REG))
7280 (clobber (reg:SI R10_REG))
7281 (clobber (reg:SI PR_REG))]
7282 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7283 "jsr @%0%#"
7284 [(set_attr "type" "call")
7285 (set (attr "fp_mode")
7286 (if_then_else (eq_attr "fpu_single" "yes")
7287 (const_string "single") (const_string "double")))
7288 (set_attr "needs_delay_slot" "yes")])
7289
7290 (define_insn "call_media"
7291 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7292 (match_operand 1 "" ""))
7293 (clobber (reg:DI PR_MEDIA_REG))]
7294 "TARGET_SHMEDIA"
7295 "blink %0, r18"
7296 [(set_attr "type" "jump_media")])
7297
7298 (define_insn "call_valuei"
7299 [(set (match_operand 0 "" "=rf")
7300 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7301 (match_operand 2 "" "")))
7302 (use (reg:PSI FPSCR_REG))
7303 (clobber (reg:SI PR_REG))]
7304 "TARGET_SH1"
7305 "jsr @%1%#"
7306 [(set_attr "type" "call")
7307 (set (attr "fp_mode")
7308 (if_then_else (eq_attr "fpu_single" "yes")
7309 (const_string "single") (const_string "double")))
7310 (set_attr "needs_delay_slot" "yes")
7311 (set_attr "fp_set" "unknown")])
7312
7313 (define_insn "call_valuei_pcrel"
7314 [(set (match_operand 0 "" "=rf")
7315 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7316 (match_operand 2 "" "")))
7317 (use (reg:PSI FPSCR_REG))
7318 (use (reg:SI PIC_REG))
7319 (use (match_operand 3 "" ""))
7320 (clobber (reg:SI PR_REG))]
7321 "TARGET_SH2"
7322 "bsrf %1\\n%O3:%#"
7323 [(set_attr "type" "call")
7324 (set (attr "fp_mode")
7325 (if_then_else (eq_attr "fpu_single" "yes")
7326 (const_string "single") (const_string "double")))
7327 (set_attr "needs_delay_slot" "yes")
7328 (set_attr "fp_set" "unknown")])
7329
7330 (define_insn_and_split "call_value_pcrel"
7331 [(set (match_operand 0 "" "=rf")
7332 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7333 (match_operand 2 "" "")))
7334 (use (reg:PSI FPSCR_REG))
7335 (use (reg:SI PIC_REG))
7336 (clobber (reg:SI PR_REG))
7337 (clobber (match_scratch:SI 3 "=r"))]
7338 "TARGET_SH2"
7339 "#"
7340 "reload_completed"
7341 [(const_int 0)]
7342 "
7343 {
7344 rtx lab = PATTERN (gen_call_site ());
7345
7346 if (SYMBOL_REF_LOCAL_P (operands[1]))
7347 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7348 else
7349 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7350 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7351 operands[2], lab));
7352 DONE;
7353 }"
7354 [(set_attr "type" "call")
7355 (set (attr "fp_mode")
7356 (if_then_else (eq_attr "fpu_single" "yes")
7357 (const_string "single") (const_string "double")))
7358 (set_attr "needs_delay_slot" "yes")
7359 (set_attr "fp_set" "unknown")])
7360
7361 (define_insn "call_value_compact"
7362 [(set (match_operand 0 "" "=rf")
7363 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7364 (match_operand 2 "" "")))
7365 (match_operand 3 "immediate_operand" "n")
7366 (use (reg:SI R0_REG))
7367 (use (reg:SI R1_REG))
7368 (use (reg:PSI FPSCR_REG))
7369 (clobber (reg:SI PR_REG))]
7370 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7371 "jsr @%1%#"
7372 [(set_attr "type" "call")
7373 (set (attr "fp_mode")
7374 (if_then_else (eq_attr "fpu_single" "yes")
7375 (const_string "single") (const_string "double")))
7376 (set_attr "needs_delay_slot" "yes")])
7377
7378 (define_insn "call_value_compact_rettramp"
7379 [(set (match_operand 0 "" "=rf")
7380 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7381 (match_operand 2 "" "")))
7382 (match_operand 3 "immediate_operand" "n")
7383 (use (reg:SI R0_REG))
7384 (use (reg:SI R1_REG))
7385 (use (reg:PSI FPSCR_REG))
7386 (clobber (reg:SI R10_REG))
7387 (clobber (reg:SI PR_REG))]
7388 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7389 "jsr @%1%#"
7390 [(set_attr "type" "call")
7391 (set (attr "fp_mode")
7392 (if_then_else (eq_attr "fpu_single" "yes")
7393 (const_string "single") (const_string "double")))
7394 (set_attr "needs_delay_slot" "yes")])
7395
7396 (define_insn "call_value_media"
7397 [(set (match_operand 0 "" "=rf")
7398 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7399 (match_operand 2 "" "")))
7400 (clobber (reg:DI PR_MEDIA_REG))]
7401 "TARGET_SHMEDIA"
7402 "blink %1, r18"
7403 [(set_attr "type" "jump_media")])
7404
7405 (define_expand "call"
7406 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7407 (match_operand 1 "" ""))
7408 (match_operand 2 "" "")
7409 (use (reg:PSI FPSCR_REG))
7410 (clobber (reg:SI PR_REG))])]
7411 ""
7412 "
7413 {
7414 if (TARGET_SHMEDIA)
7415 {
7416 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7417 emit_call_insn (gen_call_media (operands[0], operands[1]));
7418 DONE;
7419 }
7420 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7421 {
7422 rtx cookie_rtx = operands[2];
7423 long cookie = INTVAL (cookie_rtx);
7424 rtx func = XEXP (operands[0], 0);
7425 rtx r0, r1;
7426
7427 if (flag_pic)
7428 {
7429 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7430 {
7431 rtx reg = gen_reg_rtx (Pmode);
7432
7433 emit_insn (gen_symGOTPLT2reg (reg, func));
7434 func = reg;
7435 }
7436 else
7437 func = legitimize_pic_address (func, Pmode, 0);
7438 }
7439
7440 r0 = gen_rtx_REG (SImode, R0_REG);
7441 r1 = gen_rtx_REG (SImode, R1_REG);
7442
7443 /* Since such a call function may use all call-clobbered
7444 registers, we force a mode switch earlier, so that we don't
7445 run out of registers when adjusting fpscr for the call. */
7446 emit_insn (gen_force_mode_for_call ());
7447
7448 operands[0]
7449 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7450 SFUNC_GOT);
7451 operands[0] = force_reg (SImode, operands[0]);
7452
7453 emit_move_insn (r0, func);
7454 emit_move_insn (r1, cookie_rtx);
7455
7456 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7457 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7458 operands[2]));
7459 else
7460 emit_call_insn (gen_call_compact (operands[0], operands[1],
7461 operands[2]));
7462
7463 DONE;
7464 }
7465 else if (TARGET_SHCOMPACT && flag_pic
7466 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7467 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7468 {
7469 rtx reg = gen_reg_rtx (Pmode);
7470
7471 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7472 XEXP (operands[0], 0) = reg;
7473 }
7474 if (flag_pic && TARGET_SH2
7475 && GET_CODE (operands[0]) == MEM
7476 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7477 {
7478 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7479 DONE;
7480 }
7481 else
7482 {
7483 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7484 operands[1] = operands[2];
7485 }
7486
7487 emit_call_insn (gen_calli (operands[0], operands[1]));
7488 DONE;
7489 }")
7490
7491 (define_insn "call_pop_compact"
7492 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7493 (match_operand 1 "" ""))
7494 (match_operand 2 "immediate_operand" "n")
7495 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7496 (match_operand 3 "immediate_operand" "n")))
7497 (use (reg:SI R0_REG))
7498 (use (reg:SI R1_REG))
7499 (use (reg:PSI FPSCR_REG))
7500 (clobber (reg:SI PR_REG))]
7501 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7502 "jsr @%0%#"
7503 [(set_attr "type" "call")
7504 (set (attr "fp_mode")
7505 (if_then_else (eq_attr "fpu_single" "yes")
7506 (const_string "single") (const_string "double")))
7507 (set_attr "needs_delay_slot" "yes")])
7508
7509 (define_insn "call_pop_compact_rettramp"
7510 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7511 (match_operand 1 "" ""))
7512 (match_operand 2 "immediate_operand" "n")
7513 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514 (match_operand 3 "immediate_operand" "n")))
7515 (use (reg:SI R0_REG))
7516 (use (reg:SI R1_REG))
7517 (use (reg:PSI FPSCR_REG))
7518 (clobber (reg:SI R10_REG))
7519 (clobber (reg:SI PR_REG))]
7520 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521 "jsr @%0%#"
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")])
7527
7528 (define_expand "call_pop"
7529 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7530 (match_operand 1 "" ""))
7531 (match_operand 2 "" "")
7532 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533 (match_operand 3 "" "")))])]
7534 "TARGET_SHCOMPACT"
7535 "
7536 {
7537 rtx cookie_rtx;
7538 long cookie;
7539 rtx func;
7540 rtx r0, r1;
7541
7542 gcc_assert (operands[2] && INTVAL (operands[2]));
7543 cookie_rtx = operands[2];
7544 cookie = INTVAL (cookie_rtx);
7545 func = XEXP (operands[0], 0);
7546
7547 if (flag_pic)
7548 {
7549 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7550 {
7551 rtx reg = gen_reg_rtx (Pmode);
7552 emit_insn (gen_symGOTPLT2reg (reg, func));
7553 func = reg;
7554 }
7555 else
7556 func = legitimize_pic_address (func, Pmode, 0);
7557 }
7558
7559 r0 = gen_rtx_REG (SImode, R0_REG);
7560 r1 = gen_rtx_REG (SImode, R1_REG);
7561
7562 /* Since such a call function may use all call-clobbered
7563 registers, we force a mode switch earlier, so that we don't
7564 run out of registers when adjusting fpscr for the call. */
7565 emit_insn (gen_force_mode_for_call ());
7566
7567 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7568 SFUNC_GOT);
7569 operands[0] = force_reg (SImode, operands[0]);
7570
7571 emit_move_insn (r0, func);
7572 emit_move_insn (r1, cookie_rtx);
7573
7574 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7575 emit_call_insn (gen_call_pop_compact_rettramp
7576 (operands[0], operands[1], operands[2], operands[3]));
7577 else
7578 emit_call_insn (gen_call_pop_compact
7579 (operands[0], operands[1], operands[2], operands[3]));
7580
7581 DONE;
7582 }")
7583
7584 (define_expand "call_value"
7585 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7586 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7587 (match_operand 2 "" "")))
7588 (match_operand 3 "" "")
7589 (use (reg:PSI FPSCR_REG))
7590 (clobber (reg:SI PR_REG))])]
7591 ""
7592 "
7593 {
7594 if (TARGET_SHMEDIA)
7595 {
7596 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7597 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7598 operands[2]));
7599 DONE;
7600 }
7601 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7602 {
7603 rtx cookie_rtx = operands[3];
7604 long cookie = INTVAL (cookie_rtx);
7605 rtx func = XEXP (operands[1], 0);
7606 rtx r0, r1;
7607
7608 if (flag_pic)
7609 {
7610 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7611 {
7612 rtx reg = gen_reg_rtx (Pmode);
7613
7614 emit_insn (gen_symGOTPLT2reg (reg, func));
7615 func = reg;
7616 }
7617 else
7618 func = legitimize_pic_address (func, Pmode, 0);
7619 }
7620
7621 r0 = gen_rtx_REG (SImode, R0_REG);
7622 r1 = gen_rtx_REG (SImode, R1_REG);
7623
7624 /* Since such a call function may use all call-clobbered
7625 registers, we force a mode switch earlier, so that we don't
7626 run out of registers when adjusting fpscr for the call. */
7627 emit_insn (gen_force_mode_for_call ());
7628
7629 operands[1]
7630 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7631 SFUNC_GOT);
7632 operands[1] = force_reg (SImode, operands[1]);
7633
7634 emit_move_insn (r0, func);
7635 emit_move_insn (r1, cookie_rtx);
7636
7637 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7638 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7639 operands[1],
7640 operands[2],
7641 operands[3]));
7642 else
7643 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7644 operands[2], operands[3]));
7645
7646 DONE;
7647 }
7648 else if (TARGET_SHCOMPACT && flag_pic
7649 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7650 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7651 {
7652 rtx reg = gen_reg_rtx (Pmode);
7653
7654 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7655 XEXP (operands[1], 0) = reg;
7656 }
7657 if (flag_pic && TARGET_SH2
7658 && GET_CODE (operands[1]) == MEM
7659 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7660 {
7661 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7662 operands[2]));
7663 DONE;
7664 }
7665 else
7666 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7667
7668 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7669 DONE;
7670 }")
7671
7672 (define_insn "sibcalli"
7673 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7674 (match_operand 1 "" ""))
7675 (use (reg:PSI FPSCR_REG))
7676 (return)]
7677 "TARGET_SH1"
7678 "jmp @%0%#"
7679 [(set_attr "needs_delay_slot" "yes")
7680 (set (attr "fp_mode")
7681 (if_then_else (eq_attr "fpu_single" "yes")
7682 (const_string "single") (const_string "double")))
7683 (set_attr "type" "jump_ind")])
7684
7685 (define_insn "sibcalli_pcrel"
7686 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7687 (match_operand 1 "" ""))
7688 (use (match_operand 2 "" ""))
7689 (use (reg:PSI FPSCR_REG))
7690 (return)]
7691 "TARGET_SH2"
7692 "braf %0\\n%O2:%#"
7693 [(set_attr "needs_delay_slot" "yes")
7694 (set (attr "fp_mode")
7695 (if_then_else (eq_attr "fpu_single" "yes")
7696 (const_string "single") (const_string "double")))
7697 (set_attr "type" "jump_ind")])
7698
7699 ;; This uses an unspec to describe that the symbol_ref is very close.
7700 (define_insn "sibcalli_thunk"
7701 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7702 UNSPEC_THUNK))
7703 (match_operand 1 "" ""))
7704 (use (reg:PSI FPSCR_REG))
7705 (return)]
7706 "TARGET_SH1"
7707 "bra %O0"
7708 [(set_attr "needs_delay_slot" "yes")
7709 (set (attr "fp_mode")
7710 (if_then_else (eq_attr "fpu_single" "yes")
7711 (const_string "single") (const_string "double")))
7712 (set_attr "type" "jump")
7713 (set_attr "length" "2")])
7714
7715 (define_insn_and_split "sibcall_pcrel"
7716 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7717 (match_operand 1 "" ""))
7718 (use (reg:PSI FPSCR_REG))
7719 (clobber (match_scratch:SI 2 "=k"))
7720 (return)]
7721 "TARGET_SH2"
7722 "#"
7723 "reload_completed"
7724 [(const_int 0)]
7725 "
7726 {
7727 rtx lab = PATTERN (gen_call_site ());
7728 rtx call_insn;
7729
7730 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7731 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7732 lab));
7733 SIBLING_CALL_P (call_insn) = 1;
7734 DONE;
7735 }"
7736 [(set_attr "needs_delay_slot" "yes")
7737 (set (attr "fp_mode")
7738 (if_then_else (eq_attr "fpu_single" "yes")
7739 (const_string "single") (const_string "double")))
7740 (set_attr "type" "jump_ind")])
7741
7742 (define_insn "sibcall_compact"
7743 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7744 (match_operand 1 "" ""))
7745 (return)
7746 (use (match_operand:SI 2 "register_operand" "z,x"))
7747 (use (reg:SI R1_REG))
7748 (use (reg:PSI FPSCR_REG))
7749 ;; We want to make sure the `x' above will only match MACH_REG
7750 ;; because sibcall_epilogue may clobber MACL_REG.
7751 (clobber (reg:SI MACL_REG))]
7752 "TARGET_SHCOMPACT"
7753 "@
7754 jmp @%0%#
7755 jmp @%0\\n sts %2, r0"
7756 [(set_attr "needs_delay_slot" "yes,no")
7757 (set_attr "length" "2,4")
7758 (set (attr "fp_mode") (const_string "single"))
7759 (set_attr "type" "jump_ind")])
7760
7761 (define_insn "sibcall_media"
7762 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7763 (match_operand 1 "" ""))
7764 (use (reg:SI PR_MEDIA_REG))
7765 (return)]
7766 "TARGET_SHMEDIA"
7767 "blink %0, r63"
7768 [(set_attr "type" "jump_media")])
7769
7770 (define_expand "sibcall"
7771 [(parallel
7772 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7773 (match_operand 1 "" ""))
7774 (match_operand 2 "" "")
7775 (use (reg:PSI FPSCR_REG))
7776 (return)])]
7777 ""
7778 "
7779 {
7780 if (TARGET_SHMEDIA)
7781 {
7782 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7783 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7784 DONE;
7785 }
7786 else if (TARGET_SHCOMPACT && operands[2]
7787 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7788 {
7789 rtx cookie_rtx = operands[2];
7790 long cookie = INTVAL (cookie_rtx);
7791 rtx func = XEXP (operands[0], 0);
7792 rtx mach, r1;
7793
7794 if (flag_pic)
7795 {
7796 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7797 {
7798 rtx reg = gen_reg_rtx (Pmode);
7799
7800 emit_insn (gen_symGOT2reg (reg, func));
7801 func = reg;
7802 }
7803 else
7804 func = legitimize_pic_address (func, Pmode, 0);
7805 }
7806
7807 /* FIXME: if we could tell whether all argument registers are
7808 already taken, we could decide whether to force the use of
7809 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7810 simple way to tell. We could use the CALL_COOKIE, but we
7811 can't currently tell a register used for regular argument
7812 passing from one that is unused. If we leave it up to reload
7813 to decide which register to use, it seems to always choose
7814 R0_REG, which leaves no available registers in SIBCALL_REGS
7815 to hold the address of the trampoline. */
7816 mach = gen_rtx_REG (SImode, MACH_REG);
7817 r1 = gen_rtx_REG (SImode, R1_REG);
7818
7819 /* Since such a call function may use all call-clobbered
7820 registers, we force a mode switch earlier, so that we don't
7821 run out of registers when adjusting fpscr for the call. */
7822 emit_insn (gen_force_mode_for_call ());
7823
7824 operands[0]
7825 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7826 SFUNC_GOT);
7827 operands[0] = force_reg (SImode, operands[0]);
7828
7829 /* We don't need a return trampoline, since the callee will
7830 return directly to the upper caller. */
7831 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7832 {
7833 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7834 cookie_rtx = GEN_INT (cookie);
7835 }
7836
7837 emit_move_insn (mach, func);
7838 emit_move_insn (r1, cookie_rtx);
7839
7840 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7841 DONE;
7842 }
7843 else if (TARGET_SHCOMPACT && flag_pic
7844 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7845 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7846 {
7847 rtx reg = gen_reg_rtx (Pmode);
7848
7849 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7850 XEXP (operands[0], 0) = reg;
7851 }
7852 if (flag_pic && TARGET_SH2
7853 && GET_CODE (operands[0]) == MEM
7854 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7855 /* The PLT needs the PIC register, but the epilogue would have
7856 to restore it, so we can only use PC-relative PIC calls for
7857 static functions. */
7858 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7859 {
7860 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7861 DONE;
7862 }
7863 else
7864 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7865
7866 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7867 DONE;
7868 }")
7869
7870 (define_expand "sibcall_value"
7871 [(set (match_operand 0 "" "")
7872 (call (match_operand 1 "" "")
7873 (match_operand 2 "" "")))
7874 (match_operand 3 "" "")]
7875 ""
7876 "
7877 {
7878 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7879 DONE;
7880 }")
7881
7882 (define_insn "call_value_pop_compact"
7883 [(set (match_operand 0 "" "=rf")
7884 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7885 (match_operand 2 "" "")))
7886 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7887 (match_operand 4 "immediate_operand" "n")))
7888 (match_operand 3 "immediate_operand" "n")
7889 (use (reg:SI R0_REG))
7890 (use (reg:SI R1_REG))
7891 (use (reg:PSI FPSCR_REG))
7892 (clobber (reg:SI PR_REG))]
7893 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7894 "jsr @%1%#"
7895 [(set_attr "type" "call")
7896 (set (attr "fp_mode")
7897 (if_then_else (eq_attr "fpu_single" "yes")
7898 (const_string "single") (const_string "double")))
7899 (set_attr "needs_delay_slot" "yes")])
7900
7901 (define_insn "call_value_pop_compact_rettramp"
7902 [(set (match_operand 0 "" "=rf")
7903 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7904 (match_operand 2 "" "")))
7905 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7906 (match_operand 4 "immediate_operand" "n")))
7907 (match_operand 3 "immediate_operand" "n")
7908 (use (reg:SI R0_REG))
7909 (use (reg:SI R1_REG))
7910 (use (reg:PSI FPSCR_REG))
7911 (clobber (reg:SI R10_REG))
7912 (clobber (reg:SI PR_REG))]
7913 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7914 "jsr @%1%#"
7915 [(set_attr "type" "call")
7916 (set (attr "fp_mode")
7917 (if_then_else (eq_attr "fpu_single" "yes")
7918 (const_string "single") (const_string "double")))
7919 (set_attr "needs_delay_slot" "yes")])
7920
7921 (define_expand "call_value_pop"
7922 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7923 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7924 (match_operand 2 "" "")))
7925 (match_operand 3 "" "")
7926 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7927 (match_operand 4 "" "")))])]
7928 "TARGET_SHCOMPACT"
7929 "
7930 {
7931 rtx cookie_rtx;
7932 long cookie;
7933 rtx func;
7934 rtx r0, r1;
7935
7936 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7937 cookie_rtx = operands[3];
7938 cookie = INTVAL (cookie_rtx);
7939 func = XEXP (operands[1], 0);
7940
7941 if (flag_pic)
7942 {
7943 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7944 {
7945 rtx reg = gen_reg_rtx (Pmode);
7946
7947 emit_insn (gen_symGOTPLT2reg (reg, func));
7948 func = reg;
7949 }
7950 else
7951 func = legitimize_pic_address (func, Pmode, 0);
7952 }
7953
7954 r0 = gen_rtx_REG (SImode, R0_REG);
7955 r1 = gen_rtx_REG (SImode, R1_REG);
7956
7957 /* Since such a call function may use all call-clobbered
7958 registers, we force a mode switch earlier, so that we don't
7959 run out of registers when adjusting fpscr for the call. */
7960 emit_insn (gen_force_mode_for_call ());
7961
7962 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7963 SFUNC_GOT);
7964 operands[1] = force_reg (SImode, operands[1]);
7965
7966 emit_move_insn (r0, func);
7967 emit_move_insn (r1, cookie_rtx);
7968
7969 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7970 emit_call_insn (gen_call_value_pop_compact_rettramp
7971 (operands[0], operands[1], operands[2],
7972 operands[3], operands[4]));
7973 else
7974 emit_call_insn (gen_call_value_pop_compact
7975 (operands[0], operands[1], operands[2],
7976 operands[3], operands[4]));
7977
7978 DONE;
7979 }")
7980
7981 (define_expand "sibcall_epilogue"
7982 [(return)]
7983 ""
7984 "
7985 {
7986 sh_expand_epilogue (1);
7987 if (TARGET_SHCOMPACT)
7988 {
7989 rtx insn, set;
7990
7991 /* If epilogue clobbers r0, preserve it in macl. */
7992 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7993 if ((set = single_set (insn))
7994 && GET_CODE (SET_DEST (set)) == REG
7995 && REGNO (SET_DEST (set)) == R0_REG)
7996 {
7997 rtx r0 = gen_rtx_REG (SImode, R0_REG);
7998 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
7999 rtx i;
8000
8001 /* We can't tell at this point whether the sibcall is a
8002 sibcall_compact and, if it is, whether it uses r0 or
8003 mach as operand 2, so let the instructions that
8004 preserve r0 be optimized away if r0 turns out to be
8005 dead. */
8006 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8007 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8008 REG_NOTES (i));
8009 i = emit_move_insn (r0, tmp);
8010 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8011 REG_NOTES (i));
8012 break;
8013 }
8014 }
8015 DONE;
8016 }")
8017
8018 (define_insn "indirect_jump_compact"
8019 [(set (pc)
8020 (match_operand:SI 0 "arith_reg_operand" "r"))]
8021 "TARGET_SH1"
8022 "jmp @%0%#"
8023 [(set_attr "needs_delay_slot" "yes")
8024 (set_attr "type" "jump_ind")])
8025
8026 (define_expand "indirect_jump"
8027 [(set (pc)
8028 (match_operand 0 "register_operand" ""))]
8029 ""
8030 "
8031 {
8032 if (GET_MODE (operands[0]) != Pmode)
8033 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8034 }")
8035
8036 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8037 ;; which can be present in structured code from indirect jumps which can not
8038 ;; be present in structured code. This allows -fprofile-arcs to work.
8039
8040 ;; For SH1 processors.
8041 (define_insn "casesi_jump_1"
8042 [(set (pc)
8043 (match_operand:SI 0 "register_operand" "r"))
8044 (use (label_ref (match_operand 1 "" "")))]
8045 "TARGET_SH1"
8046 "jmp @%0%#"
8047 [(set_attr "needs_delay_slot" "yes")
8048 (set_attr "type" "jump_ind")])
8049
8050 ;; For all later processors.
8051 (define_insn "casesi_jump_2"
8052 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8053 (label_ref (match_operand 1 "" ""))))
8054 (use (label_ref (match_operand 2 "" "")))]
8055 "TARGET_SH2
8056 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8057 "braf %0%#"
8058 [(set_attr "needs_delay_slot" "yes")
8059 (set_attr "type" "jump_ind")])
8060
8061 (define_insn "casesi_jump_media"
8062 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8063 (use (label_ref (match_operand 1 "" "")))]
8064 "TARGET_SHMEDIA"
8065 "blink %0, r63"
8066 [(set_attr "type" "jump_media")])
8067
8068 ;; Call subroutine returning any type.
8069 ;; ??? This probably doesn't work.
8070
8071 (define_expand "untyped_call"
8072 [(parallel [(call (match_operand 0 "" "")
8073 (const_int 0))
8074 (match_operand 1 "" "")
8075 (match_operand 2 "" "")])]
8076 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8077 "
8078 {
8079 int i;
8080
8081 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8082
8083 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8084 {
8085 rtx set = XVECEXP (operands[2], 0, i);
8086 emit_move_insn (SET_DEST (set), SET_SRC (set));
8087 }
8088
8089 /* The optimizer does not know that the call sets the function value
8090 registers we stored in the result block. We avoid problems by
8091 claiming that all hard registers are used and clobbered at this
8092 point. */
8093 emit_insn (gen_blockage ());
8094
8095 DONE;
8096 }")
8097 \f
8098 ;; ------------------------------------------------------------------------
8099 ;; Misc insns
8100 ;; ------------------------------------------------------------------------
8101
8102 (define_insn "dect"
8103 [(set (reg:SI T_REG)
8104 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8105 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8106 "TARGET_SH2"
8107 "dt %0"
8108 [(set_attr "type" "arith")])
8109
8110 (define_insn "nop"
8111 [(const_int 0)]
8112 ""
8113 "nop")
8114
8115 ;; Load address of a label. This is only generated by the casesi expand,
8116 ;; and by machine_dependent_reorg (fixing up fp moves).
8117 ;; This must use unspec, because this only works for labels that are
8118 ;; within range,
8119
8120 (define_insn "mova"
8121 [(set (reg:SI R0_REG)
8122 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8123 "TARGET_SH1"
8124 "mova %O0,r0"
8125 [(set_attr "in_delay_slot" "no")
8126 (set_attr "type" "arith")])
8127
8128 ;; machine_dependent_reorg will make this a `mova'.
8129 (define_insn "mova_const"
8130 [(set (reg:SI R0_REG)
8131 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8132 "TARGET_SH1"
8133 "#"
8134 [(set_attr "in_delay_slot" "no")
8135 (set_attr "type" "arith")])
8136
8137 (define_expand "GOTaddr2picreg"
8138 [(set (reg:SI R0_REG)
8139 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8140 UNSPEC_MOVA))
8141 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8142 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8143 "" "
8144 {
8145 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8146 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8147
8148 if (TARGET_SHMEDIA)
8149 {
8150 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8151 rtx pic = operands[0];
8152 rtx lab = PATTERN (gen_call_site ());
8153 rtx insn, equiv;
8154
8155 equiv = operands[1];
8156 operands[1] = gen_rtx_MINUS (Pmode,
8157 operands[1],
8158 gen_rtx_CONST
8159 (Pmode,
8160 gen_rtx_MINUS (Pmode,
8161 gen_rtx_CONST (Pmode,
8162 lab),
8163 pc_rtx)));
8164 operands[1] = gen_sym2PIC (operands[1]);
8165 PUT_MODE (operands[1], Pmode);
8166
8167 if (Pmode == SImode)
8168 {
8169 emit_insn (gen_movsi_const (pic, operands[1]));
8170 emit_insn (gen_ptrel_si (tr, pic, lab));
8171 }
8172 else
8173 {
8174 emit_insn (gen_movdi_const (pic, operands[1]));
8175 emit_insn (gen_ptrel_di (tr, pic, lab));
8176 }
8177
8178 insn = emit_move_insn (operands[0], tr);
8179
8180 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8181 REG_NOTES (insn));
8182
8183 DONE;
8184 }
8185 }
8186 ")
8187
8188 (define_insn "*ptb"
8189 [(set (match_operand 0 "target_reg_operand" "=b")
8190 (const (unspec [(match_operand 1 "" "Csy")]
8191 UNSPEC_DATALABEL)))]
8192 "TARGET_SHMEDIA && flag_pic
8193 && EXTRA_CONSTRAINT_Csy (operands[1])"
8194 "ptb/u datalabel %1, %0"
8195 [(set_attr "type" "ptabs_media")
8196 (set_attr "length" "*")])
8197
8198 (define_insn "ptrel_si"
8199 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8200 (plus:SI (match_operand:SI 1 "register_operand" "r")
8201 (pc)))
8202 (match_operand:SI 2 "" "")]
8203 "TARGET_SHMEDIA"
8204 "%O2: ptrel/u %1, %0"
8205 [(set_attr "type" "ptabs_media")])
8206
8207 (define_insn "ptrel_di"
8208 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8209 (plus:DI (match_operand:DI 1 "register_operand" "r")
8210 (pc)))
8211 (match_operand:DI 2 "" "")]
8212 "TARGET_SHMEDIA"
8213 "%O2: ptrel/u %1, %0"
8214 [(set_attr "type" "ptabs_media")])
8215
8216 (define_expand "builtin_setjmp_receiver"
8217 [(match_operand 0 "" "")]
8218 "flag_pic"
8219 "
8220 {
8221 emit_insn (gen_GOTaddr2picreg ());
8222 DONE;
8223 }")
8224
8225 (define_expand "call_site"
8226 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8227 "TARGET_SH1"
8228 "
8229 {
8230 static HOST_WIDE_INT i = 0;
8231 operands[0] = GEN_INT (i);
8232 i++;
8233 }")
8234
8235 (define_expand "sym_label2reg"
8236 [(set (match_operand:SI 0 "" "")
8237 (const:SI (minus:SI
8238 (const:SI
8239 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8240 (const:SI
8241 (plus:SI
8242 (match_operand:SI 2 "" "")
8243 (const_int 2))))))]
8244 "TARGET_SH1" "")
8245
8246 (define_expand "symGOT_load"
8247 [(set (match_dup 2) (match_operand 1 "" ""))
8248 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8249 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8250 ""
8251 "
8252 {
8253 rtx insn, mem;
8254
8255 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8256 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8257
8258 if (TARGET_SHMEDIA)
8259 {
8260 rtx reg = operands[2];
8261
8262 if (Pmode == DImode)
8263 {
8264 if (flag_pic > 1)
8265 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8266 else
8267 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8268 }
8269 else
8270 {
8271 if (flag_pic > 1)
8272 emit_insn (gen_movsi_const (reg, operands[1]));
8273 else
8274 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8275 }
8276 }
8277 else
8278 emit_move_insn (operands[2], operands[1]);
8279
8280 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8281 operands[2],
8282 gen_rtx_REG (Pmode, PIC_REG)));
8283
8284 /* N.B. This is not constant for a GOTPLT relocation. */
8285 mem = gen_rtx_MEM (Pmode, operands[3]);
8286 MEM_NOTRAP_P (mem) = 1;
8287 /* ??? Should we have a special alias set for the GOT? */
8288 insn = emit_move_insn (operands[0], mem);
8289
8290 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8291 0), 0, 0),
8292 REG_NOTES (insn));
8293
8294 DONE;
8295 }")
8296
8297 (define_expand "sym2GOT"
8298 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8299 ""
8300 "")
8301
8302 (define_expand "symGOT2reg"
8303 [(match_operand 0 "" "") (match_operand 1 "" "")]
8304 ""
8305 "
8306 {
8307 rtx gotsym, insn;
8308
8309 gotsym = gen_sym2GOT (operands[1]);
8310 PUT_MODE (gotsym, Pmode);
8311 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8312
8313 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8314
8315 DONE;
8316 }")
8317
8318 (define_expand "sym2GOTPLT"
8319 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8320 ""
8321 "")
8322
8323 (define_expand "symGOTPLT2reg"
8324 [(match_operand 0 "" "") (match_operand 1 "" "")]
8325 ""
8326 "
8327 {
8328 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8329 DONE;
8330 }")
8331
8332 (define_expand "sym2GOTOFF"
8333 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8334 ""
8335 "")
8336
8337 (define_expand "symGOTOFF2reg"
8338 [(match_operand 0 "" "") (match_operand 1 "" "")]
8339 ""
8340 "
8341 {
8342 rtx gotoffsym, insn;
8343 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8344
8345 gotoffsym = gen_sym2GOTOFF (operands[1]);
8346 PUT_MODE (gotoffsym, Pmode);
8347 emit_move_insn (t, gotoffsym);
8348 insn = emit_move_insn (operands[0],
8349 gen_rtx_PLUS (Pmode, t,
8350 gen_rtx_REG (Pmode, PIC_REG)));
8351
8352 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8353 REG_NOTES (insn));
8354
8355 DONE;
8356 }")
8357
8358 (define_expand "symPLT_label2reg"
8359 [(set (match_operand:SI 0 "" "")
8360 (const:SI (minus:SI
8361 (const:SI
8362 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8363 (const:SI
8364 (minus:SI
8365 (const:SI (plus:SI
8366 (match_operand:SI 2 "" "")
8367 (const_int 2)))
8368 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8369 ;; Even though the PIC register is not really used by the call
8370 ;; sequence in which this is expanded, the PLT code assumes the PIC
8371 ;; register is set, so we must not skip its initialization. Since
8372 ;; we only use this expand as part of calling sequences, and never
8373 ;; to take the address of a function, this is the best point to
8374 ;; insert the (use). Using the PLT to take the address of a
8375 ;; function would be wrong, not only because the PLT entry could
8376 ;; then be called from a function that doesn't initialize the PIC
8377 ;; register to the proper GOT, but also because pointers to the
8378 ;; same function might not compare equal, should they be set by
8379 ;; different shared libraries.
8380 (use (reg:SI PIC_REG))]
8381 "TARGET_SH1"
8382 "")
8383
8384 (define_expand "sym2PIC"
8385 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8386 ""
8387 "")
8388
8389 ;; TLS code generation.
8390 ;; ??? this should be a define_insn_and_split
8391 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8392 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8393 ;; for details.
8394
8395 (define_insn "tls_global_dynamic"
8396 [(set (match_operand:SI 0 "register_operand" "=&z")
8397 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8398 UNSPEC_TLSGD))
8399 (const_int 0)))
8400 (use (reg:PSI FPSCR_REG))
8401 (use (reg:SI PIC_REG))
8402 (clobber (reg:SI PR_REG))
8403 (clobber (scratch:SI))]
8404 "TARGET_SH1"
8405 "*
8406 {
8407 return \"\\
8408 mov.l\\t1f,r4\\n\\
8409 \\tmova\\t2f,r0\\n\\
8410 \\tmov.l\\t2f,r1\\n\\
8411 \\tadd\\tr0,r1\\n\\
8412 \\tjsr\\t@r1\\n\\
8413 \\tadd\\tr12,r4\\n\\
8414 \\tbra\\t3f\\n\\
8415 \\tnop\\n\\
8416 \\t.align\\t2\\n\\
8417 1:\\t.long\\t%a1@TLSGD\\n\\
8418 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8419 3:\";
8420 }"
8421 [(set_attr "type" "tls_load")
8422 (set_attr "length" "26")])
8423
8424 (define_insn "tls_local_dynamic"
8425 [(set (match_operand:SI 0 "register_operand" "=&z")
8426 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8427 UNSPEC_TLSLDM))
8428 (const_int 0)))
8429 (use (reg:PSI FPSCR_REG))
8430 (use (reg:SI PIC_REG))
8431 (clobber (reg:SI PR_REG))
8432 (clobber (scratch:SI))]
8433 "TARGET_SH1"
8434 "*
8435 {
8436 return \"\\
8437 mov.l\\t1f,r4\\n\\
8438 \\tmova\\t2f,r0\\n\\
8439 \\tmov.l\\t2f,r1\\n\\
8440 \\tadd\\tr0,r1\\n\\
8441 \\tjsr\\t@r1\\n\\
8442 \\tadd\\tr12,r4\\n\\
8443 \\tbra\\t3f\\n\\
8444 \\tnop\\n\\
8445 \\t.align\\t2\\n\\
8446 1:\\t.long\\t%a1@TLSLDM\\n\\
8447 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8448 3:\";
8449 }"
8450 [(set_attr "type" "tls_load")
8451 (set_attr "length" "26")])
8452
8453 (define_expand "sym2DTPOFF"
8454 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8455 ""
8456 "")
8457
8458 (define_expand "symDTPOFF2reg"
8459 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8460 ""
8461 "
8462 {
8463 rtx dtpoffsym, insn;
8464 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8465
8466 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8467 PUT_MODE (dtpoffsym, Pmode);
8468 emit_move_insn (t, dtpoffsym);
8469 insn = emit_move_insn (operands[0],
8470 gen_rtx_PLUS (Pmode, t, operands[2]));
8471 DONE;
8472 }")
8473
8474 (define_expand "sym2GOTTPOFF"
8475 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8476 ""
8477 "")
8478
8479 (define_insn "tls_initial_exec"
8480 [(set (match_operand:SI 0 "register_operand" "=&r")
8481 (unspec:SI [(match_operand:SI 1 "" "")]
8482 UNSPEC_TLSIE))
8483 (use (reg:SI GBR_REG))
8484 (use (reg:SI PIC_REG))
8485 (clobber (reg:SI R0_REG))]
8486 ""
8487 "*
8488 {
8489 return \"\\
8490 mov.l\\t1f,r0\\n\\
8491 \\tstc\\tgbr,%0\\n\\
8492 \\tmov.l\\t@(r0,r12),r0\\n\\
8493 \\tbra\\t2f\\n\\
8494 \\tadd\\tr0,%0\\n\\
8495 \\t.align\\t2\\n\\
8496 1:\\t.long\\t%a1\\n\\
8497 2:\";
8498 }"
8499 [(set_attr "type" "tls_load")
8500 (set_attr "length" "16")])
8501
8502 (define_expand "sym2TPOFF"
8503 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8504 ""
8505 "")
8506
8507 (define_expand "symTPOFF2reg"
8508 [(match_operand 0 "" "") (match_operand 1 "" "")]
8509 ""
8510 "
8511 {
8512 rtx tpoffsym, insn;
8513
8514 tpoffsym = gen_sym2TPOFF (operands[1]);
8515 PUT_MODE (tpoffsym, Pmode);
8516 insn = emit_move_insn (operands[0], tpoffsym);
8517 DONE;
8518 }")
8519
8520 (define_insn "load_gbr"
8521 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8522 (use (reg:SI GBR_REG))]
8523 ""
8524 "stc gbr,%0"
8525 [(set_attr "type" "tls_load")])
8526
8527 ;; case instruction for switch statements.
8528
8529 ;; Operand 0 is index
8530 ;; operand 1 is the minimum bound
8531 ;; operand 2 is the maximum bound - minimum bound + 1
8532 ;; operand 3 is CODE_LABEL for the table;
8533 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8534
8535 (define_expand "casesi"
8536 [(match_operand:SI 0 "arith_reg_operand" "")
8537 (match_operand:SI 1 "arith_reg_operand" "")
8538 (match_operand:SI 2 "arith_reg_operand" "")
8539 (match_operand 3 "" "") (match_operand 4 "" "")]
8540 ""
8541 "
8542 {
8543 rtx reg = gen_reg_rtx (SImode);
8544 rtx reg2 = gen_reg_rtx (SImode);
8545 if (TARGET_SHMEDIA)
8546 {
8547 rtx reg = gen_reg_rtx (DImode);
8548 rtx reg2 = gen_reg_rtx (DImode);
8549 rtx reg3 = gen_reg_rtx (Pmode);
8550 rtx reg4 = gen_reg_rtx (Pmode);
8551 rtx reg5 = gen_reg_rtx (Pmode);
8552 rtx load;
8553
8554 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8555 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8556 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8557
8558 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8559 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8560 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8561 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8562 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8563 (Pmode, operands[3])));
8564 /* Messy: can we subreg to clean this up? */
8565 if (Pmode == DImode)
8566 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8567 else
8568 load = gen_casesi_load_media (reg4,
8569 gen_rtx_SUBREG (DImode, reg3, 0),
8570 reg2, operands[3]);
8571 PUT_MODE (SET_SRC (load), Pmode);
8572 emit_insn (load);
8573 /* ??? The following add could be eliminated if we used ptrel. */
8574 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8575 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8576 emit_barrier ();
8577 DONE;
8578 }
8579 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8580 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8581 /* If optimizing, casesi_worker depends on the mode of the instruction
8582 before label it 'uses' - operands[3]. */
8583 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8584 reg));
8585 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8586 if (TARGET_SH2)
8587 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8588 else
8589 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8590 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8591 operands[3], but to lab. We will fix this up in
8592 machine_dependent_reorg. */
8593 emit_barrier ();
8594 DONE;
8595 }")
8596
8597 (define_expand "casesi_0"
8598 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8599 (set (match_dup 4) (minus:SI (match_dup 4)
8600 (match_operand:SI 1 "arith_operand" "")))
8601 (set (reg:SI T_REG)
8602 (gtu:SI (match_dup 4)
8603 (match_operand:SI 2 "arith_reg_operand" "")))
8604 (set (pc)
8605 (if_then_else (ne (reg:SI T_REG)
8606 (const_int 0))
8607 (label_ref (match_operand 3 "" ""))
8608 (pc)))]
8609 "TARGET_SH1"
8610 "")
8611
8612 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8613 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8614 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8615
8616 (define_insn "casesi_worker_0"
8617 [(set (match_operand:SI 0 "register_operand" "=r,r")
8618 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8619 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8620 (clobber (match_scratch:SI 3 "=X,1"))
8621 (clobber (match_scratch:SI 4 "=&z,z"))]
8622 "TARGET_SH1"
8623 "#")
8624
8625 (define_split
8626 [(set (match_operand:SI 0 "register_operand" "")
8627 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8628 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8629 (clobber (match_scratch:SI 3 ""))
8630 (clobber (match_scratch:SI 4 ""))]
8631 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8632 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8633 (parallel [(set (match_dup 0)
8634 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8635 (label_ref (match_dup 2))] UNSPEC_CASESI))
8636 (clobber (match_dup 3))])
8637 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8638 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8639
8640 (define_split
8641 [(set (match_operand:SI 0 "register_operand" "")
8642 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8643 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8644 (clobber (match_scratch:SI 3 ""))
8645 (clobber (match_scratch:SI 4 ""))]
8646 "TARGET_SH2 && reload_completed"
8647 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8648 (parallel [(set (match_dup 0)
8649 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8650 (label_ref (match_dup 2))] UNSPEC_CASESI))
8651 (clobber (match_dup 3))])]
8652 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8653
8654 (define_insn "casesi_worker_1"
8655 [(set (match_operand:SI 0 "register_operand" "=r,r")
8656 (unspec:SI [(reg:SI R0_REG)
8657 (match_operand:SI 1 "register_operand" "0,r")
8658 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8659 (clobber (match_scratch:SI 3 "=X,1"))]
8660 "TARGET_SH1"
8661 "*
8662 {
8663 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8664
8665 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8666
8667 switch (GET_MODE (diff_vec))
8668 {
8669 case SImode:
8670 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8671 case HImode:
8672 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8673 case QImode:
8674 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8675 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8676 return \"mov.b @(r0,%1),%0\";
8677 default:
8678 gcc_unreachable ();
8679 }
8680 }"
8681 [(set_attr "length" "4")])
8682
8683 (define_insn "casesi_worker_2"
8684 [(set (match_operand:SI 0 "register_operand" "=r,r")
8685 (unspec:SI [(reg:SI R0_REG)
8686 (match_operand:SI 1 "register_operand" "0,r")
8687 (label_ref (match_operand 2 "" ""))
8688 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8689 (clobber (match_operand:SI 4 "" "=X,1"))]
8690 "TARGET_SH2 && reload_completed && flag_pic"
8691 "*
8692 {
8693 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8694 const char *load;
8695
8696 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8697
8698 switch (GET_MODE (diff_vec))
8699 {
8700 case SImode:
8701 output_asm_insn (\"shll2 %1\", operands);
8702 load = \"mov.l @(r0,%1),%0\"; break;
8703 case HImode:
8704 output_asm_insn (\"add %1,%1\", operands);
8705 load = \"mov.w @(r0,%1),%0\"; break;
8706 case QImode:
8707 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8708 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8709 else
8710 load = \"mov.b @(r0,%1),%0\";
8711 break;
8712 default:
8713 gcc_unreachable ();
8714 }
8715 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8716 return load;
8717 }"
8718 [(set_attr "length" "8")])
8719
8720 (define_insn "casesi_shift_media"
8721 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8722 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8723 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8724 UNSPEC_CASESI)))]
8725 "TARGET_SHMEDIA"
8726 "*
8727 {
8728 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8729
8730 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8731
8732 switch (GET_MODE (diff_vec))
8733 {
8734 case SImode:
8735 return \"shlli %1, 2, %0\";
8736 case HImode:
8737 return \"shlli %1, 1, %0\";
8738 case QImode:
8739 if (rtx_equal_p (operands[0], operands[1]))
8740 return \"\";
8741 return \"add %1, r63, %0\";
8742 default:
8743 gcc_unreachable ();
8744 }
8745 }"
8746 [(set_attr "type" "arith_media")])
8747
8748 (define_insn "casesi_load_media"
8749 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8750 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8751 (match_operand:DI 2 "arith_reg_operand" "r")
8752 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8753 "TARGET_SHMEDIA"
8754 "*
8755 {
8756 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8757
8758 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8759
8760 switch (GET_MODE (diff_vec))
8761 {
8762 case SImode:
8763 return \"ldx.l %1, %2, %0\";
8764 case HImode:
8765 #if 0
8766 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8767 return \"ldx.uw %1, %2, %0\";
8768 #endif
8769 return \"ldx.w %1, %2, %0\";
8770 case QImode:
8771 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8772 return \"ldx.ub %1, %2, %0\";
8773 return \"ldx.b %1, %2, %0\";
8774 default:
8775 gcc_unreachable ();
8776 }
8777 }"
8778 [(set_attr "type" "load_media")])
8779
8780 (define_expand "return"
8781 [(return)]
8782 "reload_completed && ! sh_need_epilogue ()"
8783 "
8784 {
8785 if (TARGET_SHMEDIA)
8786 {
8787 emit_jump_insn (gen_return_media ());
8788 DONE;
8789 }
8790
8791 if (TARGET_SHCOMPACT
8792 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8793 {
8794 emit_jump_insn (gen_shcompact_return_tramp ());
8795 DONE;
8796 }
8797 }")
8798
8799 (define_insn "*return_i"
8800 [(return)]
8801 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8802 && (current_function_args_info.call_cookie
8803 & CALL_COOKIE_RET_TRAMP (1)))
8804 && reload_completed"
8805 "%@ %#"
8806 [(set_attr "type" "return")
8807 (set_attr "needs_delay_slot" "yes")])
8808
8809 (define_expand "shcompact_return_tramp"
8810 [(return)]
8811 "TARGET_SHCOMPACT
8812 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8813 "
8814 {
8815 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8816
8817 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8818 emit_jump_insn (gen_shcompact_return_tramp_i ());
8819 DONE;
8820 }")
8821
8822 (define_insn "shcompact_return_tramp_i"
8823 [(parallel [(return) (use (reg:SI R0_REG))])]
8824 "TARGET_SHCOMPACT
8825 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8826 "jmp @r0%#"
8827 [(set_attr "type" "jump_ind")
8828 (set_attr "needs_delay_slot" "yes")])
8829
8830 (define_insn "return_media_i"
8831 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8832 "TARGET_SHMEDIA && reload_completed"
8833 "blink %0, r63"
8834 [(set_attr "type" "jump_media")])
8835
8836 (define_insn "return_media_rte"
8837 [(return)]
8838 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8839 "rte"
8840 [(set_attr "type" "jump_media")])
8841
8842 (define_expand "return_media"
8843 [(return)]
8844 "TARGET_SHMEDIA && reload_completed"
8845 "
8846 {
8847 int tr_regno = sh_media_register_for_return ();
8848 rtx tr;
8849
8850 if (current_function_interrupt)
8851 {
8852 emit_jump_insn (gen_return_media_rte ());
8853 DONE;
8854 }
8855 if (tr_regno < 0)
8856 {
8857 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8858
8859 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8860 tr_regno = TR0_REG;
8861 tr = gen_rtx_REG (Pmode, tr_regno);
8862 emit_move_insn (tr, r18);
8863 }
8864 else
8865 tr = gen_rtx_REG (Pmode, tr_regno);
8866
8867 emit_jump_insn (gen_return_media_i (tr));
8868 DONE;
8869 }")
8870
8871 (define_insn "shcompact_preserve_incoming_args"
8872 [(set (match_operand:SI 0 "register_operand" "+r")
8873 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8874 "TARGET_SHCOMPACT"
8875 ""
8876 [(set_attr "length" "0")])
8877
8878 (define_insn "shcompact_incoming_args"
8879 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8880 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8881 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8882 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8883 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8884 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8885 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8886 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8887 (set (mem:BLK (reg:SI MACL_REG))
8888 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8889 (use (reg:SI R0_REG))
8890 (clobber (reg:SI R0_REG))
8891 (clobber (reg:SI MACL_REG))
8892 (clobber (reg:SI MACH_REG))
8893 (clobber (reg:SI PR_REG))]
8894 "TARGET_SHCOMPACT"
8895 "jsr @r0%#"
8896 [(set_attr "needs_delay_slot" "yes")])
8897
8898 (define_insn "shmedia_save_restore_regs_compact"
8899 [(set (reg:SI SP_REG)
8900 (plus:SI (reg:SI SP_REG)
8901 (match_operand:SI 0 "immediate_operand" "i")))
8902 (use (reg:SI R0_REG))
8903 (clobber (reg:SI PR_REG))]
8904 "TARGET_SHCOMPACT
8905 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8906 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8907 "jsr @r0%#"
8908 [(set_attr "needs_delay_slot" "yes")])
8909
8910 (define_expand "prologue"
8911 [(const_int 0)]
8912 ""
8913 "sh_expand_prologue (); DONE;")
8914
8915 (define_expand "epilogue"
8916 [(return)]
8917 ""
8918 "
8919 {
8920 sh_expand_epilogue (0);
8921 emit_jump_insn (gen_return ());
8922 DONE;
8923 }")
8924
8925 (define_expand "eh_return"
8926 [(use (match_operand 0 "register_operand" ""))]
8927 ""
8928 {
8929 rtx ra = operands[0];
8930
8931 if (TARGET_SHMEDIA64)
8932 emit_insn (gen_eh_set_ra_di (ra));
8933 else
8934 emit_insn (gen_eh_set_ra_si (ra));
8935
8936 DONE;
8937 })
8938
8939 ;; Clobber the return address on the stack. We can't expand this
8940 ;; until we know where it will be put in the stack frame.
8941
8942 (define_insn "eh_set_ra_si"
8943 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8944 (clobber (match_scratch:SI 1 "=&r"))]
8945 "! TARGET_SHMEDIA64"
8946 "#")
8947
8948 (define_insn "eh_set_ra_di"
8949 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8950 (clobber (match_scratch:DI 1 "=&r"))]
8951 "TARGET_SHMEDIA64"
8952 "#")
8953
8954 (define_split
8955 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8956 (clobber (match_scratch 1 ""))]
8957 "reload_completed"
8958 [(const_int 0)]
8959 "
8960 {
8961 sh_set_return_address (operands[0], operands[1]);
8962 DONE;
8963 }")
8964
8965 (define_insn "blockage"
8966 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8967 ""
8968 ""
8969 [(set_attr "length" "0")])
8970 \f
8971 ;; ------------------------------------------------------------------------
8972 ;; Scc instructions
8973 ;; ------------------------------------------------------------------------
8974
8975 (define_insn "movt"
8976 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8977 (eq:SI (reg:SI T_REG) (const_int 1)))]
8978 "TARGET_SH1"
8979 "movt %0"
8980 [(set_attr "type" "arith")])
8981
8982 (define_expand "seq"
8983 [(set (match_operand:SI 0 "arith_reg_dest" "")
8984 (match_dup 1))]
8985 ""
8986 "
8987 {
8988 if (TARGET_SHMEDIA)
8989 {
8990 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8991 if (sh_compare_op1 != const0_rtx)
8992 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8993 ? GET_MODE (sh_compare_op0)
8994 : GET_MODE (sh_compare_op1),
8995 sh_compare_op1);
8996 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8997 {
8998 if (GET_MODE (operands[0]) != SImode)
8999 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9000
9001 switch (GET_MODE (sh_compare_op0))
9002 {
9003 case SImode:
9004 emit_insn (gen_cmpsieqsi_media (operands[0],
9005 sh_compare_op0, sh_compare_op1));
9006 break;
9007
9008 case DImode:
9009 emit_insn (gen_cmpsieqdi_media (operands[0],
9010 sh_compare_op0, sh_compare_op1));
9011 break;
9012
9013 case SFmode:
9014 if (! TARGET_SHMEDIA_FPU)
9015 FAIL;
9016 emit_insn (gen_cmpsieqsf_media (operands[0],
9017 sh_compare_op0, sh_compare_op1));
9018 break;
9019
9020 case DFmode:
9021 if (! TARGET_SHMEDIA_FPU)
9022 FAIL;
9023 emit_insn (gen_cmpsieqdf_media (operands[0],
9024 sh_compare_op0, sh_compare_op1));
9025 break;
9026
9027 default:
9028 FAIL;
9029 }
9030 DONE;
9031 }
9032
9033 if (GET_MODE (operands[0]) != DImode)
9034 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9035
9036 switch (GET_MODE (sh_compare_op0))
9037 {
9038 case SImode:
9039 emit_insn (gen_cmpeqsi_media (operands[0],
9040 sh_compare_op0, sh_compare_op1));
9041 break;
9042
9043 case DImode:
9044 emit_insn (gen_cmpeqdi_media (operands[0],
9045 sh_compare_op0, sh_compare_op1));
9046 break;
9047
9048 case SFmode:
9049 if (! TARGET_SHMEDIA_FPU)
9050 FAIL;
9051 emit_insn (gen_cmpeqsf_media (operands[0],
9052 sh_compare_op0, sh_compare_op1));
9053 break;
9054
9055 case DFmode:
9056 if (! TARGET_SHMEDIA_FPU)
9057 FAIL;
9058 emit_insn (gen_cmpeqdf_media (operands[0],
9059 sh_compare_op0, sh_compare_op1));
9060 break;
9061
9062 default:
9063 FAIL;
9064 }
9065 DONE;
9066 }
9067 if (sh_expand_t_scc (EQ, operands[0]))
9068 DONE;
9069 if (! currently_expanding_to_rtl)
9070 FAIL;
9071 operands[1] = prepare_scc_operands (EQ);
9072 }")
9073
9074 (define_expand "slt"
9075 [(set (match_operand:SI 0 "arith_reg_operand" "")
9076 (match_dup 1))]
9077 ""
9078 "
9079 {
9080 if (TARGET_SHMEDIA)
9081 {
9082 if (GET_MODE (operands[0]) != DImode)
9083 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9084 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9085 if (sh_compare_op1 != const0_rtx)
9086 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9087 ? GET_MODE (sh_compare_op0)
9088 : GET_MODE (sh_compare_op1),
9089 sh_compare_op1);
9090
9091 switch (GET_MODE (sh_compare_op0))
9092 {
9093 case SImode:
9094 emit_insn (gen_cmpgtsi_media (operands[0],
9095 sh_compare_op1, sh_compare_op0));
9096 break;
9097
9098 case DImode:
9099 emit_insn (gen_cmpgtdi_media (operands[0],
9100 sh_compare_op1, sh_compare_op0));
9101 break;
9102
9103 case SFmode:
9104 if (! TARGET_SHMEDIA_FPU)
9105 FAIL;
9106 emit_insn (gen_cmpgtsf_media (operands[0],
9107 sh_compare_op1, sh_compare_op0));
9108 break;
9109
9110 case DFmode:
9111 if (! TARGET_SHMEDIA_FPU)
9112 FAIL;
9113 emit_insn (gen_cmpgtdf_media (operands[0],
9114 sh_compare_op1, sh_compare_op0));
9115 break;
9116
9117 default:
9118 FAIL;
9119 }
9120 DONE;
9121 }
9122 if (! currently_expanding_to_rtl)
9123 FAIL;
9124 operands[1] = prepare_scc_operands (LT);
9125 }")
9126
9127 (define_expand "sle"
9128 [(match_operand:SI 0 "arith_reg_operand" "")]
9129 ""
9130 "
9131 {
9132 rtx tmp = sh_compare_op0;
9133
9134 if (TARGET_SHMEDIA)
9135 {
9136 if (GET_MODE (operands[0]) != DImode)
9137 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9138 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9139 if (sh_compare_op1 != const0_rtx)
9140 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9141 ? GET_MODE (sh_compare_op0)
9142 : GET_MODE (sh_compare_op1),
9143 sh_compare_op1);
9144
9145 switch (GET_MODE (sh_compare_op0))
9146 {
9147 case SImode:
9148 {
9149 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9150
9151 emit_insn (gen_cmpgtsi_media (tmp,
9152 sh_compare_op0, sh_compare_op1));
9153 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9154 break;
9155 }
9156
9157 case DImode:
9158 {
9159 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9160
9161 emit_insn (gen_cmpgtdi_media (tmp,
9162 sh_compare_op0, sh_compare_op1));
9163 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9164 break;
9165 }
9166
9167 case SFmode:
9168 if (! TARGET_SHMEDIA_FPU)
9169 FAIL;
9170 emit_insn (gen_cmpgesf_media (operands[0],
9171 sh_compare_op1, sh_compare_op0));
9172 break;
9173
9174 case DFmode:
9175 if (! TARGET_SHMEDIA_FPU)
9176 FAIL;
9177 emit_insn (gen_cmpgedf_media (operands[0],
9178 sh_compare_op1, sh_compare_op0));
9179 break;
9180
9181 default:
9182 FAIL;
9183 }
9184 DONE;
9185 }
9186
9187 sh_compare_op0 = sh_compare_op1;
9188 sh_compare_op1 = tmp;
9189 emit_insn (gen_sge (operands[0]));
9190 DONE;
9191 }")
9192
9193 (define_expand "sgt"
9194 [(set (match_operand:SI 0 "arith_reg_operand" "")
9195 (match_dup 1))]
9196 ""
9197 "
9198 {
9199 if (TARGET_SHMEDIA)
9200 {
9201 if (GET_MODE (operands[0]) != DImode)
9202 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9203 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9204 if (sh_compare_op1 != const0_rtx)
9205 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9206 ? GET_MODE (sh_compare_op0)
9207 : GET_MODE (sh_compare_op1),
9208 sh_compare_op1);
9209
9210 switch (GET_MODE (sh_compare_op0))
9211 {
9212 case SImode:
9213 emit_insn (gen_cmpgtsi_media (operands[0],
9214 sh_compare_op0, sh_compare_op1));
9215 break;
9216
9217 case DImode:
9218 emit_insn (gen_cmpgtdi_media (operands[0],
9219 sh_compare_op0, sh_compare_op1));
9220 break;
9221
9222 case SFmode:
9223 if (! TARGET_SHMEDIA_FPU)
9224 FAIL;
9225 emit_insn (gen_cmpgtsf_media (operands[0],
9226 sh_compare_op0, sh_compare_op1));
9227 break;
9228
9229 case DFmode:
9230 if (! TARGET_SHMEDIA_FPU)
9231 FAIL;
9232 emit_insn (gen_cmpgtdf_media (operands[0],
9233 sh_compare_op0, sh_compare_op1));
9234 break;
9235
9236 default:
9237 FAIL;
9238 }
9239 DONE;
9240 }
9241 if (! currently_expanding_to_rtl)
9242 FAIL;
9243 operands[1] = prepare_scc_operands (GT);
9244 }")
9245
9246 (define_expand "sge"
9247 [(set (match_operand:SI 0 "arith_reg_operand" "")
9248 (match_dup 1))]
9249 ""
9250 "
9251 {
9252 if (TARGET_SHMEDIA)
9253 {
9254 enum machine_mode mode = GET_MODE (sh_compare_op0);
9255
9256 if ((mode) == VOIDmode)
9257 mode = GET_MODE (sh_compare_op1);
9258 if (GET_MODE (operands[0]) != DImode)
9259 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9260 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9261 if (sh_compare_op1 != const0_rtx)
9262 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9263
9264 switch (mode)
9265 {
9266 case SImode:
9267 {
9268 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9269
9270 emit_insn (gen_cmpgtsi_media (tmp,
9271 sh_compare_op1, sh_compare_op0));
9272 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9273 break;
9274 }
9275
9276 case DImode:
9277 {
9278 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9279
9280 emit_insn (gen_cmpgtdi_media (tmp,
9281 sh_compare_op1, sh_compare_op0));
9282 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9283 break;
9284 }
9285
9286 case SFmode:
9287 if (! TARGET_SHMEDIA_FPU)
9288 FAIL;
9289 emit_insn (gen_cmpgesf_media (operands[0],
9290 sh_compare_op0, sh_compare_op1));
9291 break;
9292
9293 case DFmode:
9294 if (! TARGET_SHMEDIA_FPU)
9295 FAIL;
9296 emit_insn (gen_cmpgedf_media (operands[0],
9297 sh_compare_op0, sh_compare_op1));
9298 break;
9299
9300 default:
9301 FAIL;
9302 }
9303 DONE;
9304 }
9305
9306 if (! currently_expanding_to_rtl)
9307 FAIL;
9308 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9309 {
9310 if (TARGET_IEEE)
9311 {
9312 rtx lab = gen_label_rtx ();
9313 prepare_scc_operands (EQ);
9314 emit_jump_insn (gen_branch_true (lab));
9315 prepare_scc_operands (GT);
9316 emit_label (lab);
9317 emit_insn (gen_movt (operands[0]));
9318 }
9319 else
9320 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9321 DONE;
9322 }
9323 operands[1] = prepare_scc_operands (GE);
9324 }")
9325
9326 (define_expand "sgtu"
9327 [(set (match_operand:SI 0 "arith_reg_operand" "")
9328 (match_dup 1))]
9329 ""
9330 "
9331 {
9332 if (TARGET_SHMEDIA)
9333 {
9334 if (GET_MODE (operands[0]) != DImode)
9335 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9336 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9337 if (sh_compare_op1 != const0_rtx)
9338 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9339 ? GET_MODE (sh_compare_op0)
9340 : GET_MODE (sh_compare_op1),
9341 sh_compare_op1);
9342
9343 emit_insn (gen_cmpgtudi_media (operands[0],
9344 sh_compare_op0, sh_compare_op1));
9345 DONE;
9346 }
9347 if (! currently_expanding_to_rtl)
9348 FAIL;
9349 operands[1] = prepare_scc_operands (GTU);
9350 }")
9351
9352 (define_expand "sltu"
9353 [(set (match_operand:SI 0 "arith_reg_operand" "")
9354 (match_dup 1))]
9355 ""
9356 "
9357 {
9358 if (TARGET_SHMEDIA)
9359 {
9360 if (GET_MODE (operands[0]) != DImode)
9361 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9362 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9363 if (sh_compare_op1 != const0_rtx)
9364 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9365 ? GET_MODE (sh_compare_op0)
9366 : GET_MODE (sh_compare_op1),
9367 sh_compare_op1);
9368
9369 emit_insn (gen_cmpgtudi_media (operands[0],
9370 sh_compare_op1, sh_compare_op0));
9371 DONE;
9372 }
9373 if (! currently_expanding_to_rtl)
9374 FAIL;
9375 operands[1] = prepare_scc_operands (LTU);
9376 }")
9377
9378 (define_expand "sleu"
9379 [(set (match_operand:SI 0 "arith_reg_operand" "")
9380 (match_dup 1))]
9381 ""
9382 "
9383 {
9384 if (TARGET_SHMEDIA)
9385 {
9386 rtx tmp;
9387
9388 if (GET_MODE (operands[0]) != DImode)
9389 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9390 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9391 if (sh_compare_op1 != const0_rtx)
9392 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9393 ? GET_MODE (sh_compare_op0)
9394 : GET_MODE (sh_compare_op1),
9395 sh_compare_op1);
9396
9397 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9398
9399 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9400 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9401
9402 DONE;
9403 }
9404 if (! currently_expanding_to_rtl)
9405 FAIL;
9406 operands[1] = prepare_scc_operands (LEU);
9407 }")
9408
9409 (define_expand "sgeu"
9410 [(set (match_operand:SI 0 "arith_reg_operand" "")
9411 (match_dup 1))]
9412 ""
9413 "
9414 {
9415 if (TARGET_SHMEDIA)
9416 {
9417 rtx tmp;
9418
9419 if (GET_MODE (operands[0]) != DImode)
9420 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9421 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9422 if (sh_compare_op1 != const0_rtx)
9423 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9424 ? GET_MODE (sh_compare_op0)
9425 : GET_MODE (sh_compare_op1),
9426 sh_compare_op1);
9427
9428 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9429
9430 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9431 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9432
9433 DONE;
9434 }
9435
9436 if (! currently_expanding_to_rtl)
9437 FAIL;
9438 operands[1] = prepare_scc_operands (GEU);
9439 }")
9440
9441 ;; sne moves the complement of the T reg to DEST like this:
9442 ;; cmp/eq ...
9443 ;; mov #-1,temp
9444 ;; negc temp,dest
9445 ;; This is better than xoring compare result with 1 because it does
9446 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9447 ;; loop.
9448
9449 (define_expand "sne"
9450 [(set (match_dup 2) (const_int -1))
9451 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9452 (neg:SI (plus:SI (match_dup 1)
9453 (match_dup 2))))
9454 (set (reg:SI T_REG)
9455 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9456 (const_int 0)))])]
9457 ""
9458 "
9459 {
9460 if (TARGET_SHMEDIA)
9461 {
9462 rtx tmp;
9463
9464 if (GET_MODE (operands[0]) != DImode)
9465 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9466
9467 if (! TARGET_SHMEDIA_FPU
9468 && GET_MODE (sh_compare_op0) != DImode
9469 && GET_MODE (sh_compare_op0) != SImode)
9470 FAIL;
9471
9472 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9473 if (sh_compare_op1 != const0_rtx)
9474 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9475 ? GET_MODE (sh_compare_op0)
9476 : GET_MODE (sh_compare_op1),
9477 sh_compare_op1);
9478
9479 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9480
9481 emit_insn (gen_seq (tmp));
9482 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9483
9484 DONE;
9485 }
9486
9487 if (sh_expand_t_scc (NE, operands[0]))
9488 DONE;
9489 if (! currently_expanding_to_rtl)
9490 FAIL;
9491 operands[1] = prepare_scc_operands (EQ);
9492 operands[2] = gen_reg_rtx (SImode);
9493 }")
9494
9495 (define_expand "sunordered"
9496 [(set (match_operand:DI 0 "arith_reg_operand" "")
9497 (unordered:DI (match_dup 1) (match_dup 2)))]
9498 "TARGET_SHMEDIA_FPU"
9499 "
9500 {
9501 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9502 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9503 }")
9504
9505 ;; Use the same trick for FP sle / sge
9506
9507 ;; Apart from the constant use and the T setting, this is like movt,
9508 ;; except that it uses the logically negated value of T, i.e.
9509 ;; operand[0] := T ? 0 : 1.
9510 (define_expand "movnegt"
9511 [(set (match_dup 2) (const_int -1))
9512 (parallel [(set (match_operand 0 "" "")
9513 (neg:SI (plus:SI (match_dup 1)
9514 (match_dup 2))))
9515 (set (reg:SI T_REG)
9516 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9517 (const_int 0)))])]
9518 "TARGET_SH1"
9519 "operands[2] = gen_reg_rtx (SImode);")
9520
9521 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9522 ;; This prevents a regression that occurred when we switched from xor to
9523 ;; mov/neg for sne.
9524
9525 (define_split
9526 [(set (match_operand:SI 0 "arith_reg_dest" "")
9527 (plus:SI (reg:SI T_REG)
9528 (const_int -1)))]
9529 "TARGET_SH1"
9530 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9531 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9532 "")
9533
9534 ;; -------------------------------------------------------------------------
9535 ;; Instructions to cope with inline literal tables
9536 ;; -------------------------------------------------------------------------
9537
9538 ; 2 byte integer in line
9539
9540 (define_insn "consttable_2"
9541 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9542 (match_operand 1 "" "")]
9543 UNSPECV_CONST2)]
9544 ""
9545 "*
9546 {
9547 if (operands[1] != const0_rtx)
9548 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9549 return \"\";
9550 }"
9551 [(set_attr "length" "2")
9552 (set_attr "in_delay_slot" "no")])
9553
9554 ; 4 byte integer in line
9555
9556 (define_insn "consttable_4"
9557 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9558 (match_operand 1 "" "")]
9559 UNSPECV_CONST4)]
9560 ""
9561 "*
9562 {
9563 if (operands[1] != const0_rtx)
9564 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9565 return \"\";
9566 }"
9567 [(set_attr "length" "4")
9568 (set_attr "in_delay_slot" "no")])
9569
9570 ; 8 byte integer in line
9571
9572 (define_insn "consttable_8"
9573 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9574 (match_operand 1 "" "")]
9575 UNSPECV_CONST8)]
9576 ""
9577 "*
9578 {
9579 if (operands[1] != const0_rtx)
9580 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9581 return \"\";
9582 }"
9583 [(set_attr "length" "8")
9584 (set_attr "in_delay_slot" "no")])
9585
9586 ; 4 byte floating point
9587
9588 (define_insn "consttable_sf"
9589 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9590 (match_operand 1 "" "")]
9591 UNSPECV_CONST4)]
9592 ""
9593 "*
9594 {
9595 if (operands[1] != const0_rtx)
9596 {
9597 REAL_VALUE_TYPE d;
9598 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9599 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9600 }
9601 return \"\";
9602 }"
9603 [(set_attr "length" "4")
9604 (set_attr "in_delay_slot" "no")])
9605
9606 ; 8 byte floating point
9607
9608 (define_insn "consttable_df"
9609 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9610 (match_operand 1 "" "")]
9611 UNSPECV_CONST8)]
9612 ""
9613 "*
9614 {
9615 if (operands[1] != const0_rtx)
9616 {
9617 REAL_VALUE_TYPE d;
9618 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9619 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9620 }
9621 return \"\";
9622 }"
9623 [(set_attr "length" "8")
9624 (set_attr "in_delay_slot" "no")])
9625
9626 ;; Alignment is needed for some constant tables; it may also be added for
9627 ;; Instructions at the start of loops, or after unconditional branches.
9628 ;; ??? We would get more accurate lengths if we did instruction
9629 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9630 ;; here is too conservative.
9631
9632 ; align to a two byte boundary
9633
9634 (define_expand "align_2"
9635 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9636 ""
9637 "")
9638
9639 ; align to a four byte boundary
9640 ;; align_4 and align_log are instructions for the starts of loops, or
9641 ;; after unconditional branches, which may take up extra room.
9642
9643 (define_expand "align_4"
9644 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9645 ""
9646 "")
9647
9648 ; align to a cache line boundary
9649
9650 (define_insn "align_log"
9651 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9652 ""
9653 ""
9654 [(set_attr "length" "0")
9655 (set_attr "in_delay_slot" "no")])
9656
9657 ; emitted at the end of the literal table, used to emit the
9658 ; 32bit branch labels if needed.
9659
9660 (define_insn "consttable_end"
9661 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9662 ""
9663 "* return output_jump_label_table ();"
9664 [(set_attr "in_delay_slot" "no")])
9665
9666 ; emitted at the end of the window in the literal table.
9667
9668 (define_insn "consttable_window_end"
9669 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9670 ""
9671 ""
9672 [(set_attr "length" "0")
9673 (set_attr "in_delay_slot" "no")])
9674
9675 ;; -------------------------------------------------------------------------
9676 ;; Misc
9677 ;; -------------------------------------------------------------------------
9678
9679 ;; String/block move insn.
9680
9681 (define_expand "movmemsi"
9682 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9683 (mem:BLK (match_operand:BLK 1 "" "")))
9684 (use (match_operand:SI 2 "nonmemory_operand" ""))
9685 (use (match_operand:SI 3 "immediate_operand" ""))
9686 (clobber (reg:SI PR_REG))
9687 (clobber (reg:SI R4_REG))
9688 (clobber (reg:SI R5_REG))
9689 (clobber (reg:SI R0_REG))])]
9690 "TARGET_SH1 && ! TARGET_SH5"
9691 "
9692 {
9693 if(expand_block_move (operands))
9694 DONE;
9695 else FAIL;
9696 }")
9697
9698 (define_insn "block_move_real"
9699 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9700 (mem:BLK (reg:SI R5_REG)))
9701 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9702 (clobber (reg:SI PR_REG))
9703 (clobber (reg:SI R0_REG))])]
9704 "TARGET_SH1 && ! TARGET_HARD_SH4"
9705 "jsr @%0%#"
9706 [(set_attr "type" "sfunc")
9707 (set_attr "needs_delay_slot" "yes")])
9708
9709 (define_insn "block_lump_real"
9710 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9711 (mem:BLK (reg:SI R5_REG)))
9712 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9713 (use (reg:SI R6_REG))
9714 (clobber (reg:SI PR_REG))
9715 (clobber (reg:SI T_REG))
9716 (clobber (reg:SI R4_REG))
9717 (clobber (reg:SI R5_REG))
9718 (clobber (reg:SI R6_REG))
9719 (clobber (reg:SI R0_REG))])]
9720 "TARGET_SH1 && ! TARGET_HARD_SH4"
9721 "jsr @%0%#"
9722 [(set_attr "type" "sfunc")
9723 (set_attr "needs_delay_slot" "yes")])
9724
9725 (define_insn "block_move_real_i4"
9726 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9727 (mem:BLK (reg:SI R5_REG)))
9728 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9729 (clobber (reg:SI PR_REG))
9730 (clobber (reg:SI R0_REG))
9731 (clobber (reg:SI R1_REG))
9732 (clobber (reg:SI R2_REG))])]
9733 "TARGET_HARD_SH4"
9734 "jsr @%0%#"
9735 [(set_attr "type" "sfunc")
9736 (set_attr "needs_delay_slot" "yes")])
9737
9738 (define_insn "block_lump_real_i4"
9739 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9740 (mem:BLK (reg:SI R5_REG)))
9741 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9742 (use (reg:SI R6_REG))
9743 (clobber (reg:SI PR_REG))
9744 (clobber (reg:SI T_REG))
9745 (clobber (reg:SI R4_REG))
9746 (clobber (reg:SI R5_REG))
9747 (clobber (reg:SI R6_REG))
9748 (clobber (reg:SI R0_REG))
9749 (clobber (reg:SI R1_REG))
9750 (clobber (reg:SI R2_REG))
9751 (clobber (reg:SI R3_REG))])]
9752 "TARGET_HARD_SH4"
9753 "jsr @%0%#"
9754 [(set_attr "type" "sfunc")
9755 (set_attr "needs_delay_slot" "yes")])
9756 \f
9757 ;; -------------------------------------------------------------------------
9758 ;; Floating point instructions.
9759 ;; -------------------------------------------------------------------------
9760
9761 ;; ??? All patterns should have a type attribute.
9762
9763 (define_expand "fpu_switch0"
9764 [(set (match_operand:SI 0 "" "") (match_dup 2))
9765 (set (match_dup 1) (mem:PSI (match_dup 0)))]
9766 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9767 "
9768 {
9769 operands[1] = get_fpscr_rtx ();
9770 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9771 if (flag_pic)
9772 operands[2] = legitimize_pic_address (operands[2], SImode,
9773 no_new_pseudos ? operands[0] : 0);
9774 }")
9775
9776 (define_expand "fpu_switch1"
9777 [(set (match_operand:SI 0 "" "") (match_dup 2))
9778 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
9779 (set (match_dup 1) (mem:PSI (match_dup 3)))]
9780 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9781 "
9782 {
9783 operands[1] = get_fpscr_rtx ();
9784 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9785 if (flag_pic)
9786 operands[2] = legitimize_pic_address (operands[2], SImode,
9787 no_new_pseudos ? operands[0] : 0);
9788 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9789 }")
9790
9791 (define_expand "movpsi"
9792 [(set (match_operand:PSI 0 "register_operand" "")
9793 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9794 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9795 "")
9796
9797 ;; The c / m alternative is a fake to guide reload to load directly into
9798 ;; fpscr, since reload doesn't know how to use post-increment.
9799 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9800 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9801 ;; predicate after reload.
9802 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9803 ;; like a mac -> gpr move.
9804 (define_insn "fpu_switch"
9805 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9806 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9807 "TARGET_SH2E
9808 && (! reload_completed
9809 || true_regnum (operands[0]) != FPSCR_REG
9810 || GET_CODE (operands[1]) != MEM
9811 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9812 "@
9813 ! precision stays the same
9814 lds.l %1,fpscr
9815 mov.l %1,%0
9816 #
9817 lds %1,fpscr
9818 mov %1,%0
9819 mov.l %1,%0
9820 sts fpscr,%0
9821 sts.l fpscr,%0"
9822 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9823 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9824
9825 (define_split
9826 [(set (reg:PSI FPSCR_REG)
9827 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9828 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9829 [(set (match_dup 0) (match_dup 0))]
9830 "
9831 {
9832 rtx mem, insn;
9833
9834 mem = SET_SRC (PATTERN (curr_insn));
9835 mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
9836 insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
9837 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9838 }")
9839
9840 (define_split
9841 [(set (reg:PSI FPSCR_REG)
9842 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9843 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9844 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
9845 "
9846 {
9847 rtx mem, insn;
9848
9849 mem = SET_SRC (PATTERN (curr_insn));
9850 mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
9851 insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
9852 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9853 }")
9854
9855 ;; ??? This uses the fp unit, but has no type indicating that.
9856 ;; If we did that, this would either give a bogus latency or introduce
9857 ;; a bogus FIFO constraint.
9858 ;; Since this insn is currently only used for prologues/epilogues,
9859 ;; it is probably best to claim no function unit, which matches the
9860 ;; current setting.
9861 (define_insn "toggle_sz"
9862 [(set (reg:PSI FPSCR_REG)
9863 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9864 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9865 "fschg"
9866 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9867
9868 ;; There's no way we can use it today, since optimize mode switching
9869 ;; doesn't enable us to know from which mode we're switching to the
9870 ;; mode it requests, to tell whether we can use a relative mode switch
9871 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9872 ;; memory).
9873 (define_insn "toggle_pr"
9874 [(set (reg:PSI FPSCR_REG)
9875 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9876 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9877 "fpchg"
9878 [(set_attr "type" "fp")])
9879
9880 (define_expand "addsf3"
9881 [(set (match_operand:SF 0 "arith_reg_operand" "")
9882 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9883 (match_operand:SF 2 "arith_reg_operand" "")))]
9884 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9885 "
9886 {
9887 if (TARGET_SH2E)
9888 {
9889 expand_sf_binop (&gen_addsf3_i, operands);
9890 DONE;
9891 }
9892 }")
9893
9894 (define_insn "*addsf3_media"
9895 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9896 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9897 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9898 "TARGET_SHMEDIA_FPU"
9899 "fadd.s %1, %2, %0"
9900 [(set_attr "type" "fparith_media")])
9901
9902 (define_insn_and_split "unary_sf_op"
9903 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9904 (vec_select:V2SF
9905 (vec_concat:V2SF
9906 (vec_select:SF
9907 (match_dup 0)
9908 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9909 (match_operator:SF 2 "unary_float_operator"
9910 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9911 (parallel [(match_operand 4
9912 "const_int_operand" "n")]))]))
9913 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9914 "TARGET_SHMEDIA_FPU"
9915 "#"
9916 "TARGET_SHMEDIA_FPU && reload_completed"
9917 [(set (match_dup 5) (match_dup 6))]
9918 "
9919 {
9920 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9921 rtx op1 = gen_rtx_REG (SFmode,
9922 (true_regnum (operands[1])
9923 + (INTVAL (operands[4]) ^ endian)));
9924
9925 operands[7] = gen_rtx_REG (SFmode,
9926 (true_regnum (operands[0])
9927 + (INTVAL (operands[3]) ^ endian)));
9928 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9929 }"
9930 [(set_attr "type" "fparith_media")])
9931
9932 (define_insn_and_split "binary_sf_op"
9933 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9934 (vec_select:V2SF
9935 (vec_concat:V2SF
9936 (vec_select:SF
9937 (match_dup 0)
9938 (parallel [(match_operand 7 "const_int_operand" "n")]))
9939 (match_operator:SF 3 "binary_float_operator"
9940 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9941 (parallel [(match_operand 5
9942 "const_int_operand" "n")]))
9943 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9944 (parallel [(match_operand 6
9945 "const_int_operand" "n")]))]))
9946 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9947 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9948 "#"
9949 "&& reload_completed"
9950 [(set (match_dup 8) (match_dup 9))]
9951 "
9952 {
9953 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9954 rtx op1 = gen_rtx_REG (SFmode,
9955 (true_regnum (operands[1])
9956 + (INTVAL (operands[5]) ^ endian)));
9957 rtx op2 = gen_rtx_REG (SFmode,
9958 (true_regnum (operands[2])
9959 + (INTVAL (operands[6]) ^ endian)));
9960
9961 operands[8] = gen_rtx_REG (SFmode,
9962 (true_regnum (operands[0])
9963 + (INTVAL (operands[4]) ^ endian)));
9964 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9965 }"
9966 [(set_attr "type" "fparith_media")])
9967
9968 (define_insn "addsf3_i"
9969 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9970 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9971 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9972 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9973 "TARGET_SH2E"
9974 "fadd %2,%0"
9975 [(set_attr "type" "fp")
9976 (set_attr "fp_mode" "single")])
9977
9978 (define_expand "subsf3"
9979 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9980 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9981 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9982 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9983 "
9984 {
9985 if (TARGET_SH2E)
9986 {
9987 expand_sf_binop (&gen_subsf3_i, operands);
9988 DONE;
9989 }
9990 }")
9991
9992 (define_insn "*subsf3_media"
9993 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9994 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9995 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9996 "TARGET_SHMEDIA_FPU"
9997 "fsub.s %1, %2, %0"
9998 [(set_attr "type" "fparith_media")])
9999
10000 (define_insn "subsf3_i"
10001 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10002 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10003 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10004 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10005 "TARGET_SH2E"
10006 "fsub %2,%0"
10007 [(set_attr "type" "fp")
10008 (set_attr "fp_mode" "single")])
10009
10010 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10011 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
10012 ;; mixed-precision SH4 targets. To allow it to be still generated for the
10013 ;; SH3E, we use a separate insn for SH3E mulsf3.
10014
10015 (define_expand "mulsf3"
10016 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10017 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10018 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10019 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10020 "
10021 {
10022 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10023 expand_sf_binop (&gen_mulsf3_i4, operands);
10024 else if (TARGET_SH2E)
10025 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10026 if (! TARGET_SHMEDIA)
10027 DONE;
10028 }")
10029
10030 (define_insn "*mulsf3_media"
10031 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10032 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10033 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10034 "TARGET_SHMEDIA_FPU"
10035 "fmul.s %1, %2, %0"
10036 [(set_attr "type" "fparith_media")])
10037
10038 (define_insn "mulsf3_i4"
10039 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10040 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10041 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10042 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10043 "TARGET_SH2E"
10044 "fmul %2,%0"
10045 [(set_attr "type" "fp")
10046 (set_attr "fp_mode" "single")])
10047
10048 (define_insn "mulsf3_ie"
10049 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10050 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10051 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10052 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10053 "fmul %2,%0"
10054 [(set_attr "type" "fp")])
10055
10056 (define_insn "mac_media"
10057 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10058 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10059 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10060 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10061 "TARGET_SHMEDIA_FPU"
10062 "fmac.s %1, %2, %0"
10063 [(set_attr "type" "fparith_media")])
10064
10065 (define_insn "*macsf3"
10066 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10067 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10068 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10069 (match_operand:SF 3 "arith_reg_operand" "0")))
10070 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10071 "TARGET_SH2E && ! TARGET_SH4"
10072 "fmac fr0,%2,%0"
10073 [(set_attr "type" "fp")
10074 (set_attr "fp_mode" "single")])
10075
10076 (define_expand "divsf3"
10077 [(set (match_operand:SF 0 "arith_reg_operand" "")
10078 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10079 (match_operand:SF 2 "arith_reg_operand" "")))]
10080 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10081 "
10082 {
10083 if (TARGET_SH2E)
10084 {
10085 expand_sf_binop (&gen_divsf3_i, operands);
10086 DONE;
10087 }
10088 }")
10089
10090 (define_insn "*divsf3_media"
10091 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10092 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10093 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10094 "TARGET_SHMEDIA_FPU"
10095 "fdiv.s %1, %2, %0"
10096 [(set_attr "type" "fdiv_media")])
10097
10098 (define_insn "divsf3_i"
10099 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10100 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10101 (match_operand:SF 2 "arith_reg_operand" "f")))
10102 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10103 "TARGET_SH2E"
10104 "fdiv %2,%0"
10105 [(set_attr "type" "fdiv")
10106 (set_attr "fp_mode" "single")])
10107
10108 (define_insn "floatdisf2"
10109 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10110 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10111 "TARGET_SHMEDIA_FPU"
10112 "float.qs %1, %0"
10113 [(set_attr "type" "fpconv_media")])
10114
10115 (define_expand "floatsisf2"
10116 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10117 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10118 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10119 "
10120 {
10121 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10122 {
10123 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10124 DONE;
10125 }
10126 }")
10127
10128 (define_insn "*floatsisf2_media"
10129 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10130 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10131 "TARGET_SHMEDIA_FPU"
10132 "float.ls %1, %0"
10133 [(set_attr "type" "fpconv_media")])
10134
10135 (define_insn "floatsisf2_i4"
10136 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10137 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10138 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10139 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10140 "float %1,%0"
10141 [(set_attr "type" "fp")
10142 (set_attr "fp_mode" "single")])
10143
10144 (define_insn "*floatsisf2_ie"
10145 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10146 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10147 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10148 "float %1,%0"
10149 [(set_attr "type" "fp")])
10150
10151 (define_insn "fix_truncsfdi2"
10152 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10153 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10154 "TARGET_SHMEDIA_FPU"
10155 "ftrc.sq %1, %0"
10156 [(set_attr "type" "fpconv_media")])
10157
10158 (define_expand "fix_truncsfsi2"
10159 [(set (match_operand:SI 0 "fpul_operand" "=y")
10160 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10161 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10162 "
10163 {
10164 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10165 {
10166 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10167 DONE;
10168 }
10169 }")
10170
10171 (define_insn "*fix_truncsfsi2_media"
10172 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10173 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10174 "TARGET_SHMEDIA_FPU"
10175 "ftrc.sl %1, %0"
10176 [(set_attr "type" "fpconv_media")])
10177
10178 (define_insn "fix_truncsfsi2_i4"
10179 [(set (match_operand:SI 0 "fpul_operand" "=y")
10180 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10181 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10182 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10183 "ftrc %1,%0"
10184 [(set_attr "type" "ftrc_s")
10185 (set_attr "fp_mode" "single")])
10186
10187 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10188 ;; fix_truncsfsi2_i4.
10189 ;; (define_insn "fix_truncsfsi2_i4_2"
10190 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10191 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10192 ;; (use (reg:PSI FPSCR_REG))
10193 ;; (clobber (reg:SI FPUL_REG))]
10194 ;; "TARGET_SH4"
10195 ;; "#"
10196 ;; [(set_attr "length" "4")
10197 ;; (set_attr "fp_mode" "single")])
10198
10199 ;;(define_split
10200 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10201 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10202 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10203 ;; (clobber (reg:SI FPUL_REG))]
10204 ;; "TARGET_SH4"
10205 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10206 ;; (use (match_dup 2))])
10207 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10208
10209 (define_insn "*fixsfsi"
10210 [(set (match_operand:SI 0 "fpul_operand" "=y")
10211 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10212 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10213 "ftrc %1,%0"
10214 [(set_attr "type" "fp")])
10215
10216 (define_insn "cmpgtsf_t"
10217 [(set (reg:SI T_REG)
10218 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10219 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10220 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10221 "fcmp/gt %1,%0"
10222 [(set_attr "type" "fp")
10223 (set_attr "fp_mode" "single")])
10224
10225 (define_insn "cmpeqsf_t"
10226 [(set (reg:SI T_REG)
10227 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10228 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10229 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10230 "fcmp/eq %1,%0"
10231 [(set_attr "type" "fp")
10232 (set_attr "fp_mode" "single")])
10233
10234 (define_insn "ieee_ccmpeqsf_t"
10235 [(set (reg:SI T_REG)
10236 (ior:SI (reg:SI T_REG)
10237 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10238 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10239 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10240 "* return output_ieee_ccmpeq (insn, operands);"
10241 [(set_attr "length" "4")])
10242
10243
10244 (define_insn "cmpgtsf_t_i4"
10245 [(set (reg:SI T_REG)
10246 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10247 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10248 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10249 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10250 "fcmp/gt %1,%0"
10251 [(set_attr "type" "fp")
10252 (set_attr "fp_mode" "single")])
10253
10254 (define_insn "cmpeqsf_t_i4"
10255 [(set (reg:SI T_REG)
10256 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10257 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10258 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10259 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10260 "fcmp/eq %1,%0"
10261 [(set_attr "type" "fp")
10262 (set_attr "fp_mode" "single")])
10263
10264 (define_insn "*ieee_ccmpeqsf_t_4"
10265 [(set (reg:SI T_REG)
10266 (ior:SI (reg:SI T_REG)
10267 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10268 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10269 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10270 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10271 "* return output_ieee_ccmpeq (insn, operands);"
10272 [(set_attr "length" "4")
10273 (set_attr "fp_mode" "single")])
10274
10275 (define_insn "cmpeqsf_media"
10276 [(set (match_operand:DI 0 "register_operand" "=r")
10277 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10278 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10279 "TARGET_SHMEDIA_FPU"
10280 "fcmpeq.s %1, %2, %0"
10281 [(set_attr "type" "fcmp_media")])
10282
10283 (define_insn "cmpsieqsf_media"
10284 [(set (match_operand:SI 0 "register_operand" "=r")
10285 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10286 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10287 "TARGET_SHMEDIA_FPU"
10288 "fcmpeq.s %1, %2, %0"
10289 [(set_attr "type" "fcmp_media")])
10290
10291 (define_insn "cmpgtsf_media"
10292 [(set (match_operand:DI 0 "register_operand" "=r")
10293 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10294 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10295 "TARGET_SHMEDIA_FPU"
10296 "fcmpgt.s %1, %2, %0"
10297 [(set_attr "type" "fcmp_media")])
10298
10299 (define_insn "cmpgesf_media"
10300 [(set (match_operand:DI 0 "register_operand" "=r")
10301 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10302 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10303 "TARGET_SHMEDIA_FPU"
10304 "fcmpge.s %1, %2, %0"
10305 [(set_attr "type" "fcmp_media")])
10306
10307 (define_insn "cmpunsf_media"
10308 [(set (match_operand:DI 0 "register_operand" "=r")
10309 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10310 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10311 "TARGET_SHMEDIA_FPU"
10312 "fcmpun.s %1, %2, %0"
10313 [(set_attr "type" "fcmp_media")])
10314
10315 (define_expand "cmpsf"
10316 [(set (reg:SI T_REG)
10317 (compare (match_operand:SF 0 "arith_operand" "")
10318 (match_operand:SF 1 "arith_operand" "")))]
10319 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10320 "
10321 {
10322 sh_compare_op0 = operands[0];
10323 sh_compare_op1 = operands[1];
10324 DONE;
10325 }")
10326
10327 (define_expand "negsf2"
10328 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10329 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10330 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10331 "
10332 {
10333 if (TARGET_SH2E)
10334 {
10335 expand_sf_unop (&gen_negsf2_i, operands);
10336 DONE;
10337 }
10338 }")
10339
10340 (define_insn "*negsf2_media"
10341 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10342 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10343 "TARGET_SHMEDIA_FPU"
10344 "fneg.s %1, %0"
10345 [(set_attr "type" "fmove_media")])
10346
10347 (define_insn "negsf2_i"
10348 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10349 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10350 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10351 "TARGET_SH2E"
10352 "fneg %0"
10353 [(set_attr "type" "fmove")
10354 (set_attr "fp_mode" "single")])
10355
10356 (define_expand "sqrtsf2"
10357 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10358 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10359 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10360 "
10361 {
10362 if (TARGET_SH3E)
10363 {
10364 expand_sf_unop (&gen_sqrtsf2_i, operands);
10365 DONE;
10366 }
10367 }")
10368
10369 (define_insn "*sqrtsf2_media"
10370 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10371 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10372 "TARGET_SHMEDIA_FPU"
10373 "fsqrt.s %1, %0"
10374 [(set_attr "type" "fdiv_media")])
10375
10376 (define_insn "sqrtsf2_i"
10377 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10378 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10379 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10380 "TARGET_SH3E"
10381 "fsqrt %0"
10382 [(set_attr "type" "fdiv")
10383 (set_attr "fp_mode" "single")])
10384
10385 (define_insn "rsqrtsf2"
10386 [(set (match_operand:SF 0 "register_operand" "=f")
10387 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10388 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10389 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10390 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10391 && operands[1] == CONST1_RTX (SFmode)"
10392 "fsrra %0"
10393 [(set_attr "type" "fsrra")
10394 (set_attr "fp_mode" "single")])
10395
10396 (define_insn "fsca"
10397 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10398 (vec_concat:V2SF
10399 (unspec:SF [(mult:SF
10400 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10401 (match_operand:SF 2 "immediate_operand" "i"))
10402 ] UNSPEC_FSINA)
10403 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10404 ] UNSPEC_FCOSA)))
10405 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10406 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10407 && operands[2] == sh_fsca_int2sf ()"
10408 "fsca fpul,%d0"
10409 [(set_attr "type" "fsca")
10410 (set_attr "fp_mode" "single")])
10411
10412 (define_expand "sinsf2"
10413 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10414 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10415 UNSPEC_FSINA))]
10416 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10417 "
10418 {
10419 rtx scaled = gen_reg_rtx (SFmode);
10420 rtx truncated = gen_reg_rtx (SImode);
10421 rtx fsca = gen_reg_rtx (V2SFmode);
10422 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10423
10424 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10425 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10426 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10427 get_fpscr_rtx ()));
10428 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10429 DONE;
10430 }")
10431
10432 (define_expand "cossf2"
10433 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10434 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10435 UNSPEC_FCOSA))]
10436 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10437 "
10438 {
10439 rtx scaled = gen_reg_rtx (SFmode);
10440 rtx truncated = gen_reg_rtx (SImode);
10441 rtx fsca = gen_reg_rtx (V2SFmode);
10442 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10443
10444 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10445 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10446 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10447 get_fpscr_rtx ()));
10448 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10449 DONE;
10450 }")
10451
10452 (define_expand "sindf2"
10453 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10454 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10455 UNSPEC_FSINA))]
10456 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10457 "
10458 {
10459 rtx scaled = gen_reg_rtx (DFmode);
10460 rtx truncated = gen_reg_rtx (SImode);
10461 rtx fsca = gen_reg_rtx (V2SFmode);
10462 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10463 rtx sfresult = gen_reg_rtx (SFmode);
10464
10465 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10466 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10467 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10468 get_fpscr_rtx ()));
10469 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10470 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10471 DONE;
10472 }")
10473
10474 (define_expand "cosdf2"
10475 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10476 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10477 UNSPEC_FCOSA))]
10478 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10479 "
10480 {
10481 rtx scaled = gen_reg_rtx (DFmode);
10482 rtx truncated = gen_reg_rtx (SImode);
10483 rtx fsca = gen_reg_rtx (V2SFmode);
10484 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10485 rtx sfresult = gen_reg_rtx (SFmode);
10486
10487 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10488 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10489 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10490 get_fpscr_rtx ()));
10491 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10492 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10493 DONE;
10494 }")
10495
10496 (define_expand "abssf2"
10497 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10498 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10499 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10500 "
10501 {
10502 if (TARGET_SH2E)
10503 {
10504 expand_sf_unop (&gen_abssf2_i, operands);
10505 DONE;
10506 }
10507 }")
10508
10509 (define_insn "*abssf2_media"
10510 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10511 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10512 "TARGET_SHMEDIA_FPU"
10513 "fabs.s %1, %0"
10514 [(set_attr "type" "fmove_media")])
10515
10516 (define_insn "abssf2_i"
10517 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10518 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10519 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10520 "TARGET_SH2E"
10521 "fabs %0"
10522 [(set_attr "type" "fmove")
10523 (set_attr "fp_mode" "single")])
10524
10525 (define_expand "adddf3"
10526 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10527 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10528 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10529 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10530 "
10531 {
10532 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10533 {
10534 expand_df_binop (&gen_adddf3_i, operands);
10535 DONE;
10536 }
10537 }")
10538
10539 (define_insn "*adddf3_media"
10540 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10541 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10542 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10543 "TARGET_SHMEDIA_FPU"
10544 "fadd.d %1, %2, %0"
10545 [(set_attr "type" "dfparith_media")])
10546
10547 (define_insn "adddf3_i"
10548 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10549 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10550 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10551 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10552 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10553 "fadd %2,%0"
10554 [(set_attr "type" "dfp_arith")
10555 (set_attr "fp_mode" "double")])
10556
10557 (define_expand "subdf3"
10558 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10559 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10560 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10561 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10562 "
10563 {
10564 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10565 {
10566 expand_df_binop (&gen_subdf3_i, operands);
10567 DONE;
10568 }
10569 }")
10570
10571 (define_insn "*subdf3_media"
10572 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10573 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10574 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10575 "TARGET_SHMEDIA_FPU"
10576 "fsub.d %1, %2, %0"
10577 [(set_attr "type" "dfparith_media")])
10578
10579 (define_insn "subdf3_i"
10580 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10581 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10582 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10583 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10584 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10585 "fsub %2,%0"
10586 [(set_attr "type" "dfp_arith")
10587 (set_attr "fp_mode" "double")])
10588
10589 (define_expand "muldf3"
10590 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10591 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10592 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10593 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10594 "
10595 {
10596 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10597 {
10598 expand_df_binop (&gen_muldf3_i, operands);
10599 DONE;
10600 }
10601 }")
10602
10603 (define_insn "*muldf3_media"
10604 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10605 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10606 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10607 "TARGET_SHMEDIA_FPU"
10608 "fmul.d %1, %2, %0"
10609 [(set_attr "type" "dfmul_media")])
10610
10611 (define_insn "muldf3_i"
10612 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10613 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10614 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10615 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10616 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10617 "fmul %2,%0"
10618 [(set_attr "type" "dfp_arith")
10619 (set_attr "fp_mode" "double")])
10620
10621 (define_expand "divdf3"
10622 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10623 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10624 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10625 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10626 "
10627 {
10628 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10629 {
10630 expand_df_binop (&gen_divdf3_i, operands);
10631 DONE;
10632 }
10633 }")
10634
10635 (define_insn "*divdf3_media"
10636 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10637 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10638 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10639 "TARGET_SHMEDIA_FPU"
10640 "fdiv.d %1, %2, %0"
10641 [(set_attr "type" "dfdiv_media")])
10642
10643 (define_insn "divdf3_i"
10644 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10645 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10646 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10647 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10648 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10649 "fdiv %2,%0"
10650 [(set_attr "type" "dfdiv")
10651 (set_attr "fp_mode" "double")])
10652
10653 (define_insn "floatdidf2"
10654 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10655 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10656 "TARGET_SHMEDIA_FPU"
10657 "float.qd %1, %0"
10658 [(set_attr "type" "dfpconv_media")])
10659
10660 (define_expand "floatsidf2"
10661 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10662 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10663 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10664 "
10665 {
10666 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10667 {
10668 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10669 get_fpscr_rtx ()));
10670 DONE;
10671 }
10672 }")
10673
10674 (define_insn "*floatsidf2_media"
10675 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10676 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10677 "TARGET_SHMEDIA_FPU"
10678 "float.ld %1, %0"
10679 [(set_attr "type" "dfpconv_media")])
10680
10681 (define_insn "floatsidf2_i"
10682 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10683 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10684 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10685 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10686 "float %1,%0"
10687 [(set_attr "type" "dfp_conv")
10688 (set_attr "fp_mode" "double")])
10689
10690 (define_insn "fix_truncdfdi2"
10691 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10692 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10693 "TARGET_SHMEDIA_FPU"
10694 "ftrc.dq %1, %0"
10695 [(set_attr "type" "dfpconv_media")])
10696
10697 (define_expand "fix_truncdfsi2"
10698 [(set (match_operand:SI 0 "fpul_operand" "")
10699 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10700 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10701 "
10702 {
10703 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10704 {
10705 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10706 get_fpscr_rtx ()));
10707 DONE;
10708 }
10709 }")
10710
10711 (define_insn "*fix_truncdfsi2_media"
10712 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10713 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10714 "TARGET_SHMEDIA_FPU"
10715 "ftrc.dl %1, %0"
10716 [(set_attr "type" "dfpconv_media")])
10717
10718 (define_insn "fix_truncdfsi2_i"
10719 [(set (match_operand:SI 0 "fpul_operand" "=y")
10720 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10721 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10722 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10723 "ftrc %1,%0"
10724 [(set_attr "type" "dfp_conv")
10725 (set_attr "dfp_comp" "no")
10726 (set_attr "fp_mode" "double")])
10727
10728 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10729 ;; fix_truncdfsi2_i.
10730 ;; (define_insn "fix_truncdfsi2_i4"
10731 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10732 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10733 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10734 ;; (clobber (reg:SI FPUL_REG))]
10735 ;; "TARGET_SH4"
10736 ;; "#"
10737 ;; [(set_attr "length" "4")
10738 ;; (set_attr "fp_mode" "double")])
10739 ;;
10740 ;; (define_split
10741 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10742 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10743 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10744 ;; (clobber (reg:SI FPUL_REG))]
10745 ;; "TARGET_SH4"
10746 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10747 ;; (use (match_dup 2))])
10748 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10749
10750 (define_insn "cmpgtdf_t"
10751 [(set (reg:SI T_REG)
10752 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10753 (match_operand:DF 1 "arith_reg_operand" "f")))
10754 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10755 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10756 "fcmp/gt %1,%0"
10757 [(set_attr "type" "dfp_cmp")
10758 (set_attr "fp_mode" "double")])
10759
10760 (define_insn "cmpeqdf_t"
10761 [(set (reg:SI T_REG)
10762 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10763 (match_operand:DF 1 "arith_reg_operand" "f")))
10764 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10765 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10766 "fcmp/eq %1,%0"
10767 [(set_attr "type" "dfp_cmp")
10768 (set_attr "fp_mode" "double")])
10769
10770 (define_insn "*ieee_ccmpeqdf_t"
10771 [(set (reg:SI T_REG)
10772 (ior:SI (reg:SI T_REG)
10773 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10774 (match_operand:DF 1 "arith_reg_operand" "f"))))
10775 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10776 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10777 "* return output_ieee_ccmpeq (insn, operands);"
10778 [(set_attr "length" "4")
10779 (set_attr "fp_mode" "double")])
10780
10781 (define_insn "cmpeqdf_media"
10782 [(set (match_operand:DI 0 "register_operand" "=r")
10783 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10784 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10785 "TARGET_SHMEDIA_FPU"
10786 "fcmpeq.d %1,%2,%0"
10787 [(set_attr "type" "fcmp_media")])
10788
10789 (define_insn "cmpsieqdf_media"
10790 [(set (match_operand:SI 0 "register_operand" "=r")
10791 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10792 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10793 "TARGET_SHMEDIA_FPU"
10794 "fcmpeq.d %1,%2,%0"
10795 [(set_attr "type" "fcmp_media")])
10796
10797 (define_insn "cmpgtdf_media"
10798 [(set (match_operand:DI 0 "register_operand" "=r")
10799 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10800 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10801 "TARGET_SHMEDIA_FPU"
10802 "fcmpgt.d %1,%2,%0"
10803 [(set_attr "type" "fcmp_media")])
10804
10805 (define_insn "cmpgedf_media"
10806 [(set (match_operand:DI 0 "register_operand" "=r")
10807 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10808 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10809 "TARGET_SHMEDIA_FPU"
10810 "fcmpge.d %1,%2,%0"
10811 [(set_attr "type" "fcmp_media")])
10812
10813 (define_insn "cmpundf_media"
10814 [(set (match_operand:DI 0 "register_operand" "=r")
10815 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10816 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10817 "TARGET_SHMEDIA_FPU"
10818 "fcmpun.d %1,%2,%0"
10819 [(set_attr "type" "fcmp_media")])
10820
10821 (define_expand "cmpdf"
10822 [(set (reg:SI T_REG)
10823 (compare (match_operand:DF 0 "arith_operand" "")
10824 (match_operand:DF 1 "arith_operand" "")))]
10825 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10826 "
10827 {
10828 sh_compare_op0 = operands[0];
10829 sh_compare_op1 = operands[1];
10830 DONE;
10831 }")
10832
10833 (define_expand "negdf2"
10834 [(set (match_operand:DF 0 "arith_reg_operand" "")
10835 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10836 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10837 "
10838 {
10839 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10840 {
10841 expand_df_unop (&gen_negdf2_i, operands);
10842 DONE;
10843 }
10844 }")
10845
10846 (define_insn "*negdf2_media"
10847 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10848 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10849 "TARGET_SHMEDIA_FPU"
10850 "fneg.d %1, %0"
10851 [(set_attr "type" "fmove_media")])
10852
10853 (define_insn "negdf2_i"
10854 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10855 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10856 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10857 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10858 "fneg %0"
10859 [(set_attr "type" "fmove")
10860 (set_attr "fp_mode" "double")])
10861
10862 (define_expand "sqrtdf2"
10863 [(set (match_operand:DF 0 "arith_reg_operand" "")
10864 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10865 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10866 "
10867 {
10868 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10869 {
10870 expand_df_unop (&gen_sqrtdf2_i, operands);
10871 DONE;
10872 }
10873 }")
10874
10875 (define_insn "*sqrtdf2_media"
10876 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10877 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10878 "TARGET_SHMEDIA_FPU"
10879 "fsqrt.d %1, %0"
10880 [(set_attr "type" "dfdiv_media")])
10881
10882 (define_insn "sqrtdf2_i"
10883 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10884 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10885 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10886 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10887 "fsqrt %0"
10888 [(set_attr "type" "dfdiv")
10889 (set_attr "fp_mode" "double")])
10890
10891 (define_expand "absdf2"
10892 [(set (match_operand:DF 0 "arith_reg_operand" "")
10893 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10894 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10895 "
10896 {
10897 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10898 {
10899 expand_df_unop (&gen_absdf2_i, operands);
10900 DONE;
10901 }
10902 }")
10903
10904 (define_insn "*absdf2_media"
10905 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10906 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10907 "TARGET_SHMEDIA_FPU"
10908 "fabs.d %1, %0"
10909 [(set_attr "type" "fmove_media")])
10910
10911 (define_insn "absdf2_i"
10912 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10913 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10914 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10916 "fabs %0"
10917 [(set_attr "type" "fmove")
10918 (set_attr "fp_mode" "double")])
10919
10920 (define_expand "extendsfdf2"
10921 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10922 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10923 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10924 "
10925 {
10926 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10927 {
10928 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10929 get_fpscr_rtx ()));
10930 DONE;
10931 }
10932 }")
10933
10934 (define_insn "*extendsfdf2_media"
10935 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10936 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10937 "TARGET_SHMEDIA_FPU"
10938 "fcnv.sd %1, %0"
10939 [(set_attr "type" "dfpconv_media")])
10940
10941 (define_insn "extendsfdf2_i4"
10942 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10943 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10944 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10945 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10946 "fcnvsd %1,%0"
10947 [(set_attr "type" "fp")
10948 (set_attr "fp_mode" "double")])
10949
10950 (define_expand "truncdfsf2"
10951 [(set (match_operand:SF 0 "fpul_operand" "")
10952 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10953 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10954 "
10955 {
10956 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10957 {
10958 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10959 get_fpscr_rtx ()));
10960 DONE;
10961 }
10962 }")
10963
10964 (define_insn "*truncdfsf2_media"
10965 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10966 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10967 "TARGET_SHMEDIA_FPU"
10968 "fcnv.ds %1, %0"
10969 [(set_attr "type" "dfpconv_media")])
10970
10971 (define_insn "truncdfsf2_i4"
10972 [(set (match_operand:SF 0 "fpul_operand" "=y")
10973 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10974 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10975 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10976 "fcnvds %1,%0"
10977 [(set_attr "type" "fp")
10978 (set_attr "fp_mode" "double")])
10979 \f
10980 ;; Bit field extract patterns. These give better code for packed bitfields,
10981 ;; because they allow auto-increment addresses to be generated.
10982
10983 (define_expand "insv"
10984 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10985 (match_operand:SI 1 "immediate_operand" "")
10986 (match_operand:SI 2 "immediate_operand" ""))
10987 (match_operand:SI 3 "general_operand" ""))]
10988 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10989 "
10990 {
10991 rtx addr_target, orig_address, shift_reg, qi_val;
10992 HOST_WIDE_INT bitsize, size, v = 0;
10993 rtx x = operands[3];
10994
10995 /* ??? expmed doesn't care for non-register predicates. */
10996 if (! memory_operand (operands[0], VOIDmode)
10997 || ! immediate_operand (operands[1], VOIDmode)
10998 || ! immediate_operand (operands[2], VOIDmode)
10999 || ! general_operand (x, VOIDmode))
11000 FAIL;
11001 /* If this isn't a 16 / 24 / 32 bit field, or if
11002 it doesn't start on a byte boundary, then fail. */
11003 bitsize = INTVAL (operands[1]);
11004 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11005 || (INTVAL (operands[2]) % 8) != 0)
11006 FAIL;
11007
11008 size = bitsize / 8;
11009 orig_address = XEXP (operands[0], 0);
11010 shift_reg = gen_reg_rtx (SImode);
11011 if (GET_CODE (x) == CONST_INT)
11012 {
11013 v = INTVAL (x);
11014 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11015 }
11016 else
11017 {
11018 emit_insn (gen_movsi (shift_reg, operands[3]));
11019 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11020 }
11021 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11022
11023 operands[0] = replace_equiv_address (operands[0], addr_target);
11024 emit_insn (gen_movqi (operands[0], qi_val));
11025
11026 while (size -= 1)
11027 {
11028 if (GET_CODE (x) == CONST_INT)
11029 qi_val
11030 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11031 else
11032 {
11033 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11034 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11035 }
11036 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11037 emit_insn (gen_movqi (operands[0], qi_val));
11038 }
11039
11040 DONE;
11041 }")
11042
11043 (define_insn "movua"
11044 [(set (match_operand:SI 0 "register_operand" "=z")
11045 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11046 (const_int 32) (const_int 0)))]
11047 "TARGET_SH4A_ARCH"
11048 "movua.l %1,%0"
11049 [(set_attr "type" "movua")])
11050
11051 ;; We shouldn't need this, but cse replaces increments with references
11052 ;; to other regs before flow has a chance to create post_inc
11053 ;; addressing modes, and only postreload's cse_move2add brings the
11054 ;; increments back to a usable form.
11055 (define_peephole2
11056 [(set (match_operand:SI 0 "register_operand" "")
11057 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11058 (const_int 32) (const_int 0)))
11059 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11060 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11061 [(set (match_operand:SI 0 "register_operand" "")
11062 (sign_extract:SI (mem:SI (post_inc:SI
11063 (match_operand:SI 1 "register_operand" "")))
11064 (const_int 32) (const_int 0)))]
11065 "")
11066
11067 (define_expand "extv"
11068 [(set (match_operand:SI 0 "register_operand" "")
11069 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11070 (match_operand 2 "const_int_operand" "")
11071 (match_operand 3 "const_int_operand" "")))]
11072 "TARGET_SH4A_ARCH"
11073 {
11074 if (TARGET_SH4A_ARCH
11075 && INTVAL (operands[2]) == 32
11076 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11077 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11078 {
11079 emit_insn (gen_movua (operands[0],
11080 adjust_address (operands[1], SImode, 0)));
11081 DONE;
11082 }
11083
11084 FAIL;
11085 })
11086
11087 (define_expand "extzv"
11088 [(set (match_operand:SI 0 "register_operand" "")
11089 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11090 (match_operand 2 "const_int_operand" "")
11091 (match_operand 3 "const_int_operand" "")))]
11092 "TARGET_SH4A_ARCH"
11093 {
11094 if (TARGET_SH4A_ARCH
11095 && INTVAL (operands[2]) == 32
11096 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11097 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11098 {
11099 emit_insn (gen_movua (operands[0],
11100 adjust_address (operands[1], SImode, 0)));
11101 DONE;
11102 }
11103
11104 FAIL;
11105 })
11106
11107 \f
11108 ;; -------------------------------------------------------------------------
11109 ;; Peepholes
11110 ;; -------------------------------------------------------------------------
11111
11112 ;; This matches cases where a stack pointer increment at the start of the
11113 ;; epilogue combines with a stack slot read loading the return value.
11114
11115 (define_peephole
11116 [(set (match_operand:SI 0 "arith_reg_operand" "")
11117 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11118 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11119 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11120 "mov.l @%1+,%0")
11121
11122 ;; See the comment on the dt combiner pattern above.
11123
11124 (define_peephole
11125 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11126 (plus:SI (match_dup 0)
11127 (const_int -1)))
11128 (set (reg:SI T_REG)
11129 (eq:SI (match_dup 0)
11130 (const_int 0)))]
11131 "TARGET_SH2"
11132 "dt %0")
11133
11134 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11135 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11136 ;; reload when the constant is too large for a reg+offset address.
11137
11138 ;; ??? We would get much better code if this was done in reload. This would
11139 ;; require modifying find_reloads_address to recognize that if the constant
11140 ;; is out-of-range for an immediate add, then we get better code by reloading
11141 ;; the constant into a register than by reloading the sum into a register,
11142 ;; since the former is one instruction shorter if the address does not need
11143 ;; to be offsettable. Unfortunately this does not work, because there is
11144 ;; only one register, r0, that can be used as an index register. This register
11145 ;; is also the function return value register. So, if we try to force reload
11146 ;; to use double-reg addresses, then we end up with some instructions that
11147 ;; need to use r0 twice. The only way to fix this is to change the calling
11148 ;; convention so that r0 is not used to return values.
11149
11150 (define_peephole
11151 [(set (match_operand:SI 0 "register_operand" "=r")
11152 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11153 (set (mem:SI (match_dup 0))
11154 (match_operand:SI 2 "general_movsrc_operand" ""))]
11155 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11156 "mov.l %2,@(%0,%1)")
11157
11158 (define_peephole
11159 [(set (match_operand:SI 0 "register_operand" "=r")
11160 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11161 (set (match_operand:SI 2 "general_movdst_operand" "")
11162 (mem:SI (match_dup 0)))]
11163 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11164 "mov.l @(%0,%1),%2")
11165
11166 (define_peephole
11167 [(set (match_operand:SI 0 "register_operand" "=r")
11168 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11169 (set (mem:HI (match_dup 0))
11170 (match_operand:HI 2 "general_movsrc_operand" ""))]
11171 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11172 "mov.w %2,@(%0,%1)")
11173
11174 (define_peephole
11175 [(set (match_operand:SI 0 "register_operand" "=r")
11176 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11177 (set (match_operand:HI 2 "general_movdst_operand" "")
11178 (mem:HI (match_dup 0)))]
11179 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11180 "mov.w @(%0,%1),%2")
11181
11182 (define_peephole
11183 [(set (match_operand:SI 0 "register_operand" "=r")
11184 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11185 (set (mem:QI (match_dup 0))
11186 (match_operand:QI 2 "general_movsrc_operand" ""))]
11187 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11188 "mov.b %2,@(%0,%1)")
11189
11190 (define_peephole
11191 [(set (match_operand:SI 0 "register_operand" "=r")
11192 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11193 (set (match_operand:QI 2 "general_movdst_operand" "")
11194 (mem:QI (match_dup 0)))]
11195 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11196 "mov.b @(%0,%1),%2")
11197
11198 (define_peephole
11199 [(set (match_operand:SI 0 "register_operand" "=r")
11200 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11201 (set (mem:SF (match_dup 0))
11202 (match_operand:SF 2 "general_movsrc_operand" ""))]
11203 "TARGET_SH1 && REGNO (operands[0]) == 0
11204 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11205 || (GET_CODE (operands[2]) == SUBREG
11206 && REGNO (SUBREG_REG (operands[2])) < 16))
11207 && reg_unused_after (operands[0], insn)"
11208 "mov.l %2,@(%0,%1)")
11209
11210 (define_peephole
11211 [(set (match_operand:SI 0 "register_operand" "=r")
11212 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11213 (set (match_operand:SF 2 "general_movdst_operand" "")
11214
11215 (mem:SF (match_dup 0)))]
11216 "TARGET_SH1 && REGNO (operands[0]) == 0
11217 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11218 || (GET_CODE (operands[2]) == SUBREG
11219 && REGNO (SUBREG_REG (operands[2])) < 16))
11220 && reg_unused_after (operands[0], insn)"
11221 "mov.l @(%0,%1),%2")
11222
11223 (define_peephole
11224 [(set (match_operand:SI 0 "register_operand" "=r")
11225 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11226 (set (mem:SF (match_dup 0))
11227 (match_operand:SF 2 "general_movsrc_operand" ""))]
11228 "TARGET_SH2E && REGNO (operands[0]) == 0
11229 && ((GET_CODE (operands[2]) == REG
11230 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11231 || (GET_CODE (operands[2]) == SUBREG
11232 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11233 && reg_unused_after (operands[0], insn)"
11234 "fmov{.s|} %2,@(%0,%1)")
11235
11236 (define_peephole
11237 [(set (match_operand:SI 0 "register_operand" "=r")
11238 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11239 (set (match_operand:SF 2 "general_movdst_operand" "")
11240
11241 (mem:SF (match_dup 0)))]
11242 "TARGET_SH2E && REGNO (operands[0]) == 0
11243 && ((GET_CODE (operands[2]) == REG
11244 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11245 || (GET_CODE (operands[2]) == SUBREG
11246 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11247 && reg_unused_after (operands[0], insn)"
11248 "fmov{.s|} @(%0,%1),%2")
11249
11250 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11251 (define_insn "sp_switch_1"
11252 [(const_int 1)]
11253 "TARGET_SH1"
11254 "*
11255 {
11256 rtx xoperands[1];
11257
11258 xoperands[0] = sp_switch;
11259 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
11260 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
11261 return \"mov r0,r15\";
11262 }"
11263 [(set_attr "length" "10")])
11264
11265 ;; Switch back to the original stack for interrupt functions with the
11266 ;; sp_switch attribute. */
11267 (define_insn "sp_switch_2"
11268 [(const_int 2)]
11269 "TARGET_SH1"
11270 "mov.l @r15+,r15\;mov.l @r15+,r0"
11271 [(set_attr "length" "4")])
11272
11273 ;; Integer vector moves
11274
11275 (define_expand "movv8qi"
11276 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11277 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11278 "TARGET_SHMEDIA"
11279 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11280
11281 (define_insn "movv8qi_i"
11282 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11283 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11284 "TARGET_SHMEDIA
11285 && (register_operand (operands[0], V8QImode)
11286 || sh_register_operand (operands[1], V8QImode))"
11287 "@
11288 add %1, r63, %0
11289 movi %1, %0
11290 #
11291 ld%M1.q %m1, %0
11292 st%M0.q %m0, %N1"
11293 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11294 (set_attr "length" "4,4,16,4,4")])
11295
11296 (define_split
11297 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11298 (subreg:V8QI (const_int 0) 0))]
11299 "TARGET_SHMEDIA"
11300 [(set (match_dup 0)
11301 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11302 (const_int 0) (const_int 0) (const_int 0)
11303 (const_int 0) (const_int 0)]))])
11304
11305 (define_split
11306 [(set (match_operand 0 "arith_reg_dest" "")
11307 (match_operand 1 "sh_rep_vec" ""))]
11308 "TARGET_SHMEDIA && reload_completed
11309 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11310 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11311 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11312 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11313 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11314 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11315 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11316 [(set (match_dup 0) (match_dup 1))
11317 (match_dup 2)]
11318 "
11319 {
11320 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11321 rtx elt1 = XVECEXP (operands[1], 0, 1);
11322
11323 if (unit_size > 2)
11324 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11325 else
11326 {
11327 if (unit_size < 2)
11328 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11329 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11330 }
11331 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11332 operands[1] = XVECEXP (operands[1], 0, 0);
11333 if (unit_size < 2)
11334 {
11335 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11336 operands[1]
11337 = GEN_INT (TARGET_LITTLE_ENDIAN
11338 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11339 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11340 else
11341 {
11342 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11343 operands[1]
11344 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11345 }
11346 }
11347 }")
11348
11349 (define_split
11350 [(set (match_operand 0 "arith_reg_dest" "")
11351 (match_operand 1 "sh_const_vec" ""))]
11352 "TARGET_SHMEDIA && reload_completed
11353 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11354 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11355 [(set (match_dup 0) (match_dup 1))]
11356 "
11357 {
11358 rtx v = operands[1];
11359 enum machine_mode new_mode
11360 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11361
11362 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11363 operands[1]
11364 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11365 }")
11366
11367 (define_expand "movv2hi"
11368 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11369 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11370 "TARGET_SHMEDIA"
11371 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11372
11373 (define_insn "movv2hi_i"
11374 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11375 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11376 "TARGET_SHMEDIA
11377 && (register_operand (operands[0], V2HImode)
11378 || sh_register_operand (operands[1], V2HImode))"
11379 "@
11380 add.l %1, r63, %0
11381 movi %1, %0
11382 #
11383 ld%M1.l %m1, %0
11384 st%M0.l %m0, %N1"
11385 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11386 (set_attr "length" "4,4,16,4,4")
11387 (set (attr "highpart")
11388 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11389 (const_string "user")]
11390 (const_string "ignore")))])
11391
11392 (define_expand "movv4hi"
11393 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11394 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11395 "TARGET_SHMEDIA"
11396 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11397
11398 (define_insn "movv4hi_i"
11399 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11400 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11401 "TARGET_SHMEDIA
11402 && (register_operand (operands[0], V4HImode)
11403 || sh_register_operand (operands[1], V4HImode))"
11404 "@
11405 add %1, r63, %0
11406 movi %1, %0
11407 #
11408 ld%M1.q %m1, %0
11409 st%M0.q %m0, %N1"
11410 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11411 (set_attr "length" "4,4,16,4,4")
11412 (set_attr "highpart" "depend")])
11413
11414 (define_expand "movv2si"
11415 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11416 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11417 "TARGET_SHMEDIA"
11418 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11419
11420 (define_insn "movv2si_i"
11421 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11422 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11423 "TARGET_SHMEDIA
11424 && (register_operand (operands[0], V2SImode)
11425 || sh_register_operand (operands[1], V2SImode))"
11426 "@
11427 add %1, r63, %0
11428 #
11429 #
11430 ld%M1.q %m1, %0
11431 st%M0.q %m0, %N1"
11432 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11433 (set_attr "length" "4,4,16,4,4")
11434 (set_attr "highpart" "depend")])
11435
11436 ;; Multimedia Intrinsics
11437
11438 (define_insn "absv2si2"
11439 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11440 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11441 "TARGET_SHMEDIA"
11442 "mabs.l %1, %0"
11443 [(set_attr "type" "mcmp_media")
11444 (set_attr "highpart" "depend")])
11445
11446 (define_insn "absv4hi2"
11447 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11448 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11449 "TARGET_SHMEDIA"
11450 "mabs.w %1, %0"
11451 [(set_attr "type" "mcmp_media")
11452 (set_attr "highpart" "depend")])
11453
11454 (define_insn "addv2si3"
11455 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11456 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11457 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11458 "TARGET_SHMEDIA"
11459 "madd.l %1, %2, %0"
11460 [(set_attr "type" "arith_media")
11461 (set_attr "highpart" "depend")])
11462
11463 (define_insn "addv4hi3"
11464 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11465 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11466 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11467 "TARGET_SHMEDIA"
11468 "madd.w %1, %2, %0"
11469 [(set_attr "type" "arith_media")
11470 (set_attr "highpart" "depend")])
11471
11472 (define_insn_and_split "addv2hi3"
11473 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11474 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11475 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11476 "TARGET_SHMEDIA"
11477 "#"
11478 "TARGET_SHMEDIA"
11479 [(const_int 0)]
11480 "
11481 {
11482 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11483 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11484 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11485 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11486 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11487
11488 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11489 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11490 DONE;
11491 }"
11492 [(set_attr "highpart" "must_split")])
11493
11494 (define_insn "ssaddv2si3"
11495 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11496 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11497 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11498 "TARGET_SHMEDIA"
11499 "madds.l %1, %2, %0"
11500 [(set_attr "type" "mcmp_media")
11501 (set_attr "highpart" "depend")])
11502
11503 (define_insn "usaddv8qi3"
11504 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11505 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11506 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11507 "TARGET_SHMEDIA"
11508 "madds.ub %1, %2, %0"
11509 [(set_attr "type" "mcmp_media")
11510 (set_attr "highpart" "depend")])
11511
11512 (define_insn "ssaddv4hi3"
11513 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11514 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11515 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11516 "TARGET_SHMEDIA"
11517 "madds.w %1, %2, %0"
11518 [(set_attr "type" "mcmp_media")
11519 (set_attr "highpart" "depend")])
11520
11521 (define_insn "negcmpeqv8qi"
11522 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11523 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11524 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11525 "TARGET_SHMEDIA"
11526 "mcmpeq.b %N1, %N2, %0"
11527 [(set_attr "type" "mcmp_media")
11528 (set_attr "highpart" "depend")])
11529
11530 (define_insn "negcmpeqv2si"
11531 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11532 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11533 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11534 "TARGET_SHMEDIA"
11535 "mcmpeq.l %N1, %N2, %0"
11536 [(set_attr "type" "mcmp_media")
11537 (set_attr "highpart" "depend")])
11538
11539 (define_insn "negcmpeqv4hi"
11540 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11541 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11542 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11543 "TARGET_SHMEDIA"
11544 "mcmpeq.w %N1, %N2, %0"
11545 [(set_attr "type" "mcmp_media")
11546 (set_attr "highpart" "depend")])
11547
11548 (define_insn "negcmpgtuv8qi"
11549 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11550 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11551 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11552 "TARGET_SHMEDIA"
11553 "mcmpgt.ub %N1, %N2, %0"
11554 [(set_attr "type" "mcmp_media")
11555 (set_attr "highpart" "depend")])
11556
11557 (define_insn "negcmpgtv2si"
11558 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11559 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11560 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11561 "TARGET_SHMEDIA"
11562 "mcmpgt.l %N1, %N2, %0"
11563 [(set_attr "type" "mcmp_media")
11564 (set_attr "highpart" "depend")])
11565
11566 (define_insn "negcmpgtv4hi"
11567 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11568 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11569 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11570 "TARGET_SHMEDIA"
11571 "mcmpgt.w %N1, %N2, %0"
11572 [(set_attr "type" "mcmp_media")
11573 (set_attr "highpart" "depend")])
11574
11575 (define_insn "mcmv"
11576 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11577 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11578 (match_operand:DI 2 "arith_reg_operand" "r"))
11579 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11580 (not:DI (match_dup 2)))))]
11581 "TARGET_SHMEDIA"
11582 "mcmv %N1, %2, %0"
11583 [(set_attr "type" "arith_media")
11584 (set_attr "highpart" "depend")])
11585
11586 (define_insn "mcnvs_lw"
11587 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11588 (vec_concat:V4HI
11589 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11590 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11591 "TARGET_SHMEDIA"
11592 "mcnvs.lw %N1, %N2, %0"
11593 [(set_attr "type" "mcmp_media")])
11594
11595 (define_insn "mcnvs_wb"
11596 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11597 (vec_concat:V8QI
11598 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11599 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11600 "TARGET_SHMEDIA"
11601 "mcnvs.wb %N1, %N2, %0"
11602 [(set_attr "type" "mcmp_media")])
11603
11604 (define_insn "mcnvs_wub"
11605 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11606 (vec_concat:V8QI
11607 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11608 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11609 "TARGET_SHMEDIA"
11610 "mcnvs.wub %N1, %N2, %0"
11611 [(set_attr "type" "mcmp_media")])
11612
11613 (define_insn "mextr_rl"
11614 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11615 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11616 (match_operand:HI 3 "mextr_bit_offset" "i"))
11617 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11618 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11619 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11620 "*
11621 {
11622 static char templ[21];
11623
11624 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11625 (int) INTVAL (operands[3]) >> 3);
11626 return templ;
11627 }"
11628 [(set_attr "type" "arith_media")])
11629
11630 (define_insn "*mextr_lr"
11631 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11632 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11633 (match_operand:HI 3 "mextr_bit_offset" "i"))
11634 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11635 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11636 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11637 "*
11638 {
11639 static char templ[21];
11640
11641 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11642 (int) INTVAL (operands[4]) >> 3);
11643 return templ;
11644 }"
11645 [(set_attr "type" "arith_media")])
11646
11647 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11648 ; vector then varies depending on endianness.
11649 (define_expand "mextr1"
11650 [(match_operand:DI 0 "arith_reg_dest" "")
11651 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11652 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11653 "TARGET_SHMEDIA"
11654 "
11655 {
11656 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11657 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11658 DONE;
11659 }")
11660
11661 (define_expand "mextr2"
11662 [(match_operand:DI 0 "arith_reg_dest" "")
11663 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11664 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11665 "TARGET_SHMEDIA"
11666 "
11667 {
11668 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11669 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11670 DONE;
11671 }")
11672
11673 (define_expand "mextr3"
11674 [(match_operand:DI 0 "arith_reg_dest" "")
11675 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11676 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11677 "TARGET_SHMEDIA"
11678 "
11679 {
11680 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11681 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11682 DONE;
11683 }")
11684
11685 (define_expand "mextr4"
11686 [(match_operand:DI 0 "arith_reg_dest" "")
11687 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11688 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11689 "TARGET_SHMEDIA"
11690 "
11691 {
11692 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11693 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11694 DONE;
11695 }")
11696
11697 (define_expand "mextr5"
11698 [(match_operand:DI 0 "arith_reg_dest" "")
11699 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11700 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11701 "TARGET_SHMEDIA"
11702 "
11703 {
11704 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11705 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11706 DONE;
11707 }")
11708
11709 (define_expand "mextr6"
11710 [(match_operand:DI 0 "arith_reg_dest" "")
11711 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11712 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11713 "TARGET_SHMEDIA"
11714 "
11715 {
11716 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11717 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11718 DONE;
11719 }")
11720
11721 (define_expand "mextr7"
11722 [(match_operand:DI 0 "arith_reg_dest" "")
11723 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11724 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11725 "TARGET_SHMEDIA"
11726 "
11727 {
11728 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11729 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11730 DONE;
11731 }")
11732
11733 (define_expand "mmacfx_wl"
11734 [(match_operand:V2SI 0 "arith_reg_dest" "")
11735 (match_operand:V2HI 1 "extend_reg_operand" "")
11736 (match_operand:V2HI 2 "extend_reg_operand" "")
11737 (match_operand:V2SI 3 "arith_reg_operand" "")]
11738 "TARGET_SHMEDIA"
11739 "
11740 {
11741 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11742 operands[1], operands[2]));
11743 DONE;
11744 }")
11745
11746 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11747 ;; is depend
11748 (define_insn "mmacfx_wl_i"
11749 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11750 (ss_plus:V2SI
11751 (match_operand:V2SI 1 "arith_reg_operand" "0")
11752 (ss_truncate:V2SI
11753 (ashift:V2DI
11754 (sign_extend:V2DI
11755 (mult:V2SI
11756 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11757 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11758 (const_int 1)))))]
11759 "TARGET_SHMEDIA"
11760 "mmacfx.wl %2, %3, %0"
11761 [(set_attr "type" "mac_media")
11762 (set_attr "highpart" "depend")])
11763
11764 (define_expand "mmacnfx_wl"
11765 [(match_operand:V2SI 0 "arith_reg_dest" "")
11766 (match_operand:V2HI 1 "extend_reg_operand" "")
11767 (match_operand:V2HI 2 "extend_reg_operand" "")
11768 (match_operand:V2SI 3 "arith_reg_operand" "")]
11769 "TARGET_SHMEDIA"
11770 "
11771 {
11772 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11773 operands[1], operands[2]));
11774 DONE;
11775 }")
11776
11777 (define_insn "mmacnfx_wl_i"
11778 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11779 (ss_minus:V2SI
11780 (match_operand:V2SI 1 "arith_reg_operand" "0")
11781 (ss_truncate:V2SI
11782 (ashift:V2DI
11783 (sign_extend:V2DI
11784 (mult:V2SI
11785 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11786 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11787 (const_int 1)))))]
11788 "TARGET_SHMEDIA"
11789 "mmacnfx.wl %2, %3, %0"
11790 [(set_attr "type" "mac_media")
11791 (set_attr "highpart" "depend")])
11792
11793 (define_insn "mulv2si3"
11794 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11795 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11796 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11797 "TARGET_SHMEDIA"
11798 "mmul.l %1, %2, %0"
11799 [(set_attr "type" "d2mpy_media")
11800 (set_attr "highpart" "depend")])
11801
11802 (define_insn "mulv4hi3"
11803 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11804 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11805 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11806 "TARGET_SHMEDIA"
11807 "mmul.w %1, %2, %0"
11808 [(set_attr "type" "dmpy_media")
11809 (set_attr "highpart" "depend")])
11810
11811 (define_insn "mmulfx_l"
11812 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11813 (ss_truncate:V2SI
11814 (ashiftrt:V2DI
11815 (mult:V2DI
11816 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11817 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11818 (const_int 31))))]
11819 "TARGET_SHMEDIA"
11820 "mmulfx.l %1, %2, %0"
11821 [(set_attr "type" "d2mpy_media")
11822 (set_attr "highpart" "depend")])
11823
11824 (define_insn "mmulfx_w"
11825 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11826 (ss_truncate:V4HI
11827 (ashiftrt:V4SI
11828 (mult:V4SI
11829 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11830 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11831 (const_int 15))))]
11832 "TARGET_SHMEDIA"
11833 "mmulfx.w %1, %2, %0"
11834 [(set_attr "type" "dmpy_media")
11835 (set_attr "highpart" "depend")])
11836
11837 (define_insn "mmulfxrp_w"
11838 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11839 (ss_truncate:V4HI
11840 (ashiftrt:V4SI
11841 (plus:V4SI
11842 (mult:V4SI
11843 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11844 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11845 (const_int 16384))
11846 (const_int 15))))]
11847 "TARGET_SHMEDIA"
11848 "mmulfxrp.w %1, %2, %0"
11849 [(set_attr "type" "dmpy_media")
11850 (set_attr "highpart" "depend")])
11851
11852
11853 (define_expand "mmulhi_wl"
11854 [(match_operand:V2SI 0 "arith_reg_dest" "")
11855 (match_operand:V4HI 1 "arith_reg_operand" "")
11856 (match_operand:V4HI 2 "arith_reg_operand" "")]
11857 "TARGET_SHMEDIA"
11858 "
11859 {
11860 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11861 (operands[0], operands[1], operands[2]));
11862 DONE;
11863 }")
11864
11865 (define_expand "mmullo_wl"
11866 [(match_operand:V2SI 0 "arith_reg_dest" "")
11867 (match_operand:V4HI 1 "arith_reg_operand" "")
11868 (match_operand:V4HI 2 "arith_reg_operand" "")]
11869 "TARGET_SHMEDIA"
11870 "
11871 {
11872 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11873 (operands[0], operands[1], operands[2]));
11874 DONE;
11875 }")
11876
11877 (define_insn "mmul23_wl"
11878 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11879 (vec_select:V2SI
11880 (mult:V4SI
11881 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11882 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11883 (parallel [(const_int 2) (const_int 3)])))]
11884 "TARGET_SHMEDIA"
11885 "* return (TARGET_LITTLE_ENDIAN
11886 ? \"mmulhi.wl %1, %2, %0\"
11887 : \"mmullo.wl %1, %2, %0\");"
11888 [(set_attr "type" "dmpy_media")
11889 (set (attr "highpart")
11890 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11891 (const_string "user")))])
11892
11893 (define_insn "mmul01_wl"
11894 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11895 (vec_select:V2SI
11896 (mult:V4SI
11897 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11898 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11899 (parallel [(const_int 0) (const_int 1)])))]
11900 "TARGET_SHMEDIA"
11901 "* return (TARGET_LITTLE_ENDIAN
11902 ? \"mmullo.wl %1, %2, %0\"
11903 : \"mmulhi.wl %1, %2, %0\");"
11904 [(set_attr "type" "dmpy_media")
11905 (set (attr "highpart")
11906 (cond [(eq_attr "endian" "little") (const_string "ignore")]
11907 (const_string "user")))])
11908
11909
11910 (define_expand "mmulsum_wq"
11911 [(match_operand:DI 0 "arith_reg_dest" "")
11912 (match_operand:V4HI 1 "arith_reg_operand" "")
11913 (match_operand:V4HI 2 "arith_reg_operand" "")
11914 (match_operand:DI 3 "arith_reg_operand" "")]
11915 "TARGET_SHMEDIA"
11916 "
11917 {
11918 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11919 operands[1], operands[2]));
11920 DONE;
11921 }")
11922
11923 (define_insn "mmulsum_wq_i"
11924 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11925 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11926 (plus:DI
11927 (plus:DI
11928 (vec_select:DI
11929 (mult:V4DI
11930 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11931 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11932 (parallel [(const_int 0)]))
11933 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11934 (sign_extend:V4DI (match_dup 3)))
11935 (parallel [(const_int 1)])))
11936 (plus:DI
11937 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11938 (sign_extend:V4DI (match_dup 3)))
11939 (parallel [(const_int 2)]))
11940 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11941 (sign_extend:V4DI (match_dup 3)))
11942 (parallel [(const_int 3)]))))))]
11943 "TARGET_SHMEDIA"
11944 "mmulsum.wq %2, %3, %0"
11945 [(set_attr "type" "mac_media")])
11946
11947 (define_expand "mperm_w"
11948 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11949 (match_operand:V4HI 1 "arith_reg_operand" "r")
11950 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11951 "TARGET_SHMEDIA"
11952 "
11953 {
11954 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11955 (operands[0], operands[1], operands[2]));
11956 DONE;
11957 }")
11958
11959 ; This use of vec_select isn't exactly correct according to rtl.texi
11960 ; (because not constant), but it seems a straightforward extension.
11961 (define_insn "mperm_w_little"
11962 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11963 (vec_select:V4HI
11964 (match_operand:V4HI 1 "arith_reg_operand" "r")
11965 (parallel
11966 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11967 (const_int 2) (const_int 0))
11968 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11969 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11970 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11971 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11972 "mperm.w %1, %N2, %0"
11973 [(set_attr "type" "arith_media")])
11974
11975 (define_insn "mperm_w_big"
11976 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11977 (vec_select:V4HI
11978 (match_operand:V4HI 1 "arith_reg_operand" "r")
11979 (parallel
11980 [(zero_extract:QI (not:QI (match_operand:QI 2
11981 "extend_reg_or_0_operand" "rZ"))
11982 (const_int 2) (const_int 0))
11983 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11984 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11985 (zero_extract:QI (not:QI (match_dup 2))
11986 (const_int 2) (const_int 6))])))]
11987 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11988 "mperm.w %1, %N2, %0"
11989 [(set_attr "type" "arith_media")])
11990
11991 (define_insn "mperm_w0"
11992 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11993 (vec_duplicate:V4HI (truncate:HI (match_operand 1
11994 "trunc_hi_operand" "r"))))]
11995 "TARGET_SHMEDIA"
11996 "mperm.w %1, r63, %0"
11997 [(set_attr "type" "arith_media")
11998 (set_attr "highpart" "ignore")])
11999
12000 (define_expand "msad_ubq"
12001 [(match_operand:DI 0 "arith_reg_dest" "")
12002 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12003 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12004 (match_operand:DI 3 "arith_reg_operand" "")]
12005 "TARGET_SHMEDIA"
12006 "
12007 {
12008 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12009 operands[1], operands[2]));
12010 DONE;
12011 }")
12012
12013 (define_insn "msad_ubq_i"
12014 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12015 (plus:DI
12016 (plus:DI
12017 (plus:DI
12018 (plus:DI
12019 (match_operand:DI 1 "arith_reg_operand" "0")
12020 (abs:DI (vec_select:DI
12021 (minus:V8DI
12022 (zero_extend:V8DI
12023 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12024 (zero_extend:V8DI
12025 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12026 (parallel [(const_int 0)]))))
12027 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12028 (zero_extend:V8DI (match_dup 3)))
12029 (parallel [(const_int 1)]))))
12030 (plus:DI
12031 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12032 (zero_extend:V8DI (match_dup 3)))
12033 (parallel [(const_int 2)])))
12034 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12035 (zero_extend:V8DI (match_dup 3)))
12036 (parallel [(const_int 3)])))))
12037 (plus:DI
12038 (plus:DI
12039 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12040 (zero_extend:V8DI (match_dup 3)))
12041 (parallel [(const_int 4)])))
12042 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12043 (zero_extend:V8DI (match_dup 3)))
12044 (parallel [(const_int 5)]))))
12045 (plus:DI
12046 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12047 (zero_extend:V8DI (match_dup 3)))
12048 (parallel [(const_int 6)])))
12049 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12050 (zero_extend:V8DI (match_dup 3)))
12051 (parallel [(const_int 7)])))))))]
12052 "TARGET_SHMEDIA"
12053 "msad.ubq %N2, %N3, %0"
12054 [(set_attr "type" "mac_media")])
12055
12056 (define_insn "mshalds_l"
12057 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12058 (ss_truncate:V2SI
12059 (ashift:V2DI
12060 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12061 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12062 (const_int 31)))))]
12063 "TARGET_SHMEDIA"
12064 "mshalds.l %1, %2, %0"
12065 [(set_attr "type" "mcmp_media")
12066 (set_attr "highpart" "depend")])
12067
12068 (define_insn "mshalds_w"
12069 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12070 (ss_truncate:V4HI
12071 (ashift:V4SI
12072 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12073 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12074 (const_int 15)))))]
12075 "TARGET_SHMEDIA"
12076 "mshalds.w %1, %2, %0"
12077 [(set_attr "type" "mcmp_media")
12078 (set_attr "highpart" "depend")])
12079
12080 (define_insn "ashrv2si3"
12081 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12082 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12083 (match_operand:DI 2 "arith_reg_operand" "r")))]
12084 "TARGET_SHMEDIA"
12085 "mshard.l %1, %2, %0"
12086 [(set_attr "type" "arith_media")
12087 (set_attr "highpart" "depend")])
12088
12089 (define_insn "ashrv4hi3"
12090 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12091 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12092 (match_operand:DI 2 "arith_reg_operand" "r")))]
12093 "TARGET_SHMEDIA"
12094 "mshard.w %1, %2, %0"
12095 [(set_attr "type" "arith_media")
12096 (set_attr "highpart" "depend")])
12097
12098 (define_insn "mshards_q"
12099 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12100 (ss_truncate:HI
12101 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12102 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12103 "TARGET_SHMEDIA"
12104 "mshards.q %1, %N2, %0"
12105 [(set_attr "type" "mcmp_media")])
12106
12107 (define_expand "mshfhi_b"
12108 [(match_operand:V8QI 0 "arith_reg_dest" "")
12109 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12110 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12111 "TARGET_SHMEDIA"
12112 "
12113 {
12114 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12115 (operands[0], operands[1], operands[2]));
12116 DONE;
12117 }")
12118
12119 (define_expand "mshflo_b"
12120 [(match_operand:V8QI 0 "arith_reg_dest" "")
12121 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12122 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12123 "TARGET_SHMEDIA"
12124 "
12125 {
12126 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12127 (operands[0], operands[1], operands[2]));
12128 DONE;
12129 }")
12130
12131 (define_insn "mshf4_b"
12132 [(set
12133 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12134 (vec_select:V8QI
12135 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12136 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12137 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12138 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12139 "TARGET_SHMEDIA"
12140 "* return (TARGET_LITTLE_ENDIAN
12141 ? \"mshfhi.b %N1, %N2, %0\"
12142 : \"mshflo.b %N1, %N2, %0\");"
12143 [(set_attr "type" "arith_media")
12144 (set (attr "highpart")
12145 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12146 (const_string "user")))])
12147
12148 (define_insn "mshf0_b"
12149 [(set
12150 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12151 (vec_select:V8QI
12152 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12153 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12154 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12155 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12156 "TARGET_SHMEDIA"
12157 "* return (TARGET_LITTLE_ENDIAN
12158 ? \"mshflo.b %N1, %N2, %0\"
12159 : \"mshfhi.b %N1, %N2, %0\");"
12160 [(set_attr "type" "arith_media")
12161 (set (attr "highpart")
12162 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12163 (const_string "user")))])
12164
12165 (define_expand "mshfhi_l"
12166 [(match_operand:V2SI 0 "arith_reg_dest" "")
12167 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12168 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12169 "TARGET_SHMEDIA"
12170 "
12171 {
12172 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12173 (operands[0], operands[1], operands[2]));
12174 DONE;
12175 }")
12176
12177 (define_expand "mshflo_l"
12178 [(match_operand:V2SI 0 "arith_reg_dest" "")
12179 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12180 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12181 "TARGET_SHMEDIA"
12182 "
12183 {
12184 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12185 (operands[0], operands[1], operands[2]));
12186 DONE;
12187 }")
12188
12189 (define_insn "mshf4_l"
12190 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12191 (vec_select:V2SI
12192 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12193 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12194 (parallel [(const_int 1) (const_int 3)])))]
12195 "TARGET_SHMEDIA"
12196 "* return (TARGET_LITTLE_ENDIAN
12197 ? \"mshfhi.l %N1, %N2, %0\"
12198 : \"mshflo.l %N1, %N2, %0\");"
12199 [(set_attr "type" "arith_media")
12200 (set (attr "highpart")
12201 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12202 (const_string "user")))])
12203
12204 (define_insn "mshf0_l"
12205 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12206 (vec_select:V2SI
12207 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12208 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12209 (parallel [(const_int 0) (const_int 2)])))]
12210 "TARGET_SHMEDIA"
12211 "* return (TARGET_LITTLE_ENDIAN
12212 ? \"mshflo.l %N1, %N2, %0\"
12213 : \"mshfhi.l %N1, %N2, %0\");"
12214 [(set_attr "type" "arith_media")
12215 (set (attr "highpart")
12216 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12217 (const_string "user")))])
12218
12219 (define_expand "mshfhi_w"
12220 [(match_operand:V4HI 0 "arith_reg_dest" "")
12221 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12222 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12223 "TARGET_SHMEDIA"
12224 "
12225 {
12226 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12227 (operands[0], operands[1], operands[2]));
12228 DONE;
12229 }")
12230
12231 (define_expand "mshflo_w"
12232 [(match_operand:V4HI 0 "arith_reg_dest" "")
12233 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12234 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12235 "TARGET_SHMEDIA"
12236 "
12237 {
12238 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12239 (operands[0], operands[1], operands[2]));
12240 DONE;
12241 }")
12242
12243 (define_insn "mshf4_w"
12244 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12245 (vec_select:V4HI
12246 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12247 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12248 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12249 "TARGET_SHMEDIA"
12250 "* return (TARGET_LITTLE_ENDIAN
12251 ? \"mshfhi.w %N1, %N2, %0\"
12252 : \"mshflo.w %N1, %N2, %0\");"
12253 [(set_attr "type" "arith_media")
12254 (set (attr "highpart")
12255 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12256 (const_string "user")))])
12257
12258 (define_insn "mshf0_w"
12259 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12260 (vec_select:V4HI
12261 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12262 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12263 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12264 "TARGET_SHMEDIA"
12265 "* return (TARGET_LITTLE_ENDIAN
12266 ? \"mshflo.w %N1, %N2, %0\"
12267 : \"mshfhi.w %N1, %N2, %0\");"
12268 [(set_attr "type" "arith_media")
12269 (set (attr "highpart")
12270 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12271 (const_string "user")))])
12272
12273 (define_insn "mshflo_w_x"
12274 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12275 (vec_select:V4HI
12276 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12277 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12278 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12279 "TARGET_SHMEDIA"
12280 "mshflo.w %N1, %N2, %0"
12281 [(set_attr "type" "arith_media")
12282 (set_attr "highpart" "ignore")])
12283
12284 /* These are useful to expand ANDs and as combiner patterns. */
12285 (define_insn_and_split "mshfhi_l_di"
12286 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12287 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12288 (const_int 32))
12289 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12290 (const_int -4294967296))))]
12291 "TARGET_SHMEDIA"
12292 "@
12293 mshfhi.l %N1, %N2, %0
12294 #"
12295 "TARGET_SHMEDIA && reload_completed
12296 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12297 [(set (match_dup 3) (match_dup 4))
12298 (set (match_dup 5) (match_dup 6))]
12299 "
12300 {
12301 operands[3] = gen_lowpart (SImode, operands[0]);
12302 operands[4] = gen_highpart (SImode, operands[1]);
12303 operands[5] = gen_highpart (SImode, operands[0]);
12304 operands[6] = gen_highpart (SImode, operands[2]);
12305 }"
12306 [(set_attr "type" "arith_media")])
12307
12308 (define_insn "*mshfhi_l_di_rev"
12309 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12310 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12311 (const_int -4294967296))
12312 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12313 (const_int 32))))]
12314 "TARGET_SHMEDIA"
12315 "mshfhi.l %N2, %N1, %0"
12316 [(set_attr "type" "arith_media")])
12317
12318 (define_split
12319 [(set (match_operand:DI 0 "arith_reg_dest" "")
12320 (ior:DI (zero_extend:DI (match_operand:SI 1
12321 "extend_reg_or_0_operand" ""))
12322 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12323 (const_int -4294967296))))
12324 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12325 "TARGET_SHMEDIA"
12326 [(const_int 0)]
12327 "
12328 {
12329 emit_insn (gen_ashldi3_media (operands[3],
12330 simplify_gen_subreg (DImode, operands[1],
12331 SImode, 0),
12332 GEN_INT (32)));
12333 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12334 DONE;
12335 }")
12336
12337 (define_insn "mshflo_l_di"
12338 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12339 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12340 (const_int 4294967295))
12341 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12342 (const_int 32))))]
12343
12344 "TARGET_SHMEDIA"
12345 "mshflo.l %N1, %N2, %0"
12346 [(set_attr "type" "arith_media")
12347 (set_attr "highpart" "ignore")])
12348
12349 (define_insn "*mshflo_l_di_rev"
12350 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12351 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12352 (const_int 32))
12353 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12354 (const_int 4294967295))))]
12355
12356 "TARGET_SHMEDIA"
12357 "mshflo.l %N2, %N1, %0"
12358 [(set_attr "type" "arith_media")
12359 (set_attr "highpart" "ignore")])
12360
12361 ;; Combiner pattern for trampoline initialization.
12362 (define_insn_and_split "*double_shori"
12363 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12364 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12365 (const_int 32))
12366 (match_operand:DI 2 "const_int_operand" "n")))]
12367 "TARGET_SHMEDIA
12368 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12369 "#"
12370 "rtx_equal_p (operands[0], operands[1])"
12371 [(const_int 0)]
12372 "
12373 {
12374 HOST_WIDE_INT v = INTVAL (operands[2]);
12375
12376 emit_insn (gen_shori_media (operands[0], operands[0],
12377 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12378 emit_insn (gen_shori_media (operands[0], operands[0],
12379 gen_int_mode (v, HImode)));
12380 DONE;
12381 }"
12382 [(set_attr "highpart" "ignore")])
12383
12384
12385 (define_insn "*mshflo_l_di_x"
12386 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12387 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12388 "rZ"))
12389 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12390 (const_int 32))))]
12391
12392 "TARGET_SHMEDIA"
12393 "mshflo.l %N1, %N2, %0"
12394 [(set_attr "type" "arith_media")
12395 (set_attr "highpart" "ignore")])
12396
12397 (define_insn_and_split "concat_v2sf"
12398 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12399 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12400 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12401 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12402
12403 "TARGET_SHMEDIA"
12404 "@
12405 mshflo.l %N1, %N2, %0
12406 #
12407 #"
12408 "TARGET_SHMEDIA && reload_completed
12409 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12410 [(set (match_dup 3) (match_dup 1))
12411 (set (match_dup 4) (match_dup 2))]
12412 "
12413 {
12414 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12415 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12416 }"
12417 [(set_attr "type" "arith_media")
12418 (set_attr "highpart" "ignore")])
12419
12420 (define_insn "*mshflo_l_di_x_rev"
12421 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12422 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12423 (const_int 32))
12424 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12425
12426 "TARGET_SHMEDIA"
12427 "mshflo.l %N2, %N1, %0"
12428 [(set_attr "type" "arith_media")
12429 (set_attr "highpart" "ignore")])
12430
12431 (define_insn "ashlv2si3"
12432 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12433 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12434 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12435 "TARGET_SHMEDIA"
12436 "mshlld.l %1, %2, %0"
12437 [(set_attr "type" "arith_media")
12438 (set_attr "highpart" "depend")])
12439
12440 (define_split
12441 [(set (match_operand 0 "any_register_operand" "")
12442 (match_operator 3 "shift_operator"
12443 [(match_operand 1 "any_register_operand" "")
12444 (match_operand 2 "shift_count_reg_operand" "")]))]
12445 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12446 [(set (match_dup 0) (match_dup 3))]
12447 "
12448 {
12449 rtx count = operands[2];
12450 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12451
12452 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12453 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12454 || GET_CODE (count) == TRUNCATE)
12455 count = XEXP (count, 0);
12456 inner_mode = GET_MODE (count);
12457 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12458 subreg_lowpart_offset (outer_mode, inner_mode));
12459 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12460 operands[1], count);
12461 }")
12462
12463 (define_insn "ashlv4hi3"
12464 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12465 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12466 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12467 "TARGET_SHMEDIA"
12468 "mshlld.w %1, %2, %0"
12469 [(set_attr "type" "arith_media")
12470 (set_attr "highpart" "depend")])
12471
12472 (define_insn "lshrv2si3"
12473 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12474 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12475 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12476 "TARGET_SHMEDIA"
12477 "mshlrd.l %1, %2, %0"
12478 [(set_attr "type" "arith_media")
12479 (set_attr "highpart" "depend")])
12480
12481 (define_insn "lshrv4hi3"
12482 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12483 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12484 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12485 "TARGET_SHMEDIA"
12486 "mshlrd.w %1, %2, %0"
12487 [(set_attr "type" "arith_media")
12488 (set_attr "highpart" "depend")])
12489
12490 (define_insn "subv2si3"
12491 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12492 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12493 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12494 "TARGET_SHMEDIA"
12495 "msub.l %N1, %2, %0"
12496 [(set_attr "type" "arith_media")
12497 (set_attr "highpart" "depend")])
12498
12499 (define_insn "subv4hi3"
12500 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12501 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12502 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12503 "TARGET_SHMEDIA"
12504 "msub.w %N1, %2, %0"
12505 [(set_attr "type" "arith_media")
12506 (set_attr "highpart" "depend")])
12507
12508 (define_insn_and_split "subv2hi3"
12509 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12510 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12511 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12512 "TARGET_SHMEDIA"
12513 "#"
12514 "TARGET_SHMEDIA"
12515 [(const_int 0)]
12516 "
12517 {
12518 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12519 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12520 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12521 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12522 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12523
12524 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12525 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12526 DONE;
12527 }"
12528 [(set_attr "highpart" "must_split")])
12529
12530 (define_insn "sssubv2si3"
12531 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12532 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12533 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12534 "TARGET_SHMEDIA"
12535 "msubs.l %N1, %2, %0"
12536 [(set_attr "type" "mcmp_media")
12537 (set_attr "highpart" "depend")])
12538
12539 (define_insn "ussubv8qi3"
12540 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12541 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12542 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12543 "TARGET_SHMEDIA"
12544 "msubs.ub %N1, %2, %0"
12545 [(set_attr "type" "mcmp_media")
12546 (set_attr "highpart" "depend")])
12547
12548 (define_insn "sssubv4hi3"
12549 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12550 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12551 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12552 "TARGET_SHMEDIA"
12553 "msubs.w %N1, %2, %0"
12554 [(set_attr "type" "mcmp_media")
12555 (set_attr "highpart" "depend")])
12556
12557 ;; Floating Point Intrinsics
12558
12559 (define_insn "fcosa_s"
12560 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12561 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12562 UNSPEC_FCOSA))]
12563 "TARGET_SHMEDIA"
12564 "fcosa.s %1, %0"
12565 [(set_attr "type" "atrans_media")])
12566
12567 (define_insn "fsina_s"
12568 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12569 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12570 UNSPEC_FSINA))]
12571 "TARGET_SHMEDIA"
12572 "fsina.s %1, %0"
12573 [(set_attr "type" "atrans_media")])
12574
12575 (define_insn "fipr"
12576 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12577 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12578 "fp_arith_reg_operand" "f")
12579 (match_operand:V4SF 2
12580 "fp_arith_reg_operand" "f"))
12581 (parallel [(const_int 0)]))
12582 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12583 (parallel [(const_int 1)])))
12584 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12585 (parallel [(const_int 2)]))
12586 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12587 (parallel [(const_int 3)])))))]
12588 "TARGET_SHMEDIA"
12589 "fipr.s %1, %2, %0"
12590 [(set_attr "type" "fparith_media")])
12591
12592 (define_insn "fsrra_s"
12593 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12594 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12595 UNSPEC_FSRRA))]
12596 "TARGET_SHMEDIA"
12597 "fsrra.s %1, %0"
12598 [(set_attr "type" "atrans_media")])
12599
12600 (define_insn "ftrv"
12601 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12602 (plus:V4SF
12603 (plus:V4SF
12604 (mult:V4SF
12605 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12606 (parallel [(const_int 0) (const_int 5)
12607 (const_int 10) (const_int 15)]))
12608 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12609 (mult:V4SF
12610 (vec_select:V4SF (match_dup 1)
12611 (parallel [(const_int 4) (const_int 9)
12612 (const_int 14) (const_int 3)]))
12613 (vec_select:V4SF (match_dup 2)
12614 (parallel [(const_int 1) (const_int 2)
12615 (const_int 3) (const_int 0)]))))
12616 (plus:V4SF
12617 (mult:V4SF
12618 (vec_select:V4SF (match_dup 1)
12619 (parallel [(const_int 8) (const_int 13)
12620 (const_int 2) (const_int 7)]))
12621 (vec_select:V4SF (match_dup 2)
12622 (parallel [(const_int 2) (const_int 3)
12623 (const_int 0) (const_int 1)])))
12624 (mult:V4SF
12625 (vec_select:V4SF (match_dup 1)
12626 (parallel [(const_int 12) (const_int 1)
12627 (const_int 6) (const_int 11)]))
12628 (vec_select:V4SF (match_dup 2)
12629 (parallel [(const_int 3) (const_int 0)
12630 (const_int 1) (const_int 2)]))))))]
12631 "TARGET_SHMEDIA"
12632 "ftrv.s %1, %2, %0"
12633 [(set_attr "type" "fparith_media")])
12634
12635 (define_insn "ldhi_l"
12636 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12637 (zero_extract:SI
12638 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12639 (const_int 3))
12640 (const_int -3)))
12641 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12642 (const_int 0)))]
12643 "TARGET_SHMEDIA32"
12644 "ldhi.l %U1, %0"
12645 [(set_attr "type" "load_media")])
12646
12647 (define_insn "ldhi_q"
12648 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12649 (zero_extract:DI
12650 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12651 (const_int 7))
12652 (const_int -7)))
12653 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12654 (const_int 0)))]
12655 "TARGET_SHMEDIA32"
12656 "ldhi.q %U1, %0"
12657 [(set_attr "type" "load_media")])
12658
12659 (define_insn_and_split "*ldhi_q_comb0"
12660 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12661 (zero_extract:DI
12662 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12663 "register_operand" "r")
12664 (match_operand:SI 2
12665 "ua_offset" "I06"))
12666 (const_int 7))
12667 (const_int -7)))
12668 (plus:SI (and:SI (match_dup 1) (const_int 7))
12669 (const_int 1))
12670 (const_int 0)))]
12671 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12672 "#"
12673 ""
12674 [(pc)]
12675 "emit_insn (gen_ldhi_q (operands[0],
12676 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12677 DONE;")
12678
12679
12680 (define_insn_and_split "*ldhi_q_comb1"
12681 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12682 (zero_extract:DI
12683 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12684 "register_operand" "r")
12685 (match_operand:SI 2
12686 "ua_offset" "I06"))
12687 (const_int 7))
12688 (const_int -7)))
12689 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12690 "ua_offset" "I06"))
12691 (const_int 7))
12692 (const_int 1))
12693 (const_int 0)))]
12694 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12695 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12696 "#"
12697 ""
12698 [(pc)]
12699 "emit_insn (gen_ldhi_q (operands[0],
12700 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12701 DONE;")
12702
12703
12704 (define_insn "ldlo_l"
12705 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12706 (zero_extract:SI
12707 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12708 (const_int -4)))
12709 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12710 (and:SI (match_dup 1) (const_int 3))))]
12711 "TARGET_SHMEDIA32"
12712 "ldlo.l %U1, %0"
12713 [(set_attr "type" "load_media")])
12714
12715 (define_insn "ldlo_q"
12716 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12717 (zero_extract:DI
12718 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12719 (const_int -8)))
12720 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12721 (and:SI (match_dup 1) (const_int 7))))]
12722 "TARGET_SHMEDIA32"
12723 "ldlo.q %U1, %0"
12724 [(set_attr "type" "load_media")])
12725
12726 (define_insn_and_split "*ldlo_q_comb0"
12727 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12728 (zero_extract:DI
12729 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12730 (match_operand:SI 2 "ua_offset" "I06"))
12731 (const_int -8)))
12732 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12733 (and:SI (match_dup 1) (const_int 7))))]
12734 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12735 "#"
12736 ""
12737 [(pc)]
12738 "emit_insn (gen_ldlo_q (operands[0],
12739 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12740 DONE;")
12741
12742 (define_insn_and_split "*ldlo_q_comb1"
12743 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12744 (zero_extract:DI
12745 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12746 (match_operand:SI 2 "ua_offset" "I06"))
12747 (const_int -8)))
12748 (minus:SI (const_int 8)
12749 (and:SI (plus:SI (match_dup 1)
12750 (match_operand:SI 3 "ua_offset" "I06"))
12751 (const_int 7)))
12752 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12753 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12754 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12755 "#"
12756 ""
12757 [(pc)]
12758 "emit_insn (gen_ldlo_q (operands[0],
12759 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12760 DONE;")
12761
12762 (define_insn "sthi_l"
12763 [(set (zero_extract:SI
12764 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12765 (const_int 3))
12766 (const_int -3)))
12767 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12768 (const_int 0))
12769 (match_operand:SI 1 "arith_reg_operand" "r"))]
12770 "TARGET_SHMEDIA32"
12771 "sthi.l %U0, %1"
12772 [(set_attr "type" "ustore_media")])
12773
12774 ;; All unaligned stores are considered to be 'narrow' because they typically
12775 ;; operate on less that a quadword, and when they operate on a full quadword,
12776 ;; the vanilla store high / store low sequence will cause a stall if not
12777 ;; scheduled apart.
12778 (define_insn "sthi_q"
12779 [(set (zero_extract:DI
12780 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12781 (const_int 7))
12782 (const_int -7)))
12783 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12784 (const_int 0))
12785 (match_operand:DI 1 "arith_reg_operand" "r"))]
12786 "TARGET_SHMEDIA32"
12787 "sthi.q %U0, %1"
12788 [(set_attr "type" "ustore_media")])
12789
12790 (define_insn_and_split "*sthi_q_comb0"
12791 [(set (zero_extract:DI
12792 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12793 "register_operand" "r")
12794 (match_operand:SI 1 "ua_offset"
12795 "I06"))
12796 (const_int 7))
12797 (const_int -7)))
12798 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12799 (const_int 0))
12800 (match_operand:DI 2 "arith_reg_operand" "r"))]
12801 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12802 "#"
12803 ""
12804 [(pc)]
12805 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12806 operands[2]));
12807 DONE;")
12808
12809 (define_insn_and_split "*sthi_q_comb1"
12810 [(set (zero_extract:DI
12811 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12812 "register_operand" "r")
12813 (match_operand:SI 1 "ua_offset"
12814 "I06"))
12815 (const_int 7))
12816 (const_int -7)))
12817 (plus:SI (and:SI (plus:SI (match_dup 0)
12818 (match_operand:SI 2 "ua_offset" "I06"))
12819 (const_int 7))
12820 (const_int 1))
12821 (const_int 0))
12822 (match_operand:DI 3 "arith_reg_operand" "r"))]
12823 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12824 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12825 "#"
12826 ""
12827 [(pc)]
12828 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12829 operands[3]));
12830 DONE;")
12831
12832 ;; This is highpart user because the address is used as full 64 bit.
12833 (define_insn "stlo_l"
12834 [(set (zero_extract:SI
12835 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12836 (const_int -4)))
12837 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12838 (and:SI (match_dup 0) (const_int 3)))
12839 (match_operand:SI 1 "arith_reg_operand" "r"))]
12840 "TARGET_SHMEDIA32"
12841 "stlo.l %U0, %1"
12842 [(set_attr "type" "ustore_media")])
12843
12844 (define_insn "stlo_q"
12845 [(set (zero_extract:DI
12846 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12847 (const_int -8)))
12848 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12849 (and:SI (match_dup 0) (const_int 7)))
12850 (match_operand:DI 1 "arith_reg_operand" "r"))]
12851 "TARGET_SHMEDIA32"
12852 "stlo.q %U0, %1"
12853 [(set_attr "type" "ustore_media")])
12854
12855 (define_insn_and_split "*stlo_q_comb0"
12856 [(set (zero_extract:DI
12857 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12858 (match_operand:SI 1 "ua_offset" "I06"))
12859 (const_int -8)))
12860 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12861 (and:SI (match_dup 0) (const_int 7)))
12862 (match_operand:DI 2 "arith_reg_operand" "r"))]
12863 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12864 "#"
12865 ""
12866 [(pc)]
12867 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12868 operands[2]));
12869 DONE;")
12870
12871 (define_insn_and_split "*stlo_q_comb1"
12872 [(set (zero_extract:DI
12873 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12874 (match_operand:SI 1 "ua_offset" "I06"))
12875 (const_int -8)))
12876 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12877 (match_operand:SI 2
12878 "ua_offset" "I06"))
12879 (const_int 7)))
12880 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12881 (match_operand:DI 3 "arith_reg_operand" "r"))]
12882 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12883 "#"
12884 ""
12885 [(pc)]
12886 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12887 operands[3]));
12888 DONE;")
12889
12890 (define_insn "ldhi_l64"
12891 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12892 (zero_extract:SI
12893 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12894 (const_int 3))
12895 (const_int -3)))
12896 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12897 (const_int 0)))]
12898 "TARGET_SHMEDIA64"
12899 "ldhi.l %U1, %0"
12900 [(set_attr "type" "load_media")])
12901
12902 (define_insn "ldhi_q64"
12903 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12904 (zero_extract:DI
12905 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12906 (const_int 7))
12907 (const_int -7)))
12908 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12909 (const_int 0)))]
12910 "TARGET_SHMEDIA64"
12911 "ldhi.q %U1, %0"
12912 [(set_attr "type" "load_media")])
12913
12914 (define_insn "ldlo_l64"
12915 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12916 (zero_extract:SI
12917 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12918 (const_int -4)))
12919 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12920 (and:DI (match_dup 1) (const_int 3))))]
12921 "TARGET_SHMEDIA64"
12922 "ldlo.l %U1, %0"
12923 [(set_attr "type" "load_media")])
12924
12925 (define_insn "ldlo_q64"
12926 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12927 (zero_extract:DI
12928 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12929 (const_int -8)))
12930 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12931 (and:DI (match_dup 1) (const_int 7))))]
12932 "TARGET_SHMEDIA64"
12933 "ldlo.q %U1, %0"
12934 [(set_attr "type" "load_media")])
12935
12936 (define_insn "sthi_l64"
12937 [(set (zero_extract:SI
12938 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12939 (const_int 3))
12940 (const_int -3)))
12941 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12942 (const_int 0))
12943 (match_operand:SI 1 "arith_reg_operand" "r"))]
12944 "TARGET_SHMEDIA64"
12945 "sthi.l %U0, %1"
12946 [(set_attr "type" "ustore_media")])
12947
12948 (define_insn "sthi_q64"
12949 [(set (zero_extract:DI
12950 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12951 (const_int 7))
12952 (const_int -7)))
12953 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12954 (const_int 0))
12955 (match_operand:DI 1 "arith_reg_operand" "r"))]
12956 "TARGET_SHMEDIA64"
12957 "sthi.q %U0, %1"
12958 [(set_attr "type" "ustore_media")])
12959
12960 (define_insn "stlo_l64"
12961 [(set (zero_extract:SI
12962 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12963 (const_int -4)))
12964 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12965 (and:DI (match_dup 0) (const_int 3)))
12966 (match_operand:SI 1 "arith_reg_operand" "r"))]
12967 "TARGET_SHMEDIA64"
12968 "stlo.l %U0, %1"
12969 [(set_attr "type" "ustore_media")])
12970
12971 (define_insn "stlo_q64"
12972 [(set (zero_extract:DI
12973 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12974 (const_int -8)))
12975 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12976 (and:DI (match_dup 0) (const_int 7)))
12977 (match_operand:DI 1 "arith_reg_operand" "r"))]
12978 "TARGET_SHMEDIA64"
12979 "stlo.q %U0, %1"
12980 [(set_attr "type" "ustore_media")])
12981
12982 (define_insn "nsb"
12983 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12984 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12985 UNSPEC_NSB))]
12986 "TARGET_SHMEDIA"
12987 "nsb %1, %0"
12988 [(set_attr "type" "arith_media")])
12989
12990 (define_insn "nsbsi"
12991 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12992 (zero_extend:SI
12993 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12994 UNSPEC_NSB)))]
12995 "TARGET_SHMEDIA"
12996 "nsb %1, %0"
12997 [(set_attr "type" "arith_media")])
12998
12999 (define_insn "nsbdi"
13000 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13001 (zero_extend:DI
13002 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13003 UNSPEC_NSB)))]
13004 "TARGET_SHMEDIA"
13005 "nsb %1, %0"
13006 [(set_attr "type" "arith_media")])
13007
13008 (define_expand "ffsdi2"
13009 [(set (match_operand:DI 0 "arith_reg_dest" "")
13010 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13011 "TARGET_SHMEDIA"
13012 "
13013 {
13014 rtx scratch = gen_reg_rtx (DImode);
13015 rtx last;
13016
13017 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13018 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13019 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13020 emit_insn (gen_nsbdi (scratch, scratch));
13021 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13022 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13023 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13024 REG_NOTES (last)
13025 = gen_rtx_EXPR_LIST (REG_EQUAL,
13026 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13027 DONE;
13028 }")
13029
13030 (define_expand "ffssi2"
13031 [(set (match_operand:SI 0 "arith_reg_dest" "")
13032 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13033 "TARGET_SHMEDIA"
13034 "
13035 {
13036 rtx scratch = gen_reg_rtx (SImode);
13037 rtx discratch = gen_reg_rtx (DImode);
13038 rtx last;
13039
13040 emit_insn (gen_adddi3 (discratch,
13041 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13042 constm1_rtx));
13043 emit_insn (gen_andcdi3 (discratch,
13044 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13045 discratch));
13046 emit_insn (gen_nsbsi (scratch, discratch));
13047 last = emit_insn (gen_subsi3 (operands[0],
13048 force_reg (SImode, GEN_INT (63)), scratch));
13049 REG_NOTES (last)
13050 = gen_rtx_EXPR_LIST (REG_EQUAL,
13051 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13052 DONE;
13053 }")
13054
13055 (define_insn "byterev"
13056 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13057 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13058 (parallel [(const_int 7) (const_int 6) (const_int 5)
13059 (const_int 4) (const_int 3) (const_int 2)
13060 (const_int 1) (const_int 0)])))]
13061 "TARGET_SHMEDIA"
13062 "byterev %1, %0"
13063 [(set_attr "type" "arith_media")])
13064
13065 (define_insn "*prefetch_media"
13066 [(prefetch (match_operand:QI 0 "address_operand" "p")
13067 (match_operand:SI 1 "const_int_operand" "n")
13068 (match_operand:SI 2 "const_int_operand" "n"))]
13069 "TARGET_SHMEDIA"
13070 "*
13071 {
13072 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13073 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13074 return \"\";
13075 }"
13076 [(set_attr "type" "other")])
13077
13078 (define_insn "*prefetch_i4"
13079 [(prefetch (match_operand:SI 0 "register_operand" "r")
13080 (match_operand:SI 1 "const_int_operand" "n")
13081 (match_operand:SI 2 "const_int_operand" "n"))]
13082 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13083 "*
13084 {
13085 return \"pref @%0\";
13086 }"
13087 [(set_attr "type" "other")])
13088
13089 (define_expand "prefetch"
13090 [(prefetch (match_operand 0 "address_operand" "p")
13091 (match_operand:SI 1 "const_int_operand" "n")
13092 (match_operand:SI 2 "const_int_operand" "n"))]
13093 "TARGET_HARD_SH4 || TARGET_SH5"
13094 "
13095 {
13096 if (GET_MODE (operands[0]) != Pmode
13097 || GET_CODE (operands[1]) != CONST_INT
13098 || GET_CODE (operands[2]) != CONST_INT)
13099 FAIL;
13100 if (! TARGET_SHMEDIA)
13101 operands[0] = force_reg (Pmode, operands[0]);
13102 }")
13103
13104 (define_insn "alloco_i"
13105 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13106 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13107 "TARGET_SHMEDIA32"
13108 "*
13109 {
13110 rtx xops[2];
13111
13112 if (GET_CODE (operands[0]) == PLUS)
13113 {
13114 xops[0] = XEXP (operands[0], 0);
13115 xops[1] = XEXP (operands[0], 1);
13116 }
13117 else
13118 {
13119 xops[0] = operands[0];
13120 xops[1] = const0_rtx;
13121 }
13122 output_asm_insn (\"alloco %0, %1\", xops);
13123 return \"\";
13124 }"
13125 [(set_attr "type" "other")])
13126
13127 (define_split
13128 [(set (match_operand 0 "any_register_operand" "")
13129 (match_operand 1 "" ""))]
13130 "TARGET_SHMEDIA && reload_completed"
13131 [(set (match_dup 0) (match_dup 1))]
13132 "
13133 {
13134 int n_changes = 0;
13135
13136 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13137 if (!n_changes)
13138 FAIL;
13139 }")
13140
13141 ; Stack Protector Patterns
13142
13143 (define_expand "stack_protect_set"
13144 [(set (match_operand 0 "memory_operand" "")
13145 (match_operand 1 "memory_operand" ""))]
13146 ""
13147 {
13148 if (TARGET_SHMEDIA)
13149 {
13150 if (TARGET_SHMEDIA64)
13151 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13152 else
13153 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13154 }
13155 else
13156 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13157
13158 DONE;
13159 })
13160
13161 (define_insn "stack_protect_set_si"
13162 [(set (match_operand:SI 0 "memory_operand" "=m")
13163 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13164 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13165 "!TARGET_SHMEDIA"
13166 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13167 [(set_attr "type" "other")
13168 (set_attr "length" "6")])
13169
13170 (define_insn "stack_protect_set_si_media"
13171 [(set (match_operand:SI 0 "memory_operand" "=m")
13172 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13173 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13174 "TARGET_SHMEDIA"
13175 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13176 [(set_attr "type" "other")
13177 (set_attr "length" "12")])
13178
13179 (define_insn "stack_protect_set_di_media"
13180 [(set (match_operand:DI 0 "memory_operand" "=m")
13181 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13182 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13183 "TARGET_SHMEDIA64"
13184 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13185 [(set_attr "type" "other")
13186 (set_attr "length" "12")])
13187
13188 (define_expand "stack_protect_test"
13189 [(match_operand 0 "memory_operand" "")
13190 (match_operand 1 "memory_operand" "")
13191 (match_operand 2 "" "")]
13192 ""
13193 {
13194 if (TARGET_SHMEDIA)
13195 {
13196 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13197
13198 if (TARGET_SHMEDIA64)
13199 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13200 operands[1]));
13201 else
13202 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13203 operands[1]));
13204
13205 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13206 }
13207 else
13208 {
13209 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13210 emit_jump_insn (gen_branch_true (operands[2]));
13211 }
13212
13213 DONE;
13214 })
13215
13216 (define_insn "stack_protect_test_si"
13217 [(set (reg:SI T_REG)
13218 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13219 (match_operand:SI 1 "memory_operand" "m")]
13220 UNSPEC_SP_TEST))
13221 (set (match_scratch:SI 2 "=&r") (const_int 0))
13222 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13223 "!TARGET_SHMEDIA"
13224 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13225 [(set_attr "type" "other")
13226 (set_attr "length" "10")])
13227
13228 (define_insn "stack_protect_test_si_media"
13229 [(set (match_operand:SI 0 "register_operand" "=&r")
13230 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13231 (match_operand:SI 2 "memory_operand" "m")]
13232 UNSPEC_SP_TEST))
13233 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13234 "TARGET_SHMEDIA"
13235 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13236 [(set_attr "type" "other")
13237 (set_attr "length" "16")])
13238
13239 (define_insn "stack_protect_test_di_media"
13240 [(set (match_operand:DI 0 "register_operand" "=&r")
13241 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13242 (match_operand:DI 2 "memory_operand" "m")]
13243 UNSPEC_SP_TEST))
13244 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13245 "TARGET_SHMEDIA64"
13246 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13247 [(set_attr "type" "other")
13248 (set_attr "length" "16")])